Segment policy, shared gateways, and what the model leaves out
Asked whether a real setup is coverable — router, modem, access points — the answer splits, and one part was a genuine gap. Most equipment is invisible and the omission is deliberate. The test: does the device change what an IP packet can do? A switch moves frames within a segment. An access point bridges wireless clients onto one — a machine on wifi and a machine on cable are the same machine to IP. A controller configures equipment and has no packets of its own. Modelling any of them adds a fixture with no fault to catch. Two entries in that list do matter. A modem in bridge mode is a media converter and invisible; in router mode it is a second gateway, which is double NAT — expressible as nested segments, but publishing through two gateways still is not, and that is now named as the one real absence. And VLANs are segments, which exposed the gap: inter-segment policy was inexpressible. inbound: is a HOST firewall, per machine. A segmented router enforcing rules between networks is a different thing and blocks traffic regardless of what the destination thinks — a node behind such a rule cannot be reached even by a peer that knows exactly where it is. policy: states it as a fact about a pair rather than a property of either, defaulting to allowed and asymmetric by design, because the useful configuration is almost always one-directional. Segments may also share a gateway: identical gateway declarations mean one gateway machine, not two, because that is what a VLAN-capable router is — and two routers sharing an address would not work anyway.
This commit is contained in:
@@ -308,6 +308,86 @@ not first.
|
||||
- **Steps.** A scenario is a desired state. Anything expressed as an ordered list of actions
|
||||
belongs in the lifecycle, not the declaration.
|
||||
|
||||
## What the model deliberately does not contain
|
||||
|
||||
A real network is full of equipment: a modem, a router, switches, access points, controllers.
|
||||
Almost none of it appears here, and the omission is deliberate rather than an oversight.
|
||||
|
||||
**The test is whether a device changes what an IP packet can do.** If two machines can exchange
|
||||
packets, at the same addresses, with the same reachability and the same MTU, whether or not the
|
||||
device exists — then the device is invisible to the mesh, and modelling it would add a fixture
|
||||
with no fault to catch.
|
||||
|
||||
| Equipment | Modelled? | Why |
|
||||
|---|---|---|
|
||||
| **Switch** | no | Moves frames within a segment. Two machines on a switch are two machines on a segment. |
|
||||
| **Access point** | no | Bridges wireless clients onto a segment. A machine on wifi and a machine on cable are the same machine to IP. |
|
||||
| **Network controller** | no | Configures equipment. Its effects appear as segments and policy; it has no packets of its own. |
|
||||
| **Cabling, PoE, uplink speed** | no | Change performance and availability, not reachability. |
|
||||
| **Router / security gateway** | **yes — it *is* the gateway** | Translation, forwarding and inter-segment policy all live here. |
|
||||
| **ISP modem** | **only in router mode** | In bridge mode it is a media converter and invisible. Doing its own NAT, it is a second gateway — and that is double NAT. |
|
||||
| **VLANs** | **yes — they are segments** | Machines on separate VLANs cannot reach each other except through the router, which is the definition of a separate segment. |
|
||||
| **Inter-VLAN firewall rules** | **yes** — see below | A rule stopping one segment reaching another is a reachability fact, and the mesh will hit it. |
|
||||
|
||||
The two entries worth dwelling on are the ones where a common household setup produces
|
||||
something the mesh has to survive.
|
||||
|
||||
**A modem in router mode gives you double NAT.** Your gateway holds a private address from the
|
||||
modem, which holds the public one. Forwarding then requires a rule on *both*, and one of them
|
||||
may not be configurable. This is expressible as nested segments — `to:` chains — but publishing
|
||||
through two gateways is not, and remains open.
|
||||
|
||||
**Segmented networks are the common case, not the exotic one.** A router with separate networks
|
||||
for trusted machines, guests and devices is ordinary, and the rules between them are ordinary
|
||||
too. A mesh node on one segment and a mesh node on another are, as far as reachability goes, on
|
||||
different networks that happen to share a gateway.
|
||||
|
||||
## Segments may share a gateway
|
||||
|
||||
Several segments can name the same parent and the same external address. That is one router
|
||||
with several networks behind it, which is what a VLAN-capable gateway is:
|
||||
|
||||
```yaml
|
||||
segments:
|
||||
trusted:
|
||||
kind: private
|
||||
cidr: [192.168.1.0/24]
|
||||
gateway: { to: internet, address: 203.0.113.50, nat: [v4], forwardable: true }
|
||||
devices:
|
||||
kind: private
|
||||
cidr: [192.168.30.0/24]
|
||||
gateway: { to: internet, address: 203.0.113.50, nat: [v4], forwardable: true }
|
||||
```
|
||||
|
||||
Identical gateway declarations mean **one gateway machine**, not two. The lab materialises a
|
||||
single router serving both, because that is what the topology being reproduced is — and two
|
||||
routers sharing one address would not work anyway.
|
||||
|
||||
## Policy between segments
|
||||
|
||||
Sharing a gateway does not mean segments can reach each other. What they may do is stated
|
||||
separately, because it is a fact about a pair rather than a property of either:
|
||||
|
||||
```yaml
|
||||
policy:
|
||||
- { from: devices, to: trusted, allow: false } # devices may not initiate to trusted
|
||||
- { from: trusted, to: devices, allow: true } # the reverse is fine
|
||||
```
|
||||
|
||||
Default is `true` between segments behind the same gateway, matching a router with no rules
|
||||
configured. Asymmetry is the normal case and the reason this cannot be a single flag: the
|
||||
useful configuration is almost always one-directional.
|
||||
|
||||
This is **not** the same as `machines[].inbound`, and conflating them loses a real distinction:
|
||||
|
||||
| | Enforced by | Blocks |
|
||||
|---|---|---|
|
||||
| `policy` | the gateway, between segments | everything crossing, regardless of what the destination thinks |
|
||||
| `inbound` | the machine itself | unsolicited traffic that already reached it |
|
||||
|
||||
A mesh node behind a `policy` deny cannot be reached even by a peer that knows exactly where it
|
||||
is — and that is a real topology, not a contrived one.
|
||||
|
||||
## Is this general? — the axes a setup can vary along
|
||||
|
||||
The question that matters is not *does this cover our mesh*, but **can it express any mesh**.
|
||||
@@ -320,7 +400,9 @@ how the mesh behaves**. Bandwidth does not change correctness; MTU does.
|
||||
| **Reachability** | attached · forwardable gateway · unforwardable gateway · isolated | yes | the core of the model, and **per family** |
|
||||
| **Address family** | IPv4 · IPv6 · dual-stack · neither | yes | `cidr:` and `address:` take both; `nat:` names which families are translated |
|
||||
| **Interfaces per machine** | one · several | yes | `at:` takes a list |
|
||||
| **Reachability policy** | symmetric · asymmetric | yes | `inbound:` — a routable machine that refuses everything |
|
||||
| **Reachability policy, host** | symmetric · asymmetric | yes | `inbound:` — a routable machine that refuses everything |
|
||||
| **Reachability policy, network** | open · segmented · asymmetric between segments | yes | `policy:` — inter-segment rules, as a segmented router enforces |
|
||||
| **Segments per gateway** | one · several behind one router | yes | identical gateway declarations mean one gateway machine |
|
||||
| **Gateway state** | permanent · expiring mappings | yes | `mapping_ttl:` |
|
||||
| **Path MTU** | standard · reduced | yes | `segments[].mtu` |
|
||||
| **Overlapping ranges** | distinct · two sites both on `192.168.1.0/24` | yes | segments may carry the same range |
|
||||
@@ -357,11 +439,17 @@ revisited — and it would be revisited by a real failure, which is the right tr
|
||||
|
||||
### The honest summary
|
||||
|
||||
The model now covers **where a machine sits** and **what the path between machines is like**,
|
||||
across both address families, which together are what the mesh's reachability logic turns on.
|
||||
The model now covers **where a machine sits**, **what the path between machines is like**, and
|
||||
**what is permitted between them** — across both address families. Together those are what the
|
||||
mesh's reachability logic turns on.
|
||||
|
||||
What it does not model is *change over time* beyond moving a machine, and *degradation* short of
|
||||
failure. Both are absences chosen rather than overlooked.
|
||||
It contains almost no equipment, by the test above: a device that does not change what an IP
|
||||
packet can do has no fault for a scenario to catch. What it does contain is every device that
|
||||
does — which turns out to be the router, and a modem only when the modem is also a router.
|
||||
|
||||
What it still does not model is *change over time* beyond moving a machine, *degradation* short
|
||||
of failure, and *publishing through two gateways at once*. The first two are chosen; the third
|
||||
is the one real absence, and it is exactly the double-NAT case.
|
||||
|
||||
## Open
|
||||
|
||||
|
||||
Reference in New Issue
Block a user