From f8098c2e1597538356492dcec2b5fd78b9c0b32d Mon Sep 17 00:00:00 2001 From: sjat Date: Tue, 9 Jun 2026 17:34:57 +0200 Subject: [PATCH] docs(access): reconcile ADR-016/020 with control-node SSH source (ADR-021) Co-Authored-By: Claude Sonnet 4.6 --- docs/decisions/016-mesh-vpn.md | 8 ++++++-- docs/decisions/020-firewall.md | 10 ++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/decisions/016-mesh-vpn.md b/docs/decisions/016-mesh-vpn.md index a317d01..1893cec 100644 --- a/docs/decisions/016-mesh-vpn.md +++ b/docs/decisions/016-mesh-vpn.md @@ -61,8 +61,12 @@ allocated for it. privilege. - **Enrollment via setup keys** stored in `vault.yml` (`vault.netbird.setup_key`), consumed by `base`; prefer ephemeral/scoped keys. -- **Host firewall:** NetBird's `wt0` interface; `base` nftables allows inbound SSH - **only on `wt0`** (the ADR-015 pattern, fleet-wide). +- **Host firewall:** `base` nftables allows inbound SSH on NetBird's `wt0` interface + (primary, WireGuard-authenticated) **and** from `ubongo`'s LAN address (secondary, + mesh-independent — required by the LAN-IP recovery path below, so a mesh/coordinator + outage never blocks on-LAN SSH). All other LAN hosts remain default-denied. This makes + explicit the control-node SSH allow that the recovery model already implied; the access + doctrine and the three-tier access ladder live in **ADR-021**. - **New public surface on `askari`:** management API + dashboard (80/443) + Coturn (3478). Mitigated by TLS + embedded-IdP login, source-IP limits where practical, `base` hardening, and version-pinned NetBird (ADR-011) patched on boma's cadence. diff --git a/docs/decisions/020-firewall.md b/docs/decisions/020-firewall.md index c014bcc..a00dc6d 100644 --- a/docs/decisions/020-firewall.md +++ b/docs/decisions/020-firewall.md @@ -39,10 +39,12 @@ subnet (VLAN 20), which never reaches the gateway. added benefit once the VLAN already bounds where a host can go. - **Docker**: daemon runs with `"iptables": false`; nftables owns all filtering, including container traffic (ADR-004). -- **Guaranteed management plane**: loopback, established/related, and `wt0` (NetBird, - ADR-016) for SSH + Ansible are always allowed, independent of the catalog, applied - atomically — a malformed or empty catalog can never lock out management. (ADR-016: SSH - is allowed only on `wt0`.) +- **Guaranteed management plane**: loopback, established/related, `wt0` (NetBird, + ADR-016), and SSH from the control node's LAN address (`base__firewall_control_addr`, + the `ssh-from-control` source) for SSH + Ansible are always allowed, independent of the + catalog, applied atomically — a malformed or empty catalog can never lock out + management. The control-node source is part of the guaranteed plane, not the service + catalog (it is management, not a service); see ADR-021 for the access doctrine. So "per-host vs central" is answered: **both**, with clear ownership.