Kristoffer Dalby
5dff6ca432
policy/v2: resolve user references consistently across updates
...
Prefer email owners over usernames and validate grants and nodeAttrs on
write. Reject ambiguous writes; log and match nobody on reload. Bare @
matches nobody.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
cb47fdff36
policy/v2, mapper: align NextDNS warnings and device metadata
...
Warn about malformed attributes once at policy load, not on each map.
Include the node's stable ID as device_id in resolver queries.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
256a67e86b
policy: offer exit routes only to viewers whose rules reach the internet
...
Every destination overlaps /0, so any rule offered a peer's exit routes.
They now need a rule to the internet, the test exit-node visibility
uses; via steering defers them to a regular grant only on that test.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
1cd93ec432
policy: reduce merged destination prefixes to the node's own addresses
...
Adjacent node addresses merge into one prefix, and each node's filter
kept all of it. A prefix made only of node addresses now shrinks to the
node's own; a prefix the policy wrote, or one the node routes, stays.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
6dd0656f17
api, policy/v2: refuse route prefixes with host bits
...
Routes are matched as written, so such a prefix never equals the one a
client announces. The approval APIs answer 400 and autoApprovers refuses
it at load and write, with Tailscale's text.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
05039d3398
policy, state: log only the routes auto-approval adds
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
836d03dee2
policy/matcher: compare cached policy and node route ranges
...
Binary-search immutable policy ranges and normalize node routes once.
Large misses and self/via scans improve; small or early matches can slow,
and global policies pay extra normalization and allocation costs.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
452e14d461
policy: look up approved routes in a set when auto-approving
...
Avoid scanning the growing approval list for every announcement.
Use the sorted current routes when identifying additions.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
71dc0c1c58
types, state: derive and reduce approved routes once
...
Derive subnet and exit routes together, once each in announcement order.
Reuse matcher membership while preserving HA co-router visibility.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
0e7515eab9
state, policy/v2: classify only effective route changes
...
Compare announced-and-approved routes only when immutable route inputs
change. Publish Hostinfo without unnecessary peer adjacency rebuilds.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
4342883bd4
policy/v2, state: elect primaries by oldest control session
...
A router that reconnects joins as a standby; one that kept its session
takes its routes back once available again, as on Tailscale. Both the
global and the via election use it, in place of anti-flap stickiness.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
e0717bc116
state, policy/v2: elect available routers and retain unavailable routes
...
Recompute via elections on health changes and check online state and expiry.
With no available router, retain the previous primary or lowest-ID approver;
exclude routers the prober marked unreachable.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
d4ce109806
policy/v2: refuse check SSH rules with tag sources
...
A check asks the source's user to log in again, and a tagged node has
none. Tailscale SaaS refuses the rule; headscale accepted it.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
79daa3142f
policy/v2: bound grant destination expansion
...
Require one port or range per grant IP entry. Reject more than 100,000
declared destination/port-range combinations on every parse.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
1c833ba394
policy/v2: evaluate policy tests from compiled snapshots
...
Parse filters once and index SSH rules by source. Evaluate tests against
user and node snapshots before taking the write lock.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
33b57fdeb2
policy/v2: need every dst node for a tests accept, no range sources
...
An accept passes only when each node behind the dst is reached, as on
Tailscale SaaS; a deny keeps its rule. A CIDR, "*" or autogroup:tagged
src names no user or host, so its test fails.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
0cdd52068b
policy/v2: bound failure reports and name SSH test aliases
...
Keep source/destination labels and repeated destination occurrences.
Limit reports to 100 lines and labels to 256 bytes.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
cebe5fc903
policy/v2: validate SSH test sources and destinations like SaaS
...
Reject address-range sources and autogroup:member destinations.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
e6d04cd79a
policy/v2: map login 0 to no local user in SSH rules
...
Every rule that maps root now carries "0": "", as Tailscale SaaS writes
it, also when the policy lists "0".
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
0bfae13d6d
policy/v2: normalize emitted ACL and via destinations
...
Write single-address via destinations bare. Deduplicate repeated ACL
destination/port pairs while preserving grant duplicates.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
f2df44295a
state, db: validate and store the current policy before installing it
...
Reject empty input. Validate without changing live state, then store and
install under one lock; prune old rows only with a successful write.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
4c8330c936
policy/v2: resolve tag owners one hop deep
...
A user claims only the tags it owns directly, and a tag owns only the
tags that list it, as on Tailscale SaaS. With no walk left, validate
names an undefined owner once, with the tag that lists it.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
6fd3dbd0a2
policy/v2: evaluate sshTests sources through the nodes they cover
...
A src was expanded to every address it names, so "*" or ::/0 never
finished. Principals are node addresses: keep those plus one stand-in.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
2c7a9a22f6
policy/v2: reuse compiled policy data across rules and nodes
...
Cache shared source keys, compile SSH rules and principals once, and
resolve groups once on a policy copy.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
361b5e6556
policy/v2: keep via steering bounded across route and user changes
...
Refresh clients when the last via grant disappears. Match each ACL once,
deduplicate routes, and elect once per route the peer actually serves.
2026-11-02 19:15:40 +01:00
Kristoffer Dalby
5b578fe95f
policy/v2: recapture SSH data captures
...
Every ssh_results row captured again from SaaS. SaaS now maps login "0"
to no local user in rules that map root, quotes a refused checkPeriod as
written and rewords its tailnet-domain refusal.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
a34eb4f535
policy/v2, servertest: add policy generation golden data
...
One policy over joins, a via router swap, an admin tag, a delete and a
group edit; filter, SSH, peers and routes per step, and the manager
against a fresh one.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
a21d725853
servertest, policy/v2: replay tag owner chain joins through registration
...
A key login never asks the policy about requested tags, so the joins are
checked where headscale decides them. OAuth mints stay at
TagOwnedByTags.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
2747f111b9
policy/v2: name the destination in sshTests failure breakdowns
...
A failure reported against the wrong dst alias no longer passes.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
765f4d8cf2
policy/v2: check the SSH login 0 mapping apart from the rules
...
Its skip entries no longer hide rule count, order or principals.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
63130fb8e5
policy/v2: add grant port list refusal capture
...
Grant and ACL refusals share one check-keyed refused/message check.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
aa4721b3be
policy/v2, servertest: add via port captures
...
A port-limited ACL entry beside a via grant, and a via tag with no
advertiser. Via HA replays now compare router filters by address.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
1449dc8c4f
policy/v2, servertest: add multi-route router captures
...
A seven-route router and an exit node under six policies; replayed
through policy, peer map and map stream. Peer map now checked against
SaaS peers.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
80472006c4
policy/v2, mapper: add nextdns attr captures
...
SaaS accepts malformed nextdns profiles and keeps them in the CapMap;
its resolver skips them. DoH addresses compare per node: path, query,
ID.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
7b86005350
policy/v2: add user token captures
...
SaaS answers for unknown users, a short name and a bare "@" at every
site. Each capture also runs under headscale-only user rows, at boot and
runtime; SaaS nodes must not change and overlay nodes get nothing.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
3342e60fd4
policy/v2, servertest: add via source loss captures
...
Repeated via destinations, a user via source, and an empty one.
A rename that empties the via source must reach open streams as v67.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
389f0e137d
policy/v2, servertest: add validation matrix and grant shape captures
...
SaaS answers for sshTests sources, tests semantics, failure reports,
duplicate destinations, empty and allow-all policies, and refusals.
ACL and SSH compat checks are keyed per check; differences listed.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
c69c47409a
policy/v2: recapture tester rows with failure detail
...
Re-runs keep SaaS's error data and validate answer. Tester compat checks
verdict, message, failure breakdown and node labels.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
1915feafd5
servertest: check refused policies leave the live policy unchanged
...
Posts every policy SaaS refused through v2; filter, SSH, body and ETag
must stay as before. Policies headscale accepts are skip entries.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
b2b2bb0e38
policy/v2: build tester nodes from the capture topology
...
The fixed node list had other addresses than the captures, so address
and range tests ran against nodes SaaS never saw.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
79001007ea
policy/v2: compare compat captures through the policy manager
...
ACL, grant and SSH captures now also check FilterForNode and SSHPolicy,
which add the global merge and caches the per-node compile skips.
2026-11-02 16:09:00 +01:00
Kristoffer Dalby
526daf0841
policy/v2: resolve an ACL's sources once, not once per destination
...
An ACL compiles to one grant per destination, and each resolved and
merged the same sources again. A wide CI-style ACL took 3s and 674MB
per compile; 88ms and 23MB now.
2026-10-30 14:36:19 +01:00
Kristoffer Dalby
52842f4c0d
integration: guard SSH acceptEnv forwarding
...
Updates #3559
2026-10-29 20:51:36 +01:00
Kristoffer Dalby
c4d4e32f12
servertest, policy/v2: add re-authentication golden data
...
Expired, live, ephemeral and admin-tagged devices logging in again with
spent, revoked, valid and other users' keys, by key and by login;
tag ownership through tags per policy function.
Updates ANT-2026-LYVGXVSW
Updates ANT-2026-AWGRB7O1
2026-10-29 14:00:02 +01:00
Kristoffer Dalby
286d6ea05d
policy/v2, servertest, hscontrol: add tailnet overlap route captures
...
Routers announcing tailnet addresses, approved by policy, admin key and
devices:routes token; replayed through policy, map stream and v1/v2
APIs.
Updates ANT-2026-MLP8ZR5T
2026-10-29 14:00:02 +01:00
Kristoffer Dalby
998c4b0619
policy: pin SSH forwarding behavior and recommend upgrades
2026-10-29 12:43:14 +01:00
Kristoffer Dalby
a336e1e7e6
policy/v2: keep failing tests apart per entry
...
A refusal can then name each failing test's src.
2026-10-29 11:04:05 +01:00
Kristoffer Dalby
dd6e288aa1
policy/v2: index nodes by tag once per compile
...
Each tag alias scanned every node, so with many tags a compile, run on
every NodeStore batch, was mostly HasTag.
2026-10-23 18:23:53 +02:00
Kristoffer Dalby
4933bb83d2
policyutil: match DstPorts as ranges when reducing filters
...
Every node re-parsed every entry into an IPSet on every policy change;
under churn that was most of the batcher's CPU.
2026-10-23 18:23:53 +02:00
Kristoffer Dalby
7414c276f6
mapper: limit capability copies to requested peers
...
Small peer updates should not copy capabilities for the entire tailnet.
2026-10-22 22:17:36 +02:00