# Managed by Ansible (role: pia-gateway). Do not edit by hand — changes # are overwritten on the next run of ansible/playbooks/pia-gateway.yaml. # # Table = off: wg-quick must NOT touch the main routing table. All routing # for this interface lives in the dedicated "{{ pia_route_table_name }}" # table (see tasks/routing.yaml), reached only by traffic sourced from # {{ pia_vlan50_subnet }}. minisforum's own default route is never # affected by this interface coming up or down. [Interface] PrivateKey = {{ pia_private_key }} Address = {{ pia_peer.peer_ip }}/32 Table = off # Kill-switch ordering: the boot-time pia-killswitch.service (see # tasks/routing.yaml) has already seeded an "unreachable" default route in # table {{ pia_route_table_name }} and created the dedicated # {{ pia_iptables_chain }} chain (jumped into from FORWARD position 1 for # source {{ pia_vlan50_subnet }} only — never touches Flannel/k3s traffic) # ending in an unconditional LOG+DROP, before this unit ever starts # (systemd After=/Requires=). PostUp only ever *opens* the path narrower # than that pre-seeded closed state, by inserting ACCEPT rules ahead of # the chain's own catch-all; PreDown removes exactly those same rules, # re-closing it before removing anything else. PostUp = ip route replace default dev %i table {{ pia_route_table_name }} PostUp = iptables -I {{ pia_iptables_chain }} 1 -s {{ pia_vlan50_subnet }} -o %i -j ACCEPT PostUp = iptables -I {{ pia_iptables_chain }} 1 -d {{ pia_vlan50_subnet }} -i %i -m state --state ESTABLISHED,RELATED -j ACCEPT PostUp = iptables -t nat -A POSTROUTING -s {{ pia_vlan50_subnet }} -o %i -j MASQUERADE {% if pia_mss_clamp_enabled %} PostUp = iptables -t mangle -A FORWARD -s {{ pia_vlan50_subnet }} -o %i -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu {% endif %} # PreDown's iptables -D lines are deliberately tolerant (2>/dev/null || # true) of the rule they target not existing — confirmed against # wg-quick's own source (execute_hooks() runs each line via `(eval # "$hook")`, and wg-quick's top-level `set -e` treats that subshell's # exit code as fatal for the WHOLE up/down sequence): without this, a # single -D failing (e.g. the currently-live interface was brought up # under an OLDER config that never added the rule this line is now # trying to remove — root-caused live, 2026-08-27, when enabling MSS # clamping for the first time made this exact thing happen) aborts # every PreDown line after it, including wg-quick's own built-in `ip # link delete`, leaving an orphaned interface that then makes the # following `wg-quick up` fail too ("pia-wg already exists") — turning # any future PostUp/PreDown content change into a two-step manual # recovery (`ip link delete dev pia-wg` before a fresh start) instead # of a clean, unattended `systemctl restart`. `ip route replace` (the # first PreDown line) doesn't need this — replace never fails due to # prior state the way -D does. PreDown = ip route replace unreachable default table {{ pia_route_table_name }} PreDown = iptables -t nat -D POSTROUTING -s {{ pia_vlan50_subnet }} -o %i -j MASQUERADE 2>/dev/null || true PreDown = iptables -D {{ pia_iptables_chain }} -d {{ pia_vlan50_subnet }} -i %i -m state --state ESTABLISHED,RELATED -j ACCEPT 2>/dev/null || true PreDown = iptables -D {{ pia_iptables_chain }} -s {{ pia_vlan50_subnet }} -o %i -j ACCEPT 2>/dev/null || true {% if pia_mss_clamp_enabled %} PreDown = iptables -t mangle -D FORWARD -s {{ pia_vlan50_subnet }} -o %i -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu 2>/dev/null || true {% endif %} [Peer] # PIA WireGuard server actually used — {{ pia_region_name_used }} # ({{ pia_region_used }}), {{ pia_wg_server_used.cn }}. This is whichever # region+server in the pia_region_candidates/pia_region fallback order # (see defaults/main.yaml) responded first with status: OK — not # necessarily the first-configured region. Re-run the playbook with # pia_force_reregister (or check journalctl for the last apply's # per-attempt diagnostics) to see what else was tried before this one. PublicKey = {{ pia_peer.server_key }} # The endpoint IP is the server we actually connected to # (pia_wg_server_used, set by addkey-attempt.yaml on whichever candidate # in servers.wg succeeded), not a field from the addKey JSON response — # matching connect_to_wireguard_with_token.sh, which builds the Endpoint # from its own $WG_SERVER_IP rather than trusting a response field for it. Endpoint = {{ pia_wg_server_used.ip }}:{{ pia_peer.server_port }} AllowedIPs = 0.0.0.0/0 PersistentKeepalive = 25