Transit, host firewalls, and the whole topology raising
The full topology now raises: four machines, three routers, a transit router, six segments, in 35 seconds. Everything the declaration model can express except `place`, which is refused because the node host it would place does not exist yet. Transit was a real gap, not a bug. The design says public networks are unrelated and routed to each other, never bridged — and I built the segments and never built the thing that routes between them, so three public networks were islands and nothing crossed. A transit router now holds an interface on every public segment, forwarding and no translation: the closest thing the lab has to the internet, deliberately dumb. Proven rather than asserted, by ping TTL across the raised topology: within one segment ttl=64 no hops across two unrelated public networks ttl=62 gateway + transit multicast between public networks 0 replies A flat internet would have shown ttl=64 and answered multicast — which would let a node discover a peer it could never reach in production, and report success. That is the fault the as-is layer records the mesh already hitting with multicast name resolution. inbound: deny is implemented as a host firewall on the machine, read back after applying. A declared refusal that silently did not load leaves the machine wide open, which looks exactly like a machine that is working. Established and related traffic is accepted, so a defended machine can still dial out rather than being a disconnected one. Verified by running, all of it: home -> devices (policy allow) reachable devices -> home (policy deny) blocked behind unforwardable NAT -> out reachable in -> behind unforwardable NAT unreachable inbound: deny, dialling out reachable reaching a machine that denies inbound refused The two routers differ exactly as declared: the forwardable one carries the policy rule and no inbound drop, the unforwardable one carries `ct state new drop` and no DNAT.
This commit is contained in:
@@ -110,10 +110,11 @@ than ignored:
|
||||
| gateways, NAT, masquerade | **works** |
|
||||
| `published:` ports (DNAT through the gateway's address) | **works** |
|
||||
| `mapping_ttl:` (conntrack timeout) | **works**, and verified after setting — a declared expiry that silently did not apply would be the fault this catches |
|
||||
| `forwardable: false` | implemented, **not yet verified by running** |
|
||||
| `policy:` between segments | implemented, **not yet verified by running** |
|
||||
| `inbound: deny` | **refused at raise** |
|
||||
| `place:` | **refused at raise** |
|
||||
| `forwardable: false` | **works** — outbound only, no DNAT, unsolicited inbound dropped |
|
||||
| `policy:` between segments | **works**, asymmetric |
|
||||
| `inbound: deny` | **works** — host firewall, read back after applying |
|
||||
| several public networks, routed not bridged | **works** — a transit router, never a shared bridge |
|
||||
| `place:` | **refused at raise** — the node host it would place does not exist yet |
|
||||
|
||||
`raise` refuses a scenario declaring anything in the lower half, naming every gap. It does not
|
||||
raise a mesh that silently lacks what it declared — that is the fault this lab exists to catch
|
||||
@@ -138,12 +139,29 @@ something under test (`novox/hq` ADR 0033).
|
||||
gateway, reached from a machine on a routable address:
|
||||
|
||||
```
|
||||
home-server -> anchor 0% loss, through masquerade
|
||||
anchor -> 192.168.1.135 (private, direct) unreachable ✓
|
||||
anchor -> 192.0.2.50:8080 (the GATEWAY) HTTP 200
|
||||
home-server -> anchor 0% loss, through masquerade
|
||||
anchor -> 192.168.1.135 (private, direct) unreachable ✓
|
||||
anchor -> 192.0.2.50:8080 (the GATEWAY) HTTP 200
|
||||
home -> devices (policy allow) reachable ✓
|
||||
devices -> home (policy deny) blocked ✓
|
||||
roamer behind unforwardable NAT -> anchor reachable ✓ (outbound only)
|
||||
anchor -> roamer unreachable ✓
|
||||
workstation with inbound: deny, dialling out reachable ✓ (defended, not disconnected)
|
||||
home-server -> workstation refused ✓
|
||||
```
|
||||
|
||||
The last line is the case research 004 says only exists in production.
|
||||
The third line is the case research 004 says only exists in production.
|
||||
|
||||
**Routed, never bridged**, proven rather than asserted — ping TTL across the full topology:
|
||||
|
||||
```
|
||||
within one segment ttl=64 no hops
|
||||
across two unrelated public networks ttl=62 gateway + transit
|
||||
multicast between public networks 0 replies
|
||||
```
|
||||
|
||||
A flat "internet" would have shown ttl=64 and answered multicast, which would have let a node
|
||||
discover a peer it could never reach in production — and report success.
|
||||
|
||||
Machines boot concurrently, so a second machine costs seconds rather than doubling the wait.
|
||||
Nearly all of the remaining time is boot, which cannot be avoided.
|
||||
|
||||
Reference in New Issue
Block a user