With #6566 we started to more aggressively bind to the default interface
on Darwin. We are seeing some reports of the wrong cellular interface
being chosen on iOS. To help with the investigation, this adds to knobs
to control the behavior changes:
- CapabilityDebugDisableAlternateDefaultRouteInterface disables the
alternate function that we use to get the default interface on macOS
and iOS (implemented in tailscale/corp#8201). We still log what it
would have returned so we can see if it gets things wrong.
- CapabilityDebugDisableBindConnToInterface is a bigger hammer that
disables binding of connections to the default interface altogether.
Updates #7184
Updates #7188
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
We stopped writing network lock keys as separate items with #6315,
the constant is no longer used.
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Previously, we only printed these at startup; print those when the user
generates a bugreport as we so we don't have to go spelunking through
the logs.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: If5b0970f09fcb4cf8839958af5d37f84e0ba6ed2
The profileManager was using the LoginName as a proxy to figure out if the profile
had logged in, however the LoginName is not present if the node was created with an
Auth Key that does not have an associated user.
Signed-off-by: Maisem Ali <maisem@tailscale.com>
We now handle the case where the NetworkMap.SelfNode has already expired
and do not return an expiry time in the past (which causes an ~infinite
loop of timers to fire).
Additionally, we now add an explicit check to ensure that the next
expiry time is never before the current local-to-the-system time, to
ensure that we don't end up in a similar situation due to clock skew.
Finally, we add more tests for this logic to ensure that we don't
regress on these edge cases.
Fixes#7193
Change-Id: Iaf8e3d83be1d133a7aab7f8d62939e508cc53f9c
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Having this information near the "user bugreport" line makes it easier
to identify the node and expiry without spelunking through the rest of
the logs.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I1597c783efc06574fa4c8f211e68d835f20b6ccb
If the user passes the --diagnose flag, print a warning if any of the
default or fallback DNS resolvers are Tailscale IPs. This can interfere
with the ability to connect to the controlplane, and is typically
something to pay attention to if there's a connectivity issue.
Change-Id: Ib14bf6228c037877fbdcd22b069212b1a4b2c456
Signed-off-by: Andrew Dunham <andrew@tailscale.com>
Updates #7123
Updates #6257 (more to do in other repos)
Change-Id: I073e2a6d81a5d7fbecc29caddb7e057ff65239d0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We can log too quickly for logtail to catch up, even when we opt out of
log rate-limiting. When the user passes the --diagnose flag to
bugreport, we use a token bucket to control how many logs per second are
printed and sleep until we're able to write more.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: If27672d66b621b589280bd0fe228de367ffcbd8f
The iOS has a command to reset the persisted state of the app, but it
was doing its own direct keychain manipulation. This proved to be
brittle (since we changed how preferences are stored with #6022), so
we instead add a LocalAPI endpoint to do do this, which can be updated
in tandem.
This clears the same state as the iOS implementation (tailscale/corp#3186),
that is the machine key and preferences (which includes the node key).
Notably this does not clear the logtail ID, so that logs from the device
still end up in the same place.
Updates tailscale/corp#8923
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
This updates all source files to use a new standard header for copyright
and license declaration. Notably, copyright no longer includes a date,
and we now use the standard SPDX-License-Identifier header.
This commit was done almost entirely mechanically with perl, and then
some minimal manual fixes.
Updates #6865
Signed-off-by: Will Norris <will@tailscale.com>
When turned on via environment variable (off by default), this will use
the BSD routing APIs to query what interface index a socket should be
bound to, rather than binding to the default interface in all cases.
Updates #5719
Updates #5940
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ib4c919471f377b7a08cd3413f8e8caacb29fee0b
This allows users to temporarily enable/disable dnscache logging via a
new node capability, to aid in debugging strange connectivity issues.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I46cf2596a8ae4c1913880a78d0033f8b668edc08
The current node isn't in NetMap.Peers, so without this we would not
have fired this timer on self expiry.
Updates #6932
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Id57f96985397e372f9226802d63b42ff92c95093
On macOS (AppStore and macsys), we need to bind to ""/all-interfaces
due to the network sandbox. Ideally we would only bind to the
Tailscale interface, but macOS errors out if we try to
to listen on privileged ports binding only to a specific
interface.
We also implement the lc.Control hook, same as we do for
peerapi. It doesn't solve our problem but it's better that
we do and would likely be required when Apple gets around to
fixing per-interface priviliged port binding.
Fixes: #6364
Signed-off-by: Shayne Sweeney <shayne@tailscale.com>
They changed a type in their SDK which meant others using the AWS APIs
in their Go programs (with newer AWS modules in their caller go.mod)
and then depending on Tailscale (for e.g. tsnet) then couldn't compile
ipn/store/awsstore.
Thanks to @thisisaaronland for bringing this up.
Fixes#7019
Change-Id: I8d2919183dabd6045a96120bb52940a9bb27193b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This change delays the first flush in the /watch-ipn-bus/ handler
until after the watcher has been successfully installed on the IPN
bus. It does this by adding a new onWatchAdded callback to
LocalBackend.WatchNotifications().
Without this, the endpoint returns a 200 almost immediatly, and
only then installs a watcher for IPN events. This means there's a
small window where events could be missed by clients after calling
WatchIPNBus().
Fixestailscale/corp#8594.
Signed-off-by: salman <salman@tailscale.com>
In order to be able to synthesize a new NetMap when a node expires, have
LocalBackend start a timer when receiving a new NetMap that fires
slightly after the next node expires. Additionally, move the logic that
updates expired nodes into LocalBackend so it runs on every netmap
(whether received from controlclient or self-triggered).
Updates #6932
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I833390e16ad188983eac29eb34cc7574f555f2f3
Needed for clients that get information via the /v0/status LocalAPI
endpoint (e.g. to not offer expired exit nodes as options).
Updates tailscale/corp#8702
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
UI works remains, but data is there now.
Updates #4015
Change-Id: Ib91e94718b655ad60a63596e59468f3b3b102306
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Unsigned peers should not be allowed to generate Wake-on-Lan packets,
only access Funnel.
Updates #6934
Updates #7515
Updates #6475
Signed-off-by: James Tucker <james@tailscale.com>
For debugging #6423. This is easier than TS_DEBUG_MAP, as this means I
can pipe things into jq, etc.
Updates #6423
Change-Id: Ib3e7496b2eb3f47d4bed42e9b8045a441424b23c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This makes `tailscale debug watch-ipn` safe to use for troubleshooting
user issues, in addition to local debugging during development.
Signed-off-by: David Anderson <danderson@tailscale.com>
By default, `http.Transport` keeps idle connections open hoping to re-use them in the future. Combined with a separate transport per request in HTTP proxy this results in idle connection leak.
Fixes#6773
This ensures that we capture error returned by `Serve` and exit with a
non-zero exit code if it happens.
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
Use multierr.Range to iterate through an error tree
instead of multiple invocations of errors.As.
This scales better as we add more Go error types to the switch.
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Mainly motivated by wanting to know how much Taildrop is used, but
also useful when tracking down how many invalid requests are
generated.
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Nodes which have both -advertise-exit-node and -exit-node in prefs
should continue have them until the next invocation of `tailscale up`.
Updates #3569.
Signed-off-by: salman <salman@tailscale.com>
Fixes#6400
open up GETs for localapi serve-config to allow read-only access to
ServeConfig
`tailscale status` will include "Funnel on" status when Funnel is
configured. Prints nothing if Funnel is not running.
Example:
$ tailscale status
<nodes redacted>
# Funnel on:
# - https://node-name.corp.ts.net
# - https://node-name.corp.ts.net:8443
# - tcp://node-name.corp.ts.net:10000
Signed-off-by: Shayne Sweeney <shayne@tailscale.com>
* Do not print the status at the end of a successful operation
* Ensure the key of the current node is actually trusted to make these changes
Signed-off-by: Tom DNetto <tom@tailscale.com>
This handles the case where the inner *os.PathError is wrapped in
another error type, and additionally will redact errors of type
*os.LinkError. Finally, add tests to verify that redaction works.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ie83424ff6c85cdb29fb48b641330c495107aab7c
x/exp/slices now has ContainsFunc (golang/go#53983) so we can delete
our versions.
Change-Id: I5157a403bfc1b30e243bf31c8b611da25e995078
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
For testing of Windows GUI client.
Updates #6480
Change-Id: I42f7526d95723e14bed7085fb759e371b43aa9da
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Things are slightly less tangled now that we've migrated prefs to the
backend (and renamed the field to LegacyMigrationPrefs).
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
To simplify clients getting the initial state when they subscribe.
Change-Id: I2490a5ab2411253717c74265a46a98012b80db82
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
If user's fn returned false and never canceled their ctx, we never
stopped the NotifyWatchEngineUpdates goroutine.
This was introduced recently (this cycle).
Change-Id: I3453966ac71e00727296ddd237ef845782f4e52e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We were writing the error when getting the default interface before
setting the content type, so we'd get HTML treated as plain text.
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
The peerapi IPv6 listener has a nil listener.
But we didn't need the listener's address anyway, so don't
try to use it.
Change-Id: I8e8a1a895046d129a3683973e732d9bed82f3b02
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Previously, `TAILSCALE_USE_WIP_CODE` was needed to hit a bunch of the TKA paths. With
this change:
- Enablement codepaths (NetworkLockInit) and initialization codepaths (tkaBootstrapFromGenesisLocked via tkaSyncIfNeeded)
require either the WIP envknob or CapabilityTailnetLockAlpha.
- Normal operation codepaths (tkaSyncIfNeeded, tkaFilterNetmapLocked) require TKA to be initialized, or either-or the
envknob / capability.
- Auxillary commands (ie: changing tka keys) require TKA to be initialized.
The end result is that it shouldn't be possible to initialize TKA (or subsequently use any of its features) without being
sent the capability or setting the envknob on tailscaled yourself.
I've also pulled out a bunch of unnecessary checks for CanSupportNetworkLock().
Signed-off-by: Tom DNetto <tom@tailscale.com>
We merge/dedupe profiles based on UserID and NodeID, however we were not accounting for ControlURLs.
Updates #713
Signed-off-by: Maisem Ali <maisem@tailscale.com>
The Go style weirds people out so we try to stick to the more
well-known double hyphen style in docs.
Change-Id: Iad6db5c82cda37f6b7687eed7ecd9276f8fd94d6
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This reverts commit f1130421f0.
It was submitted with failing tests (go generate checks)
Requires a lot of API changes to fix so rolling back instead of
forward.
Change-Id: I024e8885c0ed44675d3028a662f386dda811f2ad
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We want users to have the freedom to start tailscaled with `-no-logs-no-support`,
but that is obviously in direct conflict with tailnets that have network logging
enabled.
When we detect that condition, we record the issue in health, notify the client,
set WantRunning=false, and bail.
We clear the item in health when a profile switch occurs, since it is a
per-tailnet condition that should not propagate across profiles.
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Only the macOS/iOS clients care about it still, so we'll move it
to their repo.
But keep a test that makes sure that LocalBackend continues to
implement it so we get an early warning sign before we break
macOS/iOS.
Change-Id: I56392b740fe55b4d28468b77124c821b5c46c22b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I added util/winutil/LookupPseudoUser, which essentially consists of the bits
that I am in the process of adding to Go's standard library.
We check the provided SID for "S-1-5-x" where 17 <= x <= 20 (which are the
known pseudo-users) and then manually populate a os/user.User struct with
the correct information.
Fixes https://github.com/tailscale/tailscale/issues/869
Fixes https://github.com/tailscale/tailscale/issues/2894
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
tailscaled on Windows had two entirely separate start-up paths for running
as a service vs in the foreground. It's been causing problems for ages.
This unifies the two paths, making them be the same as the path used
for every other platform.
Also, it uses the new async LocalBackend support in ipnserver.Server
so the Server can start serving HTTP immediately, even if tun takes
awhile to come up.
Updates #6535
Change-Id: Icc8c4f96d4887b54a024d7ac15ad11096b5a58cf
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We use this pattern in a number of places (in this repo and elsewhere)
and I was about to add a fourth to this repo which was crossing the line.
Add this type instead so they're all the same.
Also, we have another Set type (SliceSet, which tracks its keys in
order) in another repo we can move to this package later.
Change-Id: Ibbdcdba5443fae9b6956f63990bdb9e9443cefa9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This is step 1 of de-special-casing of Windows and letting the
LocalAPI HTTP server start serving immediately, even while the rest of
the world (notably the Engine and its TUN device) are being created,
which can take a few to dozens of seconds on Windows.
With this change, the ipnserver.New function changes to not take an
Engine and to return immediately, not returning an error, and let its
Run run immediately. If its ServeHTTP is called when it doesn't yet
have a LocalBackend, it returns an error. A TODO in there shows where
a future handler will serve status before an engine is available.
Future changes will:
* delete a bunch of tailscaled_windows.go code and use this new API
* add the ipnserver.Server ServerHTTP handler to await the engine
being available
* use that handler in the Windows GUI client
Updates #6522
Change-Id: Iae94e68c235e850b112a72ea24ad0e0959b568ee
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The "userID is empty everywhere but Windows" docs on lots of places
but not everywhere while using just a string type was getting
confusing. This makes a new type to wrap up those rules, however
weird/historical they might be.
Change-Id: I142e85a8e38760988d6c0c91d0efecedade81b9b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
So GUI clients don't need to poll for it.
We still poll internally (for now!) but that's still cheaper. And will
get much cheaper later, without having to modify clients once they
start sending this bit.
Change-Id: I36647b701c8d1fe197677e5eb76f6894e8ff79f7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We'll eventually remove it entirely, but for now move get it out of ipnserver
where it's distracting and move it to its sole caller.
Updates #6522
Change-Id: I9c6f6a91bf9a8e3c5ea997952b7c08c81723d447
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Now that everything's just HTTP, there's no longer a need to have a
header-sniffing net.Conn wraper that dispatches which route to
take. Refactor to just use an http.Server earlier instead.
Updates #6417
Change-Id: I12a2054db4e56f48660c46f81233db224fdc77cb
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It's only used by Windows. No need for it to be in ipn/ipnserver,
which we're trying to trim down.
Change-Id: Idf923ac8b6cdae8b5338ec26c16fb8b5ea548071
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Unused in this repo as of the earlier #6450 (300aba61a6)
and unused in the Windows GUI as of tailscale/corp#8065.
With this ipn.BackendServer is no longer used and could also be
removed from this repo. The macOS and iOS clients still temporarily
depend on it, but I can move it to that repo instead while and let its
migration proceed on its own schedule while we clean this repo up.
Updates #6417
Updates tailscale/corp#8051
Change-Id: Ie13f82af3eb9f96b3a21c56cdda51be31ddebdcf
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
To force an EngineStatus update to the IPN bus.
This is a temporary measure while migrating the Windows GUI entirely
to the LocalAPI and off the old IPN protocol. The old IPN protocol
had RequestEngineStatus and LocalAPI didn't.
Updates #6417
Change-Id: I8ff525fc3dd82bdd9d92c2bdad6db5b75609eacd
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Follow-up to #6467 and #6506.
LocalBackend knows the server-mode state, so move more auth checking
there, removing some bookkeeping from ipnserver.Server.
Updates #6417
Updates tailscale/corp#8051
Change-Id: Ic5d14a077bf0dccc92a3621bd2646bab2cc5b837
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This matches CanSSHD (TS_DISABLE_SSH_SERVER) for administratively
disabling the code on a node, regardless of local or server configs.
This can be configured in /etc/default/tailscaled on Linux,
%ProgramData%\Tailscale\tailscaled-env.txt on Windows,
or /etc/tailscale/tailscaled-env.txt on Synology. (see getPlatformEnvFile)
Also delete some dead code and tidy up some docs.
Change-Id: I79a87c03e33209619466ea8aeb0f6651afcb8789
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Centralize the fake GOOS stuff, start to use it more. To be used more
in the future.
Change-Id: Iabacfbeaf5fca0b53bf4d5dbcdc0367f05a205f9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We're trying to gut 90% of the ipnserver package. A lot will get
deleted, some will move to LocalBackend, and a lot is being moved into
this new ipn/ipnauth package which will be leaf-y and testable.
This is a baby step towards moving some stuff to ipnauth.
Update #6417
Updates tailscale/corp#8051
Change-Id: I28bc2126764f46597d92a2d72565009dc6927ee0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
While reading the DNS code noticed that we were still using FallbackResolvers
in this code path but the comment was out of date.
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Profile keys are not deleted but are instead set to `nil` which results
in getting a nil error and we were not handling that correctly.
Updates #713
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit implements `tailscale lock log [--limit N]`, which displays an ordered list
of changes to network-lock state in a manner familiar to `git log`.
Signed-off-by: Tom DNetto <tom@tailscale.com>
By always firing off a sync after enablement, the control plane should know the node's TKA head
at all times.
Signed-off-by: Tom DNetto <tom@tailscale.com>
We were not checking the currentUserID in all code paths that looped over
knownProfiles. This only impacted multi-user Windows setups.
Updates #713
Signed-off-by: Maisem Ali <maisem@tailscale.com>
The earlier 5f6d63936f was not complete.
Updates tailscale/corp#7515
Change-Id: I35efca51d1584c48ef6834a7d29cd42d7c943628
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We would end up with duplicate profiles for the node as the UserID
would have chnaged. In order to correctly deduplicate profiles, we
need to look at both the UserID and the NodeID. A single machine can
only ever have 1 profile per NodeID and 1 profile per UserID.
Note: UserID of a Node can change when the node is tagged/untagged,
and the NodeID of a device can change when the node is deleted so we
need to check for both.
Updates #713
Signed-off-by: Maisem Ali <maisem@tailscale.com>
The LocalClient.BugReport method already sends it via POST.
Updates tailscale/corp#7948
Change-Id: I98dbd558c99d4296d934baa5ebc97052c7413073
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The fix in 4fc8538e2 was sufficient for IPv6. Browsers (can?) send the
IPv6 literal, even without a port number, in brackets.
Updates tailscale/corp#7948
Change-Id: I0e429d3de4df8429152c12f251ab140b0c8f6b77
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I was too late with review feedback to 513780f4f8.
Updates tailscale/corp#7948
Change-Id: I8fa3b4eba4efaff591a2d0bfe6ab4795638b7c3a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We were not updating the LoginProfile.UserProfile when a netmap
updated the UserProfile (e.g. when a node was tagged via the admin panel).
Updates #713
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This moves the NetworkLock key from a dedicated StateKey to be part of the persist.Persist struct.
This struct is stored as part for ipn.Prefs and is also the place where we store the NodeKey.
It also moves the ChonkDir from "/tka" to "/tka-profile/<profile-id>". The rename was intentional
to be able to delete the "/tka" dir if it exists.
This means that we will have a unique key per profile, and a unique directory per profile.
Note: `tailscale logout` will delete the entire profile, including any keys. It currently does not
delete the ChonkDir.
Signed-off-by: Maisem Ali <maisem@tailscale.com>
We do not need to wait for it to complete. And we might have to
call Shutdown from callback from the controlclient which might
already be holding a lock that Shutdown requires.
Updates #713
Signed-off-by: Maisem Ali <maisem@tailscale.com>