Merge pull request #45 from claude-hdb/fix/pin-claudenet-resolver

fix: pin claudenet's resolver — a box's DNS is not a function of the host's VPN
This commit is contained in:
Daniel Marin 2026-07-14 13:22:47 +01:00 committed by GitHub
commit 7df9dafc40
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 17 additions and 2 deletions

View file

@ -182,9 +182,10 @@ else
no "the host resolves via a CGNAT/Tailscale resolver ($hostns), and boxes INHERIT it — see issue #33" no "the host resolves via a CGNAT/Tailscale resolver ($hostns), and boxes INHERIT it — see issue #33"
inf "· box DNS breaks whenever the tailnet's resolver does (this is what kills cold mints)" inf "· box DNS breaks whenever the tailnet's resolver does (this is what kills cold mints)"
inf "· and tailnet names RESOLVE from inside a box, though its ACL blocks connecting to them" inf "· and tailnet names RESOLVE from inside a box, though its ACL blocks connecting to them"
inf "fix + test: bash drill/doctor.sh --pin-dns" inf "fix: re-run ~/.local/share/claudebox/host/setup-host.sh (it pins the resolver)"
inf " or quick-test the pin alone: bash drill/doctor.sh --pin-dns"
else else
inf "boxes inherit the host's resolver (unpinned). Fine while it is stable; see issue #33." inf "boxes inherit the host's resolver (unpinned — setup-host.sh pins this now; re-run it)"
fi fi
fi fi

View file

@ -46,6 +46,20 @@ incus network set claudenet security.acls=claude-isolate \
# forwarding for public names is unaffected (verified live). # forwarding for public names is unaffected (verified live).
incus network set claudenet dns.mode=none incus network set claudenet dns.mode=none
# A box's resolver must not be a function of the host's VPN posture (#33).
# The bridge's dnsmasq forwards to whatever sits in the HOST's /etc/resolv.conf
# at that moment. On a Tailscale/VPN host that is MagicDNS: box DNS flaps with
# the tailnet (this is what killed cold mints), and tailnet peer names and
# split-DNS zones RESOLVE from inside a box — name-level reconnaissance of a
# private network, the same shape as the sibling enumeration closed above.
# no-resolv detaches dnsmasq from the host's resolver entirely; server= pins a
# stable public upstream (override: BOX_DNS="ip ip…"). raw.dnsmasq is the
# lever — the bridge has no first-class upstream key. Verified live on the
# drill host: pin applied, box resolves, cold mint survives.
BOX_DNS="${BOX_DNS:-1.1.1.1 8.8.8.8}"
incus network set claudenet raw.dnsmasq \
"$(printf 'no-resolv\n'; for s in $BOX_DNS; do printf 'server=%s\n' "$s"; done)"
# Sibling isolation itself is NOT an ACL rule — an L3 ACL never sees frames # Sibling isolation itself is NOT an ACL rule — an L3 ACL never sees frames
# switched between two ports of one bridge. It lives in claudebox-firewall.sh # switched between two ports of one bridge. It lives in claudebox-firewall.sh
# as an nftables bridge-family rule. See the comment there; it is the reason # as an nftables bridge-family rule. See the comment there; it is the reason