docs: Phase 1 complete — clients enrolled + NetBird client runbook
mamba + work laptop enrolled in the mesh → ubongo reachable from anywhere; the mobile-access goal is met and Phase 1 (remote access) is complete. Adds docs/runbooks/netbird-client.md (reusable client-enrollment runbook) + STATUS/ ROADMAP flips + CLAUDE.md reading-table entry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8d2a064542
commit
5d14efc864
4 changed files with 90 additions and 6 deletions
|
|
@ -258,5 +258,6 @@ Single-contributor, trunk-based (no merge requests / approval gates):
|
||||||
| Reverse proxy (Caddy) | `docs/decisions/024-reverse-proxy.md` |
|
| Reverse proxy (Caddy) | `docs/decisions/024-reverse-proxy.md` |
|
||||||
| Adding a new role | `docs/runbooks/new-role.md` |
|
| Adding a new role | `docs/runbooks/new-role.md` |
|
||||||
| Adding a new host | `docs/runbooks/new-host.md` |
|
| Adding a new host | `docs/runbooks/new-host.md` |
|
||||||
|
| Enrolling a NetBird client (laptop/phone) | `docs/runbooks/netbird-client.md` |
|
||||||
| Rotating vault secrets | `docs/runbooks/rotate-secrets.md` |
|
| Rotating vault secrets | `docs/runbooks/rotate-secrets.md` |
|
||||||
| Claude Code setup (per machine) | `docs/runbooks/claude-code-setup.md` |
|
| Claude Code setup (per machine) | `docs/runbooks/claude-code-setup.md` |
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ askari.)
|
||||||
| CIS hardening (Debian L1+L2 + Docker) | ADR-002 / TODO 15 | Implemented by the (unbuilt) `base`/`docker_host` roles; brings AppArmor + AIDE as baseline. L2 partitions affect VM provisioning (ADR-006) |
|
| CIS hardening (Debian L1+L2 + Docker) | ADR-002 / TODO 15 | Implemented by the (unbuilt) `base`/`docker_host` roles; brings AppArmor + AIDE as baseline. L2 partitions affect VM provisioning (ADR-006) |
|
||||||
| Network IDS + security alerting | ADR-002 / TODO 15 | Suricata on OPNsense + AIDE/`auditd`/`fail2ban` alerting into the monitoring stack; not built |
|
| Network IDS + security alerting | ADR-002 / TODO 15 | Suricata on OPNsense + AIDE/`auditd`/`fail2ban` alerting into the monitoring stack; not built |
|
||||||
| NetBird mesh — coordinator on `askari` | ADR-016 | **BUILT + applied (M4b, 2026-06-16)** — moved up to "Real and working today" (`roles/netbird_coordinator/`). Self-hosted control plane on askari; replaces ADR-007 WireGuard. Mesh **peer enrolment = M5** (next row). |
|
| NetBird mesh — coordinator on `askari` | ADR-016 | **BUILT + applied (M4b, 2026-06-16)** — moved up to "Real and working today" (`roles/netbird_coordinator/`). Self-hosted control plane on askari; replaces ADR-007 WireGuard. Mesh **peer enrolment = M5** (next row). |
|
||||||
| NetBird agent enrollment in `base` | ADR-016 | **BUILT + applied (M5, 2026-06-17).** The `base` `mesh` concern (opt-in `base__mesh_enabled`) installs the pinned NetBird agent + runs `netbird up` with the reusable scoped key from `vault.netbird.setup_key`. Applied to **askari (`100.99.226.39`) + ubongo (`100.99.146.14`)** — both Management+Signal Connected; ubongo↔askari mesh ping verified. Enrollment is **additive** — the "SSH only on `wt0`" firewall lockdown is the deferred mesh-hardening follow-on, NOT applied. Road-warrior clients (laptops) are operator-enrolled. |
|
| NetBird agent enrollment in `base` | ADR-016 | **BUILT + applied (M5, 2026-06-17).** The `base` `mesh` concern (opt-in `base__mesh_enabled`) installs the pinned NetBird agent + runs `netbird up` with the reusable scoped key from `vault.netbird.setup_key`. Applied to **askari (`100.99.226.39`) + ubongo (`100.99.146.14`)** — both Management+Signal Connected; ubongo↔askari mesh ping verified. Enrollment is **additive** — the "SSH only on `wt0`" firewall lockdown is the deferred mesh-hardening follow-on, NOT applied. **Road-warrior clients (`mamba` + work laptop) enrolled (2026-06-17) → `ubongo` reachable from anywhere: the mobile-access goal is met and Phase 1 (remote access) is COMPLETE.** Client enrollment runbook: `docs/runbooks/netbird-client.md`. |
|
||||||
| Service-UI verification (Level 4) | ADR-017 / ADR-008 | **Design RESOLVED** (ADR-017 + spec + plan); resolves ADR-015 deferred #2. `/verify-service` skill + `VERIFY.md` template + standards are authorable and present. **Build pending:** running needs ubongo + `playwright` plugin + Authentik + a staging deploy. |
|
| Service-UI verification (Level 4) | ADR-017 / ADR-008 | **Design RESOLVED** (ADR-017 + spec + plan); resolves ADR-015 deferred #2. `/verify-service` skill + `VERIFY.md` template + standards are authorable and present. **Build pending:** running needs ubongo + `playwright` plugin + Authentik + a staging deploy. |
|
||||||
| Logging pipeline (Loki + Alloy + off-site subset) | ADR-018 | **Design RESOLVED** (ADR-018 + spec). All logs → on-cluster Loki; security subset write-only off-site to askari. **Build pending:** Alloy in `base`, `loki`/`grafana` service roles, OPNsense syslog — none built. |
|
| Logging pipeline (Loki + Alloy + off-site subset) | ADR-018 | **Design RESOLVED** (ADR-018 + spec). All logs → on-cluster Loki; security subset write-only off-site to askari. **Build pending:** Alloy in `base`, `loki`/`grafana` service roles, OPNsense syslog — none built. |
|
||||||
| Security alerting (AIDE/auditd/fail2ban/Suricata + log-silence) | ADR-002 / ADR-018 | Wired into Grafana on the Loki stack. Designed; depends on the logging pipeline + metrics stack (TODO 3.6). |
|
| Security alerting (AIDE/auditd/fail2ban/Suricata + log-silence) | ADR-002 / ADR-018 | Wired into Grafana on the Loki stack. Designed; depends on the logging pipeline + metrics stack (TODO 3.6). |
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,10 @@ this collapses into interleaving with extra context-switching cost).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Phase 1 — Off-site / Remote-access
|
## Phase 1 — Off-site / Remote-access — ✅ COMPLETE (2026-06-17)
|
||||||
|
|
||||||
Delivers mobile access to `ubongo`; proves the machinery. Ordered by *real* dependencies.
|
Delivers mobile access to `ubongo`; proves the machinery. Ordered by *real* dependencies.
|
||||||
|
All milestones (M1–M5) done; the mobile-access goal is met. Next: the Procurement gate.
|
||||||
|
|
||||||
### M1 · boma's DNS home — a new domain at Gandi, managed as code
|
### M1 · boma's DNS home — a new domain at Gandi, managed as code
|
||||||
|
|
||||||
|
|
@ -134,14 +135,14 @@ Dashboard live at `https://netbird.askari.wingu.me` (valid LE cert); `/api` auth
|
||||||
- **Maps to:** ADR-016 (mesh), ADR-004 (one service = one role), ADR-021 (access),
|
- **Maps to:** ADR-016 (mesh), ADR-004 (one service = one role), ADR-021 (access),
|
||||||
ADR-022 (backup), ADR-008/017 (VERIFY), accepted-risk R3 (askari public surface).
|
ADR-022 (backup), ADR-008/017 (VERIFY), accepted-risk R3 (askari public surface).
|
||||||
|
|
||||||
### M5 · Enroll peers → goal reached — ✅ infra done (2026-06-17); laptops = operator step
|
### M5 · Enroll peers → goal reached — ✅ DONE (2026-06-17)
|
||||||
|
|
||||||
The `base` `mesh` concern enrolled **`ubongo` (`100.99.146.14`) + `askari`
|
The `base` `mesh` concern enrolled **`ubongo` (`100.99.146.14`) + `askari`
|
||||||
(`100.99.226.39`)** as NetBird peers — both Management+Signal Connected, the ubongo↔askari
|
(`100.99.226.39`)** as NetBird peers — both Management+Signal Connected, the ubongo↔askari
|
||||||
mesh link ping-verified. NetBird ships a default **Allow-All** peer policy, so any enrolled
|
mesh link ping-verified. NetBird ships a default **Allow-All** peer policy, so any enrolled
|
||||||
peer can already reach `ubongo` over `wt0`. **Remaining (operator):** install the NetBird
|
peer reaches `ubongo` over `wt0`. The road-warrior clients (**`mamba` + the work laptop**)
|
||||||
client on `mamba` + the work laptop and log in → `ubongo` reachable from anywhere. **← the
|
are enrolled (operator, via `docs/runbooks/netbird-client.md`) → **`ubongo` is reachable
|
||||||
mobile-access goal lands when the laptops join.**
|
from anywhere. ← the mobile-access goal is met; Phase 1 is complete.**
|
||||||
|
|
||||||
- **Deferred to a "mesh-hardening" follow-on** (was folded into M5; split out as the
|
- **Deferred to a "mesh-hardening" follow-on** (was folded into M5; split out as the
|
||||||
lockout-risky part): apply `base` nftables **default-deny** to `ubongo` + set
|
lockout-risky part): apply `base` nftables **default-deny** to `ubongo` + set
|
||||||
|
|
|
||||||
82
docs/runbooks/netbird-client.md
Normal file
82
docs/runbooks/netbird-client.md
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
# Runbook — Enrolling a NetBird client (road-warrior device)
|
||||||
|
|
||||||
|
Joins a **client/road-warrior device** (laptop, desktop, phone) to the boma NetBird mesh
|
||||||
|
so it can reach `ubongo` and other peers from anywhere. The self-hosted coordinator is on
|
||||||
|
`askari` (ADR-016, M4b); enrollment lands a device on the `100.64.0.0/10` overlay.
|
||||||
|
|
||||||
|
> **Hosts vs clients.** Managed **Linux hosts** join via the `base` role's `mesh` concern
|
||||||
|
> (`base__mesh_enabled: true` + the reusable key in `vault.netbird.setup_key`) — see
|
||||||
|
> ADR-016 / the `base` README, *not* this runbook. This runbook is for **user devices**
|
||||||
|
> NetBird doesn't manage with Ansible.
|
||||||
|
|
||||||
|
verified: NetBird client install + self-hosted `--management-url` flow · docs.netbird.io
|
||||||
|
(`/get-started/install/windows`, `/get-started/cli`) · 2026-06-17
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- The coordinator's first-boot `/setup` admin exists and you can log in at
|
||||||
|
`https://netbird.askari.wingu.me`.
|
||||||
|
- **Auth, pick one:**
|
||||||
|
- **SSO** (recommended for a personal device) — your dashboard account; no secret to copy.
|
||||||
|
- **Setup key** — dashboard → **Settings → Setup Keys** → a reusable key (mint a
|
||||||
|
client-specific one for clean ACL grouping, or reuse the existing reusable key).
|
||||||
|
- Local **admin rights** on the device (the client installs a service).
|
||||||
|
- **Coordinator facts:** management URL `https://netbird.askari.wingu.me`; `ubongo`
|
||||||
|
= `100.99.146.14` (`ubongo.netbird.selfhosted`); `askari` = `100.99.226.39`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Part A — Windows 11
|
||||||
|
|
||||||
|
1. **Install:** download + run the MSI **https://pkgs.netbird.io/windows/msi/x64**
|
||||||
|
(official x64 client; installs the tray app + the `netbird` service).
|
||||||
|
2. **Connect** from an **elevated** Windows Terminal / PowerShell ("Run as administrator"):
|
||||||
|
```powershell
|
||||||
|
netbird up --management-url https://netbird.askari.wingu.me
|
||||||
|
```
|
||||||
|
A browser opens — sign in with your dashboard account. (SSO won't open a browser?
|
||||||
|
use a key: `netbird up --setup-key <KEY> --management-url https://netbird.askari.wingu.me`.)
|
||||||
|
3. Proceed to **Part C** (verify).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Part B — Other platforms (same management URL)
|
||||||
|
|
||||||
|
- **macOS / Linux desktop:** install the client (macOS: NetBird app / Homebrew; Linux:
|
||||||
|
`pkgs.netbird.io` per the distro — same apt/rpm flow as `base`'s `mesh` concern), then
|
||||||
|
`netbird up --management-url https://netbird.askari.wingu.me` (Linux: prefix `sudo`).
|
||||||
|
- **Android / iOS:** install the **NetBird** app, then in **Settings → Advanced /
|
||||||
|
Server** set the management server to `https://netbird.askari.wingu.me` **before**
|
||||||
|
logging in; connect and complete the SSO login. (Setup keys are supported in-app too.)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Part C — Verify + use
|
||||||
|
|
||||||
|
```sh
|
||||||
|
netbird status # expect: Management: Connected, Signal: Connected, a 100.x NetBird IP
|
||||||
|
netbird status -d # peer detail — ubongo (100.99.146.14) + askari (100.99.226.39) listed
|
||||||
|
```
|
||||||
|
Reach `ubongo` over the mesh:
|
||||||
|
```sh
|
||||||
|
ssh sjat@100.99.146.14 # or: ssh sjat@ubongo.netbird.selfhosted
|
||||||
|
```
|
||||||
|
**SSH auth is separate from the mesh:** `ubongo` is key-only (passwords disabled), so the
|
||||||
|
device needs an SSH key authorised for `sjat@ubongo`. The mesh provides the network path;
|
||||||
|
the SSH key provides auth.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- **Split-tunnel:** NetBird routes only the `100.x` overlay by default — normal/work
|
||||||
|
networking is unaffected.
|
||||||
|
- **Persistence:** the service auto-starts on boot and reconnects; the tray app has
|
||||||
|
Connect/Disconnect; CLI `netbird down` / `netbird up` (no flags after first setup).
|
||||||
|
- **Troubleshooting** — *"failed while getting Management Service public key"* / won't
|
||||||
|
register: confirm `https://netbird.askari.wingu.me` loads in a browser from the device
|
||||||
|
(DNS + TLS + the gRPC routing through Caddy are reachable), the URL is exact, and the
|
||||||
|
terminal is elevated. If a peer shows Disconnected, NAT traversal is falling back to the
|
||||||
|
relay (over 443) — usually transient.
|
||||||
|
- **Removing a device:** `netbird down` then uninstall; revoke its peer in the dashboard
|
||||||
|
(and the setup key if one-off).
|
||||||
Loading…
Add table
Reference in a new issue