Kristoffer Dalby
49b848a83d
state: compare peer-visible Hostinfo through views
...
Field by field: no allocation, no reflection.
Updates #3531
2026-10-09 11:44:37 +02:00
Kristoffer Dalby
9c764e5a99
state: return the replaced node from NodeStore updates
...
UpdateNodeDiff hands back the pre-update clone the writer already makes.
Updates #3531
2026-10-09 11:44:37 +02:00
Kristoffer Dalby
b7aa328e0c
CHANGELOG: note SSH rule removal fix
...
Updates #3508
2026-10-08 10:29:23 +02:00
Kristoffer Dalby
785ba22c65
mapper: send SSHPolicy only when it changes for the connection
...
Any non-nil SSHPolicy forces a full client netmap rebuild; the empty
policy now sent to every node made each policy change one.
Updates #3508
2026-10-08 10:29:23 +02:00
Kristoffer Dalby
41c137bb3b
noise: drop unused ErrNoAuthSession
...
Kept separate so the check-rule fix cherry-picks to 0.29.
Updates #3508
2026-10-08 10:29:23 +02:00
Kristoffer Dalby
9de8e9103f
ci: regenerate integration test list
...
Updates #3508
2026-10-08 10:29:23 +02:00
Kristoffer Dalby
16c0e6b75a
integration: test SSH is denied once its rules are removed
...
Updates #3508
2026-10-08 10:29:23 +02:00
Kristoffer Dalby
957a332d5d
policy/v2: match the login user in SSHCheckParams
...
The client picks the check rule by login user; the server took the
first rule for the node pair, so a root login could get a 12h
localpart period instead of "always", or be approved after its rule
was removed while another user's rule remained. Hold URLs now carry
the concrete user: tailssh never expanded the encoded $LOCAL_USER.
Updates #3508
2026-10-08 10:29:23 +02:00
Kristoffer Dalby
dceb584c89
noise: reject SSH checks the policy no longer requires
...
A stale check rule still held and accepted after login. Deny with a 200
Reject (tailssh retries errors); re-check after the verdict.
Updates #3508
2026-10-08 10:29:23 +02:00
Kristoffer Dalby
03e723c611
policy/v2: find SSH check params for localpart self-access
...
compileSSHPolicy sends these check rules; SSHCheckParams missed them,
so they never auto-approved within checkPeriod.
Updates #3508
2026-10-08 10:29:23 +02:00
Kristoffer Dalby
d7b333d2aa
mapper: send an empty SSH policy when compiling it fails
...
Fail closed; nil kept the client's previous rules.
Updates #3508
2026-10-08 10:29:23 +02:00
Kristoffer Dalby
2a0823ca41
policy/v2: send an empty SSH policy when no rule applies
...
Nil SSHPolicy means "unchanged" to clients; removed rules stayed live.
Match SaaS: "rules":[].
Fixes #3508
2026-10-08 10:29:23 +02:00
Kristoffer Dalby
82df3e088a
servertest: test client drops SSH rules on policy removal
...
Updates #3508
2026-10-08 10:29:23 +02:00
Kristoffer Dalby
e98e9289d6
policy/v2: test SSH rule removal yields empty SSHPolicy
...
Updates #3508
2026-10-08 10:29:23 +02:00
Kristoffer Dalby
961535351f
policy/v2: check SSHPolicy nil vs empty against captures
...
Nil keeps client's old rules; empty clears them. Old normalization hid it.
Updates #3508
2026-10-08 10:29:23 +02:00
Kristoffer Dalby
2cd82ceb0c
CHANGELOG: note the own approved routes fix
...
Updates #3502
2026-10-07 23:36:16 +02:00
Kristoffer Dalby
ea6b0bf0b7
mapper: reconcile self on policy recomputes
...
Self renders from the same state as peers, so leaving it out of policy
responses hid an exit node's approved routes until it reconnected.
Fixes #3502
2026-10-07 23:36:16 +02:00
Kristoffer Dalby
ba413fca3d
state: return a node's primary routes in stable order
...
They came from map iteration, so an unchanged router rendered its self
node differently on every call.
Updates #3502
2026-10-07 23:36:16 +02:00
Kristoffer Dalby
e7bb90bac1
CHANGELOG: name both DERP verify paths
...
Embedded DERP verifies in-process, not through /verify.
2026-10-07 22:55:03 +02:00
Kristoffer Dalby
541ef40c87
state: report unindexed node key instead of panicking
...
A missing key yields the zero NodeView; its ID() panicked inside a reader
goroutine and took down the test binary instead of failing with a diagnostic.
2026-10-07 22:55:03 +02:00
Kristoffer Dalby
85bda7c2c9
types: drop unused Nodes.ContainsNodeKey
2026-10-07 22:55:03 +02:00
Kristoffer Dalby
7ffdba7175
hscontrol: admit DERP clients via NodeKey index
...
/verify scanned every node per DERP connect; use GetNodeByNodeKey.
2026-10-07 22:55:03 +02:00
Kristoffer Dalby
bc7fe6b8eb
state: test NodeKey index agrees with node list
...
Covers put, rotation and payload writes on the reuse path, and delete.
2026-10-07 22:55:03 +02:00
Kristoffer Dalby
29e18d80b4
docs: note the audit-log shutdown lasts until tailscale up
...
Clients that opt out of logging themselves hit it whatever logtail.enabled says.
2026-10-07 18:11:07 +02:00
Kristoffer Dalby
da6c8f9dd3
CHANGELOG: say audit-log clients stay down after the logtail fix
2026-10-07 18:11:07 +02:00
Kristoffer Dalby
0c9186d4a3
hscontrol: send the logtail instruction on the expired-self frame
...
It opens a deleted node's stream in place of the initial map.
2026-10-07 18:11:07 +02:00
Kristoffer Dalby
52a7f8c89c
mapper: send the logtail instruction on every full map
...
Full maps moved to buildFromChange and lost WithDebugConfig, so no
frame told clients to disable log upload. Enabled logtail sends nil.
2026-10-07 18:11:07 +02:00
Kristoffer Dalby
85587e2e29
change: drop untargeted pings when collapsing to a full
...
The ping ID in the URL is the only authentication on the answer, so
rescuing an untargeted ping for every node would let any node answer
for another. Rescue a ping only for the node it targets.
2026-10-07 15:25:25 +02:00
Kristoffer Dalby
d4948da301
mapper: keep pings when a full update collapses pending changes
...
A full renders state at drain time but cannot carry a one-shot
PingRequest; queue each ping as a ping-only frame after the full.
2026-10-07 15:25:25 +02:00
Kristoffer Dalby
c4ce3f7d14
state: revalidate pre-auth key reuse when registration applies
2026-10-07 14:03:54 +02:00
Kristoffer Dalby
b35cb278c8
CHANGELOG: reword SSH check replay fix
2026-10-07 12:50:32 +02:00
Kristoffer Dalby
97c4bf264e
noise: repeat concurrent SSH verdict waiters test
...
Nothing signals that both waiters parked before FinishAuth, so one
pass mostly checks them one after the other.
2026-10-07 12:50:32 +02:00
Kristoffer Dalby
c9992efaca
noise: cover SSH verdict replay ledger and removed check
...
A replay must neither record auth for auto-approval nor, once the
pair is no longer under a check, be answered from the consumed
verdict.
2026-10-07 12:50:32 +02:00
Kristoffer Dalby
133f8142c6
noise: re-decide SSH check follow-up after verdict consumed
...
Closed verdict channel yields zero AuthVerdict, which Accept() treats as
success; a replayed follow-up was accepted even after Reject.
2026-10-07 12:50:32 +02:00
Kristoffer Dalby
2dcd5c876e
CHANGELOG: note unknown users in groups for 0.29.5
...
Updates #3513
2026-10-07 11:10:51 +02:00
Kristoffer Dalby
925639b3aa
policy/v2: test unregistered users at every policy site
...
Each site must match the policy without them, and track their
registration and deletion.
Updates #3513
2026-10-07 11:10:51 +02:00
Kristoffer Dalby
cb299184f7
servertest: check grant-v13 group via routes against SaaS
...
Updates #3513
2026-10-07 11:10:51 +02:00
Kristoffer Dalby
85c754a1ac
policy/v2: resolve unregistered users to an empty set
...
Callers bailing on the error dropped a whole group for one missing
member: via routes, SSH check, app grants, nodeAttrs.
Fixes #3513
2026-10-07 11:10:51 +02:00
Kristoffer Dalby
545322aec7
policy/v2: fail rejected-compile tests on an ambiguous user
...
A missing user will stop failing the compile.
Updates #3513
2026-10-07 11:10:51 +02:00
Kristoffer Dalby
4776898029
state: roll back only registration fields on failed re-registration
...
Restoring the whole pre-update snapshot also reverted sessions that
connected during the failed write, stranding a live node offline.
2026-10-07 11:10:38 +02:00
Kristoffer Dalby
f7c8b4d93f
state: serialise IP backfill with node persistence
...
A persist between the backfill's database write and its NodeStore reload
wrote the old addresses back, silently undoing the backfill.
2026-10-07 11:10:38 +02:00
Kristoffer Dalby
84cf38ce24
derp/server: resolve the live DERP map in /bootstrap-dns
...
The handler captured the startup map, so hostnames added by
derp.auto_update never resolved.
2026-10-07 11:10:38 +02:00
Kristoffer Dalby
57358b7430
state: backfill only IPs into NodeStore
...
PutNode of the DB row dropped session state, stranding connected nodes
offline, and nil-dereferenced nodes without Hostinfo.
2026-10-07 11:10:38 +02:00
Kristoffer Dalby
9c34c0c90d
state: stop tag approval sorting the reported RequestTags
...
nodeToRegister.Tags aliased Hostinfo.RequestTags, so sort/compact rewrote
the stored Hostinfo ([b a a] became [a b ""]).
2026-10-07 11:10:38 +02:00
Kristoffer Dalby
a99c8a030c
policy/v2: stop ViaRoutesForPeer appending into pm.pol.Grants
...
Readers share pm.pol under RLock; appending ACL grants into its spare
capacity raced between concurrent callers.
2026-10-07 11:10:38 +02:00
Kristoffer Dalby
060f2aa59b
CHANGELOG: shorten register floor entry to one clause
2026-10-07 11:10:23 +02:00
Kristoffer Dalby
5622b519b5
noise: test a decode failure at the capability floor
...
Nothing covered a body that clears the floor yet fails to decode. Dropping
or reordering that branch would run handleRegister on a half-decoded
request with no test failing.
Inline the single-use request builder into serveRegister and finish the
OversizedBody comment.
2026-10-07 11:10:23 +02:00
Kristoffer Dalby
ed8d546675
noise: check capability floor before handleRegister
...
Below-floor register got 400 only after logout, key use or auth-cache
write had run.
2026-10-07 11:10:23 +02:00
Kristoffer Dalby
b4d5cdd6aa
mapper: keep reconnect removals tracked until delivered
...
AddNode reset lastSentPeers before the queued removal went out, so a
superseding full or a disconnect before the tick lost it for good.
2026-10-07 11:09:47 +02:00
Kristoffer Dalby
f1293a805a
servertest: require via compat netmaps to hold across ticks
...
Accepting the first matching tick let a netmap that matched once and
then drifted pass. Require several consecutive passing ticks; a netmap
that settles still passes, so no assertion loosens.
2026-10-07 11:08:58 +02:00
Kristoffer Dalby
fdb3646b67
servertest: name filters in the via HA convergence comment
...
The PacketFilter rule count lags route approval as well, so say so, as
the map compat driver already does.
2026-10-07 11:08:58 +02:00
Kristoffer Dalby
74121aa339
servertest: retry via compat netmap comparison until converged
...
Peer count arrives before routes; compare-once raced route delivery.
2026-10-07 11:08:58 +02:00
Kristoffer Dalby
eeaac680be
mapper: drop DNSConfig from policy responses
...
It forced every client into a full netmap rebuild; the resolver race it
guarded against was a client bug (tailscale/tailscale#19749 ).
2026-09-30 19:03:13 +02:00
Kristoffer Dalby
357f34a778
state: send a node's DNS config with its own refresh
...
Drained at dispatch for nodeAttrs changes from any policy, user or node
update, and for hostname/OS changes feeding NextDNS device metadata.
2026-09-30 19:03:13 +02:00
Kristoffer Dalby
59030f380d
servertest: cover a node's DNS config following its NextDNS inputs
...
Profile via policy reload or tag change, device metadata via hostname;
a hostname change today waits for the next policy response to reach DNS.
2026-09-30 19:03:13 +02:00
Kristoffer Dalby
60d42808b8
state: keep node removal apart from policy refresh in DeleteNode
...
Peers get the deletion as an explicit PeersRemoved change, independent of
their sent-peers tracking.
Updates tailscale/tailscale#15660
2026-09-30 19:03:13 +02:00
Kristoffer Dalby
1bd62737b9
mapper: send removed peers as their own delta
...
Removals derived from a policy change, full update or reconnect rode a
response whose DNSConfig, SSHPolicy, Node or Peers force a full rebuild.
Updates tailscale/tailscale#15660
2026-09-30 19:03:13 +02:00
Kristoffer Dalby
baca8309f1
servertest: reproduce removed peers missing from IPN bus deltas
...
Delta-only IPN bus watchers (the Android app since 1.100) miss removals
riding a full-rebuild response: deleted, policy-hidden, or while offline.
Updates tailscale/tailscale#15660
2026-09-30 19:03:13 +02:00
Kristoffer Dalby
00663fbbfe
nix: run the headscale VM test on the test kit
...
Drops nginx, the cert and dead ip_prefixes. Proves DERP relay and TLS noise
after a restart, and puts nix/module.nix under CI.
2026-09-28 21:42:19 +02:00
Kristoffer Dalby
200c2c01e8
nix: add a NixOS test kit for Tailscale clients
...
nixosModules.testkit makes a node a control server every client joins without
trust setup; testkit-peer joins it with hs-join.
2026-09-28 21:42:19 +02:00
Kristoffer Dalby
35a90e0018
derp: serve a self-signed TLS listener for tests
...
HEADSCALE_DEBUG_INSECURE_TLS_LISTEN_ADDR serves the router over throwaway TLS
and marks the embedded region InsecureForTests: TLS DERP for CA-less clients
(tailscale-rs, Android), plus the :443 noise fallback Go redials use.
2026-09-28 21:42:19 +02:00
Kristoffer Dalby
740f930523
nix: list flake systems explicitly
...
eachDefaultSystem includes x86_64-darwin, which nixpkgs dropped; nix flake
show failed evaluating it.
2026-09-28 21:42:19 +02:00
Kristoffer Dalby
d48883ca9b
nix: write split DNS where headscale reads it
...
module.nix emitted dns.split; headscale reads dns.nameservers.split, so the
typed option was silently ignored. Old path now asserts.
2026-09-28 21:42:19 +02:00
Kristoffer Dalby
f0ff407c05
nix: stop module.nix writing the deprecated ephemeral key
...
Its default made headscale warn on every start. The camelCase rename now
targets node.ephemeral.inactivity_timeout, and the old path asserts.
2026-09-28 21:42:19 +02:00
Kristoffer Dalby
62f89ca25d
cli: accept a user name in preauthkeys create --user
...
Resolved through lookupUser like the users commands, so scripts skip the
users list round trip. Digit-only values stay IDs.
2026-09-28 21:42:19 +02:00
Kristoffer Dalby
715c5a4a1c
cli: split the user lookup out of resolveSingleUser
...
Lets commands with their own flags resolve a user the same way.
2026-09-28 21:42:19 +02:00
Kristoffer Dalby
fbb04c5611
testcapture: read captures through util.ReadFileByExt
...
Drops its private HuJSON decoder.
2026-09-28 21:42:19 +02:00
Kristoffer Dalby
906016beb4
dns: pick the extra_records_path format by file extension
...
HuJSON and YAML records work too; an unknown extension fails instead of being
parsed as JSON.
2026-09-28 21:42:19 +02:00
Kristoffer Dalby
dd8ce695cf
derp: pick the derp.paths format by file extension
...
Adds JSON and HuJSON maps. JSON read as YAML decoded to an empty map; unknown
extensions and empty maps now fail at startup.
2026-09-28 21:42:19 +02:00
Kristoffer Dalby
d20a412079
util: decode files by their extension
...
UnmarshalByExt picks JSON, HuJSON or YAML from the file name; content can't
tell them apart, since YAML parses JSON syntax.
2026-09-28 21:42:19 +02:00
Kristoffer Dalby
90732bdaaf
derp: drop regions set to null in derp.paths
...
19d5d9de cloned regions while merging and skipped nil ones, so the documented
null-removal recipe silently kept the region.
2026-09-28 21:42:19 +02:00
Kristoffer Dalby
393dd3e2d9
db: store all credentials in one SHA-256-hashed table
...
API keys, pre-auth keys and OAuth clients/tokens share one table and verify
path. Secrets carry 256 bits of crypto/rand entropy, so a SHA-256 digest
needs no stretching; bcrypt/argon2id rows rehash on use until 0.32.
2026-09-26 00:33:12 +02:00
Kristoffer Dalby
e90500e3a9
db: drop migrations predating 0.29
...
Only 0.29.x -> 0.30 upgrades are supported; checkMinimumMigration refuses
older databases instead of silently skipping the removed steps.
2026-09-26 00:33:12 +02:00
Kristoffer Dalby
bb3c0b4cd6
servertest: drive tailscale client oauthkey flow against v2 API
...
Real feature/oauthkey resolver via tsnet: tskey-client- secret,
?baseURL attributes, CreateKey, register re-advertising key tags.
2026-09-25 17:09:19 +02:00
Kristoffer Dalby
c604874dba
policy/v2: suggest approved exit nodes by default
...
Matches SaaS; Apple clients hide the exit-node list without a suggestion.
Fixes #3415
2026-09-23 14:48:45 +02:00
Kristoffer Dalby
06fa3075da
hscontrol: replace tailscale line refs with doc links
...
Line numbers drift on every upstream bump.
2026-09-23 14:48:45 +02:00
Kristoffer Dalby
0e8a3bba54
policy/v2: compare peer CapMap against SaaS route captures
...
SaaS stamps suggest-exit-node on approved exit peers without nodeAttrs.
Updates #3415
2026-09-23 14:48:45 +02:00
Kristoffer Dalby
5401edb6a8
policy: ignore '#' metadata fields across the whole policy
...
The filter lived in ACL.UnmarshalJSON, so grants, ssh and nodeAttrs still
hit RejectUnknownMembers. Strip the members in the HuJSON AST instead, at
the single decode entrypoint. Grant "app" payloads are left untouched.
Fixes #3479
2026-09-23 09:30:22 +02:00
Kristoffer Dalby
63123196cc
all: inline deprecated tailcfg capability aliases
...
go 1.27 vet reports the //go:fix inline directives tailscale added to
the tailcfg cap aliases; applied with `go fix -inline ./...`.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
77cd81fe33
flakehashes: refresh for the tailscale.com bump
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
9ceb4511de
go.mod: set the lockstep notes off from the sorted requires
...
go 1.27 tidy folds every require into one direct and one indirect
block; a leading blank line is the only separation it keeps.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
820dc3001b
flake: build Go-parsing tools with the project's Go
...
goimports, gotools' goimports wrapper and golangci-lint-langserver were
on the nixpkgs default Go, whose parser rejects generic methods.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
941fd9ff4e
CHANGELOG: minimum client version is v1.82.0
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
7e12e46f63
capver: regenerate for Tailscale v1.102
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
fd51ec70f0
capver: sort minor versions numerically
...
Lexicographic order put v1.102 before v1.24, so the newest release fell
outside the supported window and the minimum never moved.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
d7c1ecce92
mapper: correct the send timer rationale
...
time.After has been GC-recoverable since Go 1.23, so the leak the comment
described cannot happen and the test asserting it proved nothing.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
635bda9139
hi: compare the stream error with errors.Is
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
0a4d56494f
hscontrol: drop the net/http/pprof import
...
Nothing serves DefaultServeMux; the debug mux already exposes every
profile through tsweb.Debugger.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
1994f50fe8
policy/v2: drop elided struct types in test users
...
Promoted field keys let the literals skip the embedded gorm.Model.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
93e29ec38d
all: use strings.CutLast
...
Replaces LastIndex plus slice arithmetic when splitting on the last
separator.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
373c60efe3
all: use sync.WaitGroup.Go
...
Drops the Add/Done bookkeeping, which in batcher.go was spread across
three functions.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
245b81401c
integration: make debugJSON and execJSON methods
...
Go 1.27 allows type parameters on methods, so the container no longer has
to be passed as the first argument.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
60bab7633c
golangci-lint: disable canonicalheader
...
canonicalheader v1.1.2 nil-derefs on a package that has both a generic
method and an http.Header.Set call, which aborts the whole lint run.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
1c6809089f
hscontrol: use the stdlib uuid package
...
Go 1.27 ships RFC 9562 UUIDs and NewV4 cannot fail, dropping gofrs/uuid
and two error paths.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
9f7d829aa5
go.mod: adopt the require layout Go 1.27 tidy produces
...
Go 1.27 collapses requires into one direct and one indirect block, so the
modernc lockstep note has to live inside a block to survive tidy.
-compat=1.27 is a no-op now that the go directive is 1.27.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
cbbfe613b8
flake: skip comments in go-mod-update-all
...
Comment lines inside a require block are tab-indented, so the scrape fed
`//` tokens to go get -u.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
0c0b0c68a6
derp: drop deprecated DERPRegion.Avoid
...
Zero value, superseded by NoMeasureNoHome.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
77caa94400
policy/v2: use value receiver for SSHCheckPeriod.Validate
...
recvcheck ignores UnmarshalJSON, so the pointer receiver here was the
odd one out against value-receiver MarshalJSON. Validate only reads.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
2c76d5c5b7
all: apply golangci-lint autofixes
...
Go 1.27 allows setting promoted fields of embedded structs directly in
composite literals, so gorm.Model wrappers go away. Plus strings.Cut,
errors.AsType, reflect.TypeAssert and one gofumpt nit.
2026-08-25 21:59:00 +02:00
Kristoffer Dalby
2b64b9fe3a
.golangci.yaml: disable exhaustruct_v5
...
Renamed linter, same 50 findings as the disabled exhaustruct.
2026-08-25 21:59:00 +02:00