--- # Part of role: pia-gateway # Called by: ansible/playbooks/pia-gateway.yaml # Description: Default variables for minisforum's PIA WireGuard egress # gateway for VPN VLAN 50 — policy routing, kill switch, and health # checks. See ~/repo/homelab/plan.md for the cross-repo contract this # role implements (fixed values below match that contract). # PIA regions to try, in order, for WireGuard addKey registration — # first server (in the first region that has any) to return # `status: OK` wins. These are API region **ids** from PIA's serverlist # (https://serverlist.piaservers.net/vpninfo/servers/v6), e.g. # {"id": "japan", "name": "JP Tokyo", ...} — NOT Gluetun's display names # ("JP Tokyo", "Hong Kong", "Taiwan") and not the slug you might guess # from one (confirmed live 2026-08-24: Tokyo's id is "japan", not # "jp_tokyo" — that matched zero regions on a first pass). Order matches # the region set already used by the Gluetun sidecars, Hong Kong/Taiwan # moved ahead of Tokyo after all three Tokyo servers were observed # failing in practice — see tasks/register.yaml's header for what that # means and doesn't mean. pia_region_candidates: - hk - taiwan - japan # Force a SINGLE region for troubleshooting, bypassing # pia_region_candidates entirely — e.g. `-e pia_region=hk`. This is also # an API id, not a display name; same rule as above. Leave null (the # default) to use the ordered candidate list. tasks/register.yaml # computes the actual list to try (pia_effective_regions) from whichever # of these two is set — see that file's own comment for the exact logic, # not duplicated here to avoid the two drifting out of sync. pia_region: null # WireGuard interface identity. Deliberately not "wg0" — that name is # already used by ansible/roles/wireguard, minisforum's separate *inbound* # home-VPN server role. Colliding with it would tear down remote access. pia_wg_interface: pia-wg pia_wg_config_dir: /etc/wireguard # Re-registration behaviour — two independent, unambiguous knobs (an # earlier single pia_force_reregister conflated "re-run the API calls" # with "get a new keypair", which isn't the same thing and isn't safe to # conflate — the key-generation task uses `creates:`, so a naive # "force" only re-ran the PIA API calls with the SAME existing key, # silently, unless you also knew to delete the key file yourself): # # - pia_force_reregister: re-run PIA registration (serverlist lookup, # token, addKey) even if {{ pia_wg_interface }}.conf already exists. # Reuses whatever keypair is already on disk (generates one only if # none exists yet). Use this to pick up a new PIA-assigned peer/server # without changing minisforum's own WireGuard identity. # - pia_force_key_rotation: additionally generate a NEW keypair and # register THAT with PIA (implies pia_force_reregister). Rotation is # safe-by-construction: the new key is generated to a *.key.new path # and only promoted (with the old key backed up alongside a timestamp) # after PIA has actually accepted the new key and the new config has # been written — see tasks/register.yaml. If registration fails # partway, the previous key/config are left completely untouched # rather than ending up in a broken half-state. pia_force_reregister: false pia_force_key_rotation: false # Dedicated policy-routing table for VLAN 50 egress. 0/253/254/255 are # kernel-reserved (unspec/default/main/local) — this must stay clear of # those and of any other custom table already registered on the host. pia_route_table_id: 52 pia_route_table_name: pia # Rule priority for "from 10.10.50.0/24 lookup pia". Must sort after the # kernel's built-in local table (priority 0, always evaluated first, keeps # traffic addressed to the host's own local/Technitium address delivered # locally per plan.md) and before main (priority 32766). pia_rule_priority: 100 # Fixed cross-repo contract (see plan.md "Fixed cross-repository # contract") — VLAN 50 subnet and the Flint gateway that owns the return # route back to VLAN 50. Not derived from live discovery; change only if # the contract itself changes. pia_vlan50_subnet: 10.10.50.0/24 pia_flint_gateway: 10.10.50.1 # Dedicated iptables chain the kill switch governs, jumped into by a # single rule at FORWARD position 1 matching only # {{ pia_vlan50_subnet }} — deliberately not a global FORWARD default- # policy change, so k3s/Flannel's own FORWARD-chain traffic (source # 10.42.0.0/16, disjoint from VLAN 50) is never affected by this role at # all. See templates/pia-killswitch.sh.j2 for the full reasoning. pia_iptables_chain: PIA-VLAN50 # Real parent LAN interface on minisforum — verified live 2026-08-23 via # `ip -brief addr`; it is enp1s0, not "eth0". Used for MASQUERADE-exclusion # bookkeeping and documentation only, since NAT/forward rules below key off # {{ pia_wg_interface }} rather than enumerating the normal interface. pia_lan_interface: enp1s0 # Reverse-path filtering, applied to {{ pia_wg_interface }} only. The # kernel default on minisforum (conf.default.rp_filter) is already loose # (2) at time of writing, so new interfaces inherit loose mode — this task # pins it explicitly rather than relying on that inherited default holding # across future changes. Loose mode is required because PIA's return # traffic can legitimately arrive with routing asymmetry relative to how # minisforum would route toward that source itself. pia_rp_filter_mode: 2 # MSS clamping on the pia-wg forward path — OFF by default. plan.md is # explicit: do not guess this. Flip to true only after Phase 5 canary # MTU/path-MTU testing (large-packet ping with DF set, across the # VLAN 50 -> Flint -> minisforum -> pia-wg path) shows fragmentation or # black-holing that clamping fixes. pia_mss_clamp_enabled: false # Health check cadence and thresholds. The check only observes and logs — # see tasks/healthcheck.yaml — it must never itself open the kill switch. pia_healthcheck_interval_sec: 60 pia_healthcheck_handshake_max_age_sec: 180