From a0400606c2a811466e4397e5e896ff7d2a0cd5bf Mon Sep 17 00:00:00 2001 From: claude-hdb Date: Tue, 14 Jul 2026 02:16:57 +0000 Subject: [PATCH] fix(doctor): read the isolation off the bridge, not off the config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two bugs, one in each direction. setup-host's new assertion ran 'nft list table bridge claudebox' without sudo. nft needs root, so it failed with permission denied and printed "the box-to-box drop is NOT active" about a rule that was demonstrably there. A check that cries wolf is worse than no check. And the deeper one: every check so far has asked the CONFIG whether boxes are isolated. The config is a claim. Incus can accept security.port_isolation and the kernel can still leave 'isolated off' on the tap — and then boxes reach each other while every config in sight says they cannot. That is precisely the shape of the original bug: the ACL looked airtight and never saw the traffic. So the doctor now reads the kernel's own view — 'bridge -d link show' on claudenet's ports — and reports the isolated flag as the fact it is. If the profile says true and the kernel says off, we learn that in a second instead of after another ten-minute drill. Co-Authored-By: Claude Fable 5 --- drill/doctor.sh | 24 ++++++++++++++++++++++++ host/setup-host.sh | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drill/doctor.sh b/drill/doctor.sh index 464ef59..0879743 100755 --- a/drill/doctor.sh +++ b/drill/doctor.sh @@ -127,6 +127,30 @@ else inf "claude-isolate does not exist (a fresh host)" fi +# Config is a claim; the bridge port is the fact. Incus can accept +# security.port_isolation and the kernel can still have 'isolated off' on the +# tap — and then boxes reach each other while every config says they cannot. +# Ask the kernel. +head_ "Bridge ports — the KERNEL's view (config is a claim; this is the fact)" +if command -v bridge >/dev/null 2>&1; then + ports="$(sudo bridge -d link show 2>/dev/null | grep -A1 'master claudenet')" + if [ -z "$ports" ]; then + inf "no instance is attached to claudenet right now (mint a box to check the taps)" + else + printf '%s\n' "$ports" | sed 's/^/ /' + if printf '%s' "$ports" | grep -q 'isolated on'; then + ok "the bridge ports are ISOLATED — boxes cannot exchange frames at L2" + else + no "the bridge ports are NOT isolated ('isolated off') — BOXES CAN REACH EACH OTHER" + inf "security.port_isolation in the profile is a claim; this line is the fact." + inf "if the profile says true and the kernel says off, the flag is not being" + inf "applied to VM taps and the isolation needs a different mechanism." + fi + fi +else + inf "'bridge' (iproute2) not installed — cannot read the kernel's view" +fi + head_ "Instances" left="$(incus list --format csv --columns ns 2>/dev/null)" [ -z "$left" ] && inf "(none)" || printf ' %s\n' "$left" diff --git a/host/setup-host.sh b/host/setup-host.sh index 12a1721..644d968 100755 --- a/host/setup-host.sh +++ b/host/setup-host.sh @@ -87,7 +87,7 @@ incus profile edit claude-dev < "$here/profiles/claude-dev.yaml" # The sibling drop is the one rule whose absence is invisible: everything keeps # working, and boxes can simply reach each other. Assert it landed. -if nft list table bridge claudebox >/dev/null 2>&1; then +if sudo nft list table bridge claudebox >/dev/null 2>&1; then echo "Isolation: box-to-box drop is live (nft bridge table 'claudebox')." else echo "WARNING: the box-to-box drop is NOT active — boxes can reach each other." >&2 -- 2.45.2