"public IP" is defined as an IP address configured on the exit node
itself that isn't in the list of forbidden ranges (RFC1918, CGNAT,
Tailscale).
Fixes#1522.
Signed-off-by: David Anderson <danderson@tailscale.com>
Windows was only running the localapi on the debug port which was a
stopgap at the time while doing peercreds work. Removed that, and
wired it up correctly, with some more docs.
More clean-up to do after 1.6, moving the localhost TCP auth code into
the peercreds package. But that's too much for now, so the docs will
have to suffice, even if it's at a bit of an awkward stage with the
newly-renamed "NotWindows" field, which still isn't named well, but
it's better than its old name of "Unknown" which hasn't been accurate
since unix sock peercreds work anyway.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
And if we have over 10,000 CGNAT routes, just route the entire
CGNAT range. (for the hello test server)
Fixes#1450
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Prior to e3df29d488, the Engine.SetLinkChangeCallback fired
immediately, even if there was no change. The ipnlocal code apparently
depended on that, and it broke integration tests (which live in
another repo). So mimic the old behavior and call the ipnlocal
callback immediately at init.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Gets it out of wgengine so the Engine isn't responsible for being a
callback registration hub for it.
This also removes the Engine.LinkChange method, as it's no longer
necessary. The monitor tells us about changes; it doesn't seem to
need any help. (Currently it was only used by Swift, but as of
14dc790137 we just do the same from Go)
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
And add a --socks5-server flag.
And fix a race in SOCKS5 replies where the response header was written
concurrently with the copy from the backend.
Co-authored with Naman Sood.
Updates #707
Updates #504
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
UIs need to see the full unedited netmap in order to know what exit nodes they
can offer to the user.
Signed-off-by: David Anderson <danderson@tailscale.com>
And open up socket permissions like Linux, now that we know who
connections are from.
This uses the new inet.af/peercred that supports Linux and Darwin at
the moment.
Fixes#1347Fixes#1348
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
If no exit node is specified, the filter must still run to remove
offered default routes from all peers.
Signed-off-by: David Anderson <danderson@tailscale.com>
This one alone doesn't modify the global dependency map much
(depaware.txt if anything looks slightly worse), but it leave
controlclient as only containing NetworkMap:
bradfitz@tsdev:~/src/tailscale.com/ipn$ grep -F "controlclient." *.go
backend.go: NetMap *controlclient.NetworkMap // new netmap received
fake_test.go: b.notify(Notify{NetMap: &controlclient.NetworkMap{}})
fake_test.go: b.notify(Notify{NetMap: &controlclient.NetworkMap{}})
handle.go: netmapCache *controlclient.NetworkMap
handle.go:func (h *Handle) NetMap() *controlclient.NetworkMap {
Once that goes into a leaf package, then ipn doesn't depend on
controlclient at all, and then the client gets smaller.
Updates #1278
And move a couple other types down into leafier packages.
Now cmd/tailscale doesn't bring in netlink, magicsock, wgengine, etc.
Fixes#1181
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Use tb.Cleanup to simplify both the API and the implementation.
One behavior change: When the number of goroutines shrinks, don't log.
I've never found these logs to be useful, and they frequently add noise.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This is mostly code movement from the wireguard-go repo.
Most of the new wgcfg package corresponds to the wireguard-go wgcfg package.
wgengine/wgcfg/device{_test}.go was device/config{_test}.go.
There were substantive but simple changes to device_test.go to remove
internal package device references.
The API of device.Config (now wgcfg.DeviceConfig) grew an error return;
we previously logged the error and threw it away.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This adds a new IP Protocol type, TSMP on protocol number 99 for
sending inter-tailscale messages over WireGuard, currently just for
why a peer rejects TCP SYNs (ACL rejection, shields up, and in the
future: nothing listening, something listening on that port but wrong
interface, etc)
Updates #1094
Updates tailscale/corp#1185
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This partially reverts d6e9fb1df0, which modified the permissions
on the tailscaled Unix socket and thus required "sudo tailscale" even
for "tailscale status".
Instead, open the permissions back up (on Linux only) but have the
server look at the peer creds and only permit read-only actions unless
you're root.
In the future we'll also have a group that can do mutable actions.
On OpenBSD and FreeBSD, the permissions on the socket remain locked
down to 0600 from d6e9fb1df0.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Not usefully functional yet (mostly a proof of concept), but getting
it submitted for some work @namansood is going to do atop this.
Updates #707
Updates #634
Updates #48
Updates #835
* show DNS name over hostname, removing domain's common MagicDNS suffix.
only show hostname if there's no DNS name.
but still show shared devices' MagicDNS FQDN.
* remove nerdy low-level details by default: endpoints, DERP relay,
public key. They're available in JSON mode still for those who need
them.
* only show endpoint or DERP relay when it's active with the goal of
making debugging easier. (so it's easier for users to understand
what's happening) The asterisks are gone.
* remove Tx/Rx numbers by default for idle peers; only show them when
there's traffic.
* include peers' owner login names
* add CLI option to not show peers (matching --self=true, --peers= also
defaults to true)
* sort by DNS/host name, not public key
* reorder columns
If any goroutine continues to use the logger in TestLocalLogLines
after the test finishes, the test panics.
The culprit for this was wireguard-go; the previous commit fixed that.
This commit adds suspenders: When the test is done, make logging calls
into no-ops.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
Previously the client had heuristics to calculate which DNS search domains
to set, based on the peers' names. Unfortunately that prevented us from
doing some things we wanted to do server-side related to node sharing.
So, bump MapRequest.Version to 9 to signal that the client only uses the
explicitly configured DNS search domains and doesn't augment it with its own
list.
Updates tailscale/corp#1026
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This is a replacement for the key-related parts
of the wireguard-go wgcfg package.
This is almost a straight copy/paste from the wgcfg package.
I have slightly changed some of the exported functions and types
to avoid stutter, added and tweaked some comments,
and removed some now-unused code.
To avoid having wireguard-go depend on this new package,
wgcfg will keep its key types.
We translate into and out of those types at the last minute.
These few remaining uses will be eliminated alongside
the rest of the wgcfg package.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
Addresses #964
Still to be done:
- Figure out the correct logging lines in util/systemd
- Figure out if we need to slip the systemd.Status function anywhere
else
- Log util/systemd errors? (most of the errors are of the "you cannot do
anything about this, but it might be a bad idea to crash the program if
it errors" kind)
Assistance in getting this over the finish line would help a lot.
Signed-off-by: Christine Dodrill <me@christine.website>
util/systemd: rename the nonlinux file to appease the magic
Signed-off-by: Christine Dodrill <me@christine.website>
util/systemd: fix package name
Signed-off-by: Christine Dodrill <me@christine.website>
util/systemd: fix review feedback from @mdlayher
Signed-off-by: Christine Dodrill <me@christine.website>
cmd/tailscale{,d}: update depaware manifests
Signed-off-by: Christine Dodrill <me@christine.website>
util/systemd: use sync.Once instead of func init
Signed-off-by: Christine Dodrill <me@christine.website>
control/controlclient: minor review feedback fixes
Signed-off-by: Christine Dodrill <me@christine.website>
{control,ipn,systemd}: fix review feedback
Signed-off-by: Christine Dodrill <me@christine.website>
review feedback fixes
Signed-off-by: Christine Dodrill <me@christine.website>
ipn: fix sprintf call
Signed-off-by: Christine Dodrill <me@christine.website>
ipn: make staticcheck less sad
Signed-off-by: Christine Dodrill <me@christine.website>
ipn: print IP address in connected status
Signed-off-by: Christine Dodrill <me@christine.website>
ipn: review feedback
Signed-off-by: Christine Dodrill <me@christine.website>
final fixups
Signed-off-by: Christine Dodrill <me@christine.website>
It appears some users have corrupted pref.conf files. Have LoadPrefs
treat these files as non-existent. This way tailscale will make user
login, and not crash.
Fixes#954
Signed-off-by: Alex Brainman <alex.brainman@gmail.com>
In 1.0, subnet relays were not specially handled when WPAD+PAC was
present on the network.
In 1.2, on Windows, subnet relays were disabled if WPAD+PAC was
present. That was what some users wanted, but not others.
This makes it configurable per domain, reverting back to the 1.0
default state of them not being special. Users who want that behavior
can then enable it.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We still use the packet.* alloc-free types in the data path, but
the compilation from netaddr to packet happens within the filter
package.
Signed-off-by: David Anderson <danderson@tailscale.com>
Seeing "frontend-provided legacy machine key" was weird (and not quite
accurate) on Linux machines where it comes from the _daemon key's
persist prefs, not the "frontend".
Make the log message distinguish between the cases.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
When the service was running without a client (e.g. after a reboot)
and then the owner logs in and the GUI attaches, the computed state
key changed to "" (driven by frontend prefs), and then it was falling
out of server mode, despite the GUI-provided prefs still saying it
wanted server mode.
Also add some logging. And remove a scary "Access denied" from a
user-visible error, making the two possible already-in-use error
messages consistent with each other.
On Windows, we were previously treating a server used by different
users as a fatal error, which meant the second user (upon starting
Tailscale, explicitly or via Start Up programs) got an invasive error
message dialog.
Instead, give it its own IPN state and change the Notify.ErrMessage to
be details in that state. Then the Windows GUI can be less aggresive
about that happening.
Also,
* wait to close the IPN connection until the server ownership state
changes so the GUI doesn't need to repeatedly reconnect to discover
changes.
* fix a bug discovered during testing: on system reboot, the
ipnserver's serverModeUser was getting cleared while the state
transitioned from Unknown to Running. Instead, track 'inServerMode'
explicitly and remove the old accessor method which was error prone.
* fix a rare bug where the client could start up and set the server
mode prefs in its Start call and we wouldn't persist that to the
StateStore storage's prefs start key. (Previously it was only via a
prefs toggle at runtime)
os.IsNotExist doesn't unwrap errors. errors.Is does.
The ioutil.ReadFile ones happened to be fine but I changed them so
we're consistent with the rule: if the error comes from os, you can
use os.IsNotExist, but from any other package, use errors.Is.
(errors.Is always would also work, but not worth updating all the code)
The motivation here was that we were logging about failure to migrate
legacy relay node prefs file on startup, even though the code tried
to avoid that.
See golang/go#41122
It was especially bad on our GUI platforms with a frontend that polls it.
No need to log it every few seconds if it's unchanged. Make it slightly
less allocate-y while I'm here.
If we can't find the mapping from SID ("user ID") -> username, don't
treat that as a fatal. Apparently that happens in the wild for Reasons.
Ignore it for now. It's just a nice-to-have for error messages in the
rare multi-user case.
Updates #869
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
When building with redo, also include the git commit hash
from the proprietary repo, so that we have a precise commit
that identifies all build info (including Go toolchain version).
Add a top-level build script demonstrating to downstream distros
how to burn the right information into builds.
Adjust `tailscale version` to print commit hashes when available.
Fixes#841.
Signed-off-by: David Anderson <danderson@tailscale.com>
Also replaces the IPv6Overlay bool with use of DebugFlags, since
it's currently an experimental configuration.
Signed-off-by: David Anderson <danderson@tailscale.com>
We were creating the controlclient and starting the portpoll concurrently,
which frequently resulted in the first controlclient connection being canceled
by the firsdt portpoll result ~milliseconds later, resulting in another
HTTP request.
Instead, wait a bit for the first portpoll result so it's much less likely to
interrupt our controlclient connection.
Updates tailscale/corp#557
This partially (but not yet fully) migrates Windows to tailscaled's
StateStore storage system.
This adds a new bool Pref, ForceDaemon, defined as:
// ForceDaemon specifies whether a platform that normally
// operates in "client mode" (that is, requires an active user
// logged in with the GUI app running) should keep running after the
// GUI ends and/or the user logs out.
//
// The only current applicable platform is Windows. This
// forced Windows to go into "server mode" where Tailscale is
// running even with no users logged in. This might also be
// used for macOS in the future. This setting has no effect
// for Linux/etc, which always operate in daemon mode.
Then, when ForceDaemon becomes true, we now write use the StateStore
to track which user started it in server mode, and store their prefs
under that key.
The ipnserver validates the connections/identities and informs that
LocalBackend which userid is currently in charge.
The GUI can then enable/disable server mode at runtime, without using
the CLI.
But the "tailscale up" CLI was also fixed, so Windows users can use
authkeys or ACL tags, etc.
Updates #275
It was previously possible for two different Windows users to connect
to the IPN server at once, but it didn't really work. They mostly
stepped on each other's toes and caused chaos.
Now only one can control it, but it can be active for everybody else.
Necessary dependency step for Windows server/headless mode (#275)
While here, finish wiring up the HTTP status page on Windows, now that
all the dependent pieces are available.
If no interfaces are up, calm down and stop spamming so much. It was
noticed as especially bad on Windows, but probably was bad
everywhere. I just have the best network conditions testing on a
Windows VM.
Updates #604
So previous routes aren't shadowing resources that the operating
system might need (Windows Domain Controller, DNS server, corp HTTP
proxy, WinHTTP fetching the PAC file itself, etc).
This effectively detects when we're transitioning from, say, public
wifi to corp wifi and makes Tailscale remove all its routes and stops
its TCP connections and tries connecting to everything anew.
Updates tailscale/corp#653
We depend on DERP for NAT traversal now[0] so disabling it entirely can't
work.
What we'll do instead in the future is let people specify
alternate/additional DERP servers. And perhaps in the future we could
also add a pref for nodes to say when they expect to never need/want
to use DERP for data (but allow it for NAT traversal communication).
But this isn't the right pref and it doesn't work, so delete it.
Fixes#318
[0] https://tailscale.com/blog/how-nat-traversal-works/
It's properly handled later in tsdns.NewMap anyway, but there's work
done in the meantime that can be skipped when a peer lacks a DNS name.
It's also more clear that it's okay for it to be blank.
Also remove rebinding logic from the windows router. Magicsock will
instead rebind based on link change signals.
Signed-off-by: David Anderson <danderson@tailscale.com>
The test's LocalBackend was not shut down (Shutdown both releases
resources and waits for its various goroutines to end). This should
fix the test race we were seeing. It definitely fixes the file
descriptor leak that preventing -race -count=500 from passing before.
Start of making the IPN state machine react to link changes and down
its DNS & routes if necessary to unblock proxy resolution (e.g. for
transitioning from public to corp networks where the corp network has
mandatory proxies and WPAD PAC files that can't be resolved while
using the DNS/routes configured previously)
This change should be a no-op. Just some callback plumbing.
For example:
$ tailscale ping -h
USAGE
ping <hostname-or-IP>
FLAGS
-c 10 max number of pings to send
-stop-once-direct true stop once a direct path is established
-verbose false verbose output
$ tailscale ping mon.ts.tailscale.com
pong from monitoring (100.88.178.64) via DERP(sfo) in 65ms
pong from monitoring (100.88.178.64) via DERP(sfo) in 252ms
pong from monitoring (100.88.178.64) via [2604:a880:2:d1::36:d001]:41641 in 33ms
Fixes#661
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Also, bit of behavior change: on non-nil err but expired context,
don't reset the consecutive failure count. I don't think the old
behavior was intentional.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
tailscaled receives a SIGPIPE when CLIs disconnect from it. We shouldn't
shut down in that case.
This reverts commit 43b271cb26.
Signed-off-by: David Anderson <danderson@tailscale.com>
ORder of operations to trigger a problem:
- Start an already authed tailscaled, verify you can ping stuff.
- Run `tailscale up`. Notice you can no longer ping stuff.
The problem is that `tailscale up` stops the IPN state machine before
restarting it, which zeros out the packet filter but _not_ the packet
filter hash. Then, upon restarting IPN, the uncleared hash incorrectly
makes the code conclude that the filter doesn't need updating, and so
we stay with a zero filter (reject everything) for ever.
The fix is simply to update the filterHash correctly in all cases,
so that running -> stopped -> running correctly changes the filter
at every transition.
Signed-off-by: David Anderson <danderson@tailscale.com>
We need to emit Prefs when it *has* changed, not when it hasn't.
Test is added in our e2e test, separately.
Fixes: #620
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
So a backend in server-an-error state (as used by Windows) can try to
create a new Engine again each time somebody re-connects, relaunching
the GUI app.
(The proper fix is actually fixing Windows issues, but this makes things better
in the short term)
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This prevents hostname being forced to os.Hostname despite override
when control is contacted for the first time after starting tailscaled.
Signed-off-by: Dmytro Shynkevych <dmytro@tailscale.com>
The StartLoginInteractive command is for delegating the sign-in flow
to a browser. The Android Gooogle Sign-In SDK inverts the flow by
giving the client ID tokens.
Add a new backend command for accepting such tokens by exposing the existing
controlclient.Client.Login support for OAuth2 tokens. Introduce a custom
TokenType to distinguish ID tokens from other OAuth2 tokens.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
We want the macOS Network Extension to share fate with the UI frontend,
so we need the backend to know when the frontend disappears.
One easy way to do that is to reuse the existing TCP server it's
already running (for tailscale status clietns).
We now tell the frontend our ephemeral TCP port number, and then have
the UI connect to it, so the backend can know when it disappears.
There are likely Swift ways of doing this, but I couldn't find them
quickly enough, so I reached for the hammer I knew.
This change adds to tsdns the ability to delegate lookups to upstream nameservers.
This is crucial for setting Magic DNS as the system resolver.
Signed-off-by: Dmytro Shynkevych <dmytro@tailscale.com>