Commit Graph

10256 Commits

Author SHA1 Message Date
Brad Fitzpatrick
633e892164 ssh/tailssh: fix race between termination message write and session teardown
When a recording upload fails mid-session, killProcessOnContextDone
writes the termination message to ss.Stderr() and kills the process.
Meanwhile, run() takes the ss.ctx.Done() path and proceeds to
ss.Exit(), which tears down the SSH channel. The termination message
write races with the channel teardown, so the client sometimes never
receives it.

Fix by adding an exitHandled channel that killProcessOnContextDone
closes when done. run() now waits on this channel after ctx.Done()
fires, ensuring the termination message is fully written before
the SSH channel is torn down.

Fixes #7707

Change-Id: Ib60116c928d3af46d553a4186a72963c2c731e3e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-09 14:11:07 -07:00
Fran Bull
a4614d7d17 appc,feature/conn25: conn25: send address assignments to connector
After we intercept a DNS response and assign magic and transit addresses
we must communicate the assignment to our connector so that it can
direct traffic when it arrives.

Use the recently added peerapi endpoint to send the addresses.

Updates tailscale/corp#34258
Signed-off-by: Fran Bull <fran@tailscale.com>
2026-03-09 14:10:38 -07:00
Gesa Stupperich
6a19995f13 tailcfg: reintroduce UserProfile.Groups
This change reintroduces UserProfile.Groups, a slice that contains
the ACL-defined and synced groups that a user is a member of.

The slice will only be non-nil for clients with the node attribute
see-groups, and will only contain groups that the client is allowed
to see as per the app payload of the see-groups node attribute.

For example:
```
"nodeAttrs": [
  {
    "target": ["tag:dev"],
    "app": {
      "tailscale.com/see-groups": [{"groups": ["group:dev"]}]
    }
  },

  [...]

]
```

UserProfile.Groups will also be gated by a feature flag for the time
being.

Updates tailscale/corp#31529

Signed-off-by: Gesa Stupperich <gesa@tailscale.com>
2026-03-09 11:08:45 +00:00
Gesa Stupperich
ac74dfa5cd util/osuser: extend id command fallback for group IDs to freebsd
Users on FreeBSD run into a similar problem as has been reported for
Linux #11682 and fixed in #11682: because the tailscaled binaries
that we distribute are static and don't link cgo tailscaled fails to
fetch group IDs that are returned via NSS when spawning an ssh child
process.

This change extends the fallback on the 'id' command that was put in
place as part of #11682 to FreeBSD. More precisely, we try to fetch
the group IDs with the 'id' command first, and only if that fails do
we fall back on the logic in the os/user package.

Updates #14025

Signed-off-by: Gesa Stupperich <gesa@tailscale.com>
2026-03-09 08:39:07 +00:00
Brad Fitzpatrick
e400d5aa7b cmd/testwrapper: make test tolerant of a GOEXPERIMENT being set
Otherwise it generates an syntactically invalid go.mod file
and subsequently fails.

Updates #18884

Change-Id: I1a0ea17a57b2a37bde3770187e1a6e2d8aa55bfe
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-06 14:05:35 -08:00
Brad Fitzpatrick
bd2a2d53d3 all: use Go 1.26 things, run most gofix modernizers
I omitted a lot of the min/max modernizers because they didn't
result in more clear code.

Some of it's older "for x := range 123".

Also: errors.AsType, any, fmt.Appendf, etc.

Updates #18682

Change-Id: I83a451577f33877f962766a5b65ce86f7696471c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-06 13:32:03 -08:00
Brad Fitzpatrick
4453cc5f53 go.mod: bump to Go 1.26.1
Updates #18682

