If --until-direct is set, the goal is to make a direct connection.
If we failed at that, say so, and exit with an error.
RELNOTE=tailscale ping --until-direct (the default) now exits with
a non-zero exit code if no direct connection was established.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
Yes, it printed, but that was an implementation detail for hashing.
And coming optimization will make it print even less.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The old way was way too fragile and had felt like it had more special
cases than normal cases. (see #1874, #1860, #1834, etc) It became very
obvious the old algorithm didn't work when we made the output be
pretty and try to show the user the command they need to run in
5ecc7c7200 for #1746)
The new algorithm is to map the prefs (current and new) back to flags
and then compare flags. This nicely handles the OS-specific flags and
the n:1 and 1:n flag:pref cases.
No change in the existing already-massive test suite, except some ordering
differences (the missing items are now sorted), but some new tests are
added for behavior that was broken before. In particular, it now:
* preserves non-pref boolean flags set to false, and preserves exit
node IPs (mapping them back from the ExitNodeID pref, as well as
ExitNodeIP),
* doesn't ignore --advertise-exit-node when doing an EditPrefs call
(#1880)
* doesn't lose the --operator on the non-EditPrefs paths (e.g. with
--force-reauth, or when the backend was not in state Running).
Fixes#1880
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The --advertise-routes and --advertise-exit-node flags both mutating
one pref is the gift that keeps on giving.
I need to rewrite the this up warning code to first map prefs back to
flag values and then just compare flags instead of comparing prefs,
but this is the minimal fix for now.
This also includes work on the tests, to make them easier to write
(and more accurate), by letting you write the flag args directly and
have that parse into the upArgs/MaskedPrefs directly, the same as the
code, rather than them being possibly out of sync being written by
hand.
Fixes https://twitter.com/EXPbits/status/1390418145047887877
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This is needed because the original opts.Prefs field was at some point
subverted for use in frontend->backend state migration for backward
compatibility on some platforms. We still need that feature, but we
also need the feature of providing the full set of prefs from
`tailscale up`, *not* including overwriting the prefs.Persist keys, so
we can't use the original field from `tailscale up`.
`tailscale up` had attempted to compensate for that by doing SetPrefs()
before Start(), but that violates the ipn.Backend contract, which says
you should call Start() before anything else (that's why it's called
Start()). As a result, doing SetPrefs({ControlURL=...,
WantRunning=true}) would cause a connection to the *previous* control
server (because WantRunning=true), and then connect to the *new*
control server only after running Start().
This problem may have been avoided before, but only by pure luck.
It turned out to be relatively harmless since the connection to the old
control server was immediately closed and replaced anyway, but it
created a race condition that could have caused spurious notifications
or rejected keys if the server responded quickly.
As already covered by existing TODOs, a better fix would be to have
Start() get out of the business of state migration altogether. But
we're approaching a release so I want to make the minimum possible fix.
Fixes#1840.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
We were over-eager in running tailscale in GUI mode.
f42ded7acf fixed that by
checking for a variety of shell-ish env vars and using those
to force us into CLI mode.
However, for reasons I don't understand, those shell env vars
are present when Xcode runs Tailscale.app on my machine.
(I've changed no configs, modified nothing on a brand new machine.)
Work around that by adding an additional "only in GUI mode" check.
Signed-off-by: Josh Bleecher Snyder <josharian@gmail.com>
I was going to write a test for this using the tstest/integration test
stuff, but the testcontrol implementation isn't quite there yet (it
always registers nodes and doesn't provide AuthURLs). So, manually
tested for now.
Fixes#1843
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This fixes#1833 in two ways:
* stop setting NoSNAT on non-Linux. It only matters on Linux and the flag
is hidden on non-Linux, but the code was still setting it. Because of
that, the new pref-reverting safety checks were failing when it was
changing.
* Ignore the two Linux-only prefs changing on non-Linux.
Fixes#1833
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
There's no need to warn that it was not provided on the command line
after doing a sequence of up; logout; up --args. If you're asking for
tailscale to be up, you always mean that you prefer LoggedOut to become
false.
Fixes#1828
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
- Switch to our own simpler token bucket, since x/time/rate is missing
necessary stuff (can't provide your own time func; can't check the
current bucket contents) and it's overkill anyway.
- Add tests that actually include advancing time.
- Don't remove the rate limit on a message until there's enough room to
print at least two more of them. When we do, we'll also print how
many we dropped, as a contextual reminder that some were previously
lost. (This is more like how the Linux kernel does it.)
- Reformat the [RATE LIMITED] messages to be shorter, and to not
corrupt original message. Instead, we print the message, then print
its format string.
- Use %q instead of \"%s\", for more accurate parsing later, if the
format string contained quotes.
Fixes#1772
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
We had two separate code paths for the initial UDP listener bind
and any subsequent rebinds.
IPv6 got left out of the rebind code.
Rather than duplicate it there, unify the two code paths.
Then improve the resulting code:
* Rebind had nested listen attempts to try the user-specified port first,
and then fall back to :0 if that failed. Convert that into a loop.
* Initial bind tried only the user-specified port.
Rebind tried the user-specified port and 0.
But there are actually three ports of interest:
The one the user specified, the most recent port in use, and 0.
We now try all three in order, as appropriate.
* In the extremely rare case in which binding to port 0 fails,
use a dummy net.PacketConn whose reads block until close.
This will keep the wireguard-go receive func goroutine alive.
As a pleasant side-effect of this, if we decide that
we need to resuscitate #1796, it will now be much easier.
Fixes#1799
Co-authored-by: David Anderson <danderson@tailscale.com>
Signed-off-by: Josh Bleecher Snyder <josharian@gmail.com>
Assume it'll stay at 0 forever, so hard-code it
and delete code conditional on it being non-0.
Signed-off-by: Josh Bleecher Snyder <josharian@gmail.com>
NetworkManager fixed the bug that forced us to use NetworkManager
if it's programming systemd-resolved, and in the same release also
made NetworkManager ignore DNS settings provided for unmanaged
interfaces... Which breaks what we used to do. So, with versions
1.26.6 and above, we MUST NOT use NetworkManager to indirectly
program systemd-resolved, but thankfully we can talk to resolved
directly and get the right outcome.
Fixes#1788
Signed-off-by: David Anderson <danderson@tailscale.com>
The new "tailscale up" checks previously didn't protect against
--advertise-exit-node being omitted in the case that
--advertise-routes was also provided. It wasn't done before because
there is no corresponding pref for "--advertise-exit-node"; it's a
helper flag that augments --advertise-routes. But that's an
implementation detail and we can still help users. We just have to
special case that pref and look whether the current routes include
both the v4 and v6 /0 routes.
Fixes#1767
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This doesn't make --operator implicit (which we might do in the
future), but it at least doesn't require repeating it in the future
when it already matches $USER.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
With this change, the ipnserver's safesocket.Listen (the localhost
tcp.Listen) happens right away, before any synchronous
TUN/DNS/Engine/etc setup work, which might be slow, especially on
early boot on Windows.
Because the safesocket.Listen starts up early, that means localhost
TCP dials (the safesocket.Connect from the GUI) complete successfully
and thus the GUI avoids the MessageBox error. (I verified that
pacifies it, even without a Listener.Accept; I'd feared that Windows
localhost was maybe special and avoided the normal listener backlog).
Once the GUI can then connect immediately without errors, the various
timeouts then matter less, because the backend is no longer trying to
race against the GUI's timeout. So keep retrying on errors for a
minute, or 10 minutes if the system just booted in the past 10
minutes.
This should fix the problem with Windows 10 desktops auto-logging in
and starting the Tailscale frontend which was then showing a
MessageBox error about failing to connect to tailscaled, which was
slow coming up because the Windows networking stack wasn't up
yet. Fingers crossed.
Fixes#1313 (previously #1187, etc)
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This change implements Windows version of install-system-daemon and
uninstall-system-daemon subcommands. When running the commands the
user will install or remove Tailscale Windows service.
Updates #1232
Signed-off-by: Alex Brainman <alex.brainman@gmail.com>
Logout used to be a no-op, so the ipnserver previously synthensized a Logout
on disconnect. Now that Logout actually invalidates the node key that was
forcing all GUI closes to log people out.
Instead, add a method to LocalBackend to specifically mean "the
Windows GUI closed, please forget all the state".
Fixestailscale/corp#1591 (ignoring the notification issues, tracked elsewhere)
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
On macOS, we link the CLI into the GUI executable so it can be included in
the Mac App Store build.
You then need to run it like:
/Applications/Tailscale.app/Contents/MacOS/Tailscale <command>
But our old detection of whether you're running that Tailscale binary
in CLI mode wasn't accurate and often bit people. For instance, when
they made a typo, it then launched in GUI mode and broke their
existing GUI connection (starting a new IPNExtension) and took down
their network.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The ipn.NewPrefs func returns a populated ipn.Prefs for historical
reasons. It's not used or as important as it once was, but it hasn't
yet been removed. Meanwhile, it contains some default values that are
used on some platforms. Notably, for this bug (#1725), Windows/Mac use
its Prefs.RouteAll true value (to accept subnets), but Linux users
have always gotten a "false" value for that, because that's what
cmd/tailscale's CLI default flag is _for all operating systems_. That
meant that "tailscale up" was rightfully reporting that the user was
changing an implicit setting: RouteAll was changing from true with
false with the user explicitly saying so.
An obvious fix might be to change ipn.NewPrefs to return
Prefs.RouteAll == false on some platforms, but the logic is
complicated by darwin: we want RouteAll true on windows, android, ios,
and the GUI mac app, but not the CLI tailscaled-on-macOS mode. But
even if we used build tags (e.g. the "redo" build tag) to determine
what the default is, that then means we have duplicated and differing
"defaults" between both the CLI up flags and ipn.NewPrefs. Furthering
that complication didn't seem like a good idea.
So, changing the NewPrefs defaults is too invasive at this stage of
the release, as is removing the NewPrefs func entirely.
Instead, tweak slightly the semantics of the ipn.Prefs.ControlURL
field. This now defines that a ControlURL of the empty string means
both "we're uninitialized" and also "just use the default".
Then, once we have the "empty-string-means-unintialized" semantics,
use that to suppress "tailscale up"'s recent implicit-setting-revert
checking safety net, if we've never initialized Tailscale yet.
And update/add tests.
Fixes#1725
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Will add more tests later but this locks in all the existing warnings
and errors at least, and some of the existing non-error behavior.
Mostly I want this to exist before I actually fix#1725.
Updates #1725
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
They were scattered/duplicated in misc places before.
It can't be in the client package itself for circular dep reasons.
This new package is basically tailcfg but for localhost
communications, instead of to control.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This changes the behavior of "tailscale up".
Previously "tailscale up" always did a new Start and reset all the settings.
Now "tailscale up" with no flags just brings the world [back] up.
(The opposite of "tailscale down").
But with flags, "tailscale up" now only is allowed to change
preferences if they're explicitly named in the flags. Otherwise it's
an error. Or you need to use --reset to explicitly nuke everything.
RELNOTE=tailscale up change
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It was only Linux and BSDs before, but now with netstack mode, it also works on
Windows and darwin. It's not worth limiting it to certain platforms.
Tailscaled itself can complain/fail if it doesn't like the settings
for the mode/OS it's operating under.
Updates #707
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We already had SetNotifyCallback elsewhere on controlclient, so use
that name.
Baby steps towards some CLI refactor work.
Updates tailscale/tailscale#1436
This is usually the same as the requested interface, but on some
unixes can vary based on device number allocation, and on Windows
it's the GUID instead of the pretty name, since everything relating
to configuration wants the GUID.
Signed-off-by: David Anderson <danderson@tailscale.com>
Upstream wireguard-go has changed its receive model.
NewDevice now accepts a conn.Bind interface.
The conn.Bind is stateless; magicsock.Conns are stateful.
To work around this, we add a connBind type that supports
cheap teardown and bring-up, backed by a Conn.
The new conn.Bind allows us to specify a set of receive functions,
rather than having to shoehorn everything into ReceiveIPv4 and ReceiveIPv6.
This lets us plumbing DERP messages directly into wireguard-go,
instead of having to mux them via ReceiveIPv4.
One consequence of the new conn.Bind layer is that
closing the wireguard-go device is now indistinguishable
from the routine bring-up and tear-down normally experienced
by a conn.Bind. We thus have to explicitly close the magicsock.Conn
when the close the wireguard-go device.
One downside of this change is that we are reliant on wireguard-go
to call receiveDERP to process DERP messages. This is fine for now,
but is perhaps something we should fix in the future.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
The bool was already called useNetstack at the caller.
isUserspace (to mean netstack) is confusing next to wgengine.NewUserspaceEngine, as that's
a different type of 'userspace'.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The resolver still only supports a single upstream config, and
ipn/wgengine still have to split up the DNS config, but this moves
closer to unifying the DNS configs.
As a handy side-effect of the refactor, IPv6 MagicDNS records exist
now.
Signed-off-by: David Anderson <danderson@tailscale.com>
This adds a new ipn.MaskedPrefs embedding a ipn.Prefs, along with a
bunch of "has bits", kept in sync with tests & reflect.
Then it adds a Prefs.ApplyEdits(MaskedPrefs) method.
Then the ipn.Backend interface loses its weirdo SetWantRunning(bool)
method (that I added in 483141094c for "tailscale down")
and replaces it with EditPrefs (alongside the existing SetPrefs for now).
Then updates 'tailscale down' to use EditPrefs instead of SetWantRunning.
In the future, we can use this to do more interesting things with the
CLI, reconfiguring only certain properties without the reset-the-world
"tailscale up".
Updates #1436
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Adding a subcommand which prints and logs a log marker. This should help
diagnose any issues that users face.
Fixes#1466
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Instead of having the CLI check whether IP forwarding is enabled, ask
tailscaled. It has a better idea. If it's netstack, for instance, the
sysctl values don't matter. And it's possible that only the daemon has
permission to know.
Fixes#1626
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Without this, `tailscale status` ignores the --socket flag on macOS and
always talks to the IPNExtension, even if you wanted it to inspect a
userspace tailscaled.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
For discovery when an explicit hostname/IP is known. We'll still
also send it via control for finding peers by a list.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This makes setup more explicit in prod codepaths, without
requiring a bunch of arguments or helpers for tests and
userspace mode.
Signed-off-by: David Anderson <danderson@tailscale.com>
control/controlclient: sign RegisterRequest
Some customers wish to verify eligibility for devices to join their
tailnets using machine identity certificates. TLS client certs could
potentially fulfill this role but the initial customer for this feature
has technical requirements that prevent their use. Instead, the
certificate is loaded from the Windows local machine certificate store
and uses its RSA public key to sign the RegisterRequest message.
There is room to improve the flexibility of this feature in future and
it is currently only tested on Windows (although Darwin theoretically
works too), but this offers a reasonable starting place for now.
Updates tailscale/coral#6
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
So we can empty import the guts of cmd/tailscaled from another
module for go mod tidy reasons.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This adds an easy and portable way for us to document how to get
your Tailscale IP address.
$ tailscale ip
100.74.70.3
fd7a:115c:a1e0:ab12:4843:cd96:624a:4603
$ tailscale ip -4
100.74.70.3
$ tailscale ip -6
fd7a:115c:a1e0:ab12:4843:cd96:624a:4603
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Add proto to flowtrack.Tuple.
Add types/ipproto leaf package to break a cycle.
Server-side ACL work remains.
Updates #1516
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Mash up some code from ffcli and std's flag package to make a default
usage func that's super explicit for those not familiar with the Go
style flags. Only show double hyphens in usage text (but still accept both),
and show default values, and only show the proper usage of boolean flags.
Fixes#1353Fixes#1529
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This reverts the revert commit 84aba349d9.
And changes us to use inet.af/netstack.
Updates #1518
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
gVisor fixed their google/gvisor#1446 so we can include gVisor mode
on 32-bit machines.
A few minor upstream API changes, as normal.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This change makes it impossible to set your own IP address as the exit node for this system.
Fixes#1489
Signed-off-by: Christine Dodrill <xe@tailscale.com>
This reverts commit 08949d4ef1.
I think this code was aspirational. There's no code that sets up the
appropriate NAT code using pfctl/etc. See #911 and #1475.
Updates #1475
Updates #911
The debub subcommand was moved in
6254efb9ef because the monitor brought
in tons of dependencies to the cmd/tailscale binary, but there wasn't
any need to remove the whole subcommand itself.
Add it back, with a tool to dump the local daemon's goroutines.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Part of overall effort to clean up, unify, use link monitoring more,
and make Tailscale quieter when all networks are down. This is especially
bad on macOS where we can get killed for not being polite it seems.
(But we should be polite in any case)
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>
Currently it assumes exactly 1 registered callback. This changes it to
support 0, 1, or more than 1.
This is a step towards plumbing wgengine/monitor into more places (and
moving some of wgengine's interface state fetching into monitor in a
later step)
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
For option (d) of #1405.
For an HTTPS request of /bootstrap-dns, this returns e.g.:
{
"log.tailscale.io": [
"2600:1f14:436:d603:342:4c0d:2df9:191b",
"34.210.105.16"
],
"login.tailscale.com": [
"2a05:d014:386:203:f8b4:1d5a:f163:e187",
"3.121.18.47"
]
}
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
* move probing out of netcheck into new net/portmapper package
* use PCP ANNOUNCE op codes for PCP discovery, rather than causing
short-lived (sub-second) side effects with a 1-second-expiring map +
delete.
* track when we heard things from the router so we can be less wasteful
in querying the router's port mapping services in the future
* use portmapper from magicsock to map a public port
Fixes#1298Fixes#1080Fixes#1001
Updates #864
Signed-off-by: Brad Fitzpatrick <bradfitz@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>
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>
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>
Rewrite log lines on the fly, based on the set of known peers.
This enables us to use upstream wireguard-go logging,
but maintain the Tailscale-style peer public key identifiers
that the rest of our systems (and people) expect.
Fixes#1183
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This eliminates a dependency on wgcfg.Endpoint,
as part of the effort to eliminate our wireguard-go fork.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This makes connectivity between ancient and new tailscale nodes slightly
worse in some cases, but only in cases where the ancient version would
likely have failed to get connectivity anyway.
Signed-off-by: David Anderson <danderson@tailscale.com>
netaddr.IP no longer allocates, so don't need a cache or all its associated
code/complexity.
This totally removes groupcache/lru from the deps.
Also go mod tidy.
* wengine/netstack: bump gvisor to latest version
Signed-off-by: Naman Sood <naman@tailscale.com>
* update dependencies
Signed-off-by: Naman Sood <naman@tailscale.com>
* Don't change hardcoded IP
Signed-off-by: Naman Sood <naman@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
Research in issue #1063 uncovered why tailscaled would fail with
ProtectClock enabled (it implicitly enabled DevicePolicy=closed).
This knowledge in turn also opens the door for locking down /dev
further, e.g. explicitly setting DevicePolicy=strict (instead of
closed), and making /dev private for the unit.
Additional possible future (or downstream) lockdown that can be done
is setting `PrivateDevices=true` (with `BindPaths=/dev/net/`), however,
systemd 233 or later is required for this, and tailscaled currently need
to work for systemd down to version 215.
Closes https://github.com/tailscale/tailscale/issues/1063
Signed-off-by: Frederik “Freso” S. Olesen <freso.dk@gmail.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>
While not a full capability lockdown of the systemd unit, this still
improves sandboxing and security of the running process a good deal.
Signed-off-by: Frederik “Freso” S. Olesen <freso.dk@gmail.com>
Log levels can now be specified with "[v1] " or "[v2] " substrings
that are then stripped and filtered at the final logger. This follows
our existing "[unexpected]" etc convention and doesn't require a
wholesale reworking of our logging at the moment.
cmd/tailscaled then gets a new --verbose=N flag to take a log level
that controls what gets logged to stderr (and thus systemd, syslog,
etc). Logtail is unaffected by --verbose.
This commit doesn't add annotations to any existing log prints. That
is in the next commit.
Updates #924
Updates #282
Signed-off-by: Brad Fitzpatrick <bradfitz@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>
Upgrading staticcheck upgraded golang.org/x/sync
(one downside of mixing our tools in with our regular go.mod),
which introduced a new dependency via
https://go-review.googlesource.com/c/sync/+/251677
That CL could and probably should be written without runtime/debug,
but it's not clear to me that that is better at this moment
than simply accepting the additional package as a dependency.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
Cache DNS results of earlier login.tailscale.com control dials, and use
them for future dials if DNS is slow or broken.
Fixes various issues with trickier setups with the domain's DNS server
behind a subnet router.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
These accidentally make the tag syntax more flexible than was intended,
which will create forward compatibility problems later. Let's go back
to the old stricter parser.
Revert "cmd/tailscale/cli: fix double tag: prefix in tailscale up"
Revert "cmd/tailscale/cli, tailcfg: allow tag without "tag:" prefix in 'tailscale up'"
This reverts commit a702921620.
This reverts commit cd07437ade.
Affects #861.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
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
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>
The RusagePrefixLog is rarely useful, hasn't been useful in a long
time, is rarely the measurement we need, and is pretty spammy (and
syscall-heavy). Disable it by default. We can enable it when we're
debugging memory.
Use golang.zx2c4.com/wireguard/windows/tunnel/winipcfg
instead of github.com/tailscale/winipcfg-go package.
Updates #760
Signed-off-by: Alex Brainman <alex.brainman@gmail.com>
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
When the network link changes, existing UDP sockets fail immediately
and permanently on macOS.
The forwarder set up a single UDP conn and never changed it.
As a result, any time there was a network link change,
all forwarded DNS queries failed.
To fix this, create a new connection when send requests
fail because of network unreachability.
This change is darwin-only, although extended it to other platforms
should be straightforward.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
Part of unforking our winipcfg-go and using upstream (#760), move our
additions into our repo. (We might upstream them later if upstream has
interest)
Originally these were:
@apenwarr: "Add ifc.SyncAddresses() and SyncRoutes()."
609dcf2df5
@bradfitz: "winipcfg: make Interface.AddRoutes do as much as possible, return combined error"
e9f93d53f3
@bradfitz: "prevent unnecessary Interface.SyncAddresses work; normalize IPNets in deltaNets"
decb9ee8e1
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/
This change is to restore /etc/resolv.conf after tailscale down is called. This is done by setting the dns.Manager before errors occur. Error collection is also added.
Fixes#723
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>
For now. Get it working again so it's not stuck on 0.98.
Subnet relay can come later.
Updates #451
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This Clone function knows how to clone any types
for which it has generated Clone methods.
This allows callers to efficiently clone
an inbound interface{} that might contain one of these types.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This was causing any type to be reported as found,
as long as there were any type decls at all. Oops.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
If you change a struct and don't re-run cloner,
your Cloner method might be inaccurate, leading to bad things.
To prevent this, write out the struct as it is at the moment that
cloner is caller, and attempt a conversion from that type.
If the struct gets changed in any way, this conversion will fail.
This will yield false positives: If you change a non-pointer field,
you will be forced to re-run cloner, even though the actual generated
code won't change. I think this is an acceptable cost: It is a minor
annoyance, which will prevent real bugs.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* advertise server's DERP public key following its ServerHello
* have client look for that DEPR public key in the response
PeerCertificates
* let client advertise it's going into a "fast start" mode
if it finds it
* modify server to support that fast start mode, just not
sending the HTTP response header
Cuts down another round trip, bringing the latency of being able to
write our first DERP frame from SF to Bangalore from ~725ms
(3 RTT) to ~481ms (2 RTT: TCP and TLS).
Fixes#693
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
This will make it easier for a human to tell what
version is deployed, for (say) correlating line numbers
in profiles or panics to corresponding source code.
It'll also let us observe version changes in prometheus.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
SIGPIPE can be generated when CLIs disconnect from tailscaled. This
should not terminate the process.
Signed-off-by: David Anderson <danderson@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>
It appears that systemd has sensible defaults for limiting
crash loops:
DefaultStartLimitIntervalSec=10s
DefaultStartLimitBurst=5
Remove our insta-restart configuration so that it works.
Signed-off-by: David Crawshaw <crawshaw@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>
There's a lot of confusion around what tailscale status shows, so make it better:
show region names, last write time, and put stars around DERP too if active.
Now stars are always present if activity, and always somewhere.
The remove hook implementation was copy/pasted from the line above and
I didn't change the body, resulting in packet forwarding routes never
being removed.
Fortunately we weren't using this path yet, but it led to stats being
off, and (very) slow memory growth.
The magicsock derpReader was holding onto 65KB for each DERP
connection forever, just in case.
Make the derp{,http}.Client be in charge of memory instead. It can
reuse its bufio.Reader buffer space.
This lets a trusted DERP client that knows a pre-shared key subscribe
to the connection list. Upon subscribing, they get the current set
of connected public keys, and then all changes over time.
This lets a set of DERP server peers within a region all stay connected to
each other and know which clients are connected to which nodes.
Updates #388
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The flags were --no-blah for a brief time, then we switched them to
--blah=true/false with a default of true, but didn't fix the boolean
inversions in the code. So up was down, true was false, etc.
Signed-off-by: David Anderson <danderson@tailscale.com>
Also:
* add -verbose flag to cmd/tailscale netcheck
* remove some API from the interfaces package
* convert some of the interfaces package to netaddr.IP
* don't even send IPv4 probes on machines with no IPv4 (or only v4
loopback)
* and once three regions have replied, stop waiting for other probes
at 2x the slowest duration.
Updates #376
On startup, and when switching into =off and =nodivert, we were
deleting netfilter rules even if we weren't the ones that added them.
In order to avoid interfering with rules added by the sysadmin, we have
to be sure to delete rules only in the case that we added them in the
first place.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
Let's actually list the file we checked
(/proc/sys/net/ipv4/ip_forward). That gives the admin something
specific to look for when they get this message.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
We would print a message about "nothing more to do", which some people
thought was an error or warning. Let's only print a message after
authenticating if we previously asked for interaction, and let's
shorten that message to just "Success," which is what it means.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
Instead of hard-coding the DERP map (except for cmd/tailscale netcheck
for now), get it from the control server at runtime.
And make the DERP map support multiple nodes per region with clients
picking the first one that's available. (The server will balance the
order presented to clients for load balancing)
This deletes the stunner package, merging it into the netcheck package
instead, to minimize all the config hooks that would've been
required.
Also fix some test flakes & races.
Fixes#387 (Don't hard-code the DERP map)
Updates #388 (Add DERP region support)
Fixes#399 (wgengine: flaky tests)
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
- Reformat the warning about a message being rate limited to print the
format string, rather than the formatted message. This helps give a
clue what "type" of message is being limited.
- Change the rate limit warning to be [RATE LIMITED] in all caps. This
uses less space on each line, plus is more noticeable.
- In tailscaled, change the frequency to be less often (once every 5
seconds per format string) but to allow bursts of up to 5 messages.
This greatly reduces the number of messages that are rate limited
during startup, but allows us to tighten the limit even further during
normal runtime.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
This cuts RSS from ~30MB to ~20MB on my machine, after the previous fix
to get rid of unnecessary zstd buffers.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
Also stop logging data sent/received from nodes we're not connected to (ie all those `x`s being logged in the `peers: ` line)
Signed-off-by: Wendi <wendi.yu@yahoo.ca>
For "tailscale status" on macOS (from separately downloaded
cmd/tailscale binary against App Store IPNExtension).
(This isn't all of it, but I've had this sitting around uncommitted.)
Implement rate limiting on log messages
Addresses issue #317, where logs can get spammed with the same message
nonstop. Created a rate limiting closure on logging functions, which
limits the number of messages being logged per second based on format
string. To keep memory usage as constant as possible, the previous cache
purging at periodic time intervals has been replaced by an LRU that
discards the oldest string when the capacity of the cache is reached.
Signed-off-by: Wendi Yu <wendi.yu@yahoo.ca>
These will be used for dynamically changing the identity of a node, so
its ACL rights can be different from your own.
Note: Not all implemented yet on the server side, but we need this so
we can request the tagged rights in the first place.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
This sets a default packet filter that blocks all incoming requests,
giving end users more control over who can get into their machine, even
if the admin hasn't set any central ACLs.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
The name's been bugging me for a long time.
I liked neither the overlap between tsweb.Handler and http.Handler,
nor the name "ServeHTTPErr" which sounds like it's an error being
returned, like it's an error handler and not sometimes a happy path.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This avoids the server blocking on misbehaving or heavily contended
clients. We attempt to drop from the head of the queue to keep
overall queueing time lower.
Also:
- fixes server->client keepalives, which weren't happening.
- removes read rate-limiter, deferring instead to kernel-level
global limiter/fair queuer.
Signed-off-by: David Anderson <dave@natulte.net>
This removes the need for go-cmp, which is extremely bloaty so we had
to leave it out of iOS. As a result, we had also left it out of macOS,
and so we didn't print netmap diffs at all on darwin-based platforms.
Oops.
As a bonus, the output format of the new function is way better.
Minor oddity: because I used the dumbest possible diff algorithm, the
sort order is a bit dumb. We print all "removed" lines and then print
all "added" lines, rather than doing the usual diff-like thing of
interspersing them. This probably doesn't matter (maybe it's an
improvement).
Basically, don't trust the OS-level link monitor to only tell you
interesting things. Sanity check it.
Also, move the interfaces package into the net directory now that we
have it.
The device name "tailscale0" will be used for all platforms except for
OpenBSD where "tun" is enforced by the kernel. `CreateTUN()` in
`wireguard-go` will select the next available "tunX" device name on the
OpenBSD system.
Signed-off-by: Martin Baillie <martin@baillie.email>
This lets us publish sets of vars that are breakdowns along one
dimension in a format that Prometheus and Grafana natively know
how to do useful things with.
Signed-off-by: David Anderson <dave@natulte.net>
Both RPM and Deb require us to specify both Replaces and Conflicts:
Conflicts tells them that the packages cannot coexist on the system,
Replaces tells them which one to keep.
Two commands for now, `up` and `netcheck`. The commands and the flags they take
will change a bunch in the future, but this is good enough to launch on parity
with relaynode.
Signed-Off-By: David Anderson <dave@natulte.net>
* adds new packet "netcheck" to do the checking of UDP, IPv6, and
nearest DERP server, and the Report type for all that (and more
in the future, probably pulling in danderson's natprobe)
* new tailcfg.NetInfo type
* cmd/tailscale netcheck subcommand (tentative name, likely to
change/move) to print out the netcheck.Report.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Prefs has become a heavy object with non-memcpy copy
semantics. We should not pass such a thing by value.
Signed-off-by: David Anderson <dave@natulte.net>
relaynode itself is not long for this world, deprecated in favour of
tailscale/tailscaled. But now that the control server supports central
distribution of packet filters, let's actually take advantage of it in
a final, backward compatible release of relaynode.
The autoselection should pick sensible paths for all of:
- Windows (LocalAppData)
- Mac (Library/Caches)
- Unix user (XDG_CACHE_DIR)
- Linux systemd service (CACHE_DIRECTORY)
As a last resort, if cache dir lookup fails, plops sufficiently
uniquely named files into the current working directory.
Signed-off-by: David Anderson <dave@natulte.net>
We can't rely on a frontend to provide a control
server URL, so this naturally belongs in server-persisted
state.
Signed-off-by: David Anderson <dave@natulte.net>
Port number has to be by itself for substitution to work.
Disabling the restart rate-limiting has to be in [Unit] not
[Service].
Signed-off-by: David Anderson <dave@natulte.net>
On unix, we want to provide a full path to the desired unix socket.
On windows, currently we want to provide a TCP port, but someday
we'll also provide a "path-ish" object for a named pipe.
For now, simplify the API down to exactly a path and a TCP port.
Signed-off-by: David Anderson <dave@natulte.net>
With this change, tailscaled can be restarted and reconnect
without interaction from `tailscale`, and `tailscale` is merely
there to provide login assistance and adjust preferences.
Signed-off-by: David Anderson <dave@natulte.net>
* make RouterGen return an error, not take both tunname and tundev
* also remove RouteGen taking a wireguard/device.Device; currently unused
* remove derp parameter (it'll work differently)
* unexport NewUserspaceRouter in per-OS impls, add documented wrapper
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It was previously used by the MacOS client, but it now does
something different. ipnserver should never obey a client's
request to exit.
Signed-off-by: David Anderson <dave@natulte.net>
The store is passed-in by callers of NewLocalBackend and
ipnserver.Run, but currently all callers are hardcoded to
an in-memory store. The store is unused.
Signed-Off-By: David Anderson <dave@natulte.net>
This is a prelude to making it truly optional, once state
management has moved into the backend. For now though, it's
still required. This change is just isolating the bubbling-up
of the pointerification into other layers.
Signed-Off-By: David Anderson <dave@natulte.net>
- It was only used in one currently-unused client.
- It's an imperative command, not a configuration setting.
- The LoginFlags stuff in controlclient feels like it needs
a refactor anyway.
I'll put this logic back once ipnd owns its state and Backend
commands reflect that.
Signed-Off-By: David Anderson <dave@natulte.net>
OpenBSD tunnel names are prefixed with `tun`.
Controlling the port allows for deterministic configuration of firewall
rules (using `pf` in this case).
Signed-off-by: Martin Baillie <martin@baillie.email>
It seems changelog generation got broken by moving the code between
corp and OSS repos, because one of the commit SHAs doesn't have an
associated tag.
In the interest of fixing the build, and because we're not yet trying
to upstream the debian package, I fixed this by allowing hash-based
versions to show up in the changelog. This maybe wrong from a
debian standards perspective, but for our current point in life
it'll work until we learn to do it better.
Signed-Off-By: David Anderson <dave@natulte.net>