feat(base): NetBird agent enrollment concern (mesh)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
98eb09d8ba
commit
44c4978b5f
4 changed files with 111 additions and 0 deletions
|
|
@ -27,3 +27,30 @@ render + validate without applying (used by Molecule).
|
||||||
- `make test ROLE=base` — Molecule renders + `nft -c` syntax-checks (never applies; it
|
- `make test ROLE=base` — Molecule renders + `nft -c` syntax-checks (never applies; it
|
||||||
shares the host kernel). Enforcement + the apply/rollback path are verified at ADR-008
|
shares the host kernel). Enforcement + the apply/rollback path are verified at ADR-008
|
||||||
Level 2 on staging VMs.
|
Level 2 on staging VMs.
|
||||||
|
|
||||||
|
## Mesh enrollment (NetBird agent)
|
||||||
|
|
||||||
|
Enrols the host as a NetBird *agent* on the self-hosted mesh (ADR-016): installs the
|
||||||
|
pinned `netbird` daemon from the upstream APT repo (keyring in `/etc/apt/keyrings`,
|
||||||
|
mirroring the `docker_host` repo idiom) and runs `netbird up` against the coordinator
|
||||||
|
with a setup key. Tagged `mesh`.
|
||||||
|
|
||||||
|
**Additive only — this concern makes no firewall change.** SSH is already gated to the
|
||||||
|
NetBird overlay interface by the `firewall` concern (`base__firewall_mgmt_interface`,
|
||||||
|
default `wt0`); enrolling a host simply brings that interface up. No port is opened here.
|
||||||
|
|
||||||
|
Enrolment is **opt-in**: `base__mesh_enabled` defaults to `false`, so applying `base` to
|
||||||
|
a host not on the mesh is a no-op for this concern. Re-enrolment is guarded on
|
||||||
|
`netbird status` reporting `Management: Connected`, so re-runs are idempotent. The setup
|
||||||
|
key is sourced from `vault.netbird.setup_key` and passed with `no_log` (it lands on the
|
||||||
|
process argv).
|
||||||
|
|
||||||
|
### Variables
|
||||||
|
|
||||||
|
| Variable | Default | Purpose |
|
||||||
|
|------------------------------|--------------------------------------|---------|
|
||||||
|
| `base__mesh_enabled` | `false` | Opt-in switch — include the concern at all. Set per-host/group to enrol. |
|
||||||
|
| `base__mesh_manage` | `true` | Test gate — when `false`, skips the live network/daemon tasks (apt install, status check, `netbird up`) so Molecule can exercise the wiring without a coordinator. |
|
||||||
|
| `base__mesh_management_url` | `https://netbird.askari.wingu.me` | Coordinator (management) URL. |
|
||||||
|
| `base__mesh_setup_key` | `{{ vault.netbird.setup_key }}` | Enrolment setup key, from vault. |
|
||||||
|
| `base__mesh_version` | `"0.72.4"` | Pinned agent version (matches the coordinator). The exact apt version string is confirmed on-host at deploy. |
|
||||||
|
|
|
||||||
|
|
@ -20,3 +20,13 @@ base__fail2ban_bantime: 1h
|
||||||
base__fail2ban_findtime: 10m
|
base__fail2ban_findtime: 10m
|
||||||
# base__ssh_authorised_keys lives in group_vars/all/vars.yml (per-person control keys).
|
# base__ssh_authorised_keys lives in group_vars/all/vars.yml (per-person control keys).
|
||||||
base__ssh_authorised_keys: []
|
base__ssh_authorised_keys: []
|
||||||
|
|
||||||
|
# NetBird mesh agent enrollment (ADR-016). Opt-in: default off so applying `base` to a
|
||||||
|
# host not on the mesh is a no-op for this concern. The live actions (apt install over
|
||||||
|
# the network, `netbird up` against the coordinator) are additionally gated by
|
||||||
|
# base__mesh_manage so Molecule can exercise the wiring without a coordinator.
|
||||||
|
base__mesh_enabled: false
|
||||||
|
base__mesh_manage: true
|
||||||
|
base__mesh_management_url: "https://netbird.askari.wingu.me"
|
||||||
|
base__mesh_setup_key: "{{ vault.netbird.setup_key }}"
|
||||||
|
base__mesh_version: "0.72.4" # match the coordinator; exact apt pin confirmed on-host at deploy
|
||||||
|
|
|
||||||
|
|
@ -22,3 +22,11 @@
|
||||||
apply:
|
apply:
|
||||||
tags: [hardening]
|
tags: [hardening]
|
||||||
tags: [hardening]
|
tags: [hardening]
|
||||||
|
|
||||||
|
- name: NetBird mesh enrollment
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: mesh.yml
|
||||||
|
apply:
|
||||||
|
tags: [mesh]
|
||||||
|
when: base__mesh_enabled | bool
|
||||||
|
tags: [mesh]
|
||||||
|
|
|
||||||
66
roles/base/tasks/mesh.yml
Normal file
66
roles/base/tasks/mesh.yml
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
---
|
||||||
|
# NetBird agent enrollment (ADR-016). Additive only — no firewall change here.
|
||||||
|
- name: Install NetBird apt prerequisites
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: [ca-certificates, curl, gnupg]
|
||||||
|
state: present
|
||||||
|
update_cache: true
|
||||||
|
when: base__mesh_manage | bool
|
||||||
|
tags: [mesh]
|
||||||
|
|
||||||
|
- name: Ensure /etc/apt/keyrings exists
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/apt/keyrings
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
when: base__mesh_manage | bool
|
||||||
|
tags: [mesh]
|
||||||
|
|
||||||
|
- name: Add the NetBird APT GPG key
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: https://pkgs.netbird.io/debian/public.key
|
||||||
|
dest: /etc/apt/keyrings/netbird.asc
|
||||||
|
mode: "0644"
|
||||||
|
when: base__mesh_manage | bool
|
||||||
|
tags: [mesh]
|
||||||
|
|
||||||
|
- name: Add the NetBird APT repository
|
||||||
|
ansible.builtin.apt_repository:
|
||||||
|
repo: >-
|
||||||
|
deb [signed-by=/etc/apt/keyrings/netbird.asc]
|
||||||
|
https://pkgs.netbird.io/debian stable main
|
||||||
|
filename: netbird
|
||||||
|
state: present
|
||||||
|
when: base__mesh_manage | bool
|
||||||
|
tags: [mesh]
|
||||||
|
|
||||||
|
# The apt pin string can't be confirmed from docs — it might be a bare "0.72.4" or
|
||||||
|
# carry a packaging suffix. The live deploy task confirms the exact on-host string.
|
||||||
|
- name: Install the NetBird agent (pinned)
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: "netbird={{ base__mesh_version }}"
|
||||||
|
state: present
|
||||||
|
update_cache: true
|
||||||
|
when: base__mesh_manage | bool
|
||||||
|
tags: [mesh]
|
||||||
|
|
||||||
|
- name: Check current NetBird connection status
|
||||||
|
ansible.builtin.command: netbird status
|
||||||
|
register: _netbird_status
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
when: base__mesh_manage | bool
|
||||||
|
tags: [mesh]
|
||||||
|
|
||||||
|
- name: Enrol this host in the mesh
|
||||||
|
ansible.builtin.command: >-
|
||||||
|
netbird up
|
||||||
|
--management-url {{ base__mesh_management_url }}
|
||||||
|
--setup-key {{ base__mesh_setup_key }}
|
||||||
|
register: _netbird_up
|
||||||
|
changed_when: _netbird_up.rc == 0
|
||||||
|
when:
|
||||||
|
- base__mesh_manage | bool
|
||||||
|
- "'Management: Connected' not in (_netbird_status.stdout | default(''))"
|
||||||
|
no_log: true # setup key is on the argv
|
||||||
|
tags: [mesh]
|
||||||
Loading…
Add table
Reference in a new issue