Change-Id: I855c0dfa4c61eb33123bbb7b00c1ab5506e80b09
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-06 11:27:29 -08:00
Mike O'Driscoll
3cc7b8530c prober: fix queuing delay probe txRecords overflow under high DERP server load (#18803)
The txRecords buffer had two compounding bugs that caused the
overflow guard to fire on every send tick under high DERP server load,
spamming logs at the full send rate (e.g. 100x/second).

First, int(packetTimeout.Seconds()) truncates fractional-second timeouts,
under-allocating the buffer. Second, the capacity was sized to exactly the
theoretical maximum number of in-flight records with no headroom,
and the expiry check used strict > rather than >=, so records at exactly
the timeout boundary were never evicted by applyTimeouts,
leaving len==cap on the very next tick.

Fixes tailscale/corp#37696

Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
2026-03-06 09:54:25 -05:00
Michael Ben-Ami
40858a61fe ipnext,ipnlocal: add ExtraWireGuardAllowedIPs hook
This hook addition is motivated by the Connectors 2025 work, in which
NATed "Transit IPs" are used to route interesting traffic to the
appropriate peer, without advertising the actual real IPs.

It overlaps with #17858, and specifically with the WIP PR #17861.
If that work completes, this hook may be replaced by other ones
that fit the new WireGuard configuration paradigm.

Fixes tailscale/corp#37146

Signed-off-by: Michael Ben-Ami <mzb@tailscale.com>
2026-03-06 09:42:44 -05:00
Brad Fitzpatrick
8e3d176f1c control/controlbase: deflake, speed up TestConnMemoryOverhead
This had gotten flaky with Go 1.26.

Use synctest + AllocsPerRun to make it fast and deterministic.

Updates #18682

Change-Id: If673d6ecd8c1177f59c1b9c0f3fca42309375dff
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-06 06:19:11 -08:00
Kristoffer Dalby
bb45b2ebbd nix: update flakes to get a nixpkgs version with go 1.26
We override 1.26, but its not in the old commit we are tracking.

Updates #18682

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2026-03-06 04:06:57 -08:00
Brad Fitzpatrick
2a64c03c95 types/ptr: deprecate ptr.To, use Go 1.26 new
Updates #18682

Change-Id: I62f6aa0de2a15ef8c1435032c6aa74a181c25f8f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-05 20:13:18 -08:00
Brad Fitzpatrick
8cfbaa717d go.mod: bump staticcheck to version that supports Go 1.26
Otherwise it gets confused on new(123) etc.

Updates #18682

Change-Id: I9e2e93ea24f2b952b2396dceaf094b4db64424b0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-05 14:28:58 -08:00
Brad Fitzpatrick
2810f0c6f1 all: fix typos in comments
Fix its/it's, who's/whose, wether/whether, missing apostrophes
in contractions, and other misspellings across the codebase.

Updates #cleanup

Change-Id: I20453b81a7aceaa14ea2a551abba08a2e7f0a1d8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-05 13:52:01 -08:00
Claus Lensbøl
9657a93217 tstest/natlab: add test for no control and rotated disco key (#18261)
Updates #12639

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
2026-03-05 16:00:36 -05:00
Jonathan Nobels
c17ec8ce1c VERSION.txt: this is v1.97.0 (#18898)
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
v1.97.0-pre
2026-03-05 15:24:48 -05:00
Raj Singh
19e2c8c49f cmd/k8s-proxy: use L4 TCPForward instead of L7 HTTP proxy (#18179)
considerable latency was seen when using k8s-proxy with ProxyGroup
in the kubernetes operator. Switching to L4 TCPForward solves this.

Fixes tailscale#18171

Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
Co-authored-by: chaosinthecrd <tom@tmlabs.co.uk>
2026-03-05 18:47:54 +00:00
Claus Lensbøl
1b53c00f2b clientupdate,net/tstun: add support for OpenWrt 25.12.0 using apk (#18545)
OpenWrt is changing to using alpine like `apk` for package installation
over its previous opkg. Additionally, they are not using the same repo
files as alpine making installation fail.

Add support for the new repository files and ensure that the required
package detection system uses apk.

Updates #18535

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
2026-03-05 13:39:07 -05:00
Kristoffer Dalby
d82e478dbc cli: --json for tailscale dns status|query
This commit adds `--json` output mode to dns debug commands.

It defines structs for the data that is returned from:
`tailscale dns status` and `tailscale dns query <DOMAIN>` and
populates that as it runs the diagnostics.

When all the information is collected, it is serialised to JSON
or string built into an output and returned to the user.

The structs are defined and exported to golang consumers of this command
can use them for unmarshalling.

Updates #13326

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2026-03-05 05:31:41 -08:00
BeckyPauley
faf7f2bc45 cmd/k8s-operator: remove deprecated TS_EXPERIMENTAL_KUBE_API_EVENTS (#18893)
Remove the TS_EXPERIMENTAL_KUBE_API_EVENTS env var from the operator and its
helm chart. This has already been marked as deprecated, and has been
scheduled to be removed in release 1.96.

Add a check in helm chart to fail if the removed variable is set to true,
prompting users to move to ACLs instead.

Fixes: #18875

Signed-off-by: Becky Pauley <becky@tailscale.com>
2026-03-05 12:09:11 +00:00
Brad Fitzpatrick
d784dcc61b go.toolchain.branch: switch to Go 1.26
Updates #18682

Change-Id: I1eadfab950e55d004484af880a5d8df6893e85e8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-04 21:57:05 -08:00
Brad Fitzpatrick
87bf76de89 net/porttrack: change magic listen address format for Go 1.26
Go 1.26's url.Parser is stricter and made our tests elsewhere fail
with this scheme because when these listen addresses get shoved
into a URL, it can't parse back out.

I verified this makes tests elsewhere pass with Go 1.26.

Updates #18682

Change-Id: I04dd3cee591aa85a9417a0bbae2b6f699d8302fa
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-04 21:57:05 -08:00
Daniel Pañeda
d58bfb8a1b net/udprelay: use GOMAXPROCS instead of NumCPU for socket count
runtime.NumCPU() returns the number of CPUs on the host, which in
containerized environments is the node's CPU count rather than the
container's CPU limit. This causes excessive memory allocation in
pods with low CPU requests running on large nodes, as each socket's
packetReadLoop allocates significant buffer memory.

Use runtime.GOMAXPROCS(0) instead, which is container-aware since
Go 1.25 and respects CPU limits set via cgroups.

Fixes #18774

Signed-off-by: Daniel Pañeda <daniel.paneda@clickhouse.com>
2026-03-04 16:30:12 -08:00
M. J. Fromberger
26951a1cbb ipn/ipnlocal: skip writing netmaps to disk when disabled (#18883)
We use the TS_USE_CACHED_NETMAP knob to condition loading a cached netmap, but
were hitherto writing the map out to disk even when it was disabled. Let's not
do that; the two should travel together.

Updates #12639

Change-Id: Iee5aa828e2c59937d5b95093ea1ac26c9536721e
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2026-03-04 15:13:30 -08:00
Claus Lensbøl
ea1f1616b9 .github/workflows: enable natlab in CI
After fixing the flakey tests in #18811 and #18814 we can enable running
the natlab testsuite running on CI generally.

Fixes #18810

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
2026-03-04 15:02:07 -08:00
Brad Fitzpatrick
30adf4527b feature/portlist: address case where poller misses CollectServices updates
This is a minimal hacky fix for a case where the portlist poller extension
could miss updates to NetMap's CollectServices bool.

Updates tailscale/corp#36813

Change-Id: I9b50de8ba8b09e4a44f9fbfe90c9df4d8ab4d586
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-04 13:07:23 -08:00
Mike O'Driscoll
2c9ffdd188 cmd/tailscale,ipn,net/netutil: remove rp_filter strict mode warnings (#18863)
PR #18860 adds firewall rules in the mangle table to save outbound packet
marks to conntrack and restore them on reply packets before the routing
decision. When reply packets have their marks restored, the kernel uses
the correct routing table (based on the mark) and the packets pass the
rp_filter check.

This makes the risk check and reverse path filtering warnings unnecessary.

Updates #3310
Fixes tailscale/corp#37846

Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
2026-03-04 14:09:19 -05:00
Mike O'Driscoll
26ef46bf81 util/linuxfw,wgengine/router: add connmark rules for rp_filter workaround (#18860)
When a Linux system acts as an exit node or subnet router with strict
reverse path filtering (rp_filter=1), reply packets may
be dropped because they fail the RPF check. Reply packets arrive on the
WAN interface but the routing table indicates they should have arrived
on the Tailscale interface, causing the kernel to drop them.

This adds firewall rules in the mangle table to save outbound packet
marks to conntrack and restore them on reply packets before the routing
decision. When reply packets have their marks restored, the kernel uses
the correct routing table (based on the mark) and the packets pass the
rp_filter check.

Implementation adds two rules per address family (IPv4/IPv6):

- mangle/OUTPUT: Save packet marks to conntrack for NEW connections
with non-zero marks in the Tailscale fwmark range (0xff0000)

- mangle/PREROUTING: Restore marks from conntrack to packets for
ESTABLISHED,RELATED connections before routing decision and rp_filter
check

The workaround is automatically enabled when UseConnmarkForRPFilter is
set in the router configuration, which happens when subnet routes are
advertised on Linux systems.

Both iptables and nftables implementations are provided, with automatic
backend detection.

Fixes #3310
Fixes #14409
Fixes #12022
Fixes #15815
Fixes #9612

Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
2026-03-04 14:09:11 -05:00
Andrew Lytvynov
dab8922fcf go.mod: bump github.com/cloudflare/circl version (#18878)
Pick up a fix in https://pkg.go.dev/vuln/GO-2026-4550

Updates #cleanup

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2026-03-04 10:59:43 -08:00
Brad Fitzpatrick
d42b3743b7 net/porttrack: add net.Listen wrapper to help tests allocate ports race-free
Updates tailscale/corp#27805
Updates tailscale/corp#27806
Updates tailscale/corp#37964

Change-Id: I7bb5ed7f258e840a8208e5d725c7b2f126d7ef96
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-03 20:56:20 -08:00
Fran Bull
120f27f383 feature/conn25: stop adding multiple entries for same domain+dst
We should only add one entry to our magic ips for each domain+dst and
look up any existing entry instead of always creating a new one.

Fixes tailscale/corp#34252
Signed-off-by: Fran Bull <fran@tailscale.com>
2026-03-03 13:29:45 -08:00
Claus Lensbøl
2d21dd46cd wgengine/magicsoc,net/tstun: put disco key advertisement behind a nob (#18857)
To be less spammy in stable, add a nob that disables the creation and
processing of TSMPDiscoKeyAdvertisements until we have a proper rollout
mechanism.

Updates #12639

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
2026-03-03 09:04:37 -05:00
Alex Chan
0cca3bd417 wgengine/magicsock: improve error message for moving Mullvad node keys
The "public key moved" panic has caused confusion on multiple occasions,
and is a known issue for Mullvad. Add a loose heuristic to detect
Mullvad nodes, and trigger distinct panics for Mullvad and non-Mullvad
instances, with a link to the associated bug.

When this occurs again with Mullvad, it'll be easier for somebody to
find the existing bug.

If it occurs again with something other than Mullvad, it'll be more
obvious that it's a distinct issue.

Updates tailscale/corp#27300

Change-Id: Ie47271f45f2ff28f767578fcca5e6b21731d08a1
Signed-off-by: Alex Chan <alexc@tailscale.com>
2026-03-03 09:13:48 +00:00
Amal Bansode
8fd02bb626 types/geo: fix floating point bug causing NaN returns in SphericalAngleTo (#18777)
Subtle floating point imprecision can propagate and lead to
trigonometric functions receiving inputs outside their
domain, thus returning NaN. Clamp the input to the valid domain
to prevent this.

Also adds a fuzz test for SphericalAngleTo.

Updates tailscale/corp#37518

Signed-off-by: Amal Bansode <amal@tailscale.com>
2026-03-02 17:33:57 -08:00
Erisa A
5a2168da9e scripts/installer.sh: handle KDE Linux (#18861)
Display a message pointing to KDE Linux documentation on installing Tailscale

Fixes #18306

Signed-off-by: Erisa A <erisa@tailscale.com>
2026-03-02 18:29:49 +00:00
dependabot[bot]
eeb1fa047b .github: Bump actions/setup-go from 6.2.0 to 6.3.0
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6.2.0 to 6.3.0.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](7a3fe6cf4c...4b73464bb3)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: 6.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 09:52:11 -07:00
dependabot[bot]
e0ca836c99 .github: Bump github/codeql-action from 4.32.3 to 4.32.5
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.32.3 to 4.32.5.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](9e907b5e64...c793b717bc)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.32.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 09:49:25 -07:00
License Updater
3e8913f959 licenses: update license notices
Signed-off-by: License Updater <noreply+license-updater@tailscale.com>
2026-03-02 08:04:19 -08:00
Tom Proctor
2743e0b681 .github/actions/go-cache: check for pre-built cigocacher (#18833)
Some CI runner images now have cigocacher baked in. Skip building if
it's already present.

Updates tailscale/corp#35667

Change-Id: I5ea0d606d44b1373bc1c8f7bca4ab780e763e2a9

Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
2026-03-02 16:01:48 +00:00
James Tucker
48e0334aac tsnet: fix Listen for unspecified addresses and ephemeral ports
Normalize 0.0.0.0 and :: to wildcard in resolveListenAddr so listeners
match incoming connections.

Fix ephemeral port allocation across all three modes: extract assigned
ports from gVisor listeners (TUN TCP and UDP), and add an ephemeral port
allocator for netstack TCP.

Updates #6815
Updates #12182
Fixes #14042

Signed-off-by: James Tucker <jftucker@gmail.com>
2026-02-28 16:33:56 -08:00
James Tucker
142ce997cb .github/workflows: rename tidy workflow to match what it is
I was confused when everything I was reading in the CI failure was
saying `go mod tidy`, but the thing that was actually failing was
related to nix flakes. Rename the pipeline and step name to the `make
tidy` that it actually runs.

Updates #16637

Signed-off-by: James Tucker <james@tailscale.com>
2026-02-28 16:33:39 -08:00
James Tucker
fa13f83375 tsnet: fix deadlock in Server.Close during shutdown
Server.Close held s.mu for the entire shutdown duration, including
netstack.Close (which waits for gVisor goroutines to exit) and
lb.Shutdown. gVisor callbacks like getTCPHandlerForFlow acquire s.mu via
listenerForDstAddr, so any in-flight gVisor goroutine attempting that
callback during stack shutdown would deadlock with Close.

Replace the mu-guarded closed bool with a sync.Once, and release s.mu
after closing listeners but before the heavy shutdown operations. Also
cancel shutdownCtx before netstack.Close so pending handlers observe
cancellation rather than contending on the lock.

Updates #18423

Signed-off-by: James Tucker <james@tailscale.com>
2026-02-28 16:33:06 -08:00
James Tucker
439d84134d tsnet: fix slow test shutdown leading to flakes
TestDial in particular sometimes gets stuck in CI for minutes, letting
chantun drop packets during shutdown avoids blocking shutdown.

Updates #18423

Signed-off-by: James Tucker <jftucker@gmail.com>
2026-02-28 14:22:19 -08:00
James Tucker
45305800a6 net/netmon: ignore NetBird interface on Linux
Windows and macOS are not covered by this change, as neither have safely
distinct names to make it easy to do so. This covers the requested case
on Linux.

Updates #18824

Signed-off-by: James Tucker <james@tailscale.com>
2026-02-27 17:38:52 -08:00
James Tucker
0fb207c3d0 wgengine/netstack: deliver self-addressed packets via loopback
When a tsnet.Server dials its own Tailscale IP, TCP SYN packets are
silently dropped. In inject(), outbound packets with dst=self fail the
shouldSendToHost check and fall through to WireGuard, which has no peer
for the node's own address.

Fix this by detecting self-addressed packets in inject() using isLocalIP
and delivering them back into gVisor's network stack as inbound packets
via a new DeliverLoopback method on linkEndpoint. The outbound packet
must be re-serialized into a new PacketBuffer because outbound packets
have their headers parsed into separate views, but DeliverNetworkPacket
expects raw unparsed data.

Updates #18829

Signed-off-by: James Tucker <james@tailscale.com>
2026-02-27 14:30:41 -08:00
James Tucker
30e12310f1 cmd/tailscaled/*.{target,unit}: add systemd online target
Using the new wait command from #18574 provide a tailscale-online.target
that has a similar usage model to the conventional
`network-online.target`.

Updates #3340
Updates #11504

Signed-off-by: James Tucker <james@tailscale.com>
2026-02-26 18:39:28 -08:00
Brad Fitzpatrick
a98036b41d go.mod: bump gvisor
Updates #8043

Change-Id: Ia229ad4f28f2ff20e0bdecb99ca9e1bd0356ad8e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-02-26 18:29:36 -08:00
Claus Lensbøl
5ac35b665b client/systray: add installer for a freedesktop autostart file (#18767)
Adds freedesktop as an option for installing autostart desktop files for
starting the systray application.

Fixes #18766

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
2026-02-26 12:59:45 -05:00
Fernando Serboncini
da90ea664d wgengine/magicsock: only run derpActiveFunc after connecting to DERP (#18814)
derpActiveFunc was being called immediately as a bare goroutine,
before startGate was resolved. For the firstDerp case, startGate
is c.derpStarted which only closes after dc.Connect() completes,
so derpActiveFunc was firing before the DERP connection existed.

We now block it with the same logic used by runDerpReader and by
runDerpWriter.

Updates: #18810

Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
2026-02-26 12:36:26 -05:00
Brad Fitzpatrick
15836e5624 util/set: make Set.Slice return elements in sorted order for ordered types
This makes Set.MarshalJSON produce deterministic output in many cases now.
We still need to do make it deterministic for non-ordered types.

Updates #18808

Change-Id: I7f341ec039c661a8e88d07d7f4dc0f15d5d4ab86
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-02-26 08:40:06 -08:00