Replaces the Go pia-wg-config (Go 1.23 rejects PIA legacy-CN no-SAN certs) with PIA's official CA-pinned curl flow. Adds CA-aware region auto-pick so ExpressVPN-CA migrated regions (e.g. us_chicago) auto-skip; region moved to us_denver. Tunnel restored + egress verified 2026-06-30. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
gluetun PIA WireGuard peer regenerator
Generates wg0.conf for gluetun custom mode (gluetun has no native PIA
WireGuard). sabnzbd + transmission ride gluetun's netns. Live stack runs from
~/downloads/ on media-server (.183) — that compose is part of the docker stack,
not this repo; the regenerator source is captured here.
Why this exists (2026-06-30 rewrite)
The previous approach built kylegrantlucas/pia-wg-config (Go 1.23), which
TLS-rejects PIA's legacy-CommonName (no-SAN) server certs:
x509: certificate relies on legacy Common Name field. Compounding it, the old
region us_chicago was migrated onto Kape/ExpressVPN-CA infra whose certs don't
chain to PIA's ca.rsa.4096.crt.
Fix: regen-entrypoint.sh now uses PIA's official CA-pinned curl flow
(authv3/generateToken + addKey, --connect-to <CN>::<ip>: --cacert). OpenSSL
honors CN-fallback on no-SAN certs where Go won't. It also does CA-aware region
auto-pick: tries $PIA_REGION then a US-centric fallback list; the CA-pinned
token step is the gate, so ExpressVPN-migrated regions auto-skip (self-heals future
Kape migrations).
Files
regen-entrypoint.sh— the regenerator (container ENTRYPOINT)Dockerfile— alpine + curl/jq/wireguard-tools; bakes PIA CA at/etc/pia/ca.rsa.4096.crtca.rsa.4096.crt— PIA's public CA (from pia-foss/manual-connections)regen-and-up.sh— recovery command: regen peer → recreate gluetun → reconnect sab/transmission (run this on aVpnTunnelDownalert)regen-wg.sh— regen config only (no gluetun restart)
Required docker-compose wiring (in the ~/downloads stack)
pia-wg-regen:
build: ./pia-wg
image: pia-wg-regen:v1.1.1
container_name: pia-wg-regen
environment:
- PIA_REGION=us_denver # was us_chicago (moved to ExpressVPN CA)
volumes:
- ./.env:/pia/.env:ro # OPENVPN_USER / OPENVPN_PASSWORD (gitignored — never commit)
- ./pia-wg/config:/config # wg0.conf output (contains the private key — never commit)
restart: "no"
Recovery
cd ~/downloads/pia-wg && ./regen-and-up.sh
Verify: docker exec gluetun wget -qO- http://localhost:8000/v1/publicip/ip
should show a PIA IP (not the home WAN). NB: gluetun /v1/openvpn/status reads
stopped under WireGuard — normal; use /v1/publicip/ip.