Files
hq/02-DECISIONS/0168-a-converged-machine-is-filtered-by-the-mesh-alone.md
T

10 KiB

topic, status, date, deciders, reconstructed, extends
topic status date deciders reconstructed extends
the mesh accepted 2026-10-02 jochen false 02-DECISIONS/0100-a-node-in-use-is-adopted-before-it-is-converged.md

168. A converged machine is filtered by the mesh alone, and the host says what else refuses

Context

ADR 0100 says what converging does to the firewall a machine was found with: the mesh's derived filter is loaded in place of the refusal-only guard, and the found firewall is retired — disabled, never flushed. Four issues from the first two convergences are four ways that sentence was not the machine:

  • the flip reported the found firewall retired and it was active two minutes later; fifty minutes on, a reconcile found it disabled by hand and recorded that the mesh had done it (143);
  • "the firewall found" named one front end, and what filtered the forwarded path on that machine was a chain a predecessor had installed in the container runtime's user hook — invisible to the mesh, refusing two ports the mesh declared open, and when it was removed, carrying an allowance every module reaching another by the machine's own name had been relying on (144, 145);
  • the forward chain listed address ranges that followed neither the modules nor the machine (141), answered by ADR 0140 before this record;
  • the networking module wrote two machine-wide files whole, so taking it restarted every container (084), answered by ADR 0102 and the hosts file's marked region (issue 128).

Read on the four machines of this mesh on 2026-10-02, after every one had converged: on both machines that had a front end it is inactive, and the host's record says the mesh retired it on both — true of one, false of the other. On the home server the predecessor's chain is still in force on the forwarded path, in the legacy packet filter the mesh's reader of rules does not consult once a machine is converged, so that machine is filtered by two things and the mesh says one. The host's reader already knows how to tell a table that refuses traffic from the runtime's own plumbing and from a ban list; it is asked once, at adoption, and only to refuse a machine whose firewall nobody speaks. Nothing asks it afterwards, and nothing reports what it saw.

The group's exit is one sentence: a converged machine has exactly one thing filtering it, and the mesh says truthfully which. The first half the mesh can enforce only for what it owns; the second half it can always do, and it is the half that was missing.

Decision

1. Convergence is a state the host keeps, not a step it takes once. Every apply of a converged declaration reads whether the found firewall is in force. Active — enabled again by a package, a boot, a hand — it is retired again and said. The record distinguishes the mesh disabled it from it was found inactive, and a reconcile that finds it inactive never records that the mesh did it. When the step is skipped because the apply had failures, the report says the found firewall was left in force and why; a step that does nothing is never silent.

2. The host reports what filters the machine, with every apply, adopted or converged. Every table of the packet filter, and every chain of the legacy filter, that refuses traffic — a drop or a reject, or a base chain whose policy drops — with an owner: the mesh's, the found firewall's, the container runtime's own, a ban (a refusal that names the sources it refuses, in a chain that accepts nothing), or other. The runtime's own is its plumbing — its chains, the forward policy it sets when it turns forwarding on, its guard against reaching a container's address from off its bridge. The user chain the runtime leaves for an administrator is not the runtime's: anything refusing in it is other, which is where both predecessors' chains lived. Each entry says in one line what it refuses. The mesh removes none of it: a rule it did not write is the operator's to remove, now that they can see it.

3. The mesh says which. node show lists the filters with their owners. status names every converged machine that something other than the mesh's table, the runtime's plumbing and a ban list filters, the way it names strays and untaken modules, and such a machine is not "all well". The converge preview lists the filters found and the fate of each: the found firewall retired, the runtime's and the bans left, other left and named — so a person knows before the flip that the machine will not be filtered by the mesh alone until they remove it, and what they would be removing. A converged machine is filtered by the mesh alone when its list holds nothing but the mesh's, the runtime's own and bans.

4. Adoption's threshold does not move. A machine whose front end nobody speaks is still refused adoption; a refusing rule in the runtime's user chain still does not refuse it — on both machines of this mesh it would have, and the migration would not have happened. It is reported instead, from the first report on.

5. Two of the group's issues are settled by records already accepted. The forward chain follows the machine's outward links and says nothing about networks (ADR 0140), which answers 141 whole. The runtime's file is written into and reloaded, and the hosts file's region is the mesh's alone (ADR 0102, issue 128), which answers 084. One machine-wide file the mesh still writes whole is its own filter, at the path the distribution's packet filter reads; an operator's own rules at that path would be contested, and are held as found until the filter module is taken (ADR 0163). That is a difference a take shows, not a fault, and is decided when it bites.

Consequences

  • The host's report grows by the filters it found and, for a converged machine, the state of its found firewall and who retired it; the controller keeps both on the node's record.
  • retireFirewall runs on every converged apply and can disable the found firewall more than once; the record's disabled by the mesh means exactly that.
  • The reader of rules gains an owner per table and chain; what it refuses adoption for does not change. A ban stays what it was: not a firewall.
  • Issues 143 and 144 close on rules 1 to 3 once a machine's record names the predecessor's chain; 141 closes on ADR 0140 and 084 on ADR 0102, both by reading.
  • Removing what is reported is the operator's act, by hand, with the preview's words in front of them. The mesh never flushes and never deletes a rule it did not mark.

How this is checked

Rule Checked by
Every refusing table and chain is classified, the user chain's refusals as other host tests over rulesets captured from three machines of this mesh: a predecessor's chain in the legacy filter, a ban list and empty front-end chains beside the runtime's, a virtualisation host and an endpoint agent that refuse nothing
The found firewall active again on a converged machine is retired again and said; found inactive is recorded as found, not done; a skipped step is said host tests over a fake front end
The report carries the filters and the found firewall's state for a converged machine a host test reading the report
node show lists filters with owners; status names a converged machine something else filters and is not well; the preview lists filters and fates controller tests over a fixture report
Live the home server's record names the predecessor's chain in the runtime's user chain as other; status names the machine; after the operator removes the chain, the next report drops it and status is well

Built and proven live, 2026-10-02

Progressive insight — 2026-10-02. The decision stands; these are the facts of its building.

Built in mesh-host 67 (every refusing table and legacy chain classified with an owner, reported with every apply; the found firewall retired on every converged apply, found inactive kept apart from disabled by the mesh, a skipped step said) and mesh-controller 211 (kept per node, shown on node show, named by status and not well, previewed with fates). The live row was read at 10:10Z: the home server's record named the predecessor's chain in the legacy filter's user chain as other, beside two chains a retired front end left in the IPv6 legacy filter; the control node's record named the same two leftovers; the laptop and the workstation read the mesh alone; status named both machines. The five rule sets were removed at 12:46Z through the packet filter seat's remove verb (ADR 0170), and the next report read the mesh alone on all four machines. The control node's record still says the mesh retired its front end, which issue 143 records as a hand's work: the host trusts its record, and from this build on the distinction is kept.

References