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 1822 commits into
MultiMx:mainfrom
tailscale:main
Open

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

Conversation

@github-actions

Copy link
Copy Markdown

No description provided.

fserb and others added 30 commits June 7, 2026 13:24
…hs (#20020)

Assign the Kubernetes operator, kube libraries, container build
commands, and related paths to @tailscale/k8s-devs.

Updates #cleanup

Change-Id: I9d8c7ebfd9a2b6401dd8cb0ff335151afe58357c

Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
To avoid breaking downstream code, add deprecated aliases for all the
old names.

Updates tailscale/corp#37904

Change-Id: I86d0b0d7da371946440b181c665448f91c3ef8d2
Signed-off-by: Alex Chan <alexc@tailscale.com>
Track lastSeen on each cached flow and add a sweeper goroutine
that periodically removes flows idle past the idle timeout.

Introduce tunables for idle timeout, maximum flows removed per sweep (to
limit mutex hold time), and the sweeper interval.

Also cap the previously-unlimited tables: 10k client flows, 100k
connector flows.

Updates tailscale/corp#38630

Signed-off-by: Michael Ben-Ami <mzb@tailscale.com>
…20051)

Add a vmtest that guards the fix in #20025: after an in-process control
client swap (profile switch / interactive re-login), magicsock's NetInfo
dedup cache (netInfoLast) must be cleared so the structurally-identical
post-switch NetInfo (same PreferredDERP, same NAT shape) is re-reported to
the new control session rather than suppressed as unchanged.

The test brings a node up, pins its home DERP so the reported NetInfo is
identical across the switch, records the home DERP the test control learned,
switches to a fresh login profile on the same control/network/NAT/DERP, and
asserts the control re-learns the same non-zero home DERP for the node's new
identity. Without ResetNetInfoLast the assertion times out at HomeDERP=0.

To support this, vnet now serves the test control on port 443 (TLS) in
addition to port 80: an immediate re-login makes a fresh noise dial, and
because the prior dial was recent the control client forces an HTTPS (443)
dial (controlhttp.Dialer.forceNoise443), which the harness previously did
not answer. The control endpoint gets its own self-signed cert (the existing
selfSignedDERPCert helper, renamed to the generic selfSignedCert); the cert
is not validated since control noise dials authenticate via the Noise
handshake, so it only needs a TLS peer to complete the forced 443 dial.

Add Env.ForcePreferredDERP and Env.Relogin helpers for the above.

Updates #20024

Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
Did you know that Gilbert Baker used the Pantone color scale when
designing the rainbow flag? I suppose that's not too surprising. There
are also other color scales like munsell and werner. I guess the rainbow
itself is a color scale, with its seven "roygbiv" colors. (It's also
a fish, with both a tail and scales.) We have so many ways to measure
color on so many different scales. And it turns out "pride" itself is
a scale.

Updates #words

Signed-off-by: Will Norris <will@tailscale.com>
macOS 26.4 emits RTM_MISS on the routing socket for every failed route
lookup. skipRouteMessage never inspected the message type, so each miss
woke the monitor as a link change and triggered a netcheck. On networks
without an IPv6 default route the netcheck's IPv6 DERP probes fail and
emit more RTM_MISS messages, sustaining the loop indefinitely: netchecks
run at roughly 40x the intended rate, with sustained probe traffic and
corresponding CPU and battery cost.

RTM_MISS scales with traffic volume, not network state, and is never
the leading signal for a topology change: route withdrawals emit
RTM_DELETE synchronously before any subsequent lookup can miss, so
ignoring it loses no signal. Other routing daemons (bird, dhcpcd, frr)
ignore it as well.

Same fix as coder/tailscale@e956a950741f.

Fixes #19324

Signed-off-by: Doug Bryant <dougbryant@anthropic.com>
Fixes #17188

Signed-off-by: Anthony SCHWARTZ <antho.schwartz@gmail.com>
Signed-off-by: Anthony SCHWARTZ <anthony.schwartz@ext.ec.europa.eu>
This removes deprecated magic-dns formats for 4via6 subnet routers.

These are superseded by the current format: Q-R-S-T-via-X.

Fixes #20053

Change-Id: I0eed1f057f856f248c4dc8ce3b751f6c7edcfbfd

