diff --git a/docs/FRICTION.md b/docs/FRICTION.md index 888ef73..994ba59 100644 --- a/docs/FRICTION.md +++ b/docs/FRICTION.md @@ -146,6 +146,18 @@ harness on ubongo and shaking it down against real KVM (spec/plan in docs/superp the holistic cross-file review. → for infra this novel, budget for BOTH an adversarial cross-file review AND a real-hardware run; neither alone would have shipped it working. + + +- `[friction]` **Raw DHCP leases pinned in ubongo's host firewall (admin-addr SSH allows)** + (2026-06-19): mesh-hardening 2/3 lets the operator workstations reach ubongo's LAN SSH by + *raw lease* — `base__firewall_admin_addrs: ["10.20.10.50" (mamba), "10.20.10.17"]` — because + there is no DHCP reservation yet (OPNsense isn't managed as code). A lease reassignment + silently moves the allow to whatever host next holds the IP (still SSH-key-gated) and drops + the workstation's *LAN* path (mesh still works, so never a full lockout). → when + OPNsense-as-code lands (ADR-020 perimeter / TODO 3.5), replace both with **MAC-pinned DHCP + reservations** (`10.20.10.17` = MAC `bc:0f:f3:c8:4a:8a`; mamba's MAC TBD) and allow the + reserved IPs. Spec: `docs/superpowers/specs/2026-06-19-mesh-hardening-ubongo-default-deny-design.md`. + --- ## Kaizen reviews — decisions ledger diff --git a/docs/superpowers/specs/2026-06-19-mesh-hardening-ubongo-default-deny-design.md b/docs/superpowers/specs/2026-06-19-mesh-hardening-ubongo-default-deny-design.md index e76a29c..4aafdd2 100644 --- a/docs/superpowers/specs/2026-06-19-mesh-hardening-ubongo-default-deny-design.md +++ b/docs/superpowers/specs/2026-06-19-mesh-hardening-ubongo-default-deny-design.md @@ -65,7 +65,8 @@ ct state established,related accept ct state invalid drop iifname "wt0" tcp dport 22 accept # mesh (road-warriors, askari) ip saddr 10.20.10.151 tcp dport 22 accept # ssh-from-control (Ansible self) — group_vars/all -ip saddr 10.20.10.50 tcp dport 22 accept # mamba on the LAN — base__firewall_admin_addrs +ip saddr 10.20.10.50 tcp dport 22 accept # mamba on the LAN — base__firewall_admin_addrs +ip saddr 10.20.10.17 tcp dport 22 accept # 2nd operator wkstn — base__firewall_admin_addrs ip protocol icmp accept ; ip6 nexthdr ipv6-icmp accept # (no catalog services on ubongo) → default drop chain forward: policy accept # Docker + libvirt-NAT forwarding preserved @@ -112,6 +113,7 @@ chain forward: policy accept # Docker + libvirt-NAT forwarding p base__firewall_input_only: true base__firewall_admin_addrs: - "10.20.10.50" # mamba over the LAN (NetBird off). Raw DHCP lease — see note below. + - "10.20.10.17" # a 2nd operator workstation (MAC bc:0f:f3:c8:4a:8a). Raw lease — ditto. # base__firewall_apply defaults true; base__firewall_control_addr (= ubongo's own 10.20.10.151) # is set in group_vars/all and covers Ansible's self-connection. ``` @@ -132,18 +134,20 @@ base__firewall_admin_addrs: Enables `make test-integration HOST=ubongo`. -## The mamba admin-addr — a deliberately interim value +## The admin-addrs — deliberately interim values -`base__firewall_admin_addrs: ["10.20.10.50"]` is mamba's **current raw DHCP lease**, not a -reservation (operator decision, 2026-06-19). Caveats, accepted for now: +`base__firewall_admin_addrs: ["10.20.10.50", "10.20.10.17"]` are the operator workstations' +**current raw DHCP leases** (mamba + a second box), not reservations (operator decision, +2026-06-19). Both share the operator's `sjat` SSH key. Caveats, accepted for now: -- **Lease drift:** if DHCP reassigns `10.20.10.50`, the rule allows whatever host then holds it - (still SSH-key-gated, so low risk) and mamba loses its *LAN* path. **Backstop:** mamba also - reaches ubongo over `wt0` (mesh), so it is never cut off — only the off-mesh LAN convenience - lapses until the IP is corrected. -- **Revisit trigger:** when OPNsense-as-code lands (ADR-020 perimeter layer), replace this with - a **DHCP reservation** (MAC → fixed IP) and allow the reserved address. Tracked here and in - the implementation plan's follow-ups. +- **Lease drift:** if DHCP reassigns either IP, the rule allows whatever host then holds it + (still SSH-key-gated, so low risk) and that workstation loses its *LAN* path. **Backstop:** + the workstations also reach ubongo over `wt0` (mesh), so they are never cut off — only the + off-mesh LAN convenience lapses until the IP is corrected. +- **Revisit trigger (flagged for follow-up):** when OPNsense-as-code lands (ADR-020 perimeter / + TODO 3.5), replace both raw leases with **MAC-pinned DHCP reservations** (`10.20.10.17` = + MAC `bc:0f:f3:c8:4a:8a`) and allow the reserved addresses. Recorded as a `FRICTION.md` open + signal so the next `/kaizen` surfaces it. ## Testing @@ -192,6 +196,8 @@ anyway. The physical console is open throughout. - askari SSH → `wt0` redesign (sub-project 1) — needs the boot-race + coordinator-bootstrap resolved; folds in the coordinator-robustness (geo-DB FATAL-loop) + off-site backup lessons. - NetBird ACL off Allow-All (sub-project 3) — open mechanism question (no headless API path). -- OPNsense DHCP reservation for mamba (and ubongo) — replaces the raw lease; with OPNsense-as-code. +- OPNsense DHCP reservations for the admin workstations (`10.20.10.50` mamba, `10.20.10.17`) + and ubongo — replace the raw leases with MAC-pinned reservations; flagged in `FRICTION.md`, + with OPNsense-as-code. - Forward-chain container isolation on ubongo — deliberately not done here. - `STATUS.md` / `ROADMAP.md` edits land with the implementation, not this spec.