Skip to content
This repository was archived by the owner on Jul 13, 2025. It is now read-only.

Fork Sync: Update from parent repository#36

Open
github-actions[bot] wants to merge 1089 commits intoMultiMx:mainfrom
tailscale:main
Open

Fork Sync: Update from parent repository#36
github-actions[bot] wants to merge 1089 commits intoMultiMx:mainfrom
tailscale:main

Conversation

@github-actions
Copy link

No description provided.

irbekrm and others added 30 commits January 6, 2026 11:29
…on keys for stores that are not bound to a node (#18322)

Ensure that hardware attestation keys are not added to tailscaled
state stores that are Kubernetes Secrets or AWS SSM as those Tailscale
devices should be able to be recreated on different nodes, for example,
when moving Pods between nodes.

Updates #18302

Signed-off-by: Irbe Krumina <irbekrm@gmail.com>
…18225)

The funnel command is sort of an alias for the serve command. This means
that the subcommands added to serve to support Services appear as
subcommands for funnel as well, despite having no meaning for funnel.
This change removes all such Services-specific subcommands from funnel.

Fixes tailscale/corp#34167

Signed-off-by: Harry Harpham <harry@tailscale.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.2 to 5.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@11bd719...08c6903)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bump peter-evans/create-pull-request to 8.0.0 to ensure compatibility
with actions/checkout 6.x.

Updates #cleanup

Signed-off-by: Mario Minardi <mario@tailscale.com>
…18334)

Moves magicksock.cloudInfo into util/cloudinfo with minimal changes.

Updates #17796

Change-Id: I83f32473b9180074d5cdbf00fa31e5b3f579f189

Signed-off-by: Alex Valiushko <alexvaliushko@tailscale.com>
…rvices (#17752)

Fixes #17749.

Signed-off-by: Naman Sood <mail@nsood.in>
Updates #35374

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Fixes tailscale/corp#34430

Signed-off-by: Raj Singh <raj@tailscale.com>
…18182)

Raw Linux consoles support UTF-8, but we cannot assume that all UTF-8
characters are available. The default Fixed and Terminus fonts don’t
contain half-block characters (`▀` and `▄`), but do contain the
full-block character (`█`).

Sometimes, Linux doesn’t have a framebuffer, so it falls back to VGA.
When this happens, the full-block character could be anywhere in
extended ASCII block, because we don’t know which code page is active.

This PR introduces `--qr-format=auto` which tries to heuristically
detect when Tailscale is printing to a raw Linux console, whether
UTF-8 is enabled, and which block characters have been mapped in the
console font.

If Unicode characters are unavailable, the new `--qr-format=ascii`
formatter uses `#` characters instead of full-block characters.

Fixes #12935

Signed-off-by: Simon Law <sfllaw@tailscale.com>
…17415)

* cmd/k8s-operator/e2e: run self-contained e2e tests with devcontrol

Adds orchestration for more of the e2e testing setup requirements to
make it easier to run them in CI, but also run them locally in a way
that's consistent with CI. Requires running devcontrol, but otherwise
supports creating all the scaffolding required to exercise the operator
and proxies.

Updates tailscale/corp#32085

Change-Id: Ia7bff38af3801fd141ad17452aa5a68b7e724ca6
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>

* cmd/k8s-operator/e2e: being more specific on tmp dir cleanup

Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>

---------

Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
Co-authored-by: chaosinthecrd <tom@tmlabs.co.uk>
It's not worth adding the v2 client just for these e2e tests. Remove
that dependency for now to keep a clear separation, but we should revive
the v2 client version if we ever decide to take that dependency for the
tailscale/tailscale repo as a whole.

Updates tailscale/corp#32085

Change-Id: Ic51ce233d5f14ce2d25f31a6c4bb9cf545057dd0
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Brings in tailscale/mkctr#29.

Updates tailscale/corp#32085

Change-Id: I90160ed1cdc47118ac8fd0712d63a7b590e739d3

Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Updates #7436

Signed-off-by: Andrew Dunham <andrew@tailscale.com>
QR codes are used by `tailscale up --qr` to provide an easy way to
open a web-page without transcribing a difficult URI. However, there’s
no need for this feature if the client will never be called
interactively. So this PR adds the `ts_omit_qrcodes` build tag.

Updates #18182

Signed-off-by: Simon Law <sfllaw@tailscale.com>
Add support for authenticating the gitops-pusher using workload identity
federation.

Updates tailscale/corp#34172

Signed-off-by: Mario Minardi <mario@tailscale.com>
To prevent peer relay servers from sending packets *over* Tailscale.

Updates tailscale/corp#35651

Signed-off-by: Jordan Whited <jordan@tailscale.com>
Prior to this change, we were resetting the tsnet's serve config every
time tsnet.Server.Up was run. This is important to do on startup, to
prevent messy interactions with stale configuration when the code has
changed.

