Adopt the tunnel as a mesh fact, refuse a mismatched takeover, and rekey after enrolment
Review of the ADR 0105 build (hq ADR 0105). Four things it got wrong and one path it lacked: - A predecessor spoke's tunnel names one peer, the hub, routed the whole range; recording refused it and the whole enrolment failed. Range-routed peers are skipped now — only the hub's peers are ever carried. - The range and the carried peers were conditions on the node being adopted, so converging the hub would have renumbered the mesh and dropped the peers still reaching it. They are facts of the tunnel record now, mode aside; the takeover alone is declared to an adopted node. Converging the hub is refused while a carried peer has not enrolled, naming it. - A push composed a takeover for a hub whose address or endpoint disagreed with the tunnel, which would have the host stop the found interface and raise the mesh's where no peer listens. The graph refuses to compose it, naming both and the placement that fixes it. - The host's account said taken or not; "found down and the mesh's not up" read as not taken. Three states now, and an account on every takeover. - A hub that enrolled before this feature holds a key of its own, and re-enrolling would rotate every key the mesh sealed credentials to. A node now rekeys in a report, signed with its identity key over the key it leaves, the key it takes and the tunnel; the mesh verifies against the live key, refuses a stale or foreign proof, records key and tunnel, and moves a hub to the tunnel's address. `overlay show` names the path for a hub that found no tunnel. Also: a carried IPv6 peer is routed /128, and identity.ForTest exists so the link can be tested against a real identity store.
This commit is contained in:
@@ -43,8 +43,28 @@ anchor's firewall is the predecessor's, installed by the bed):
|
||||
installer finds `wg0` itself (one interface besides `mesh0`) and takes its port and range. The
|
||||
bed asserts genesis **says** it found and took the tunnel.
|
||||
|
||||
**Review changes (2026-09-24).** A spoke's `wg0.conf` names one peer — the hub — routed the
|
||||
whole range; the controller skips range-routed peers, so T2's enrolment carries no peer from the
|
||||
spoke. A hub that enrolled *before* this feature (a generated key) takes the tunnel over without
|
||||
re-enrolling: `mesh-host overlay take --tunnel wg0` on the machine rekeys the overlay key only and
|
||||
sends a signed rekey; the bed adds **R0** for it below. A takeover is composed only for a hub
|
||||
placed at the tunnel's address on the tunnel's port, and the host stops nothing until the declared
|
||||
interface matches the found one and the key file holds the found key; a mesh interface that fails
|
||||
to start gives the found unit back. The host's account has three states: `not-taken`, `taken`,
|
||||
`down`.
|
||||
|
||||
## Assertions, in the record's order
|
||||
|
||||
- **R0 — a hub enrolled with its own key takes the tunnel over by rekeying.** Genesis is run
|
||||
adopted *without* the tunnel being found (the bed stops `wg-quick@wg0` for the run, so the
|
||||
installer sees no tunnel, then starts it again — the pre-feature shape). Then on the anchor:
|
||||
`mesh-host overlay take --tunnel wg0`; `node show anchor` says "tunnel found wg0 …"; `overlay
|
||||
place anchor --hub --endpoint 192.0.2.10:51900 --site hosting` (with `:51820` first, which must
|
||||
be refused naming 51900); `plan anchor --json` names `Address = 10.10.0.1/32`, `ListenPort =
|
||||
51900`, two `/32` peers, `takes-over` wg0 and nothing in 10.42.0.0/16; then `push anchor --wait
|
||||
2m` and T1's assertions hold. `overlay take` run a second time is refused by the controller as
|
||||
stale and changes nothing.
|
||||
|
||||
- **T1 — the tunnel changes hands and the peers notice nothing.** After genesis and the push
|
||||
that raises the private network on the anchor:
|
||||
- `wg show interfaces` on the anchor lists `mesh0` and not `wg0`;
|
||||
|
||||
Reference in New Issue
Block a user