summaryrefslogtreecommitdiffhomepage
path: root/ipn
AgeCommit message (Collapse)AuthorFilesLines
2025-10-24ipn/ipnlocal: skip TKA bootstrap request if Tailnet Lock is unavailableAlex Chan1-0/+4
If you run tailscaled without passing a `--statedir`, Tailnet Lock is unavailable -- we don't have a folder to store the AUMs in. This causes a lot of unnecessary requests to bootstrap TKA, because every time the node receives a NetMap with some TKA state, it tries to bootstrap, fetches the bootstrap TKA state from the control plane, then fails with the error: TKA sync error: bootstrap: network-lock is not supported in this configuration, try setting --statedir We can't prevent the error, but we can skip the control plane request that immediately gets dropped on the floor. In local testing, a new node joining a tailnet caused *three* control plane requests which were unused. Updates tailscale/corp#19441 Signed-off-by: Alex Chan <alexc@tailscale.com>
2025-10-23feature/tpm: check TPM family data for compatibility (#17624)Patrick O'Doherty1-0/+1
Check that the TPM we have opened is advertised as a 2.0 family device before using it for state sealing / hardware attestation. Updates #17622 Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
2025-10-21ipn, tka: improve the logging around TKA sync and AUM errorsAlex Chan1-5/+6
* When we do the TKA sync, log whether TKA is enabled and whether we want it to be enabled. This would help us see if a node is making bootstrap errors. * When we fail to look up an AUM locally, log the ID of the AUM rather than a generic "file does not exist" error. These AUM IDs are cryptographic hashes of the TKA state, which itself just contains public keys and signatures. These IDs aren't sensitive and logging them is safe. Signed-off-by: Alex Chan <alexc@tailscale.com> Updates https://github.com/tailscale/corp/issues/33594
2025-10-20ipn/ipnlocal: use eventbus.SubscribeFunc in LocalBackend (#17524)M. J. Fromberger1-75/+44
This does not change which subscriptions are made, it only swaps them to use the SubscribeFunc API instead of Subscribe. Updates #15160 Updates #17487 Change-Id: Id56027836c96942206200567a118f8bcf9c07f64 Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-10-16all: use a consistent capitalisation for "Tailnet Lock"Alex Chan1-1/+1
Updates https://github.com/tailscale/corp/issues/13108 Signed-off-by: Alex Chan <alexc@tailscale.com>
2025-10-10ipn/ipnlocal: strip AttestationKey in redacted prefs view (#17527)Patrick O'Doherty1-0/+1
Updates tailscale/corp#31269 Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
2025-10-10types/persist: add AttestationKey (#17281)Patrick O'Doherty7-9/+118
Extend Persist with AttestationKey to record a hardware-backed attestation key for the node's identity. Add a flag to tailscaled to allow users to control the use of hardware-backed keys to bind node identity to individual machines. Updates tailscale/corp#31269 Change-Id: Idcf40d730a448d85f07f1bebf387f086d4c58be3 Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
2025-10-10cmd/tailscale/cli,ipn/conffile: add declarative config mode for Services ↵Naman Sood1-0/+239
(#17435) This commit adds the subcommands `get-config` and `set-config` to Serve, which can be used to read the current Tailscale Services configuration in a standard syntax and provide a configuration to declaratively apply with that same syntax. Both commands must be provided with either `--service=svc:service` for one service, or `--all` for all services. When writing a config, `--set-config --all` will overwrite all existing Services configuration, and `--set-config --service=svc:service` will overwrite all configuration for that particular Service. Incremental changes are not supported. Fixes tailscale/corp#30983. cmd/tailscale/cli: hide serve "get-config"/"set-config" commands for now tailscale/corp#33152 tracks unhiding them when docs exist. Signed-off-by: Naman Sood <mail@nsood.in>
2025-10-08ipn/ipnlocal: use eventbus.SubscribeFunc in expiryManagerM. J. Fromberger1-23/+6
Updates #15160 Updates #17487 Change-Id: I8721e3ac1af505630edca7c5cb50695b0aad832a Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-10-08ipn/ipnlocal: fix data race on captiveCtx in enterStateLockedOnEntry (#17495)James 'zofrex' Sanderson1-2/+3
Updates #17491 Signed-off-by: James Sanderson <jsanderson@tailscale.com>
2025-10-07ipn/localapi: dead code eliminate unreachable/useless LocalAPI handlers when ↵Brad Fitzpatrick2-53/+63
disabled Saves ~94 KB from the min build. Updates #12614 Change-Id: I3b0b8a47f80b9fd3b1038c2834b60afa55bf02c2 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-10-07ipn/ipnlocal: use named arguments for `mockControl.send()`Alex Chan2-38/+46
Updates #cleanup Signed-off-by: Alex Chan <alexc@tailscale.com>
2025-10-07ipn/ipnlocal: don't send LoginFinished unless auth was in progress (#17266)James 'zofrex' Sanderson2-1/+17
Before we introduced seamless, the "blocked" state was used to track: * Whether a login was required for connectivity, and therefore we should keep the engine deconfigured until that happened * Whether authentication was in progress "blocked" would stop authReconfig from running. We want this when a login is required: if your key has expired we want to deconfigure the engine and keep it down, so that you don't keep using exit nodes (which won't work because your key has expired). Taking the engine down while auth was in progress was undesirable, so we don't do that with seamless renewal. However, not entering the "blocked" state meant that we needed to change the logic for when to send LoginFinished on the IPN bus after seeing StateAuthenticated from the controlclient. Initially we changed the "if blocked" check to "if blocked or seamless is enabled" which was correct in other places. In this place however, it introduced a bug: we are sending LoginFinished every time we see StateAuthenticated, which happens even on a down & up, or a profile switch. This in turn made it harder for UI clients to track when authentication is complete. Instead we should only send it out if we were blocked (i.e. seamless is disabled, or our key expired) or an auth was in progress. Updates tailscale/corp#31476 Updates tailscale/corp#32645 Fixes #17363 Signed-off-by: James Sanderson <jsanderson@tailscale.com>
2025-10-06util/checkchange: stop using deephash everywhereBrad Fitzpatrick1-20/+50
Saves 45 KB from the min build, no longer pulling in deephash or util/hashx, both with unsafe code. It can actually be more efficient to not use deephash, as you don't have to walk all bytes of all fields recursively to answer that two things are not equal. Instead, you can just return false at the first difference you see. And then with views (as we use ~everywhere nowadays), the cloning the old value isn't expensive, as it's just a pointer under the hood. Updates #12614 Change-Id: I7b08616b8a09b3ade454bb5e0ac5672086fe8aec Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-10-06ipn/ipnlocal: fix another racy test (#17472)M. J. Fromberger1-2/+2
Some of the test cases access fields of the backend that are supposed to be locked while the test is running, which can trigger the race detector. I fixed a few of these in #17411, but I missed these two cases. Updates #15160 Updates #17192 Change-Id: I45664d5e34320ecdccd2844e0f8b228145aaf603 Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-10-06appc,ipn/ipnlocal: receive AppConnector updates via the event bus (#17411)M. J. Fromberger3-93/+135
Add subscribers for AppConnector events Make the RouteAdvertiser interface optional We cannot yet remove it because the tests still depend on it to verify correctness. We will need to separately update the test fixtures to remove that dependency. Publish RouteInfo via the event bus, so we do not need a callback to do that. Replace it with a flag that indicates whether to treat the route info the connector has as "definitive" for filtering purposes. Update the tests to simplify the construction of AppConnector values now that a store callback is no longer required. Also fix a couple of pre-existing racy tests that were hidden by not being concurrent in the same way production is. Updates #15160 Updates #17192 Change-Id: Id39525c0f02184e88feaf0d8a3c05504850e47ee Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-10-06ipn/ipnlocal: fix setAuthURL / setWgengineStatus race condition (#17408)James 'zofrex' Sanderson3-24/+278
If we received a wg engine status while processing an auth URL, there was a race condition where the authURL could be reset to "" immediately after we set it. To fix this we need to check that we are moving from a non-Running state to a Running state rather than always resetting the URL when we "move" into a Running state even if that is the current state. We also need to make sure that we do not return from stopEngineAndWait until the engine is stopped: before, we would return as soon as we received any engine status update, but that might have been an update already in-flight before we asked the engine to stop. Now we wait until we see an update that is indicative of a stopped engine, or we see that the engine is unblocked again, which indicates that the engine stopped and then started again while we were waiting before we checked the state. Updates #17388 Signed-off-by: James Sanderson <jsanderson@tailscale.com> Co-authored-by: Nick Khyl <nickk@tailscale.com>
2025-10-06feature/featuretags: make usermetrics modularBrad Fitzpatrick1-1/+3
Saves ~102 KB from the min build. Updates #12614 Change-Id: Ie1d4f439321267b9f98046593cb289ee3c4d6249 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-10-06all: use buildfeatures consts in a few more placesBrad Fitzpatrick3-33/+63
Saves ~25 KB. Updates #12614 Change-Id: I7b976e57819a0d2692824d779c8cc98033df0d30 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-10-04ipn/ipnlocal: use buildfeature consts in a few more placesBrad Fitzpatrick1-4/+11
Updates #12614 Change-Id: I561d434d9829172a3d7f6933399237924ff80490 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-10-03ipn/ipnlocal: remove junk from suggestExitNodeUsingTrafficSteering (#17436)Simon Law1-4/+0
This patch removes some code that didn’t get removed before merging the changes in #16580. Updates #cleanup Updates #16551 Signed-off-by: Simon Law <sfllaw@tailscale.com>
2025-10-03all: use buildfeature constants in a few more placesBrad Fitzpatrick3-26/+46
Saves 21 KB. Updates #12614 Change-Id: I0cd3e735937b0f5c0fcc9f09a24476b1c4ac9a15 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-10-03ipn/ipnauth: fix a null pointer panic in GetConnIdentityAlex Chan1-2/+3
When running integration tests on macOS, we get a panic from a nil pointer dereference when calling `ci.creds.PID()`. This panic occurs because the `ci.creds != nil` check is insufficient after a recent refactoring (c45f881) that changed `ci.creds` from a pointer to the `PeerCreds` interface. Now `ci.creds` always compares as non-nil, so we enter this block even when the underlying value is nil. The integration tests fail on macOS when `peercred.Get()` returns the error `unix.GetsockoptInt: socket is not connected`. This error isn't new, and the previous code was ignoring it correctly. Since we trust that `peercred` returns either a usable value or an error, checking for a nil error is a sufficient and correct gate to prevent the method call and avoid the panic. Fixes #17421 Signed-off-by: Alex Chan <alexc@tailscale.com>
2025-10-02ipn/ipnlocal: introduce the concept of client-side-reachability (#17367)Simon Law3-2/+112
The control plane will sometimes determine that a node is not online, while the node is still able to connect to its peers. This patch doesn’t solve this problem, but it does mitigate it. This PR introduces the `client-side-reachability` node attribute that switches the node to completely ignore the online signal from control. In the future, the client itself should collect reachability data from active Wireguard flows and Tailscale pings. Updates #17366 Updates tailscale/corp#30379 Updates tailscale/corp#32686 Signed-off-by: Simon Law <sfllaw@tailscale.com>
2025-10-02control/controlclient,health,ipn/ipnlocal,health: fix deadlock by deleting ↵Brad Fitzpatrick1-0/+10
health reporting A recent change (009d702adfa0fc) introduced a deadlock where the /machine/update-health network request to report the client's health status update to the control plane was moved to being synchronous within the eventbus's pump machinery. I started to instead make the health reporting be async, but then we realized in the three years since we added that, it's barely been used and doesn't pay for itself, for how many HTTP requests it makes. Instead, delete it all and replace it with a c2n handler, which provides much more helpful information. Fixes tailscale/corp#32952 Change-Id: I9e8a5458269ebfdda1c752d7bbb8af2780d71b04 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-10-02feature/featuretags: add features for c2n, peerapi, advertise/use ↵Brad Fitzpatrick7-66/+182
routes/exit nodes Saves 262 KB so far. I'm sure I missed some places, but shotizam says these were the low hanging fruit. Updates #12614 Change-Id: Ia31c01b454f627e6d0470229aae4e19d615e45e3 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-10-02feature/featuretags: make clientmetrics optionalBrad Fitzpatrick1-0/+5
Saves 57 KB Updates #12614 Change-Id: If7eebec12b3cb30ae6264171d36a258c04b05a70 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-10-02appc,*: publish events for route updates and storage (#17392)M. J. Fromberger4-19/+25
Add and wire up event publishers for these two event types in the AppConnector. Nothing currently subscribes to them, so this is harmless. Subscribers for these events will be added in a near-future commit. As part of this, move the appc.RouteInfo type to the types/appctype package. It does not contain any package-specific details from appc. Beside it, add appctype.RouteUpdate to carry route update event state, likewise not specific to appc. Update all usage of the appc.* types throughout to use appctype.* instead, and update depaware files to reflect these changes. Add a Close method to the AppConnector to make sure the client gets cleaned up when the connector is dropped (we re-create connectors). Update the unit tests in the appc package to also check the events published alongside calls to the RouteAdvertiser. For now the tests still rely on the RouteAdvertiser for correctness; this is OK for now as the two methods are always performed together. In the near future, we need to rework the tests so not require that, but that will require building some more test fixtures that we can handle separately. Updates #15160 Updates #17192 Change-Id: I184670ba2fb920e0d2cb2be7c6816259bca77afe Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-10-02feature/featuretags, all: add build features, use existing ones in more placesBrad Fitzpatrick9-49/+129
Saves 270 KB. Updates #12614 Change-Id: I4c3fe06d32c49edb3a4bb0758a8617d83f291cf5 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-10-01cmd/tailscaled: default --encrypt-state to true if TPM is available (#17376)Andrew Lytvynov1-5/+1
Whenever running on a platform that has a TPM (and tailscaled can access it), default to encrypting the state. The user can still explicitly set this flag to disable encryption. Updates https://github.com/tailscale/corp/issues/32909 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2025-10-01appc,ipn/ipnlocal: add a required event bus to the AppConnector type (#17390)M. J. Fromberger3-6/+18
Require the presence of the bus, but do not use it yet. Check for required fields and update tests and production use to plumb the necessary arguments. Updates #15160 Updates #17192 Change-Id: I8cefd2fdb314ca9945317d3320bd5ea6a92e8dcb Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-10-01net/netmon: remove usage of direct callbacks from netmon (#17292)Claus Lensbøl4-4/+11
The callback itself is not removed as it is used in other repos, making it simpler for those to slowly transition to the eventbus. Updates #15160 Signed-off-by: Claus Lensbøl <claus@tailscale.com>
2025-10-01appc: factor app connector arguments into a Config type (#17389)M. J. Fromberger3-11/+38
Replace the positional arguments to NewAppConnector with a Config struct. Update the existing uses. Other than the API change, there are no functional changes in this commit. Updates #15160 Updates #17192 Change-Id: Ibf37f021372155a4db8aaf738f4b4f2c746bf623 Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-10-01tsnet: remove AuthenticatedAPITransport (API-over-noise) supportBrad Fitzpatrick1-57/+0
It never launched and I've lost hope of it launching and it's in my way now, so I guess it's time to say goodbye. Updates tailscale/corp#4383 Updates #17305 Change-Id: I2eb551d49f2fb062979cc307f284df4b3dfa5956 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-10-01all: use Go 1.20's errors.Join instead of our multierr packageBrad Fitzpatrick1-3/+2
Updates #7123 Change-Id: Ie9be6814831f661ad5636afcd51d063a0d7a907d Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-10-01ipn/store, feature/condregister: permit callers to empty import optonal ipn ↵Brad Fitzpatrick3-2/+21
stores This permits other programs (in other repos) to conditionally import ipn/store/awsstore and/or ipn/store/kubestore and have them register themselves, rather than feature/condregister doing it. Updates tailscale/corp#32922 Change-Id: I2936229ce37fd2acf9be5bf5254d4a262d090ec1 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-10-01ipn/ipnlocal: fail test if more notifies are put than expectedJames Sanderson1-3/+13
The `put` callback runs on a different goroutine to the test, so calling t.Fatalf in put had no effect. `drain` is always called when checking what was put and is called from the test goroutine, so that's a good place to fail the test if the channel was too full. Updates #17363 Signed-off-by: James Sanderson <jsanderson@tailscale.com>
2025-09-30ipn/ipnlocal: plumb logf into nodeBackendNick Khyl4-14/+18
Updates #cleanup Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-09-30ipn/ipnlocal, engine: avoid runtime/pprof with two usages of ts_omit_debugBrad Fitzpatrick1-1/+1
Saves 258 KB. Updates #12614 Change-Id: I37c2f7f916480e3534883f338de4c64d08f7ef2b Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-30feature/featuretags, ipn/conffile: make HuJSON support in config files optionalBrad Fitzpatrick3-9/+17
Saves 33 KB. Updates #12614 Change-Id: Ie701c230e0765281f409f29ed263910b9be9cc77 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-30feature/appconnectors: start making it modularBrad Fitzpatrick4-35/+46
Saves 45 KB. Updates #12614 Change-Id: Iaeb73e69633878ce0a0f58c986024784bbe218f1 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-30cmd/tailscaled, ipn/localapi, util/eventbus: don't link in regexp when debug ↵Brad Fitzpatrick1-1/+1
is omitted Saves 442 KB. Lock it with a new min test. Updates #12614 Change-Id: Ia7bf6f797b6cbf08ea65419ade2f359d390f8e91 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-30feature/featuretags: add a catch-all "Debug" feature flagBrad Fitzpatrick7-450/+523
Saves 168 KB. Updates #12614 Change-Id: Iaab3ae3efc6ddc7da39629ef13e5ec44976952ba Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-30feature, net/tshttpproxy: pull out support for using proxies as a featureBrad Fitzpatrick1-1/+2
Saves 139 KB. Also Synology support, which I saw had its own large-ish proxy parsing support on Linux, but support for proxies without Synology proxy support is reasonable, so I pulled that out as its own thing. Updates #12614 Change-Id: I22de285a3def7be77fdcf23e2bec7c83c9655593 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-30ipn/ipnlocal: proxy h2c grpc using net/http.Transport instead of x/net/http2Brad Fitzpatrick2-12/+98
(Kinda related: #17351) Updates #17305 Change-Id: I47df2612732a5713577164e74652bc9fa3cd14b3 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-30ipn/ipnlocal: drop h2c package, use net/http's supportBrad Fitzpatrick2-28/+4
In Dec 2021 in d3d503d9977ed I had grand plans to make exit node DNS cheaper by using HTTP/2 over PeerAPI, at least on some platforms. I only did server-side support though and never made it to the client. In the ~4 years since, some things have happened: * Go 1.24 got support for http.Protocols (https://pkg.go.dev/net/http#Protocols) and doing UnencryptedHTTP2 ("HTTP2 with prior knowledge") * The old h2c upgrade mechanism was deprecated; see https://github.com/golang/go/issues/63565 and https://github.com/golang/go/issues/67816 * Go plans to deprecate x/net/http2 and move everything to the standard library. So this drops our use of the x/net/http2/h2c package and instead enables h2c (on all platforms now) using the standard library. This does mean we lose the deprecated h2c Upgrade support, but that's fine. If/when we do the h2c client support for ExitDNS, we'll have to probe the peer to see whether it supports it. Or have it reply with a header saying that future requests can us h2c. (It's tempting to use capver, but maybe people will disable that support anyway, so we should discover it at runtime instead.) Also do the same in the sessionrecording package. Updates #17305 Change-Id: If323f5ef32486effb18ed836888aa05c0efb701e Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-30feature/featuretags: add option to turn off DNSBrad Fitzpatrick4-1/+30
Saves 328 KB (2.5%) off the minimal binary. For IoT devices that don't need MagicDNS (e.g. they don't make outbound connections), this provides a knob to disable all the DNS functionality. Rather than a massive refactor today, this uses constant false values as a deadcode sledgehammer, guided by shotizam to find the largest DNS functions which survived deadcode. A future refactor could make it so that the net/dns/resolver and publicdns packages don't even show up in the import graph (along with their imports) but really it's already pretty good looking with just these consts, so it's not at the top of my list to refactor it more soon. Also do the same in a few places with the ACME (cert) functionality, as I saw those while searching for DNS stuff. Updates #12614 Change-Id: I8e459f595c2fde68ca16503ff61c8ab339871f97 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-29ipn/ipnlocal, feature/posture: pull posture out into a modular featureBrad Fitzpatrick2-75/+3
Updates #12614 Change-Id: I9d08a1330b9c55e1a23e7979a707e11d8e090d79 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-29feature/clientupdate: move clientupdate to a modular feature, disabled for tsnetBrad Fitzpatrick8-453/+27
Updates #12614 Change-Id: I5f685dec84a5396b7c2b66f2788ae3d286e1ddc6 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-29ipn/store, feature/condregister: move AWS + Kube store registration to ↵Brad Fitzpatrick2-43/+0
condregister Otherwise they're uselessly imported by tsnet applications, even though they do nothing. tsnet applications wanting to use these already had to explicitly import them and use kubestore.New or awsstore.New and assign those to their tsnet.Server.Store fields. Updates #12614 Change-Id: I358e3923686ddf43a85e6923c3828ba2198991d4 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>