96 lines
3.4 KiB
YAML
96 lines
3.4 KiB
YAML
---
|
|
- name: Ensure WireGuard kernel module is loaded
|
|
ansible.builtin.modprobe:
|
|
name: wireguard
|
|
state: present
|
|
|
|
- name: Persist WireGuard kernel module across reboots
|
|
ansible.builtin.copy:
|
|
dest: /etc/modules-load.d/wg-easy.conf
|
|
content: |
|
|
wireguard
|
|
nft_masq
|
|
mode: '0644'
|
|
|
|
# WireGuard Easy VPN (v15) — UI at 10.10.0.36:51821 on npm_internal, fronted by NPM
|
|
# (vpn.boxswapper.io -> http://10.10.0.36:51821). Login: admin / wireguard_ui_password from vars.yml.
|
|
# v15 init is ONE-TIME: the INIT_* envs below are consumed only when /etc/wireguard/wg-easy.db is ABSENT.
|
|
# Force a re-init (wipes clients + server keys): podman rm -f wg-easy && rm -rf /opt/apps/wireguard, then re-run.
|
|
# NAT from VPN clients to LAN/apps (10.10.1.0/24 -> 10.10.0.0/24) uses NFTABLES hooks —
|
|
# wg-easy's iptables-legacy hooks cannot init the nat table inside a podman netns
|
|
# ("Table does not exist"), which makes wg-quick up fail and every client API call
|
|
# 500 with "Unable to access interface". scripts/patch-wg-hooks.py rewrites the hooks
|
|
# to nft rules and the tasks below restart wg-easy to apply them. See the official
|
|
# wg-easy "Podman + nftables" tutorial.
|
|
# EXTERNAL ACCESS: router MUST forward UDP 51820 -> 192.168.0.98. Test from LTE,
|
|
# not your LAN — NAT hairpin breaks public-IP handshakes from inside the network.
|
|
- name: Create WireGuard data directory
|
|
ansible.builtin.file:
|
|
path: /opt/apps/wireguard
|
|
state: directory
|
|
mode: '0755'
|
|
|
|
- name: Deploy WireGuard Easy (wg-easy)
|
|
containers.podman.podman_container:
|
|
name: wg-easy
|
|
image: "{{ wireguard_image }}"
|
|
restart_policy: always
|
|
recreate: true
|
|
state: started
|
|
env:
|
|
INIT_ENABLED: "true"
|
|
INIT_USERNAME: "{{ wireguard_ui_username }}"
|
|
INIT_PASSWORD: "{{ wireguard_ui_password }}"
|
|
INIT_HOST: "{{ wireguard_host }}"
|
|
INIT_PORT: "{{ wireguard_port }}"
|
|
INIT_DNS: "{{ wireguard_default_dns }}"
|
|
INIT_IPV4_CIDR: "{{ wireguard_cidr }}"
|
|
INIT_IPV6_CIDR: "{{ wireguard_ipv6_cidr }}"
|
|
INIT_ALLOWED_IPS: "{{ wireguard_allowed_ips }}"
|
|
PORT: "{{ wireguard_ui_port }}"
|
|
INSECURE: "true"
|
|
DISABLE_VERSION_CHECK: "true"
|
|
ports:
|
|
- "{{ wireguard_port }}:{{ wireguard_port }}/udp"
|
|
- "{{ wireguard_ui_port }}:{{ wireguard_ui_port }}/tcp"
|
|
volumes:
|
|
- "/opt/apps/wireguard:/etc/wireguard:z"
|
|
- "/lib/modules:/lib/modules:ro"
|
|
cap_add:
|
|
- NET_ADMIN
|
|
- SYS_MODULE
|
|
- NET_RAW
|
|
sysctl:
|
|
net.ipv4.ip_forward: "1"
|
|
net.ipv4.conf.all.src_valid_mark: "1"
|
|
net.ipv6.conf.all.disable_ipv6: "0"
|
|
net.ipv6.conf.all.forwarding: "1"
|
|
net.ipv6.conf.default.forwarding: "1"
|
|
network:
|
|
- npm_internal
|
|
ip: '{{ wireguard_ip }}'
|
|
|
|
- name: Copy wg-easy hook repair script
|
|
ansible.builtin.copy:
|
|
src: ./scripts/patch-wg-hooks.py
|
|
dest: /opt/apps/wireguard/patch-wg-hooks.py
|
|
owner: root
|
|
group: root
|
|
mode: '0755'
|
|
|
|
- name: Replace iptables hooks with nftables (iptables-legacy broken in podman)
|
|
ansible.builtin.command: python3 /opt/apps/wireguard/patch-wg-hooks.py
|
|
register: wg_hooks_patch
|
|
changed_when: "'patched hooks' in wg_hooks_patch.stdout"
|
|
|
|
- name: Restart wg-easy to apply nft hooks
|
|
ansible.builtin.command: podman restart wg-easy
|
|
when: "'patched hooks' in wg_hooks_patch.stdout"
|
|
|
|
- name: Wait for WireGuard Easy web UI
|
|
ansible.builtin.wait_for:
|
|
host: '{{ wireguard_ip }}'
|
|
port: '{{ wireguard_ui_port }}'
|
|
delay: 5
|
|
timeout: 120
|