The two-node bed proves a machine joins through the tunnel with the bus closed to it

A third machine makes its tunnel key, is issued a token for it, and
enrols while the anchor drops its packets to the bus at the first hook;
it can only have arrived over the tunnel (novox/hq ADR 0169).
This commit is contained in:
2026-10-02 15:11:18 +02:00
parent a4f6bb8ce0
commit 1a4f570e54
2 changed files with 34 additions and 0 deletions
+7
View File
@@ -28,6 +28,13 @@ machines:
egress: true
inbound: allow
memory: 2GiB
# A third machine that joins through the tunnel with the bus closed to it (novox/hq ADR 0169). It
# carries none of the images: it only has to join.
joiner:
at: { segment: hosting, address: [192.0.2.30] }
egress: true
inbound: allow
images: []
images:
- mesh-controller:development
+27
View File
@@ -1662,3 +1662,30 @@ test("a third-party workload is adopted, with the credential it already had", {
// a gap that bed should close; "a consumer's cache grant means exactly its own keys" — its tenancy
// assertions (a write outside the consumer's keys and a FLUSHALL are refused) moved into
// mesh-grant-end-to-end, against the catalogue's redis.
// **A machine joins through the tunnel, and needs the bus only through it** (novox/hq ADR 0169).
// The bus is closed to this machine at the anchor's very first hook, before the container runtime's
// forwarding, so the only way its enrolment can arrive is over the tunnel the token gave it.
test("a machine joins through the tunnel, with the bus closed to it", { skip, timeout: 900_000 }, async () => {
await must("anchor", `nft add table ip lab_bus_closed && ` +
`nft add chain ip lab_bus_closed pre '{ type filter hook prerouting priority -300; }' && ` +
`nft add rule ip lab_bus_closed pre ip saddr 192.0.2.30 tcp dport 4222 drop`);
try {
await must("joiner", `pacman -Sy --noconfirm --needed wireguard-tools >/dev/null 2>&1`);
const key = (await must("joiner", `${HOST_PATH} key 2>/dev/null`)).trim();
assert.match(key, /^[A-Za-z0-9+/]{43}=$/, `not a tunnel key: ${key}`);
// Asked again, the same key: a token may already have been issued for it.
assert.equal((await must("joiner", `${HOST_PATH} key 2>/dev/null`)).trim(), key);
const token = tokenFrom(await mesh(`token issue --new joiner --overlay-key ${key}`));
const said = await must("joiner", `${HOST_PATH} enrol --token ${quote(token)}`);
assert.match(said, /the tunnel to the hub is up/, said);
assert.match(said, /enrolled as joiner/, said);
const shakes = await must("joiner", `wg show mesh0 latest-handshakes`);
assert.ok(/\s[1-9]\d*\s*$/m.test(shakes), `the tunnel never shook hands with the hub: ${shakes}`);
} finally {
await on("anchor", `nft delete table ip lab_bus_closed`);
}
});