Commit Graph

10281 Commits

Author SHA1 Message Date
Tom Proctor 621f71981c cmd/k8s-operator: fix Service reconcile triggers for default ProxyClass (#18983)
The e2e ingress test was very occasionally flaky. On looking at operator
logs from one failure, you can see the default ProxyClass was not ready
before the first reconcile loop for the exposed Service. The ProxyClass
became ready soon after, but no additional reconciles were triggered for
the exposed Service because we only triggered reconciles for Services
that explicitly named their ProxyClass.

This change adds additional list API calls for when it's the default
ProxyClass that's been updated in order to catch Services that use it by
default. It also adds indexes for the fields we need to search on to
ensure the list is efficient.

Fixes tailscale/corp#37533

Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
2026-03-13 14:31:16 +00:00
Brad Fitzpatrick dd480f0fb9 gokrazy: fix busybox breakglass support, add test
Updates #1866

Change-Id: Ica73ae8268b08a04ae97bc570869a04180585e75
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-12 11:25:31 -07:00
Mike O'Driscoll 7412fc00ac flake.nix: update build to use buildGo126Module (#18977)
Updates #fixup

Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
2026-03-12 10:42:41 -04:00
Kristoffer Dalby be62e6dc68 tsnet: make tsnet fallback to control url from environment
This commit adds a "fallback" mechanism to tsnet to allow
the consumer to set "TS_CONTROL_URL" to override the control server.

This allows tsnet applications to gain support for an alternative
control server by just updating without explicitly exposing the
ControlURL option.

Updates #16934

Signed-off-by: Kristoffer Dalby <kristoffer@dalby.cc>
2026-03-12 05:06:55 -07:00
dependabot[bot] 0a4e0e2940 .github: Bump github/codeql-action from 4.32.5 to 4.32.6
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.32.5 to 4.32.6.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/c793b717bc78562f491db7b0e93a3a178b099162...0d579ffd059c29b07949a3cce3983f0780820c98)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-11 22:13:04 -06:00
dependabot[bot] 224305b577 .github: Bump actions/download-artifact from 7.0.0 to 8.0.0
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7.0.0 to 8.0.0.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/37930b1c2abaa49bbe596cd826c3c89aef350131...70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-11 22:12:39 -06:00
dependabot[bot] 0c53cf7ad9 .github: Bump actions/upload-artifact from 6.0.0 to 7.0.0
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6.0.0 to 7.0.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/b7c566a772e6b6bfb58ed0dc250532a479d7789f...bbbca2ddaa5d8feaa63e36b76fdaad77386f024f)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-11 21:36:40 -06:00
Brad Fitzpatrick 073a9a8c9e wgengine{,/magicsock}: add DERP hooks for filtering+sending packets
Add two small APIs to support out-of-tree projects to exchange custom
signaling messages over DERP without requiring disco protocol
extensions:

- OnDERPRecv callback on magicsock.Options / wgengine.Config: called for
  every non-disco DERP packet before the peer map lookup, allowing callers
  to intercept packets from unknown peers that would otherwise be dropped.

- SendDERPPacketTo method on magicsock.Conn: sends arbitrary bytes to a
  node key via a DERP region, creating the connection if needed. Thin
  wrapper around the existing internal sendAddr.

Also allow netstack.Start to accept a nil LocalBackend for use cases
that wire up TCP/UDP handlers directly without a full LocalBackend.

Updates tailscale/corp#24454