Signed-off-by: Becky Pauley <becky@tailscale.com>
New-style IPN bus subscribers consume stateful delta streams. Reject
NotifyRateLimit when it is combined with those subscription bits so
tailscaled cannot merge or delay messages that clients need to apply in
order.

Also stop silently dropping notifications when a watcher falls behind.
Remove the watcher, replace its stale queue with one terminal ErrMessage
notification, and close the watch.

Updates #20062

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

Signed-off-by: Adriano Sela Aviles <adriano@tailscale.com>
Add NotifyInProcessNoDisconnect for in-process IPN bus subscribers that
must apply every bus update. When such a subscriber falls behind, block
Notify production instead of sending the terminal fell-behind message and
closing the watch.

This is intentionally not available over LocalAPI, where a slow or stuck
out-of-process client should still be disconnected rather than allowed to
stall tailscaled. In-process callers that use the bit must keep their
callbacks fast and must not call back into LocalBackend from the callback.

Updates #20062

Change-Id: I730ad61a07475243bb226fba2262c1a3ded211ae
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Updates tailscale/corp#43105

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
For real, we're supposed to use min, not max.

Updates tailscale/corp#43105

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This commit modifies the reconciler for the `Tailnet` custom resource
to allow referenced secrets to specify an `audience` field. If a
referenced secret contains both an `audience` and `client_id` we assume
the user's intention is to use workload identity.

In that case, we configure the tailscale API client to authenticate
using the Kubernetes token request API against the operator's service
account. This requires the operator to be aware of its own service
account name.

A small change has also been made to the messages added to the `Tailnet`
CRD's status field in the even that it is missing scopes to make it
clearer that certain scopes may not be applied.

Closes: #19090
Updates: #19471

