75 lines
3.8 KiB
Markdown
75 lines
3.8 KiB
Markdown
---
|
|
status: resolved
|
|
opened: 2026-09-28
|
|
located-in: [mesh-controller internal/catalogue]
|
|
fixed-by: mesh-controller — a machine says which networks it routes and the derived filter forwards them, their guests keeping address and name service ([ADR 0137](../../02-DECISIONS/0137-a-machine-says-which-networks-it-routes.md)).
|
|
amended-design:
|
|
---
|
|
|
|
# 137 — Converging a machine cut off its own guests, and nothing said so
|
|
|
|
## What was observed
|
|
|
|
A workstation was flipped from adopted to converged, so the mesh's derived filter replaced what was
|
|
there. The flip reported success, the machine reported that it had applied its declaration, and every
|
|
surface of the mesh read green.
|
|
|
|
A container on one of that machine's networks could no longer reach anything:
|
|
|
|
```
|
|
192.168.64.2/20
|
|
OUTBOUND BLOCKED
|
|
```
|
|
|
|
Five of the machine's container networks were affected, and every network its test beds create. The
|
|
reason is in the filter's forward chain, which denies by default and then allows two ranges:
|
|
|
|
```
|
|
ip saddr 172.16.0.0/12 accept # the container runtime's bridge networks
|
|
ip saddr 192.168.128.0/17 accept # the networks its compose files are given
|
|
```
|
|
|
|
Those two are constants in the controller. The machine's guests were allocated from neither: its
|
|
compose networks from other parts of `192.168/16`, and each test bed a fresh `10.x/24`. So the rules
|
|
were correct for a machine whose runtime was left at its defaults, and a guess on this one.
|
|
|
|
Two further things were closed by the same flip, and for the same reason nobody saw them: a guest asks
|
|
its host for an address over DHCP and for names over DNS, both of which arrive at the input chain,
|
|
where no module had declared them.
|
|
|
|
## Why it matters beyond this instance
|
|
|
|
**The preview could not have warned.** It lists what the machine reported as *listening*, and says so
|
|
honestly: it ends with a line that traffic the machine routes is "not previewed". What it did not say
|
|
is that routing was about to be denied by default, or which ranges would survive. An operator reading
|
|
a 350-line preview approves what it shows.
|
|
|
|
**It is the second time today that a constant stood in for something the mesh cannot know.** The
|
|
intrusion-prevention module named a firewall front-end two machines do not have
|
|
([issue 136](../136-a-module-may-name-a-program-the-machine-does-not-have/00-report.md)), and the
|
|
filter names the address ranges one runtime happens to use. Both were true where they were written and
|
|
silently false elsewhere.
|
|
|
|
**And the code already knew.** The comment above those two lines says a machine configured otherwise
|
|
"needs this to say so — which is a thing the mesh cannot derive and a reason this list is named here
|
|
rather than computed". The gap was documented at the point where it was introduced, and the way to say
|
|
it was never built. A comment naming a missing mechanism is a rule that is not enforced.
|
|
|
|
## What was done
|
|
|
|
A machine says which networks it routes; the filter forwards them and admits their guests' address and
|
|
name service. Added to the runtime's defaults rather than replacing them, so a machine that names one
|
|
range keeps the others. Node-level, because the machine routes them and the module that loads the
|
|
filter may be replaced. The converge preview now says what a machine routes, and what it will keep
|
|
forwarding if it says nothing.
|
|
|
|
## What is still true
|
|
|
|
**The flip is still the moment a machine's unmanaged services close.** That is what converging means
|
|
and the preview names each one. This issue is not about the ports that were meant to close; it is about
|
|
the ones nothing could name.
|
|
|
|
**Egress is still not previewed per network.** The preview says which ranges will be forwarded, not
|
|
which of the machine's guests sit inside them. Deriving that would need the machine to report its
|
|
bridges, and a bed's bridge does not exist until the bed runs.
|