9944 Commits

Author SHA1 Message Date
Alex Chan
af7c26aa05 cmd/vet/jsontags: fix a typo in an error message
Updates #17945

Change-Id: I8987271420feb190f5e4d85caff305c8d4e84aae
Signed-off-by: Alex Chan <alexc@tailscale.com>
2025-11-18 13:01:35 +00:00
Alex Chan
85373ef822 tka: move RemoveAll() to CompactableChonk
I added a RemoveAll() method on tka.Chonk in #17946, but it's only used
in the node to purge local AUMs. We don't need it in the SQLite storage,
which currently implements tka.Chonk, so move it to CompactableChonk
instead.

Also add some automated tests, as a safety net.

Updates tailscale/corp#33599

Change-Id: I54de9ccf1d6a3d29b36a94eccb0ebd235acd4ebc
Signed-off-by: Alex Chan <alexc@tailscale.com>
2025-11-18 12:53:52 +00:00
Alex Chan
c2e474e729 all: rename variables with lowercase-l/uppercase-I
See http://go/no-ell

Signed-off-by: Alex Chan <alexc@tailscale.com>

Updates #cleanup

Change-Id: I8c976b51ce7a60f06315048b1920516129cc1d5d
2025-11-18 09:12:34 +00:00
James 'zofrex' Sanderson
9048ea25db
ipn/localapi: log calls to localapi (#17880)
Updates tailscale/corp#34238

Signed-off-by: James Sanderson <jsanderson@tailscale.com>
2025-11-18 08:04:03 +00:00
James 'zofrex' Sanderson
a2e9dfacde
cmd/tailscale/cli: warn if a simple up would change prefs (#17877)
Updates tailscale/corp#21570

Signed-off-by: James Sanderson <jsanderson@tailscale.com>
2025-11-18 07:53:42 +00:00
Joe Tsai
4860c460f5
wgengine/netlog: strip dot suffix from node name (#17954)
The REST API does not return a node name
with a trailing dot, while the internal node name
reported in the netmap does have one.

In order to be consistent with the API,
strip the dot when recording node information.

Updates tailscale/corp#33352

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2025-11-17 19:17:02 -08:00
James Tucker
41662f5128 ssh/tailssh: fix incubator tests on macOS arm64
Perform a path check first before attempting exec of `true`.

Try /usr/bin/true first, as that is now and increasingly so, the more
common and more portable path.

Fixes tests on macOS arm64 where exec was returning a different kind of
path error than previously checked.

Updates #16569

Signed-off-by: James Tucker <james@tailscale.com>
2025-11-17 16:20:46 -08:00
Andrew Lytvynov
26f9b50247
feature/tpm: disable dictionary attack protection on sealing key (#17952)
DA protection is not super helpful because we don't set an authorization
password on the key. But if authorization fails for other reasons (like
TPM being reset), we will eventually cause DA lockout with tailscaled
trying to load the key. DA lockout then leads to (1) issues for other
processes using the TPM and (2) the underlying authorization error being
masked in logs.

Updates #17654

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2025-11-17 14:42:15 -08:00
Brad Fitzpatrick
f1cddc6ecf ipn{,/local},cmd/tailscale: add "sync" flag and pref to disable control map poll
For manual (human) testing, this lets the user disable control plane
map polls with "tailscale set --sync=false" (which survives restarts)
and "tailscale set --sync" to restore.

A high severity health warning is shown while this is active.

Updates #12639
Updates #17945

Change-Id: I83668fa5de3b5e5e25444df0815ec2a859153a6d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-11-17 12:37:31 -08:00
Brad Fitzpatrick
165a24744e tka: fix typo in comment
Let's fix all the typos, which lets the code be more readable, lest we
confuse our readers.

Updates #cleanup

Change-Id: I4954601b0592b1fda40269009647bb517a4457be
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-11-17 10:13:24 -08:00
Alex Chan
1723cb83ed ipn/ipnlocal: use an in-memory TKA store if FS is unavailable
This requires making the internals of LocalBackend a bit more generic,
and implementing the `tka.CompactableChonk` interface for `tka.Mem`.

Signed-off-by: Alex Chan <alexc@tailscale.com>

Updates https://github.com/tailscale/corp/issues/33599
2025-11-17 18:12:33 +00:00
Andrew Lytvynov
d01081683c
go.mod: bump golang.org/x/crypto (#17907)
Pick up a fix for https://pkg.go.dev/vuln/GO-2025-4116 (even though
we're not affected).

Updates #cleanup

Change-Id: I9f2571b17c1f14db58ece8a5a34785805217d9dd

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2025-11-17 09:05:18 -08:00
Alex Chan
200383dce5 various: add more missing apostrophes in comments
Updates #cleanup

Change-Id: I79a0fda9783064a226ee9bcee2c1148212f6df7b
Signed-off-by: Alex Chan <alexc@tailscale.com>
2025-11-17 16:47:17 +00:00
Brad Fitzpatrick
1e95bfa184 ipn: fix typo in comment
Updates #cleanup

Change-Id: Iec66518abd656c64943a58eb6d92f342e627a613
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-11-17 08:40:07 -08:00
Brad Fitzpatrick
a5b2f18567 control/controlclient: remove some public API, move to Options & test-only
Includes adding StartPaused, which will be used in a future change to
enable netmap caching testing.

Updates #12639

Change-Id: Iec39915d33b8d75e9b8315b281b1af2f5d13a44a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-11-17 07:52:59 -08:00
Alex Chan
139c395d7d cmd/tailscale/cli: stabilise the output of tailscale lock log --json
This patch changes the behaviour of `tailscale lock log --json` to make
it more useful for users. It also introduces versioning of our JSON output.

## Changes to `tailscale lock log --json`

Previously this command would print the hash and base64-encoded bytes of
each AUM, and users would need their own CBOR decoder to interpret it in
a useful way:

```json
[
  {
    "Hash": [
      80,
      136,
      151,
      …
    ],
    "Change": "checkpoint",
    "Raw": "pAEFAvYFpQH2AopYIAkPN+8V3cJpkoC5ZY2+RI2Bcg2q5G7tRAQQd67W3YpnWCDPOo4KGeQBd8hdGsjoEQpSXyiPdlm+NXAlJ5dS1qEbFlggylNJDQM5ZQ2ULNsXxg2ZBFkPl/D93I1M56/rowU+UIlYIPZ/SxT9EA2Idy9kaCbsFzjX/s3Ms7584wWGbWd/f/QAWCBHYZzYiAPpQ+NXN+1Wn2fopQYk4yl7kNQcMXUKNAdt1lggcfjcuVACOH0J9pRNvYZQFOkbiBmLOW1hPKJsbC1D1GdYIKrJ38XMgpVMuTuBxM4YwoLmrK/RgXQw1uVEL3cywl3QWCA0FilVVv8uys8BNhS62cfNvCew1Pw5wIgSe3Prv8d8pFggQrwIt6ldYtyFPQcC5V18qrCnt7VpThACaz5RYzpx7RNYIKskOA7UoNiVtMkOrV2QoXv6EvDpbO26a01lVeh8UCeEA4KjAQECAQNYIORIdNHqSOzz1trIygnP5w3JWK2DtlY5NDIBbD7SKcjWowEBAgEDWCD27LpxiZNiA19k0QZhOWmJRvBdK2mz+dHu7rf0iGTPFwQb69Gt42fKNn0FGwRUiav/k6dDF4GiAVgg5Eh00epI7PPW2sjKCc/nDclYrYO2Vjk0MgFsPtIpyNYCWEDzIAooc+m45ay5PB/OB4AA9Fdki4KJq9Ll+PF6IJHYlOVhpTbc3E0KF7ODu1WURd0f7PXnW72dr89CSfGxIHAF"
  }
]
```

Now we print the AUM in an expanded form that can be easily read by scripts,
although we include the raw bytes for verification and auditing.

```json
{
  "SchemaVersion": "1",
  "Messages": [
    {
      "Hash": "KCEJPRKNSXJG2TPH3EHQRLJNLIIK2DV53FUNPADWA7BZJWBDRXZQ",
      "AUM": {
        "MessageKind": "checkpoint",
        "PrevAUMHash": null,
        "Key": null,
        "KeyID": null,
        "State": {
          …
        },
        "Votes": null,
        "Meta": null,
        "Signatures": [
          {
            "KeyID": "tlpub:e44874d1ea48ecf3d6dac8ca09cfe70dc958ad83b656393432016c3ed229c8d6",
            "Signature": "8yAKKHPpuOWsuTwfzgeAAPRXZIuCiavS5fjxeiCR2JTlYaU23NxNChezg7tVlEXdH+z151u9na/PQknxsSBwBQ=="
          }
        ]
      },
      "Raw": "pAEFAvYFpQH2AopYIAkPN-8V3cJpkoC5ZY2-RI2Bcg2q5G7tRAQQd67W3YpnWCDPOo4KGeQBd8hdGsjoEQpSXyiPdlm-NXAlJ5dS1qEbFlggylNJDQM5ZQ2ULNsXxg2ZBFkPl_D93I1M56_rowU-UIlYIPZ_SxT9EA2Idy9kaCbsFzjX_s3Ms7584wWGbWd_f_QAWCBHYZzYiAPpQ-NXN-1Wn2fopQYk4yl7kNQcMXUKNAdt1lggcfjcuVACOH0J9pRNvYZQFOkbiBmLOW1hPKJsbC1D1GdYIKrJ38XMgpVMuTuBxM4YwoLmrK_RgXQw1uVEL3cywl3QWCA0FilVVv8uys8BNhS62cfNvCew1Pw5wIgSe3Prv8d8pFggQrwIt6ldYtyFPQcC5V18qrCnt7VpThACaz5RYzpx7RNYIKskOA7UoNiVtMkOrV2QoXv6EvDpbO26a01lVeh8UCeEA4KjAQECAQNYIORIdNHqSOzz1trIygnP5w3JWK2DtlY5NDIBbD7SKcjWowEBAgEDWCD27LpxiZNiA19k0QZhOWmJRvBdK2mz-dHu7rf0iGTPFwQb69Gt42fKNn0FGwRUiav_k6dDF4GiAVgg5Eh00epI7PPW2sjKCc_nDclYrYO2Vjk0MgFsPtIpyNYCWEDzIAooc-m45ay5PB_OB4AA9Fdki4KJq9Ll-PF6IJHYlOVhpTbc3E0KF7ODu1WURd0f7PXnW72dr89CSfGxIHAF"
    }
  ]
}
```

This output was previously marked as unstable, and it wasn't very useful,
so changing it should be fine.

## Versioning our JSON output

This patch introduces a way to version our JSON output on the CLI, so we
can make backwards-incompatible changes in future without breaking existing
scripts or integrations.

You can run this command in two ways:

```
tailscale lock log --json
tailscale lock log --json=1
```

Passing an explicit version number allows you to pick a specific JSON schema.
If we ever want to change the schema, we increment the version number and
users must opt-in to the new output.

A bare `--json` flag will always return schema version 1, for compatibility
with existing scripts.

Updates https://github.com/tailscale/tailscale/issues/17613
Updates https://github.com/tailscale/corp/issues/23258

Signed-off-by: Alex Chan <alexc@tailscale.com>

Change-Id: I897f78521cc1a81651f5476228c0882d7b723606
2025-11-17 09:44:52 +00:00
Brad Fitzpatrick
99b06eac49 syncs: add Mutex/RWMutex alias/wrappers for future mutex debugging
Updates #17852

Change-Id: I477340fb8e40686870e981ade11cd61597c34a20
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-11-16 19:13:59 -08:00
Andrew Dunham
3a41c0c585 ipn/ipnlocal: add PROXY protocol support to Funnel/Serve
This adds the --proxy-protocol flag to 'tailscale serve' and
'tailscale funnel', which tells the Tailscale client to prepend a PROXY
protocol[1] header when making connections to the proxied-to backend.

I've verified that this works with our existing funnel servers without
additional work, since they pass along source address information via
PeerAPI already.

Updates #7747

[1]: https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

Change-Id: I647c24d319375c1b33e995555a541b7615d2d203
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
2025-11-16 21:00:49 -05:00
Brad Fitzpatrick
653d0738f9 types/netmap: remove PrivateKey from NetworkMap
It's an unnecessary nuisance having it. We go out of our way to redact
it in so many places when we don't even need it there anyway.

Updates #12639

Change-Id: I5fc72e19e9cf36caeb42cf80ba430873f67167c3
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-11-16 15:32:51 -08:00
Brad Fitzpatrick
98aadbaf54 util/cache: remove unused code
Updates #cleanup

Change-Id: I9be7029c5d2a7d6297125d0147e93205a7c68989
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-11-15 12:52:45 -08:00
Brad Fitzpatrick
4e01e8a66e wgengine/netlog: fix send to closed channel in test
Fixes #17922

Change-Id: I2cd600b0ecda389079f2004985ac9a25ffbbfdd1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-11-15 10:20:17 -08:00
Avery Palmer
8aa46a3956 util/clientmetric: fix regression causing Metric.v to be uninitialised
m.v was uninitialised when Tailscale built with ts_omit_logtail
Fixes #17918

Signed-off-by: Avery Palmer <quagsirus@catpowered.net>
2025-11-15 09:55:51 -08:00
Xinyu Kuo
8444659ed8 cmd/tailscale/cli: fix panic in netcheck with mismatched DERP region IDs
Fixes #17564

Signed-off-by: Xinyu Kuo <gxylong@126.com>
2025-11-15 09:55:14 -08:00
Jordan Whited
e1f0ad7a05
net/udprelay: implement Server.SetStaticAddrPorts (#17909)
Only used in tests for now.

Updates tailscale/corp#31489

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-11-14 19:43:44 -08:00
James Tucker
a96ef432cf control/controlclient,ipn/ipnlocal: replace State enum with boolean flags
Remove the State enum (StateNew, StateNotAuthenticated, etc.) from
controlclient and replace it with two explicit boolean fields:
- LoginFinished: indicates successful authentication
- Synced: indicates we've received at least one netmap

This makes the state more composable and easier to reason about, as
multiple conditions can be true independently rather than being
encoded in a single enum value.

The State enum was originally intended as the state machine for the
whole client, but that abstraction moved to ipn.Backend long ago.
This change continues moving away from the legacy state machine by
representing state as a combination of independent facts.

Also adds test helpers in ipnlocal that check independent, observable
facts (hasValidNetMap, needsLogin, etc.) rather than relying on
derived state enums, making tests more robust.

Updates #12639

Signed-off-by: James Tucker <james@tailscale.com>
2025-11-14 16:18:34 -08:00
Andrew Lytvynov
c5919b4ed1
feature/tpm: check IsZero in clone instead of just nil (#17884)
The key.NewEmptyHardwareAttestationKey hook returns a non-nil empty
attestationKey, which means that the nil check in Clone doesn't trigger
and proceeds to try and clone an empty key. Check IsZero instead to
reduce log spam from Clone.

As a drive-by, make tpmAvailable check a sync.Once because the result
won't change.

Updates #17882

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2025-11-14 13:23:25 -08:00
Andrew Lytvynov
888a5d4812
ipn/localapi: use constant-time comparison for RequiredPassword (#17906)
Updates #cleanup

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2025-11-14 12:58:53 -08:00
Alex Chan
9134440008 various: adds missing apostrophes to comments
Updates #cleanup

Change-Id: I7bf29cc153c3c04e087f9bdb146c3437bed0129a
Signed-off-by: Alex Chan <alexc@tailscale.com>
2025-11-14 20:10:07 +00:00
Simon Law
bd36817e84
scripts/installer.sh: compare major versions numerically (#17904)
Most /etc/os-release files set the VERSION_ID to a `MAJOR.MINOR`
string, but we were trying to compare this numerically against a major
version number. I can only assume that Linux Mint used switched from a
plain integer, since shells only do integer comparisons.

This patch extracts a VERSION_MAJOR from the VERSION_ID using
parameter expansion and unifies all the other ad-hoc comparisons to
use it.

Fixes #15841

Signed-off-by: Simon Law <sfllaw@tailscale.com>
Co-authored-by: Xavier <xhienne@users.noreply.github.com>
2025-11-14 12:05:48 -08:00
M. J. Fromberger
ab4b990d51
net/netmon: do not abandon a subscriber when exiting early (#17899)
LinkChangeLogLimiter keeps a subscription to track rate limits for log
messages.  But when its context ended, it would exit the subscription loop,
leaving the subscriber still alive. Ensure the subscriber gets cleaned up
when the context ends, so we don't stall event processing.

Updates tailscale/corp#34311

Change-Id: I82749e482e9a00dfc47f04afbc69dd0237537cb2
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-11-14 11:57:41 -08:00
Brad Fitzpatrick
ce10f7c14c wgengine/wgcfg/nmcfg: reduce wireguard reconfig log spam
On the corp tailnet (using Mullvad exit nodes + bunch of expired
devices + subnet routers), these were generating big ~35 KB blobs of
logging regularly.

This logging shouldn't even exist at this level, and should be rate
limited at a higher level, but for now as a bandaid, make it less
spammy.

Updates #cleanup

Change-Id: I0b5e9e6e859f13df5f982cd71cd5af85b73f0c0a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-11-14 11:13:49 -08:00
Andrew Dunham
208a32af5b logpolicy: fix nil pointer dereference with invalid TS_LOG_TARGET
When TS_LOG_TARGET is set to an invalid URL, url.Parse returns an error
and nil pointer, which caused a panic when accessing u.Host.

Now we check the error from url.Parse and log a helpful message while
falling back to the default log host.

Fixes #17792

Signed-off-by: Andrew Dunham <andrew@tailscale.com>
2025-11-14 14:03:04 -05:00
Brad Fitzpatrick
052602752f control/controlclient: make Observer optional
As a baby step towards eventbus-ifying controlclient, make the
Observer optional.

This also means callers that don't care (like this network lock test,
and some tests in other repos) can omit it, rather than passing in a
no-op one.

Updates #12639

Change-Id: Ibd776b45b4425c08db19405bc3172b238e87da4e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-11-14 10:40:41 -08:00
Jordan Whited
0285e1d5fb
feature/relayserver: fix Shutdown() deadlock (#17898)
Updates #17894

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-11-14 10:22:58 -08:00
James 'zofrex' Sanderson
124301fbb6
ipn/ipnlocal: log prefs changes and reason in Start (#17876)
Updates tailscale/corp#34238

Signed-off-by: James Sanderson <jsanderson@tailscale.com>
2025-11-14 13:21:56 +00:00
Alex Chan
b5cd29932e tka: add a test for unmarshaling existing AUMs
Updates https://github.com/tailscale/tailscale/issues/17613

Change-Id: I693a580949eef59263353af6e7e03a7af9bbaa0b
Signed-off-by: Alex Chan <alexc@tailscale.com>
2025-11-14 12:41:08 +00:00
Jordan Whited
9e4d1fd87f
feature/relayserver,ipn/ipnlocal,net/udprelay: plumb DERPMap (#17881)
This commit replaces usage of local.Client in net/udprelay with DERPMap
plumbing over the eventbus. This has been a longstanding TODO. This work
was also accelerated by a memory leak in net/http when using
local.Client over long periods of time. So, this commit also addresses
said leak.

Updates #17801

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-11-13 20:57:48 -08:00
Brad Fitzpatrick
146ea42822 ipn/ipnlocal: remove all the weird locking (LockedOnEntry, UnlockEarly, etc)
Fixes #11649
Updates #16369

Co-authored-by: James Sanderson <jsanderson@tailscale.com>
Change-Id: I63eaa18fe870ddf81d84b949efac4d1b44c3db86
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-11-13 19:20:07 -08:00
Andrew Dunham
08e74effc0 cmd/cloner: support cloning arbitrarily-nested maps
Fixes #17870

Signed-off-by: Andrew Dunham <andrew@tailscale.com>
2025-11-13 14:04:47 -05:00
Naman Sood
ca9b68aafd
cmd/tailscale/cli: remove service flag from funnel command (#17850)
Fixes #17849.

Signed-off-by: Naman Sood <mail@nsood.in>
2025-11-13 07:19:17 -05:00
Andrew Dunham
6ac80b7334 cmd/{cloner,viewer}: handle maps of views
Instead of trying to call View() on something that's already a View
type (or trying to Clone the view unnecessarily), we can re-use the
existing View values in a map[T]ViewType.

Fixes #17866

Signed-off-by: Andrew Dunham <andrew@tailscale.com>
2025-11-12 22:09:49 -05:00
Jordan Whited
f4f9dd7f8c
net/udprelay: replace VNI pool with selection algorithm (#17868)
This reduces memory usage when tailscaled is acting as a peer relay.

Updates #17801

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-11-12 15:47:01 -08:00
License Updater
31fe75ad9e licenses: update license notices
Signed-off-by: License Updater <noreply+license-updater@tailscale.com>
2025-11-12 12:39:13 -08:00
Fran Bull
37aa7e6935 util/dnsname: fix test error message
Updates #17788

Signed-off-by: Fran Bull <fran@tailscale.com>
2025-11-12 11:01:19 -08:00
Brad Fitzpatrick
f387b1010e wgengine/wgcfg: remove two unused Config fields
They distracted me in some refactoring. They're set but never used.

Updates #17858

Change-Id: I6ec7d6841ab684a55bccca7b7cbf7da9c782694f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-11-12 09:08:45 -08:00
Fran Bull
27a0168cdc util/dnsname: increase maxNameLength to account for trailing dot
Fixes #17788

Signed-off-by: Fran Bull <fran@tailscale.com>
2025-11-12 08:04:42 -08:00
Jonathan Nobels
e8d2f96449
ipn/ipnlocal, net/netns: add node cap to disable netns interface binding on netext Apple clients (#17691)
updates tailscale/corp#31571

It appears that on the latest macOS, iOS and tVOS versions, the work
that netns is doing to bind outgoing connections to the default interface (and all
of the trimmings and workarounds in netmon et al that make that work) are
not needed. The kernel is extension-aware and doing nothing, is the right
thing.  This is, however, not the case for tailscaled (which is not a
special process).

To allow us to test this assertion (and where it might break things), we add a
new node cap that turns this behaviour off only for network-extension equipped clients,
making it possible to turn this off tailnet-wide, without breaking any tailscaled
macos nodes.

Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
2025-11-12 10:25:27 -05:00
Sachin Iyer
16e90dcb27
net/batching: fix gro size handling for misordered UDP_GRO messages (#17842)
Fixes #17835

Signed-off-by: Sachin Iyer <siyer@detail.dev>
2025-11-12 10:13:21 -05:00
Sachin Iyer
d37884c734
cmd/k8s-operator: remove early return in ingress matching (#17841)
Fixes #17834

Signed-off-by: Sachin Iyer <siyer@detail.dev>
2025-11-12 10:46:40 +00:00
Sachin Iyer
85cb64c4ff
wf: correct IPv6 link-local range from ff80::/10 to fe80::/10 (#17840)
Fixes #17833

Signed-off-by: Sachin Iyer <siyer@detail.dev>
2025-11-11 10:07:02 -08:00