48 lines
3 KiB
Markdown
48 lines
3 KiB
Markdown
|
|
# Access — netbird_coordinator (NetBird control plane)
|
||
|
|
|
||
|
|
Rendered from the role's `access__*` data (`roles/netbird_coordinator/defaults/main.yml`)
|
||
|
|
— the source of truth that also drives `/check-access`. Regenerate from the data; edit the
|
||
|
|
data, not the tables. Host: `askari` (off-site Hetzner; ADR-007/016).
|
||
|
|
|
||
|
|
## Access paths
|
||
|
|
|
||
|
|
The documented ways in, by tier (rendered from `access__*`):
|
||
|
|
|
||
|
|
| Tier | Path | Invocation |
|
||
|
|
|---|---|---|
|
||
|
|
| primary | `wt0` mesh SSH | `ssh askari` (over the NetBird mesh — pending M5; see notes) |
|
||
|
|
| secondary | LAN/WAN SSH from `ubongo` | `ssh ansible@askari` (from the control node; Hetzner firewall allows only ubongo's WAN) |
|
||
|
|
| — | container exec + compose | `docker compose -p netbird -f /opt/services/netbird/docker-compose.yml ps` / `… exec netbird-server sh` |
|
||
|
|
| — | logs | `docker logs netbird-server` / `docker logs netbird-dashboard` now; Loki labels `{service: netbird}` once the ADR-018 pipeline lands |
|
||
|
|
| — | admin API | management REST/gRPC API at `https://netbird.askari.wingu.me/api` (and gRPC), via Caddy, **behind embedded-Dex auth** (`access__api.enabled: true`) — admin surface is the dashboard at `https://netbird.askari.wingu.me` |
|
||
|
|
|
||
|
|
## Break-glass
|
||
|
|
|
||
|
|
Mesh-and-LAN-independent fallback for this host's class (recorded, not routine):
|
||
|
|
|
||
|
|
- **Hetzner rescue system + Cloud Console** (VNC) for `askari` — boot the rescue image
|
||
|
|
or attach the web console from the Hetzner Cloud panel if SSH is unreachable.
|
||
|
|
|
||
|
|
## Operational notes
|
||
|
|
|
||
|
|
- **The admin surface is the dashboard, not a raw port.** Day-to-day administration
|
||
|
|
(peers, setup keys, ACLs, users) is the web dashboard at
|
||
|
|
`https://netbird.askari.wingu.me`, behind the embedded Dex login. The management REST
|
||
|
|
API (`/api`) + gRPC are the same control plane the dashboard calls — reachable for
|
||
|
|
scripting **only with a Dex-issued JWT**; there is no separate unauthenticated admin
|
||
|
|
port (metrics `:9090` / healthcheck `:9000` are in-container only, never published).
|
||
|
|
- **First-admin bootstrap is one-shot.** On a fresh deploy the first admin is created via
|
||
|
|
`https://netbird.askari.wingu.me/setup`, reachable only while zero users exist — it
|
||
|
|
self-closes after the first account. If you ever lose all admins, recovery means
|
||
|
|
resetting the datastore (and re-enrolling), not re-opening `/setup`.
|
||
|
|
- **Mesh not yet enrolled (M5).** Until `askari` joins the NetBird mesh, the `wt0`
|
||
|
|
primary SSH path does not exist — the only SSH route is the secondary one (from
|
||
|
|
ubongo's WAN IP, which the Hetzner Cloud Firewall allowlists). Promote `wt0` to primary
|
||
|
|
once M5 lands. (askari runs the coordinator the mesh depends on, so a coordinator
|
||
|
|
outage can also take down its own `wt0` path — fall back to LAN/WAN SSH then.)
|
||
|
|
- **Config wedged / bad render:** `config.yaml` is rendered read-only by Ansible (mode
|
||
|
|
`0640`, `no_log` — it holds the two vault secrets). To recover, fix the
|
||
|
|
`netbird_coordinator__*` vars and re-run the role (the `restart netbird` handler
|
||
|
|
recreates the stack). Note the compose project name is **`netbird`** (the base-dir
|
||
|
|
basename), not `netbird_coordinator`.
|