Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bed54d3be | ||
|
|
413daf8ad5 | ||
|
|
5c993c09b7 | ||
|
|
7c3be48db2 | ||
|
|
b665d06701 |
@@ -1,10 +1,10 @@
|
||||
---
|
||||
status: located
|
||||
status: resolved
|
||||
opened: 2026-09-29
|
||||
located-in:
|
||||
- mesh-host internal/apply/opening.go (retireFirewall)
|
||||
- mesh-host internal/apply/apply.go (the condition it is called under)
|
||||
fixed-by:
|
||||
fixed-by: mesh-host 67 (retire on every converged apply; found-inactive apart from disabled-by-mesh; a skipped step said), mesh-controller 211 (the found firewall's state on node show)
|
||||
amended-design:
|
||||
---
|
||||
|
||||
@@ -108,3 +108,13 @@ convergence is a state the host keeps — the found firewall active again is ret
|
||||
reconcile that finds it inactive records *found so* and never *done by the mesh*, and a step skipped
|
||||
after a failed apply is said. Built in mesh-host on `feat/one-thing-filters-a-converged-machine`; the
|
||||
record of both machines of this mesh is corrected by the first report under it.
|
||||
|
||||
## Resolved, 2026-10-02
|
||||
|
||||
mesh-host 67 and mesh-controller 211, live on every machine at 10:10Z. The step now runs on every
|
||||
converged apply and says what it did; a found firewall enabled again is retired again. The record's
|
||||
one inherited lie stands as history: on the control node the machine's own record already said the
|
||||
mesh had disabled the firewall, and the host trusts its record, so `node show` says "retired by the
|
||||
mesh" there. From this build on, a reconcile that finds the firewall inactive records *found inactive*
|
||||
and never the other thing. Whether the flip's step took on 2026-09-29 is not recoverable and is not
|
||||
owed by this record any more.
|
||||
|
||||
+14
-2
@@ -1,10 +1,10 @@
|
||||
---
|
||||
status: located
|
||||
status: resolved
|
||||
opened: 2026-09-29
|
||||
located-in:
|
||||
- mesh-host internal/apply/opening.go
|
||||
- mesh-controller cmd/mesh-controller (the converge preview)
|
||||
fixed-by:
|
||||
fixed-by: mesh-host 67 (every refusing table and legacy chain classified with an owner; the runtime's user chain is other), mesh-controller 211 (kept, shown on node show, named by status, previewed with fates)
|
||||
amended-design:
|
||||
---
|
||||
|
||||
@@ -91,3 +91,15 @@ chain's refusals as *other*; `node show`, `status` and the converge preview say
|
||||
`feat/one-thing-filters-a-converged-machine` in mesh-host and mesh-controller. On 2026-10-02 the home
|
||||
server still carries the predecessor's chain in its legacy filter; the record's live row is reading it
|
||||
there.
|
||||
|
||||
## Resolved, 2026-10-02
|
||||
|
||||
mesh-host 67 and mesh-controller 211, live at 10:10Z. The live row of
|
||||
[ADR 0168](../../02-DECISIONS/0168-a-converged-machine-is-filtered-by-the-mesh-alone.md) was read the
|
||||
same hour: the home server's record names the predecessor's chain in the legacy filter's user chain
|
||||
as *other*, with what it refuses, beside two chains a retired front end left in the IPv6 legacy filter;
|
||||
the control node's record names the same two leftovers; the laptop and the workstation read *the mesh
|
||||
alone*. `status` names both machines and is not well until the operator removes what the mesh did not
|
||||
write. The allowance the predecessor's chain carried is
|
||||
[issue 145](../145-a-machine-reads-healthy-while-its-modules-cannot-reach-each-other/00-report.md)'s,
|
||||
and that record is not closed by this one.
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
---
|
||||
status: resolved
|
||||
opened: 2026-10-02
|
||||
located-in: [mesh-host internal/outward (Links reported only the links carrying a default route)]
|
||||
fixed-by: mesh-host PR 66 (a link backed by a physical device is named outward, up or down), live 2026-10-02
|
||||
amended-design: []
|
||||
---
|
||||
|
||||
# 197 — A physical link that is down is not filtered when it comes up
|
||||
|
||||
## What was observed
|
||||
|
||||
A sweep of every machine's filter on 2026-10-02. A laptop-class machine connected by its radio has a
|
||||
wired port that was unplugged. Its filter guarded the radio and the tunnel, and accepted everything
|
||||
arriving on any other link:
|
||||
|
||||
```
|
||||
iifname != { "mesh0", "<radio>" } accept
|
||||
```
|
||||
|
||||
The wired port was not in the list. Plugged in, everything arriving on it would have been accepted,
|
||||
every port of the machine open to whatever network the cable reached. That would last until the
|
||||
machine reported again and was pushed a new filter.
|
||||
|
||||
## Why it matters
|
||||
|
||||
**The filter's one rule about links fails open.** [ADR 0140](../../02-DECISIONS/0140-the-filter-constrains-what-arrives-from-outside.md)
|
||||
has the filter constrain what arrives from outside, and has the machine say which links face outside.
|
||||
Everything not named is treated as the machine's own, its containers and bridges. So a link the machine
|
||||
fails to name is not filtered at all. The host named only the links carrying a default route at the
|
||||
moment it reported. A cable plugged in later is the ordinary case for a laptop. A second wired network
|
||||
that never carries the default route, such as a direct link to a storage box, is never named at all.
|
||||
|
||||
## Open questions
|
||||
|
||||
- A virtual link that faces outside (a VPN client's interface, a USB tether that appears as a virtual
|
||||
device) has no physical device behind it. It is named only while it carries the default route. Is
|
||||
that enough?
|
||||
|
||||
## Resolved (2026-10-02)
|
||||
|
||||
Live on the affected machine after the host was delivered and one more push: its filter now guards the
|
||||
radio, the tunnel and the unplugged wired port, before anything is plugged into it.
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
# Diagnosis
|
||||
|
||||
*2026-10-02.*
|
||||
|
||||
**Located in `mesh-host` `internal/outward`.** `Links` read the kernel's routing tables and returned the
|
||||
interfaces carrying a default route. An unplugged port carries none, so it was never reported, and the
|
||||
controller rendered the filter around the links it was given.
|
||||
|
||||
**The fix.** A link faces outside if it carries a default route **or** has a physical device behind it.
|
||||
The kernel lists every interface under `/sys/class/net`, with a `device` entry for one backed by
|
||||
hardware. A bridge, a veth, the tunnel and the loopback have none, so they stay the machine's own. The
|
||||
wired port is now reported up or down, and the filter guards it before anything is plugged in. Tested
|
||||
with a radio carrying the default route and an unplugged wired port beside a bridge, a veth, the docker
|
||||
bridge, the tunnel and the loopback: the two physical links are reported, nothing else.
|
||||
Reference in New Issue
Block a user