However, Up is frequently run as a just-in-case step (for example, by
Server.ListenTLS/ListenFunnel and possibly by consumers of tsnet). When
the serve config is reset on each of these calls to Up, this creates
situations in which the serve config disappears unexpectedly. The
solution is to reset the serve config only on the first call to Up.

Fixes #8800
Updates tailscale/corp#27200
Signed-off-by: Harry Harpham <harry@tailscale.com>
Previously the funnel listener would leave artifacts in the serve
config. This caused weird out-of-sync effects like the admin panel
showing that funnel was enabled for a node, but the node rejecting
packets because the listener was closed.

This change resolves these synchronization issues by ensuring that
funnel listeners clean up the serve config when closed.

See also:
e109cf9

Updates #cleanup
Signed-off-by: Harry Harpham <harry@tailscale.com>
Updates #cleanup

Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
Expose the node's home DERP region ID as a Prometheus gauge via the
usermetrics endpoint.

Fixes #18061

Signed-off-by: Raj Singh <raj@tailscale.com>
Updates #18376 (follow up on feedback)
Signed-off-by: Harry Harpham <harry@tailscale.com>
Updates #cleanup
Signed-off-by: Harry Harpham <harry@tailscale.com>
Fixes a bug where, for kube HA proxies, TLS certs for the replica
responsible for cert issuance where loaded in memory on startup,
although the in-memory store was not updated after renewal (to
avoid failing re-issuance for re-created Ingresses).
Now the 'write' replica always reads certs from the kube Secret.

Updates #18394

Signed-off-by: Irbe Krumina <irbekrm@gmail.com>
…#18398)

Recently, the golangci-lint workflow has been taking longer and longer
to complete, causing it to timeout after the default of 5 minutes.

    Running error: context loading failed: failed to load packages: failed to load packages: failed to load with go/packages: context deadline exceeded
    Timeout exceeded: try increasing it by passing --timeout option

This PR upgrades actions/setup-go to version 6, the latest, and
enables caching for Go modules and build outputs. This should speed up
linting because most packages won’t have to be downloaded over and
over again.

Fixes #18366

Signed-off-by: Simon Law <sfllaw@tailscale.com>
Updates tailscale/corp#31174

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
Updates tailscale/corp#31174

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
…#18373)

Adds the ability to detect what provider the client is running on and tries fetch the ID token to use with Workload Identity.

Updates tailscale/corp#33316

Signed-off-by: Danni Popova <danni@tailscale.com>
…ck to ./tool/go (#18409)

If local tailscale/tailscale checkout is not available,
pulll cigocacher remotely.
Fall back to ./tool/go if no other Go installation
is present.

Updates tailscale/corp#32493

Signed-off-by: Irbe Krumina <irbekrm@gmail.com>
Allow for optionally specifiying an audience for tsnet. This is passed
to the underlying identity federation logic to allow for tsnet auth to
use automatic ID token generation for authentication.

Updates tailscale/corp#33316

Signed-off-by: Mario Minardi <mario@tailscale.com>
Allow for optionally specifying an audience for containerboot. This is
passed to tailscale up to allow for containerboot to use automatic ID
token generation for authentication.

Updates tailscale/corp#34430

Signed-off-by: Mario Minardi <mario@tailscale.com>
bradfitz and others added 30 commits March 5, 2026 14:28
Otherwise it gets confused on new(123) etc.

Updates #18682

Change-Id: I9e2e93ea24f2b952b2396dceaf094b4db64424b0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Updates #18682

Change-Id: I62f6aa0de2a15ef8c1435032c6aa74a181c25f8f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We override 1.26, but its not in the old commit we are tracking.

Updates #18682

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
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>
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>
…rver 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>
Updates #18682

Change-Id: I855c0dfa4c61eb33123bbb7b00c1ab5506e80b09
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
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>
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>
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>
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>
…eardown

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>
This picks up the change in tailscale/go@5cce30e

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

Signed-off-by: Nick Khyl <nickk@tailscale.com>
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>
…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: tailscale/corp#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>
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>
Updates tailscale/corp#36382

Change-Id: Ida55b7b1a2cdd0a4653bb41852008e7088fc4a48
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
…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>
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>
…laky again

Updates #7707

Change-Id: I98cdace78cd5060643894fb0c9be02574edb2894
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
Updates #12639
Updates tailscale/corp#24454

Change-Id: I2361206aec197a7eecbdf29d87b1b75335ee8eec
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
#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 969927c)

Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Co-authored-by: chaosinthecrd <tom@tmlabs.co.uk>
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 #13420

Change-Id: I7b090a4dc229a862c1a52161b3f2547ec1d1f23f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
…nge (#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 #2855

Signed-off-by: kari-ts <kari@tailscale.com>
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 #6152

Signed-off-by: kari-ts <kari@tailscale.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.