Amend ADR-0013: VPN protocol WireGuard -> OpenVPN-UDP (Gluetun lacks PIA+WG)

Gluetun does not support Private Internet Access over WireGuard (upstream:
native support "cannot be added... slow work in progress"; confirmed live
rejecting the provider on v3.40/v3.41/latest). PIA in Gluetun is OpenVPN-only.

Amend ADR-0013 to PIA over OpenVPN-UDP. The egress ARCHITECTURE is unchanged
(single shared gateway, central kill-switch/fail-closed, native PF, Cilium
egress steering, active/standby) and R-NET-05/06/07 remain met; only the tunnel
protocol changes. OpenVPN-UDP satisfies "non-TCP", and Gluetun's HTTP control
API (health + forwarded-port lookup) is what the shared-gateway topology needs.
thrnz/docker-wireguard-pia retained as a documented WireGuard fallback.

Propagated the protocol correction to all active specs: ADR-0013 (+amendment
note), decisions/README, docs/00, docs/01, docs/03, docs/07, agents/task-board.
Superseded ADR-0008/0012 left immutable as historical record.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
jakman85andClaude Opus 4.8 committed 2026-08-22 09:02:31 -05:00
1 parent a7fc19fad5
commit 95b4b6af21
7 files changed
+39 -15

No files matched your search

+1 -1
View File
@@ -54,5 +54,5 @@ serves. **Do not edit an accepted decision in place** — supersede it with a ne
| [0010](adr-0010-conformance-testing.md) | Conformance testing: automated, reproducible, behavior-based | Accepted | R-TEST-01..06 |
| [0011](adr-0011-test-tooling-kyverno-chainsaw.md) | Conformance test tooling: Kyverno + Chainsaw | Accepted | R-TEST-01..05 |
| [0012](adr-0012-vpn-egress-single-expressvpn-gateway.md) | VPN egress: single shared in-cluster ExpressVPN gateway | ~~Superseded by 0013~~ | R-NET-05/06/07 |
| [0013](adr-0013-vpn-provider-pia-gluetun-wireguard.md) | VPN provider: PIA via Gluetun (WireGuard + port forwarding) | Accepted | R-NET-05/06/07 |
| [0013](adr-0013-vpn-provider-pia-gluetun-wireguard.md) | VPN provider: PIA via Gluetun (OpenVPN-UDP + port forwarding) | Accepted (amended 2026-08-22) | R-NET-05/06/07 |
| [0014](adr-0014-idp-keycloak.md) | Identity Provider: Keycloak (SSO via OIDC + forward-auth) | Accepted | R-IDP-01..06 |
@@ -1,9 +1,24 @@
# ADR-0013 — VPN provider: PIA via Gluetun (WireGuard + native port forwarding)
- Status: Accepted
# ADR-0013 — VPN provider: PIA via Gluetun (OpenVPN-UDP + native port forwarding)
- Status: Accepted (amended 2026-08-22 — protocol WireGuard → OpenVPN-UDP)
- Date: 2026-08-15
- Serves: R-NET-05, R-NET-06, R-NET-07
- Supersedes: [ADR-0012](adr-0012-vpn-egress-single-expressvpn-gateway.md)
> **Amendment — 2026-08-22 (protocol: WireGuard → OpenVPN-UDP).** The original decision specified
> PIA over **WireGuard**. This is **not implementable with Gluetun**: Gluetun does not support PIA
> over WireGuard — upstream states native support "cannot be added… slow work in progress," and it
> was confirmed live rejecting `private internet access` as a WireGuard provider on v3.40 / v3.41 /
> latest. **PIA in Gluetun is OpenVPN-only.** The decision is amended to **PIA over OpenVPN-UDP via
> Gluetun**; everything else in this ADR stands (single shared gateway, central kill-switch /
> fail-closed, native port forwarding, egress steering, active/standby). OpenVPN-UDP satisfies
> R-NET's "non-TCP, UDP or better" requirement, and Gluetun's HTTP control API (health +
> forwarded-port lookup) is what the shared-gateway topology relies on — a file-based PF handoff
> (the WireGuard-container alternative) would pull toward the sidecar model ADR-0008 rejected.
> **WireGuard fallback (documented, not primary):** if OpenVPN-UDP throughput ever proves a
> bottleneck, `thrnz/docker-wireguard-pia` provides PIA-over-WireGuard as a drop-in gateway — a
> contained swap, since the egress-steering design is protocol-agnostic. The filename retains the
> `-wireguard` slug as a stable historical identifier.
## Context
ADR-0012 kept the operator's required model — a single shared in-cluster VPN gateway with rules
enforced outside the service — but named **ExpressVPN** as the provider, which forced a custom
@@ -13,13 +28,16 @@ which *is* first-class in Gluetun. The egress **model is unchanged**; only the p
protocol change — so ADR-0012 is superseded.
## Decision
The single shared in-cluster VPN gateway runs **Gluetun** configured for **PIA** over **WireGuard**,
The single shared in-cluster VPN gateway runs **Gluetun** configured for **PIA** over **OpenVPN-UDP**,
with Gluetun's **native automated port forwarding** for qBittorrent:
- **Provider/client:** PIA via the **Gluetun** container as the gateway VPN client (Gluetun provides
the built-in **kill-switch/firewall**, health checks, and auto-reconnect).
- **Protocol:** **WireGuard** (UDP) — satisfies "non-TCP, UDP or better" and is a strict upgrade over
ExpressVPN's OpenVPN-UDP.
- **Protocol:** **OpenVPN-UDP** — satisfies "non-TCP, UDP or better." (WireGuard was the original
choice but is not supported for PIA in Gluetun — see the amendment above.) Unlike the ExpressVPN
plan this needs **no bespoke OpenVPN build**: PIA is a first-class Gluetun provider, so it is
stock env-var config (`VPN_TYPE=openvpn`), and Gluetun exposes the tunnel state + forwarded port
over its HTTP control API.
- **Credentials:** just the **PIA username/password**, stored **SOPS-encrypted** ([ADR-0007](adr-0007-secrets-sops-age.md)).
No manual `.ovpn` extraction (the ExpressVPN prerequisite is gone).
- **Port forwarding:** Gluetun native (`VPN_PORT_FORWARDING=on`, provider `private internet
@@ -32,8 +50,13 @@ with Gluetun's **native automated port forwarding** for qBittorrent:
## Alternatives considered
- **ExpressVPN (ADR-0012)** — dropped: not Gluetun-native, needed a custom OpenVPN workaround; and the
operator's subscription is lapsing.
- **ProtonVPN** — equally good fit (Gluetun-native NAT-PMP PF, WireGuard); viable if PIA
disappoints, but the operator has purchased PIA.
- **PIA over WireGuard via a dedicated container (`thrnz/docker-wireguard-pia`)** — the only way to
keep **WireGuard** with PIA, since Gluetun cannot. Rejected as primary: it exposes the forwarded
port as a shared **file** (`/pia-shared/port.dat`) rather than an HTTP API, which fits a same-netns
sidecar (the model ADR-0008 rejected) better than a shared gateway, plus script-based health and a
smaller single-maintainer image. Retained as the WireGuard **fallback** (see amendment).
- **ProtonVPN** — equally good fit (Gluetun-native NAT-PMP PF, and Gluetun **does** support ProtonVPN
over WireGuard); viable if PIA disappoints, but the operator has purchased PIA.
- **AirVPN** — WireGuard works in Gluetun but automated PF is not integrated (static port only);
less hands-off.
- **Mullvad** — no port forwarding since 2023 → degraded qBittorrent seeding; rejected for this