Signed-off-by: David Bond <davidsbond93@gmail.com>
…ndpoints (#20088)

9be2108 changed sending disco pings so
a callMeMaybe would be not be gated by endpoints existing if the node
was running off of a cached netmap.

This commit partly reverts that change, but keeps in a few bug fixes in
that commit and the tests that was introduced and now skipped.

The behaviour prior to 9be2108 is
retained.

Updates #20085

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
…es (#20084)

The 1 minute timeout was hitting timers inside wireguard-go, leading
stale connections hanging forever. Increasing the timeout to 2 minutes
makes a small subset of cached connections establish direct connections
slightly slower.

Updates to wireguard-go will allow a better hook for when to send these
messages in the future. This change only makes fixes the error mode but
if we have better triggers coming in wireguard-go, we should be using
those.

Updates #20081

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
We aren't supposed to be using CODEOWNERS as blocking
reviews, blocking global cleanups.

(This is why we want to move to go/policybot)

Updates tailscale/corp#13972

Change-Id: I380258e2d4ffd0720d57d891adab06c8ca388617
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Updates tailscale/corp#43243
Updaets #20067

Change-Id: I27e19f34e2216f3ac1a4e2a6b38c0ac473b8c7ad
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I previously (in #20096) had only considered the tailscaled deps
and forgot about the CLI deps. This does the CLI ones too.

containerboot and k8s-operator aren't applicable because they build
from oss already.

Updates tailscale/corp#43243
Updates #20067

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

Change-Id: Ib6ff2e678670ecc001207a0b8be02b035958cb88
Signed-off-by: Alex Chan <alexc@tailscale.com>
Updates #cleanup

Change-Id: I088aa91218354f6208190c8f6673f9c5a98e65fc
Signed-off-by: Alex Chan <alexc@tailscale.com>
Prevent tailscale ssh from automatically adding a username when
connecting to a server, only forward one if provided. The previous
behaviour prevented username overrides in the ssh configuration, since
the provided username takes precedence to the configured one.

This also keeps the tailscale ssh a thin wrapper around ssh by not
adding any extra arguments unless required.

Fixes #19357

Signed-off-by: Örjan Fors <o@42mm.org>
* cmd/k8s-operator: rework [unexpected] log lines

This commit modifies several places in the operator logs where we
prepend `[unexpected]` to instead use an appropriate logging level.

The `[unexpected]` prefix is intended to be used when the program
violates some internal invariant (or for example, a database has
become corrupted). Many of these cases were simply log lines that
then fell back to a default value/behaviour. These have been releveled
to warnings.

Some of these log lines also seemed extraeneous as for the example of
service reconcilers logging when there is no proxy group annotation. As
far as I can tell we've never had any predicates for limiting the
services reconciled to ones with that annotation, so they can just
be removed to reduce log spam.

Fixes: #cleanup

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

* Update cmd/k8s-operator/egress-services-readiness.go

Co-authored-by: BeckyPauley <64131207+BeckyPauley@users.noreply.github.com>
Signed-off-by: David Bond <davidsbond@users.noreply.github.com>

* Update cmd/k8s-operator/operator.go

Co-authored-by: BeckyPauley <64131207+BeckyPauley@users.noreply.github.com>
Signed-off-by: David Bond <davidsbond@users.noreply.github.com>

---------

Signed-off-by: David Bond <davidsbond93@gmail.com>
Signed-off-by: David Bond <davidsbond@users.noreply.github.com>
Co-authored-by: BeckyPauley <64131207+BeckyPauley@users.noreply.github.com>
… extensions

When a client's node key expires and the user clicks "Login" (or runs
`tailscale up`), the Login() method was cancelling the map poll context.
This caused key extension notifications from the server to be lost,
leaving clients stuck in NeedsLogin state even after an admin extended
their key.

The fix has three parts:

1. Login(): Don't cancel mapCtx if we have valid credentials (loggedIn=true)
   or a valid node key. This allows the map poll to continue receiving
   server notifications while the auth flow proceeds in parallel.

2. mapRoutine(): Poll when we have a node key, even if !loggedIn. This
   handles the tsnet restart scenario where control returns an AuthURL
   (so loggedIn=false) but we still have a valid node key that can
   receive map updates.

3. sendStatus()/UpdateFullNetmap(): Forward netmaps when we have a node
   key, not just when loggedIn. This ensures the backend sees key expiry
   changes even when the auth flow hasn't completed.

"First successful flow wins": if a key extension arrives via map poll,
the client recovers automatically. If the auth flow completes first,
that works too. Either way, the client is no longer stuck.

This aligns with the SeamlessKeyRenewal philosophy: maintain connectivity
paths while authentication proceeds, allowing server-initiated recovery.

Fixes #19326

Change-Id: I26dbbc1fa7c1159ba075362e44d02814355d6b44
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
authRoutine snapshots c.loginGoal, runs TryLogin without the lock,
then writes back loggedIn/loginGoal under the lock. If a concurrent
Login() or Logout() changes the goal during the in-flight request,
the write-back overwrites the new intent: the more recent login goal
is silently dropped, or a logout is reverted to logged-in.

Gate both the URL-followup and success commits on c.loginGoal still
matching the goal we were processing. Stale results are ignored and
the next iteration runs with the current goal.

Updates #19326

Signed-off-by: Gesa Stupperich <gesa@tailscale.com>
This adds testcontrol support for expiring individual node keys,
in order to enable test scenarios involving to key-expiry and
 extension.

Updates #19326

Signed-off-by: Gesa Stupperich <gesa@tailscale.com>
Updates #19326

Signed-off-by: Gesa Stupperich <gesa@tailscale.com>
Dissallow purely numeric usernames for SSH as these are ambiguous with
numeric UID values.

Updates tailscale/corp#43245

Signed-off-by: Mario Minardi <mario@tailscale.com>
…KUBECONFIG (#20009)

When running under the macOS sandbox, "tailscale configure kubeconfig"
refused outright whenever $KUBECONFIG was set, assuming the path would
not be writable. Yet when $KUBECONFIG was unset it happily relied on the
home-relative-path entitlement to write to ~/.kube/config, so the two
paths made inconsistent assumptions about what the sandbox can reach.

Resolve the kubeconfig path first, then check whether the target file
(or the nearest existing parent directory) is actually writable. Only
report an error if it is not, and include macOS sandbox guidance in that
error since a path outside the home directory is the likely cause. This
lets a $KUBECONFIG that does point under the home directory work, rather
than being rejected unconditionally.

Fixes #20007

Change-Id: I9880363c38b981efaed7e97367851ddacf647be1

Signed-off-by: James Tucker <james@tailscale.com>
…nections (#19991)

Adds tailscaled_serve_{inbound,outbound}_bytes_total, labeled by Tailscale
Service name, by wrapping the peer-facing conn in tcpHandlerForVIPService.
Per-service counters persist for the process lifetime rather than being
evicted on serve-config changes.

Fixes #19572

Signed-off-by: Raj Singh <raj@tailscale.com>
Co-authored-by: Ethan Smith <ethan.smith@grafana.com>
bradfitz and others added 30 commits July 15, 2026 10:12
… hook

The ExtraWireGuardAllowedIPs hook was called once per peer on every
authReconfig, so each netmap delta paid an O(n) scan over all peers
even when conn25 (the only implementer) wasn't configured and every
call returned nothing.

Invert the API: the hook now receives an iter.Seq2 of the current
peers and returns the extra prefixes keyed by node ID. An idle
extension returns nil without iterating, so the unconfigured case
does no per-peer work at all.

With this, the runtime.DidRange analysis (see the ts_rangehook test)
no longer reports the updateRouteManagerExtras peer scan on netmap
deltas.

Updates #12542

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I9181e77416fa22f4c904620d42e9bcb934165216
… path

Processing a peer add/remove delta still materialized the full netmap
(an O(n) slicesx.MapValues plus sort over all peers, at 10k+
peers in a large tailnet) twice per delta: once in UpdateNetmapDelta
purely to hand the self node to Engine.SetSelfNode, and once in
authReconfigLocked.

Neither needs peers anymore. SetSelfNode gets the self node from the
existing nodeBackend.Self accessor. authReconfigLocked only reads
self-node fields (SelfNode, NodeKey, GetAddresses, HasCap) now that
WireGuard peers ride the incremental route manager and per-peer config
source, so it can use the peers-free NetMap accessor.

That also makes nmcfg.WGCfg vestigial: since wgcfg.Config lost its
Peers field, its peer walk existed only to emit the [v1] skip logs
(expired peers, unselected exit nodes, unaccepted subnet routes),
duplicating filtering the route manager already does. Delete the
package and construct the two-field wgcfg.Config inline. The skip
logs go away; if they're missed, the route manager can log them
incrementally at upsert time instead of rescanning every peer on
every reconfig.

With this, the runtime.DidRange analysis (see the ts_rangehook test)
shows a delta netmap update performing no O(n) range loops except
updateRouteManagerExtras, and the delta phase of that test drops from
1.09s to 0.14s for 400 deltas at n=10000 (from 4.79s at the
start of this effort, before the incremental route manager work).

Updates #12542

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: Ia0e03ef9db0c988790b2c29de1f0505305e93f58
The tailscale/gokrazy-kernel module was a fork of rtr7/kernel that
stalled at Linux 6.8.9 (July 2024). All of the kernel config options we
had added in that fork (ENA, Xen for EC2, virtio-mmio for qemu microvm,
virtio RNG, IPv6 policy routing, netlink diag, etc) are now present in
the gokrazy project's own gokrazy/kernel.amd64 module, which tracks
current kernel.org releases (Linux 7.1.3 as of this change) and is the
gokrazy project's supported kernel for x86_64 PCs and VMs.

Switch the tsapp and natlabapp images, the natlab VM tests, and the
CI workflow to gokrazy/kernel.amd64, drop the tailscale/gokrazy-kernel
dependency, and update gokrazy/kernel.arm64 to latest while here.

Verified with TestEasyEasy, TestJustIPv6, and TestTailscaleSSH in
tstest/natlab/vmtest with --run-vm-tests.

Updates #1866

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I90c3765a4e18f5609b4d77b51ac38d17c8e3688a
Split TestTailscaleSSH into separate tests per host OS being tested to
allow for potentially running these tests in parallel on different
machines.

Updates #13038

Signed-off-by: Mario Minardi <mario@tailscale.com>
The nodeBackend's netMap.Peers slice is frozen at the last full netmap
install; the live per-peer state lives in the nodeBackend.peers map,
updated by delta mutations. Three spots still read the stale slice or
paid to materialize a fresh one:

AppendMatchingPeers iterated netMap.Peers and re-looked-up each ID in
the peers map (with a lock round-trip per peer), so peers added by a
delta since the last full netmap were invisible to it. That affected
its callers: taildrop's file-target list, exit node suggestions, and
conn25's connector discovery. It now snapshots the peers map directly
(sorted by node ID, matching the old netmap ordering).

DebugPeerDiscoKeys read netMap.Peers and so returned stale disco keys
after deltas. It now reads the peers map via the new
nodeBackend.peerDiscoKeys.

pingPeerAPI called NetMapWithPeers, building and sorting the full
O(n) peer slice, just to linearly scan it for one IP. It now uses the
nodeBackend's existing by-address index and the new O(1) PeerByID
accessor, and passes the peers-free netmap to peerAPIBase, which only
reads the self node's addresses.

Updates #12542

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I2e57527d64733b4eb17006f896faaa907b1d128c
The android client was converted in tailscale/tailscale-android#797

Updates #12542

Change-Id: Ibb2cc6fbafdad93ae44e1a60e5cc5de8183f9b97
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The Apple clients' last consumer of the legacy Notify.NetMap field was
converted to peer deltas in tailscale/corp#44962, so tailscaled no
longer needs to build and emit full netmaps on the IPN bus for darwin
and ios. Windows is now the only remaining platform on the legacy path.

Updates #12542

Change-Id: I295d826735191bb601d2b69d8d85d37a5a82b6c9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
…tests

The "vm" CI job ran a single test (TestRunUbuntu2404 from
tstest/integration/vms) on a privileged self-hosted runner. Its coverage
is nearly all redundant with the modern natlab vmtest suite, which boots
real Ubuntu VMs and already exercises connectivity, kernel TUN, SSH,
Taildrop, ACME, and OS DNS integration on GitHub-hosted runners.

The two things it tested that natlab didn't are added back as natlab
tests so the runner can be decommissioned:

TestUbuntuSystemdUnit runs tailscaled via the stock systemd unit that
Linux packages ship (cmd/tailscaled/tailscaled.service with
tailscaled.defaults as its EnvironmentFile) instead of launching the
binary directly, verifying the unit's directives and its Type=notify
readiness handshake.

TestDNSExtraRecordsSearchDomains verifies that control-plane DNS
ExtraRecords and search domains are resolvable through the guest's OS
resolver (libc to systemd-resolved to quad-100).

Updates #13038

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I8d0dfb8b8153289e7ca78f3af03dfece9497bfe8
…ertificate (#20478)

ModifyTLSConfigToAddMetaCert (and its inline copy in cmd/derper) appended
the DERP meta cert directly to the *tls.Certificate returned by the
underlying GetCertificate. autocert returns a certificate sharing a cached
chain slice (and, on the TLS-ALPN token path, the same pointer) across
concurrent handshakes, so the in-place append was a data race and could
grow the served chain unboundedly.

Return a shallow copy with the meta cert appended to a fresh backing
array instead, and have cmd/derper reuse ModifyTLSConfigToAddMetaCert
rather than duplicating the wrapper.

Fixes #20352

Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
The job is consistently failing on main when it hits the 5 minute
timeout; let's double it to get useful results.

Updates #cleanup

Change-Id: Iaff2f95d4944929e6832273c94d628f376e2d30e
Signed-off-by: Alex Chan <alexc@tailscale.com>
…erve

Allow `tailscale serve --tcp <port> unix:/path/to/socket` and `tailscale serve --tls-terminated-tcp <port> unix:/path/to/socket` to forward TCP connections to a Unix domain socket. Previously only host:port targets were supported for TCP serve mode.

Updates #20161

Signed-off-by: ayanamist <ayanamist@gmail.com>
Updates #20081

Signed-off-by: Jordan Whited <jordan@tailscale.com>
Updates tailscale/corp#41997

Change-Id: I5fb3d4705766deb71abd0b79a186e99e86be0b15

Signed-off-by: Mike Jensen <mikej@tailscale.com>
At /v0/conn25-state.

State includes whether the node is configured for Connectors 2025, as
well as client-specific and connector-specific state, if the node is
acting in those contexts.

Client-specific state includes the reserved Magic IPs and Transit IPs on
the client that have not been returned to their IP pools, and their
associated apps, domains, real destination IPs, and active flow counts.

We also report IP pool utilization: the number of magic and transit IPs
in use versus each pool's capacity, split by IP family.

Connector-specific state includes a peer list of clients that have
registered Transit IPs with the connector, and the apps are real
destination IPs the Transit IPs map to.

Updates tailscale/corp#40125

Signed-off-by: Michael Ben-Ami <mzb@tailscale.com>
* wgengine: configure DNS even when router.Set fails

Reconfig configured the router first and returned on any router.Set error,
before the DNS block ran. On a host where router config fails on every
reconfig -- e.g. a tun MTU below 1280 that breaks IPv6, or a kernel missing
netfilter features -- the OS resolver was never told about MagicDNS or the
tailnet search domain, so tailnet names failed to resolve with no DNS error
in the logs.

Record the router error and continue instead of returning on it, still
attempt dns.Set, and join the router, DNS, and VPN-reconfigure errors into
the return value. DNS stays after router config (still needed: some DNS
managers refuse to apply settings before the device has an address); only
the error coupling is broken. Fixes a regression from 84430cd (v1.8.0).

Updates #20447

Signed-off-by: Brendan Creane <bcreane@gmail.com>

* wgengine/router/osrouter: gate IPv6 on per-interface support, not just global

getV6Available reported IPv6 usable whenever the netfilter runner reported
global IPv6 support, missing the case where the kernel has IPv6 but has not
enabled it on tailscale0 specifically -- e.g. when the tun MTU is below the
1280-byte IPv6 minimum, so /proc/sys/net/ipv6/conf/tailscale0 never exists
and the v6 address and route adds fail, aborting the whole Set. See #20447.

AND a per-interface check into getV6Available, evaluated per call so a later
Set picks up v6 if the interface gains it. All v6-gated operations funnel
through getV6Available, so Set now skips v6 gracefully instead of erroring.
Also remove the dead r.v6Available field that masked this with its global
name.

Updates #20447

Signed-off-by: Brendan Creane <bcreane@gmail.com>

---------

Signed-off-by: Brendan Creane <bcreane@gmail.com>
We were accidentally hardcoding TTL 0 before.

Fixes tailscale/corp#45025

Signed-off-by: Michael Ben-Ami <mzb@tailscale.com>
Fixes tailscale/corp#45066

Signed-off-by: Jordan Whited <jordan@tailscale.com>
Updates #cleanup

Signed-off-by: Jordan Whited <jordan@tailscale.com>
Updates #cleanup

Signed-off-by: Jordan Whited <jordan@tailscale.com>
…os.OpenInRoot (#20505)

interfaceV6UsableForTun interpolates the interface name into a /proc path.
A plain filepath.Join + os.Open only cleans the path, so a tunname with
".." (or a symlinked component) could read outside /proc/sys/net/ipv6/conf.
Open under that fixed directory with os.OpenInRoot, which rejects any path
escaping the root (openat-based, so also TOCTOU-resistant), still using
filepath.Join to build the relative name. See https://go.dev/blog/osroot.

Updates #20447

Signed-off-by: Brendan Creane <bcreane@gmail.com>
…ero keys in TSMP (#20508)

Updates tailscale/corp#45042

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
Enforce that TSMP messages are only accepted for transmission over the
wireguard connection from within the client.

Updates tailscale/corp#45059

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
This variable wasn't used in the commit when it was introduced (bd5c509).

Fixes #19841

Change-Id: I82a2ba613c71eb99d98c5e7063e8cd077ba03ece
Signed-off-by: Alex Chan <alexc@tailscale.com>
…vice (#20382)

* tstest/integration: run a test against a real Windows tailscaled service

Updates #20381

Signed-off-by: Yaruk Asghar <yaruk@tailscale.com>

* tstest/integration: serialize Windows service tests and clean up state

Updates #20381

Signed-off-by: Yaruk Asghar <yaruk@tailscale.com>

* tstest/integration: address review feedback on Windows service tests

Updates #20381

Signed-off-by: Yaruk Asghar <yaruk@tailscale.com>

* tstest/integration: use background context for service teardown

Updates #20381

Signed-off-by: Yaruk Asghar <yaruk@tailscale.com>

* tstest/integration: run Windows service test via the normal windows CI run

Updates #20381

Signed-off-by: Yaruk Asghar <yaruk@tailscale.com>

* tstest/integration: address review feedback on Windows service tests

Updates #20381

Signed-off-by: Yaruk Asghar <yaruk@tailscale.com>

---------

Signed-off-by: Yaruk Asghar <yaruk@tailscale.com>
Add a new modular syslog feature providing a tailscaled --syslog flag
that sends the daemon's logs to the system syslog daemon instead of
stderr, which is useful when running as a daemon without a service
manager that captures stderr (e.g. OpenWrt's procd).

The feature package registers two new hooks: one to register its flag
before flag parsing, and one that tailscaled calls early in main to
redirect the standard library's default logger. Because logpolicy later
points the default logger at logtail, whose local console copy writes
to stderr, logpolicy now also consults the hook and sends its console
copy to the same sink (with timestamps disabled, as syslog records its
own).

The feature is linked by default only on Linux, FreeBSD, and OpenBSD,
and can be removed with the ts_omit_syslog build tag. If connecting to
the syslog daemon fails at startup, tailscaled logs a warning and
continues logging to stderr.

Fixes #16270

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I8f3a92d4c1e6b70a5d29e4f61b3c874250a9de13
…20304)

* net/tsaddr: unmap IPv4-mapped IPv6 addrs in IsTailscaleIP

IsTailscaleIP branched on ip.Is4() before checking the CGNAT range, so an
IPv4-mapped IPv6 address (e.g. ::ffff:100.64.0.1) took the IPv6 path and was
tested only against the ULA range, wrongly returning false for a Tailscale
CGNAT address. Unmap at the top so both forms are classified identically;
Unmap is cheap and IsTailscaleIPv4 stays IPv4-only for callers that need it.

Signed-off-by: Brendan Creane <bcreane@gmail.com>

* wgengine/router/osrouter: remove orphaned tailnet addrs on cleanup

The orphan-address sweep added in #20199 ran only inside Router.Set, so the
teardown path (tailscaled --cleanup, and the unconditional cleanup at daemon
start) never removed stale Tailscale addresses a previous instance left on a
persistent tailscale0 -- it only flushed iptables/nftables.

Wire address removal into cleanUp: with no desired config, every Tailscale-range
address on the interface is an orphan, so enumerate and delete them all (IPv4
and IPv6, best-effort) in removeOrphanedAddrsForCleanup.

tailscaleInterfaceAddrs now yields the interface's addresses as an
iter.Seq[netip.Prefix], and the filters compose lazily over it: tailscaleAddrs
(every Tailscale-range address; used by cleanup), deletableAddrs (isDeletableAddr:
Tailscale-range and deletable now, i.e. excluding v6 when v6 is unavailable; used
by the live Set sweep), and orphanedAddrs (drops the desired addresses). The Set
sweep ranges the composed iterator directly, so no throwaway slices are built.
delAddress is made idempotent: it attempts both the loopback-rule teardown and
the address delete and joins their errors, so a missing firewall rule can't leak
the address, and it no longer no-ops on v6 (cleanup relies on that to remove v6
orphans even when this process never brought IPv6 up).

The Set-time sweep is otherwise unchanged; re-running it on network changes
(netmon) for late orphans remains a follow-up (tailscale/corp#43882).

Updates #19974
Fixes tailscale/corp#44173

Signed-off-by: Brendan Creane <bcreane@gmail.com>

---------

Signed-off-by: Brendan Creane <bcreane@gmail.com>
…eers (#20513)

This change ensures `packetFilterPermitsUnlockedNodes` also considers SrcCaps-based grants when checking for unsigned peer access.

Fixes tailscale/corp#45116

Change-Id: I0ac938367888f67ed6f355fc19959cc8c31722a2

Signed-off-by: Mike Jensen <mikej@tailscale.com>
…DoH (#20463)

DoHEndpointFromIP mapped the entire 2606:1a40::/48 range to a
dns.controld.com/<id> DoH URL, but the ID-encoded addresses in that range
are legacy plaintext-DNS endpoints that refuse :443. They now fall through
as ordinary port-53 resolvers; the free anycast freedns.controld.com/pN
addresses still upgrade via exact match.

Fixes #20433

Signed-off-by: Brendan Creane <bcreane@gmail.com>
Simplifies cmd/containerboot env var parsing. Most of the private helpers did
not earn their abstraction: defaultEnv(name, "") is just os.Getenv(name), and
the rest collapse into cmp.Or and the existing def.Bool. defaultEnv,
defaultEnvs and defaultBool are gone.

Adds def.LookupEnv, the env companion to def.Bool, for the one case that needs
it: TS_KUBE_SECRET, where an explicit "" disables Kubernetes secret storage and
must stay distinct from unset (cmp.Or cannot express that).

Updates #20018

Signed-off-by: Nick Rossi <nrossi0530@gmail.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.