The first thing the control plane decides rather than relays. Every node's peer list is derived from every node at once, which is what makes this control-plane work by definition: no node has that view. A hub, with direct peering between nodes at the same site. Not a full mesh, and the reason is a property of WireGuard rather than a preference -- there is no failover, so a more specific route to a dead endpoint blackholes instead of falling back. A node gets exactly one path to any peer, because two would mean one of them silently swallowing traffic. A roaming node is hub-only for the same reason. Reachability and the hub are declared, never inferred from an address. The address is evidence and is not the fact: carrier-grade NAT looks public and is not, a routable address behind a closed firewall looks public and is not, and the regular expression that used to decide it got the lab wrong too. Hub election by address prefix failed silently when nobody knew the convention. No private key travels, and that is the whole design. The node generated its own keypair and kept the private half; the configuration points at a file the node wrote, using WireGuard's own PostUp. So the control plane composes a complete configuration for a node it cannot pretend to be -- it knows every public key and holds none of the private ones. Delivered as an ordinary declaration: a package, a file and a service. The host does not know what a private network is and does not learn one. There is a test holding that line, because the moment connectivity needs a new shape in tier 0 is the moment the host stops being small enough to trust. The generated file is written to be read: each peer says why it is there, a peer with no endpoint says why it has none, and the header says not to edit it -- an edit survives until the graph next changes and then vanishes, which is worse than never being applied, because the machine works and then stops and nothing changed that anybody remembers. Fault injection found one weak test. The keepalive rule was asserted only against the hub, whose peer entries happen not to set the field at all, so it was testing an absence rather than the rule. It now checks two direct peers where one is reachable and one is not.
39 lines
2.2 KiB
SQL
39 lines
2.2 KiB
SQL
-- What the mesh needs in order to compute a private network.
|
|
--
|
|
-- novox/hq 08-connectivity. Three declared inputs and one reported key. All four are facts about
|
|
-- a node that only the mesh can hold, because computing the graph needs every node at once —
|
|
-- which is the definition of control-plane work.
|
|
|
|
-- The node's public key on the overlay. Reported by the node, which generated the pair and kept
|
|
-- the private half. So the control plane computes a graph it cannot itself impersonate.
|
|
alter table node add column overlay_key text;
|
|
|
|
-- Where the node can be dialled, or null for nowhere.
|
|
--
|
|
-- DECLARED, never inferred from the address. The address is evidence of reachability and is not
|
|
-- the fact: carrier-grade NAT looks public and is not, a routable address behind a closed
|
|
-- firewall looks public and is not, and the regular expression that used to decide this got the
|
|
-- lab wrong as well (novox/hq ADR 0007).
|
|
alter table node add column endpoint text;
|
|
|
|
-- Where the machine physically is, or null if it roams.
|
|
--
|
|
-- Two nodes at one site peer directly; everything else routes through the hub. A node with no
|
|
-- site is hub-only, and that is not a simplification — WireGuard has no failover, so a more
|
|
-- specific route to a dead endpoint blackholes rather than falling back. One path is better than
|
|
-- two when one of them can swallow traffic silently.
|
|
alter table node add column site text;
|
|
|
|
-- Whether this node is the hub. DECLARED, never derived from an address prefix: an election
|
|
-- decided by the first four characters of an address fails silently, cannot be queried, and makes
|
|
-- renumbering an outage.
|
|
alter table node add column is_hub boolean not null default false;
|
|
|
|
-- At most one hub. Partial, so it constrains the true ones and says nothing about the rest.
|
|
create unique index node_one_hub on node ((is_hub)) where is_hub;
|
|
|
|
-- The node's address on the overlay, assigned by the mesh. A node computes nothing about the
|
|
-- network it is joining: it generates a keypair, publishes the public half, and receives the rest.
|
|
alter table node add column overlay_address inet;
|
|
create unique index node_overlay_address on node (overlay_address) where overlay_address is not null;
|