forked from heavy-duty/box
docs: BOX_SUBNET, the setup-host refusal, and the doctor signature (#80)
README's setup-host section documents the subnet input and the refusal; 'box help setup-host' names BOX_SUBNET and the nested-box trap; 'box help doctor' names the #80 signature it now judges; the changelog carries the full story, including that suggested fix 4 (the agent-context guard note for the templates) lands in heavy-duty/rig#31's bootstrap roles per the thin-templates split (#81). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
7d48822cc0
commit
53dc2b9047
3 changed files with 57 additions and 2 deletions
28
CHANGELOG.md
28
CHANGELOG.md
|
|
@ -7,6 +7,34 @@ which records not just what changed but what each drill run proved.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- **`setup-host` refuses a claimed subnet, and `BOX_SUBNET` picks another**
|
||||||
|
(#80) — run inside a box, `setup-host` used to build a nested `boxnet` on
|
||||||
|
the exact subnet and gateway of the guest's own uplink: the guest then held
|
||||||
|
its gateway's address as a *local* address, carried duplicate connected
|
||||||
|
routes for its uplink subnet, and suffered intermittent, self-recovering
|
||||||
|
egress blackouts that looked like flaky internet (measured live: ~24–36 s
|
||||||
|
outages, roughly hourly, with the host clean throughout). `setup-host` now
|
||||||
|
scans the target subnet **before any mutation** — the default route's
|
||||||
|
gateway inside it, or any non-`boxnet` interface holding an address in it —
|
||||||
|
and refuses, naming the way out. A prior `boxnet` owning the subnet is the
|
||||||
|
legitimate converge path and does not trip it. `BOX_SUBNET=<a.b.c.0/24>`
|
||||||
|
(validated, alongside the existing `BOX_DNS`) moves the whole stack: the
|
||||||
|
bridge address, the ACL's gateway carve-out (now converged via
|
||||||
|
`network acl edit`, so a bridge moved off a colliding subnet no longer
|
||||||
|
strands box DNS behind a stale `/32`), the firewall (`box-firewall` reads
|
||||||
|
the gateway off the live bridge), and every drill/migrate probe that used
|
||||||
|
to hardcode `10.88`.
|
||||||
|
- **`box doctor` knows the #80 signature** — a default gateway held as a
|
||||||
|
LOCAL address, and duplicate connected routes for the uplink subnet, judged
|
||||||
|
from `ip route`/`ip addr` on the machine doctor runs on (both tiers, before
|
||||||
|
any daemon check — the nested daemon answering could be the impostor) and
|
||||||
|
probed *inside* every box it examines. The existing "egress broken but DNS
|
||||||
|
fine" split now names itself as #80's fingerprint (the impostor dnsmasq on
|
||||||
|
a captured gateway keeps resolving while IP egress dies), and the admin ACL
|
||||||
|
section verifies the gateway carve-out matches `boxnet`'s actual gateway.
|
||||||
|
The agent-context guard for the templates (suggested fix 4) lands in
|
||||||
|
heavy-duty/rig#31's bootstrap roles per the thin-templates split (#81).
|
||||||
|
|
||||||
- **Server-posture template keys** (#81, carved from #69) — two optional
|
- **Server-posture template keys** (#81, carved from #69) — two optional
|
||||||
`box.env` allowlist keys. `BOX_REQUIRE_VM=1` refuses both the silent
|
`box.env` allowlist keys. `BOX_REQUIRE_VM=1` refuses both the silent
|
||||||
container fallback (no `/dev/kvm`, exit 1) and an explicit `--container`
|
container fallback (no `/dev/kvm`, exit 1) and an explicit `--container`
|
||||||
|
|
|
||||||
14
README.md
14
README.md
|
|
@ -126,6 +126,20 @@ re-apply at boot via `box-firewall.service` — no post-reboot ritual. If
|
||||||
the host lacks `dnsmasq-base` (Debian cloud images skip Recommends):
|
the host lacks `dnsmasq-base` (Debian cloud images skip Recommends):
|
||||||
`sudo apt-get install -y dnsmasq-base`.
|
`sudo apt-get install -y dnsmasq-base`.
|
||||||
|
|
||||||
|
The stack's subnet is `10.88.0.0/24` by default; `BOX_SUBNET` picks another
|
||||||
|
`/24` (`BOX_SUBNET=10.89.0.0/24 box setup-host` — the bridge address, the
|
||||||
|
ACL's gateway carve-out and the firewall all derive from it). setup-host
|
||||||
|
**refuses to build on a subnet something already claims** — most tellingly
|
||||||
|
when this machine's own default gateway sits inside it, which means it is
|
||||||
|
being run *inside a box*: a nested `boxnet` on the guest's own uplink subnet
|
||||||
|
captures its gateway address and blackholes the guest's egress in
|
||||||
|
intermittent, maddening-to-attribute blackouts
|
||||||
|
([#80](https://github.com/heavy-duty/box/issues/80)). `BOX_SUBNET` is the
|
||||||
|
sanctioned way out for a nested or otherwise-conflicted install, and
|
||||||
|
`box doctor` recognizes the poisoned state (a gateway held as a local
|
||||||
|
address, duplicate uplink routes) on the machine it runs on and inside every
|
||||||
|
box it probes.
|
||||||
|
|
||||||
A host still carrying the pre-0.4.0 stack: `box migrate-host --all-boxes`
|
A host still carrying the pre-0.4.0 stack: `box migrate-host --all-boxes`
|
||||||
re-homes each legacy box onto `boxnet` (authed state preserved), and
|
re-homes each legacy box onto `boxnet` (authed state preserved), and
|
||||||
`box migrate-host --retire-legacy` removes the old bridge and profile once no
|
`box migrate-host --retire-legacy` removes the old bridge and profile once no
|
||||||
|
|
|
||||||
17
bin/box
17
bin/box
|
|
@ -459,8 +459,12 @@ EOF
|
||||||
Answer "is this host fit to mint boxes?" from ground truth, not config claims:
|
Answer "is this host fit to mint boxes?" from ground truth, not config claims:
|
||||||
is the Incus daemon answering, is a dnsmasq actually serving boxnet, does
|
is the Incus daemon answering, is a dnsmasq actually serving boxnet, does
|
||||||
the kernel's bridge port say 'isolated on', is the resolver pinned or is a
|
the kernel's bridge port say 'isolated on', is the resolver pinned or is a
|
||||||
host VPN's DNS leaking into boxes, can a box actually resolve names. Every
|
host VPN's DNS leaking into boxes, can a box actually resolve names — and
|
||||||
check exists because its fault has happened — most kill a cold mint with a
|
the #80 nested-stack signature: a default gateway held as a LOCAL address,
|
||||||
|
or duplicate connected routes for the uplink subnet, judged on this machine
|
||||||
|
AND inside every box it probes (a box stack installed inside a box squats on
|
||||||
|
the guest's gateway and blackholes its egress, intermittently). Every check
|
||||||
|
exists because its fault has happened — most kill a cold mint with a
|
||||||
cloud-init error that names none of them.
|
cloud-init error that names none of them.
|
||||||
|
|
||||||
--fix also revert what a drill run may have left behind
|
--fix also revert what a drill run may have left behind
|
||||||
|
|
@ -484,7 +488,16 @@ install.sh runs it for you, so this is for re-applying by hand.
|
||||||
One run is enough. If it has to add you to the incus-admin group it re-runs
|
One run is enough. If it has to add you to the incus-admin group it re-runs
|
||||||
itself under that group — no re-login, no second invocation.
|
itself under that group — no re-login, no second invocation.
|
||||||
|
|
||||||
|
The stack's subnet is 10.88.0.0/24 by default; BOX_SUBNET picks another /24
|
||||||
|
(the bridge, the gateway carve-out and the firewall all derive from it). It
|
||||||
|
REFUSES, before touching anything, where the target subnet is already claimed
|
||||||
|
— most tellingly when this machine's own default gateway sits inside it,
|
||||||
|
i.e. when you are running setup-host INSIDE a box: a nested stack on the
|
||||||
|
guest's own uplink subnet captures its gateway address and blackholes its
|
||||||
|
egress, intermittently (issue #80). The sanctioned way to nest:
|
||||||
|
|
||||||
box setup-host
|
box setup-host
|
||||||
|
BOX_SUBNET=10.89.0.0/24 box setup-host # nested, or a conflicted host
|
||||||
|
|
||||||
Multi-user hosts: setup-host builds the stack once, for everyone. An admin
|
Multi-user hosts: setup-host builds the stack once, for everyone. An admin
|
||||||
then hands individual users the restricted tier with 'box grant <user>' —
|
then hands individual users the restricted tier with 'box grant <user>' —
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue