From 8ffc92b6db42ef2e6d1778e9b7d9cb071d2b4097 Mon Sep 17 00:00:00 2001 From: n0mad1k Date: Mon, 9 Mar 2026 16:49:56 -0400 Subject: [PATCH] Fix invalid AllowedIPs in WireGuard peer config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: regex_replace chains to extract subnet base from CIDR weren't working in Ansible shell blocks, producing 10.66.66.0/24.2/32 instead of 10.66.66.2/32 — invalid CIDR that wg-quick can't parse. Fix: replace fragile regex with simple string split via set_fact (_subnet_base = wg_subnet.split('.')[0:3] | join('.')). Use echo statements for lines needing shell expansion (PrivateKey, peer keys) and quoted heredoc for static Jinja2-rendered lines (PostUp/PostDown). Co-Authored-By: Claude Opus 4.6 --- phantom/playbooks/vpn/tasks/configure.yml | 31 +++++++++++++---------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/phantom/playbooks/vpn/tasks/configure.yml b/phantom/playbooks/vpn/tasks/configure.yml index 65c91e1..79b4435 100644 --- a/phantom/playbooks/vpn/tasks/configure.yml +++ b/phantom/playbooks/vpn/tasks/configure.yml @@ -6,6 +6,11 @@ register: primary_interface changed_when: false +- name: Set computed vars + set_fact: + _iface: "{{ primary_interface.stdout | trim }}" + _subnet_base: "{{ wg_subnet.split('.')[0:3] | join('.') }}" + - name: Generate client keys shell: | mkdir -p /etc/wireguard/clients @@ -26,19 +31,18 @@ ignore_errors: true - name: Build WireGuard server config - vars: - _iface: "{{ primary_interface.stdout | trim }}" - _addr: "{{ wg_subnet | regex_replace('/\\d+$', '') | regex_replace('\\.[0-9]+$', '.1/24') }}" shell: | SERVER_PRIVKEY=$(cat /etc/wireguard/server_private.key) - cat > /etc/wireguard/wg0.conf << 'CONFEOF' - [Interface] - Address = {{ _addr }} - ListenPort = {{ wg_port }} - SaveConfig = false - CONFEOF + + # Header + PrivateKey (needs shell expansion) + echo "[Interface]" > /etc/wireguard/wg0.conf + echo "Address = {{ _subnet_base }}.1/24" >> /etc/wireguard/wg0.conf + echo "ListenPort = {{ wg_port }}" >> /etc/wireguard/wg0.conf echo "PrivateKey = ${SERVER_PRIVKEY}" >> /etc/wireguard/wg0.conf - cat >> /etc/wireguard/wg0.conf << 'CONFEOF' + echo "SaveConfig = false" >> /etc/wireguard/wg0.conf + + # PostUp/PostDown rules (Jinja2 vars, no shell expansion needed) + cat >> /etc/wireguard/wg0.conf << 'RULESEOF' PostUp = iptables -A FORWARD -i wg0 -o {{ _iface }} -j ACCEPT PostUp = iptables -A FORWARD -i {{ _iface }} -o wg0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT PostUp = iptables -t nat -A POSTROUTING -o {{ _iface }} -s {{ wg_subnet }} -j MASQUERADE @@ -57,8 +61,9 @@ PostDown = iptables -D INPUT -i wg0 -p tcp --dport 22 -j DROP PostDown = iptables -D INPUT -i wg0 -p tcp --dport 80 -j DROP PostDown = iptables -D INPUT -i wg0 -p tcp --dport 443 -j DROP - CONFEOF + RULESEOF + # Peers for i in $(seq 1 {{ wg_clients }}); do CLIENT_PUBKEY=$(cat /etc/wireguard/clients/client${i}_public.key) CLIENT_PSK=$(cat /etc/wireguard/clients/client${i}_psk.key) @@ -66,7 +71,7 @@ echo "[Peer]" >> /etc/wireguard/wg0.conf echo "PublicKey = ${CLIENT_PUBKEY}" >> /etc/wireguard/wg0.conf echo "PresharedKey = ${CLIENT_PSK}" >> /etc/wireguard/wg0.conf - echo "AllowedIPs = {{ wg_subnet | regex_replace('/\\d+$', '') | regex_replace('\\.[0-9]+$', '') }}.$(( i + 1 ))/32" >> /etc/wireguard/wg0.conf + echo "AllowedIPs = {{ _subnet_base }}.$(( i + 1 ))/32" >> /etc/wireguard/wg0.conf done chmod 600 /etc/wireguard/wg0.conf @@ -90,7 +95,7 @@ for i in $(seq 1 {{ wg_clients }}); do CLIENT_PRIVKEY=$(cat /etc/wireguard/clients/client${i}_private.key) CLIENT_PSK=$(cat /etc/wireguard/clients/client${i}_psk.key) - CLIENT_IP="{{ wg_subnet | regex_replace('/\\d+$', '') | regex_replace('\\.[0-9]+$', '') }}.$(( i + 1 ))" + CLIENT_IP="{{ _subnet_base }}.$(( i + 1 ))" cat > /etc/wireguard/clients/client${i}.conf << CLIENTEOF [Interface]