feat(vpn): enable vpn-egress on OpenVPN-UDP; align docs to ADR-0013 amendment

Gluetun cannot do PIA over WireGuard (upstream unsupported; live "provider name
is not valid for Wireguard"). Operator approved OpenVPN-UDP and ADR-0013 was
amended in the spec. This aligns the impl:

- platform/kustomization.yaml: re-enable `- vpn-egress` (Phase 3, OpenVPN-UDP)
- gluetun-gateway.yaml: clean stale WireGuard comments (header, image note,
  VPN_TYPE/creds comments); config already VPN_TYPE=openvpn
- README.md: PIA-over-OpenVPN, status=enabled, steering iface wg0 -> tun0
- DECISIONS-LOG.md: disk/drive incident (k3s -> NVMe; failing Seagate) + Phase-3
  OpenVPN resolution

Stale WireGuard comments inside the operator's encrypted pia-credentials.sops.yaml
header left untouched (editing breaks the SOPS MAC; cosmetic).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
jakman85andClaude Opus 4.8 committed 2026-08-22 14:49:16 -05:00
1 parent 41da3d96e5
commit 015b423353
4 files changed
+60 -21

No files matched your search

+11 -10
View File
@@ -1,17 +1,18 @@
# platform/vpn-egress — shared VPN egress gateway (Phase 3, ADR-0013)
Single shared **Gluetun** gateway: **PIA over WireGuard**, built-in kill-switch, native port
forwarding. `vpn`-class services (sonarr, radarr, jackett, qbittorrent) egress **only** through this
tunnel; `internet`-class services go out the normal WAN. Serves **R-NET-05/06/07**.
Single shared **Gluetun** gateway: **PIA over OpenVPN-UDP** (ADR-0013 amendment — Gluetun does not
support PIA over WireGuard), built-in kill-switch, native port forwarding. `vpn`-class services
(sonarr, radarr, jackett, qbittorrent) egress **only** through this tunnel; `internet`-class services
go out the normal WAN. Serves **R-NET-05/06/07**.
> **STATUS: authored, NOT deployed.** Not wired into `platform/kustomization.yaml` yet. Deploy needs
> (a) the `pia-credentials` SOPS secret, and (b) validation of the egress-steering mechanism below,
> which cannot be tested without a live PIA tunnel.
> **STATUS: enabled in `platform/kustomization.yaml` (Phase 3).** `pia-credentials` SOPS secret is
> provisioned. Remaining work: validate the tunnel comes up + correct egress IP, then the
> egress-steering mechanism below (the hard part) and the kill-switch conformance test.
## Pieces
- `gluetun-gateway.yaml` — the Gluetun Deployment (`replicas: 1`, `Recreate`) + the `gluetun-control`
Service (control API :8000 for forwarded-port lookup + tunnel-state health). Kill-switch = `FIREWALL=on`.
- `pia-credentials` (SOPS) — PIA username/password only; Gluetun derives the WireGuard config at runtime.
- `pia-credentials` (SOPS) — PIA username/password only; Gluetun ships PIA's OpenVPN configs.
## Operator hand-off (when deploying Phase 3)
1. Provision `pia-credentials` (see `bootstrap/sops/secret-templates/pia-credentials.yaml.example`,
@@ -35,8 +36,8 @@ natively route through a *pod's* tunnel. Options considered:
1. **Cilium Egress Gateway → the Gluetun node's tunnel interface (recommended).** Pin Gluetun to a
node; a `CiliumEgressGatewayPolicy` selects pods labeled `homelab.keithjackson.dev/egress-class=vpn`
and egresses them via that node's WireGuard interface (`wg0`). If the tunnel drops, `wg0` is gone →
traffic has no egress path → **fail-closed** (the kill-switch behavior R-NET-06 needs). This is the
and egresses them via that node's tunnel interface (`tun0`, OpenVPN). If the tunnel drops, `tun0`
is gone → traffic has no egress path → **fail-closed** (the kill-switch behavior R-NET-06 needs). This is the
most Cilium-native fit but requires Gluetun's tunnel interface to be visible to the node datapath
(hostNetwork Gluetun, or a shared netns) — the detail to VALIDATE.
2. **Gateway-pod routing:** client pods default-route to the Gluetun pod IP (init-container +
@@ -44,7 +45,7 @@ natively route through a *pod's* tunnel. Options considered:
Cilium egress gateway but is more moving parts and pod-IP-fragile.
3. **Per-pod Gluetun sidecar** — explicitly REJECTED by ADR-0013 (single shared gateway preferred).
**Plan:** validate option 1 against a live PIA tunnel (confirm `wg0` on the Gluetun node + a
**Plan:** validate option 1 against a live PIA tunnel (confirm `tun0` on the Gluetun node + a
`CiliumEgressGatewayPolicy` steering `egress-class=vpn` pods, then run the `egress-class` (R-NET-05/07)
and `vpn-killswitch` (R-NET-06) conformance tests). Fall back to option 2 if the interface isn't
addressable. The `CiliumEgressGatewayPolicy` is intentionally NOT committed until validated, to avoid