Change-Id: I99a523ef281625b8c0024a963f5f5bf5d8792c17
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-11 16:37:19 -07:00
kari-ts 4c7c1091ba netns: add Android callback to bind socket to network (#18915)
After switching from cellular to wifi without ipv6, ForeachInterface still sees rmnet prefixes, so HaveV6 stays true, and magicsock keeps attempting ipv6 connections that either route through cellular or time out for users on wifi without ipv6

This:
-Adds SetAndroidBindToNetworkFunc, a callback to bind the socket to the selected Android Network object

Updates tailscale/tailscale#6152

Signed-off-by: kari-ts <kari@tailscale.com>
2026-03-11 12:28:28 -07:00
kari-ts dd1da0b389 wgengine: search randomly for unused port instead of in contiguous range (#18974)
In TestUserspaceEnginePortReconfig, when selecting a port, use a random offset rather than searching in a continguous range in case there is a range that is blocked

Updates tailscale/tailscale#2855

Signed-off-by: kari-ts <kari@tailscale.com>
2026-03-11 12:21:50 -07:00
Jordan Whited 607d01cdae net/batching: clarify & simplify single packet read limitations
ReadFromUDPAddrPort worked if UDP GRO was unsupported, but we don't
actually want attempted usage, nor does any exist today. Future work
on tailscale/corp#37679 would have required more complexity in this
method, vs clarifying the API intents.

Updates tailscale/corp#37679

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2026-03-11 10:25:58 -07:00
Brad Fitzpatrick 70de111394 wgengine/magicsock: fix three race conditions in TestTwoDevicePing
Fix three independent flake sources, at least as debugged by Claude,
though empirically no longer flaking as it was before:

1. Poll for connection counter data instead of reading immediately.
   The conncount callback fires asynchronously on received WireGuard
   traffic, so after counts.Reset() there is no guarantee the counter
   has been repopulated before checkStats reads it. Use tstest.WaitFor
   with a 5s timeout to retry until a matching connection appears.

2. Replace the *2 symmetry assumption in global metric assertions.
   metricSendUDP and friends are AggregateCounters that sum per-conn
   expvars from both magicsock instances. The old assertion assumed
   both instances had identical packet counts, which breaks under
   asymmetric background WireGuard activity (handshake retries, etc).
   The new assertGlobalMetricsMatchPerConn computes the actual sum of
   both conns' expvars and compares against the AggregateCounter value.

3. Tolerate physical stats being 0 when user metrics are non-zero.
   A rebind event replaces the socket mid-measurement, resetting the
   physical connection counter while user metrics still reflect packets
   processed before the rebind. Log instead of failing in this case.
   Also move counts.Reset() after metric reads and reorder the reset
   sequence (counts before metrics) to minimize the race window.

Fixes tailscale/tailscale#13420

Change-Id: I7b090a4dc229a862c1a52161b3f2547ec1d1f23f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-11 07:34:52 -07:00
Tom Proctor 95a135ead1 cmd/{containerboot,k8s-operator}: reissue auth keys for broken proxies (#16450)
Adds logic for containerboot to signal that it can't auth, so the
operator can reissue a new auth key. This only applies when running with
a config file and with a kube state store.

If the operator sees reissue_authkey in a state Secret, it will create a
new auth key iff the config has no auth key or its auth key matches the
value of reissue_authkey from the state Secret. This is to ensure we
don't reissue auth keys in a tight loop if the proxy is slow to start or
failing for some other reason. The reissue logic also uses a burstable
rate limiter to ensure there's no way a terminally misconfigured
or buggy operator can automatically generate new auth keys in a tight loop.

Additional implementation details (ChaosInTheCRD):

- Added `ipn.NotifyInitialHealthState` to ipn watcher, to ensure that
  `n.Health` is populated when notify's are returned.
- on auth failure, containerboot:
  - Disconnects from control server
  - Sets reissue_authkey marker in state Secret with the failing key
  - Polls config file for new auth key (10 minute timeout)
  - Restarts after receiving new key to apply it

- modified operator's reissue logic slightly:
  - Deletes old device from tailnet before creating new key
  - Rate limiting: 1 key per 30s with initial burst equal to replica count
  - In-flight tracking (authKeyReissuing map) prevents duplicate API calls
    across reconcile loops

Updates #14080

Change-Id: I6982f8e741932a6891f2f48a2936f7f6a455317f


(cherry picked from commit 969927c47c3d4de05e90f5b26a6d8d931c5ceed4)

Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Co-authored-by: chaosinthecrd <tom@tmlabs.co.uk>
2026-03-11 10:25:57 +00:00
Gesa Stupperich 7a43e41a27 client/web: signal need to wait for auth across tabs
This amends the session creation and auth status querying logic of the device UI
backend. On creation of new browser sessions we now store a PendingAuth flag
as part of the session that indicates a pending auth process that needs to be
awaited. On auth status queries, the server initiates a polling for the auth result
if it finds this flag to be true. Once the polling is completes, the flag is set to false.

Why this change was necessary: with regular browser settings, the device UI
frontend opens the control auth URL in a new tab and starts polling for the
results of the auth flow in the current tab. With certain browser settings (that
we still want to support), however, the auth URL opens in the same tab, thus
aborting the subsequent call to auth/session/wait that initiates the polling,
and preventing successful registration of the auth results in the session
status. The new logic ensures the polling happens on the next call to /api/auth
in these kinds of scenarios.

In addition to ensuring the auth wait happens, we now also revalidate the auth
state whenever an open tab regains focus, so that auth changes effected in one
tab propagate to other tabs without the need to refresh. This improves the
experience for all users of the web client when they've got multiple tabs open,
regardless of their browser settings.

Fixes #11905

Signed-off-by: Gesa Stupperich <gesa@tailscale.com>
2026-03-11 08:15:21 +00:00
Brad Fitzpatrick 16fa81e804 wgengine: add API to force a disco key for experiments, testing
Updates #12639
Updates tailscale/corp#24454

Change-Id: I2361206aec197a7eecbdf29d87b1b75335ee8eec
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-10 20:42:29 -07:00
Brad Fitzpatrick f905871fb1 ipn/ipnlocal, feature/ssh: move SSH code out of LocalBackend to feature
This makes tsnet apps not depend on x/crypto/ssh and locks that in with a test.

It also paves the wave for tsnet apps to opt-in to SSH support via a
blank feature import in the future.

Updates #12614

Change-Id: Ica85628f89c8f015413b074f5001b82b27c953a9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-10 17:27:17 -07:00
Brad Fitzpatrick 99e3e9af51 ssh/tailssh: mark TestSSHRecordingCancelsSessionsOnUploadFailure as flaky again
Updates #7707

Change-Id: I98cdace78cd5060643894fb0c9be02574edb2894
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-10 15:49:54 -07:00
Brad Fitzpatrick 99bde5a406 tstest/integration: deflake TestCollectPanic
Two issues caused TestCollectPanic to flake:

1. ETXTBSY: The test exec'd the tailscaled binary directly without
   going through StartDaemon/awaitTailscaledRunnable, so it lacked
   the retry loop that other tests use to work around a mysterious
   ETXTBSY on GitHub Actions.

2. Shared filch files: The test didn't pass --statedir or TS_LOGS_DIR,
   so all parallel test instances wrote panic logs to the shared system
   state directory (~/.local/share/tailscale). Concurrent runs would
   clobber each other's filch log files, causing the second run to not
   find the panic data from the first.

Fix both by adding awaitTailscaledRunnable before the first exec, and
passing --statedir and TS_LOGS_DIR to isolate each test's log files,
matching what StartDaemon does.

It now passes x/tools/cmd/stress.

Fixes #15865

Change-Id: If18b9acf8dbe9a986446a42c5d98de7ad8aae098
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-10 14:16:47 -07:00
Mike O'Driscoll 021de2e1bc util/linuxfw: fix nil pointer panic in connmark rules without IPv6 (#18946)
When IPv6 is unavailable on a system, AddConnmarkSaveRule() and
DelConnmarkSaveRule() would panic with a nil pointer dereference.
Both methods directly iterated over []iptablesInterface{i.ipt4, i.ipt6}
without checking if ipt6 was nil.

Use `getTables()` instead to properly retrieve the available tables
on a given system

Fixes #3310

Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
2026-03-10 15:19:15 -04:00
Brad Fitzpatrick 525f7a1e47 types/key: add NodePrivate.Raw32 and DiscoPrivateFromRaw32
Raw byte accessors for key types, mirroring existing patterns
(NodePublic.Raw32 and DiscoPublicFromRaw32 already exist).

NodePrivate.Raw32 returns the raw 32 bytes of a node private key.
DiscoPrivateFromRaw32 parses a 32-byte raw value as a DiscoPrivate.

Updates tailscale/corp#24454

Change-Id: Ibc08bed14ab359eddefbebd811c375b6365c7919
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-10 07:36:35 -07:00
Brad Fitzpatrick 32adca78f1 pull-toolchain.sh: advance the next hash if it's behind
Updates tailscale/corp#36382

Change-Id: Ida55b7b1a2cdd0a4653bb41852008e7088fc4a48
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-10 06:58:53 -07:00
Jason O'Donnell 16c4780f0a go.toolchain.next.rev: update to final Go 1.26.1 [next] (#18939)
This updates the TS_GO_NEXT=1 (testing) toolchain to Go 1.26.1

The default one is still Go 1.26.0.

Updates #18682

Signed-off-by: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com>
2026-03-10 08:23:01 -04:00
David Bond 9522619031 cmd/k8s-operator: use correct tailnet client for L7 & L3 ingresses (#18749)
* cmd/k8s-operator: use correct tailnet client for L7 & L3 ingresses

This commit fixes a bug when using multi-tailnet within the operator
to spin up L7 & L3 ingresses where the client used to create the
tailscale services was not switching depending on the tailnet used
by the proxygroup backing the service/ingress.

Updates: https://github.com/tailscale/corp/issues/34561

Signed-off-by: David Bond <davidsbond93@gmail.com>

* cmd/k8s-operator: adding server url to proxygroups when a custom tailnet has been specified

Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
(cherry picked from commit 3b21ac5504e713e32dfcd43d9ee21e7e712ac200)

---------

Signed-off-by: David Bond <davidsbond93@gmail.com>
Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
Co-authored-by: chaosinthecrd <tom@tmlabs.co.uk>
2026-03-10 10:33:55 +00:00
Brad Fitzpatrick 0023f1a969 .github/workflows: use tailscale/go for Windows CI too
We did so for Linux and macOS already, so also do so for Windows. We
only didn't already because originally we never produced binaries for
it (due to our corp repo not needing them), and later because we had
no ./tool/go wrapper. But we have both of those things now.

Updates #18884

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-09 15:36:24 -07:00
Nick Khyl 8d3efd488d go.mod: bump for internal/poll: move rsan to heap on windows
This picks up the change in tailscale/go@5cce30e20c

Updates #18884
Updates tailscale/go#158
Updates golang/go#77975

Signed-off-by: Nick Khyl <nickk@tailscale.com>
2026-03-09 16:48:31 -05:00
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>
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