Glossary, the mesh-controller/foundation vocabulary, ADR 0076, Phase 3 closed #43

Merged
jschoubben merged 32 commits from issue/047-the-other-half into main 2026-09-16 21:25:51 +00:00
Showing only changes of commit b163ed1fcc - Show all commits
@@ -0,0 +1,71 @@
---
status: open
opened: 2026-09-14
located-in: []
fixed-by:
amended-design:
---
# 052 — The firewall closes the port the mesh runs on
## Symptom
A one-node mesh with the packet filter assigned generates this input chain:
```
policy drop
ct state established,related accept
iif "lo" accept
icmp / icmpv6 accept
<mesh address> tcp dport 22 accept ssh
<mesh address> tcp dport 5000 accept the registry
<mesh address> tcp dport 20000 accept
udp dport 51820 accept the overlay
```
**The substrate broker's port is not there.** Every machine dials it to enrol and to receive every
declaration it is ever sent. Nothing opens it.
The rules are generated from what modules declare they listen on. The broker is not a module — it
is raised by the installer from the bundle — so it declares nothing, and the generator has nothing
to generate from.
## Why this matters
**It is invisible on the mesh where it is first assembled and fatal on the next one.** A mesh of one
never dials its own broker across the network, so the missing rule changes nothing and the firewall
looks correct. The first machine that tries to join is refused at the packet filter, during
enrolment, before the mesh can report anything about it — and the cause is several steps from the
symptom.
**It would have been met during the migration, not before it.** The intended order is to raise the
anchor, assign its modules, then join the other machines. Assigning the firewall before the second
machine enrols is both the natural order and the one that breaks.
**It is [051](../051-the-mesh-cannot-update-what-it-depends-on/00-report.md) in a second place.** That
issue records that the substrate cannot be updated because the mesh holds no record of it. The same
absence means the firewall cannot know the substrate exists. Anything else generated from what
modules declare has the same hole: the store, the broker, and their ports are outside every such
computation.
**The store is the same shape and has not been checked.** It binds on the machine and is reached by
the control plane; whether that survives a default-drop policy has not been established here.
## Open questions
- **Should the substrate declare its listens** — which means the substrate being something the mesh
holds a record of, i.e. 051's adoption?
- **Or should the firewall have a floor** that is not derived from modules at all, the way ssh
already is? Ssh is in the rules for exactly this reason: a machine nobody can reach is a machine
nobody can repair, and that is not a thing any module declares. The broker is arguably the same
class of fact — the mesh cannot manage a machine it cannot talk to.
- **What else is in that class?** Whatever the answer, the question "which ports must be open for
the mesh itself to work" should be answerable from one place rather than assembled from modules
that happen to exist.
## How this would be checked
| Rule | Checked by |
|---|---|
| A machine with the firewall assigned can still be joined | The packet filter is assigned to an anchor, and a second machine enrols afterwards. |
| The mesh's own ports are open | The generated ruleset is compared against the substrate's own bindings, not only against module declarations. |