mirror of
https://github.com/fscotto/infra.git
synced 2026-09-27 19:03:47 +00:00
Verify WireGuard handshakes and restore Podman networking
This commit is contained in:
@@ -161,8 +161,11 @@ The dotfile vars follow the same split: `desktop_common_dotfiles` carries mode-i
|
|||||||
use `10.0.0.2:4533` for Navidrome and `10.0.0.2:8384` for the Syncthing GUI. Syncthing does not use host networking:
|
use `10.0.0.2:4533` for Navidrome and `10.0.0.2:8384` for the Syncthing GUI. Syncthing does not use host networking:
|
||||||
its GUI, transfer, QUIC and discovery ports are explicitly published only on `10.0.0.2`; native transfer/discovery does not use the HTTP proxy.
|
its GUI, transfer, QUIC and discovery ports are explicitly published only on `10.0.0.2`; native transfer/discovery does not use the HTTP proxy.
|
||||||
- `wireguard_overlay` manages the required `wg0` path between Prometheus and Atlas, persists private keys only on their
|
- `wireguard_overlay` manages the required `wg0` path between Prometheus and Atlas, persists private keys only on their
|
||||||
respective hosts, and exchanges only derived public keys. The initial run must include both hosts. Prometheus
|
respective hosts, exchanges only derived public keys, and verifies a real peer handshake. The initial run must
|
||||||
opens `51820/udp`; the Atlas backend role admits service ports only in the WireGuard firewalld zone.
|
include both hosts. Prometheus
|
||||||
|
opens `51820/udp`; after creating the WireGuard firewalld zone, restore Prometheus' rootful Podman networking with
|
||||||
|
`podman network reload --all` so the existing proxy stack retains container DNS. The Atlas backend role admits
|
||||||
|
service ports only in the WireGuard firewalld zone.
|
||||||
|
|
||||||
## Atlas NAS TODO
|
## Atlas NAS TODO
|
||||||
- Provide the required Vault variables and validate the first remote bootstrap on the real Rocky Linux 9 host.
|
- Provide the required Vault variables and validate the first remote bootstrap on the real Rocky Linux 9 host.
|
||||||
|
|||||||
15
README.md
15
README.md
@@ -219,13 +219,18 @@ clients use NFSv4 and Windows/WSL clients use SMB; both are restricted to the co
|
|||||||
|
|
||||||
For the first run, provide `vault_atlas_admin_password_hash`, `vault_atlas_samba_password`, and
|
For the first run, provide `vault_atlas_admin_password_hash`, `vault_atlas_samba_password`, and
|
||||||
`vault_atlas_immich_db_password`. Bootstrap the host through its
|
`vault_atlas_immich_db_password`. Bootstrap the host through its
|
||||||
existing administrator:
|
existing administrator. Open `51820/udp` towards Prometheus in the provider firewall first, then
|
||||||
|
include both WireGuard peers in the same idempotent playbook run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ansible-playbook ansible/site.yml --limit atlas \
|
ansible-playbook ansible/site.yml --limit prometheus,atlas \
|
||||||
-e atlas_connection_username=<existing-admin>
|
-e atlas_connection_username=<existing-admin> \
|
||||||
|
-e atlas_create_pool=true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The explicit pool gate is safe to repeat: the role creates the RAIDZ2 pool only when it is absent.
|
||||||
|
WireGuard waits for a real peer handshake before the play continues.
|
||||||
|
|
||||||
`vault_atlas_admin_password_hash` must be an `/etc/shadow`-compatible hash, not a clear-text
|
`vault_atlas_admin_password_hash` must be an `/etc/shadow`-compatible hash, not a clear-text
|
||||||
Cockpit password. Subsequent runs use `atlas_admin_username`. Atlas declares storage, sharing, and its
|
Cockpit password. Subsequent runs use `atlas_admin_username`. Atlas declares storage, sharing, and its
|
||||||
LAN firewall rules enabled. Before the first apply, check the existing pool and mountpoints, LAN subnet,
|
LAN firewall rules enabled. Before the first apply, check the existing pool and mountpoints, LAN subnet,
|
||||||
@@ -262,7 +267,9 @@ storage paths from the `zpool` mounted at `/zpool`: music is read-only at
|
|||||||
containers. The backend role never creates the pool. The separate `wireguard_overlay` role manages `wg0`
|
containers. The backend role never creates the pool. The separate `wireguard_overlay` role manages `wg0`
|
||||||
between Prometheus (`10.0.0.1`) and Atlas (`10.0.0.2`), generating private keys once
|
between Prometheus (`10.0.0.1`) and Atlas (`10.0.0.2`), generating private keys once
|
||||||
on their respective hosts and exchanging only public keys through Ansible. Prometheus alone opens
|
on their respective hosts and exchanging only public keys through Ansible. Prometheus alone opens
|
||||||
`51820/udp` publicly. Backend ports are admitted only in the WireGuard firewalld zone.
|
`51820/udp` publicly. When the WireGuard zone is created, Ansible reloads firewalld and immediately
|
||||||
|
reloads Prometheus' rootful Podman networks so the existing proxy stack retains container DNS and
|
||||||
|
connectivity. Backend ports are admitted only in the WireGuard firewalld zone.
|
||||||
|
|
||||||
`backend_phase1_start_services` stays false during the application-state transfer, so the first real
|
`backend_phase1_start_services` stays false during the application-state transfer, so the first real
|
||||||
backend run renders the Quadlets without creating an empty Atlas database. After stopping Navidrome
|
backend run renders the Quadlets without creating an empty Atlas database. After stopping Navidrome
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ wireguard_overlay_enabled: true
|
|||||||
wireguard_address: 10.0.0.1/24
|
wireguard_address: 10.0.0.1/24
|
||||||
wireguard_listen_port: 51820
|
wireguard_listen_port: 51820
|
||||||
wireguard_enable_ipv4_forwarding: true
|
wireguard_enable_ipv4_forwarding: true
|
||||||
|
wireguard_reload_rootful_podman_networks: true
|
||||||
wireguard_peers:
|
wireguard_peers:
|
||||||
- name: atlas
|
- name: atlas
|
||||||
host: atlas
|
host: atlas
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ wireguard_mtu: 1420
|
|||||||
wireguard_firewalld_zone: wireguard
|
wireguard_firewalld_zone: wireguard
|
||||||
wireguard_public_firewalld_zone: public
|
wireguard_public_firewalld_zone: public
|
||||||
wireguard_enable_ipv4_forwarding: false
|
wireguard_enable_ipv4_forwarding: false
|
||||||
|
wireguard_reload_rootful_podman_networks: false
|
||||||
|
wireguard_handshake_retries: 12
|
||||||
|
wireguard_handshake_delay: 5
|
||||||
wireguard_peers: []
|
wireguard_peers: []
|
||||||
wireguard_packages:
|
wireguard_packages:
|
||||||
- wireguard-tools
|
- wireguard-tools
|
||||||
|
|||||||
@@ -132,6 +132,20 @@
|
|||||||
- wireguard_firewalld_zone_result is changed
|
- wireguard_firewalld_zone_result is changed
|
||||||
- not ansible_check_mode
|
- not ansible_check_mode
|
||||||
|
|
||||||
|
- name: Restore rootful Podman networking after firewalld reload
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- podman
|
||||||
|
- network
|
||||||
|
- reload
|
||||||
|
- --all
|
||||||
|
register: wireguard_podman_network_reload
|
||||||
|
changed_when: wireguard_podman_network_reload.stdout_lines | length > 0
|
||||||
|
when:
|
||||||
|
- wireguard_firewalld_zone_result is changed
|
||||||
|
- wireguard_reload_rootful_podman_networks | bool
|
||||||
|
- not ansible_check_mode
|
||||||
|
|
||||||
- name: Assign the WireGuard interface to its firewalld zone
|
- name: Assign the WireGuard interface to its firewalld zone
|
||||||
ansible.posix.firewalld:
|
ansible.posix.firewalld:
|
||||||
interface: "{{ wireguard_interface }}"
|
interface: "{{ wireguard_interface }}"
|
||||||
@@ -156,3 +170,23 @@
|
|||||||
state: started
|
state: started
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
when: not ansible_check_mode
|
when: not ansible_check_mode
|
||||||
|
|
||||||
|
- name: Apply pending WireGuard handlers before verification
|
||||||
|
ansible.builtin.meta: flush_handlers
|
||||||
|
when: not ansible_check_mode
|
||||||
|
|
||||||
|
- name: Wait for every WireGuard peer handshake
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- wg
|
||||||
|
- show
|
||||||
|
- "{{ wireguard_interface }}"
|
||||||
|
- latest-handshakes
|
||||||
|
register: wireguard_latest_handshakes
|
||||||
|
changed_when: false
|
||||||
|
retries: "{{ wireguard_handshake_retries }}"
|
||||||
|
delay: "{{ wireguard_handshake_delay }}"
|
||||||
|
until:
|
||||||
|
- wireguard_latest_handshakes.stdout_lines | length == wireguard_peers | length
|
||||||
|
- wireguard_latest_handshakes.stdout_lines | select('search', '\t0$') | list | length == 0
|
||||||
|
when: not ansible_check_mode
|
||||||
|
|||||||
Reference in New Issue
Block a user