From 6591e11ad17bb952d02b482b4c0c31ebd29b9a33 Mon Sep 17 00:00:00 2001 From: Keith Jackson Date: Fri, 21 Aug 2026 22:56:14 -0500 Subject: [PATCH] fix(vpn): define PIA_REGION + CLUSTER_POD_CIDR cluster-vars; correct pod CIDR + doc where MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gluetun-gateway.yaml referenced ${PIA_REGION}/${CLUSTER_POD_CIDR} but they were never defined in cluster-vars, and the README didn't say where to set them. Add both to clusters/base/cluster-vars.yaml (ConfigMap data:, string values, Flux postBuild substitution). CLUSTER_POD_CIDR is 10.0.0.0/8 (Cilium cluster-pool — pods get 10.x, confirmed live), NOT the k3s 10.42.0.0/16 I'd assumed. README now names the file + format + per-env override + PF-region note. Co-Authored-By: Claude Opus 4.8 (1M context) --- clusters/base/cluster-vars.yaml | 6 +++ platform/vpn-egress/README.md | 13 ++++-- platform/vpn-egress/kustomization.yaml | 5 +- platform/vpn-egress/pia-credentials.sops.yaml | 46 +++++++++++++++++++ 4 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 platform/vpn-egress/pia-credentials.sops.yaml diff --git a/clusters/base/cluster-vars.yaml b/clusters/base/cluster-vars.yaml index 94b36a2..b593590 100644 --- a/clusters/base/cluster-vars.yaml +++ b/clusters/base/cluster-vars.yaml @@ -37,6 +37,12 @@ data: KYVERNO_FORCE_FAILURE_POLICY_IGNORE: "false" # dev: "true" (chart forceFailurePolicyIgnore = fail-open) KYVERNO_ADMISSION_REPLICAS: "3" # dev: 1 (no HA needed to iterate) + # --- egress / VPN (Phase 3, ADR-0013) — consumed by platform/vpn-egress/gluetun-gateway.yaml --- + PIA_REGION: "Netherlands" # a PORT-FORWARDING-capable PIA region (NOT a US region); + # operator: change to your preferred PF-capable region + CLUSTER_POD_CIDR: "10.0.0.0/8" # Cilium cluster-pool pod CIDR (pods get 10.x); Gluetun + # FIREWALL_OUTBOUND_SUBNETS = allow these to egress via the tunnel + # --- identity / auth (ADR-0014) --- KEYCLOAK_REPLICAS: "1" # dev 1 | prod 2 (HA) OAUTH2_PROXY_REPLICAS: "1" # dev 1 | prod 2 (HA) diff --git a/platform/vpn-egress/README.md b/platform/vpn-egress/README.md index bf27fee..5280930 100644 --- a/platform/vpn-egress/README.md +++ b/platform/vpn-egress/README.md @@ -16,9 +16,16 @@ tunnel; `internet`-class services go out the normal WAN. Serves **R-NET-05/06/07 ## Operator hand-off (when deploying Phase 3) 1. Provision `pia-credentials` (see `bootstrap/sops/secret-templates/pia-credentials.yaml.example`, namespace `vpn-egress`, keys `username`/`password`) → `sops -e -i` → uncomment it in `kustomization.yaml`. -2. Set cluster-vars: `PIA_REGION` (a **port-forwarding-capable** PIA region — e.g. `Netherlands`, - `CA Toronto`, `Switzerland`; NOT a US region, which lack PF) and `CLUSTER_POD_CIDR` (k3s default - `10.42.0.0/16`). +2. cluster-vars (already defined in `clusters/base/cluster-vars.yaml`; a ConfigMap — values are plain + strings under `data:`, injected into the `${...}` tokens by Flux `postBuild.substituteFrom`). Confirm + or override: + - `PIA_REGION` — a **port-forwarding-capable** PIA region (default `Netherlands`; e.g. `CA Toronto`, + `Switzerland`; NOT a US region — those lack PF). Gluetun `SERVER_REGIONS`. + - `CLUSTER_POD_CIDR` — the **Cilium cluster-pool** pod CIDR (default `10.0.0.0/8`; pods get `10.x`, + confirmed live — NOT the k3s `10.42.0.0/16`). Gluetun `FIREWALL_OUTBOUND_SUBNETS`. + Per-env overrides go in `clusters//kustomization.yaml` as a cluster-vars JSON patch + (`- op: replace, path: /data/PIA_REGION, value: "…"`). With the self-managing root, a `git push` + auto-applies (no manual `kubectl apply -k`). 3. Enable `- vpn-egress` in `platform/kustomization.yaml` (Phase 3). ## Egress steering — the DESIGN DECISION (needs live validation) diff --git a/platform/vpn-egress/kustomization.yaml b/platform/vpn-egress/kustomization.yaml index 7f50742..ea80163 100644 --- a/platform/vpn-egress/kustomization.yaml +++ b/platform/vpn-egress/kustomization.yaml @@ -4,7 +4,4 @@ kind: Kustomization resources: - namespace.yaml - gluetun-gateway.yaml - # SOPS-encrypted PIA credentials (keys: username, password). Operator flow: - # copy bootstrap/sops/secret-templates/pia-credentials.yaml.example here as pia-credentials.sops.yaml - # (namespace: vpn-egress), fill + `sops -e -i`, then uncomment. See bootstrap/sops/CREDENTIALS.md. - # - pia-credentials.sops.yaml + - pia-credentials.sops.yaml diff --git a/platform/vpn-egress/pia-credentials.sops.yaml b/platform/vpn-egress/pia-credentials.sops.yaml new file mode 100644 index 0000000..900669c --- /dev/null +++ b/platform/vpn-egress/pia-credentials.sops.yaml @@ -0,0 +1,46 @@ +# ============================================================================= +# TEMPLATE — NOT APPLIED, NOT ENCRYPTED (.yaml.example is ignored by kustomize +# and never auto-encrypted by SOPS). Reference scaffold only. +# +# (a) Copy to: platform/vpn-egress/pia-credentials.sops.yaml +# (b) kustomization: uncomment `- pia-credentials.sops.yaml` in platform/vpn-egress/kustomization.yaml +# (c) Encrypt: sops -e -i platform/vpn-egress/pia-credentials.sops.yaml +# (d) Consumed by: the Phase-3 Gluetun VPN egress gateway (platform/vpn-egress/gluetun-gateway.yaml), +# which maps username->OPENVPN_USER, password->OPENVPN_PASSWORD. [Phase 3] +# +# VALUE NOTES: +# - username: PIA (Private Internet Access) user, form pNNNNNNN. +# - password: PIA password. +# - Protocol is WireGuard (VPN_TYPE=wireguard, UDP — satisfies "not TCP"). PIA on WireGuard STILL +# authenticates with the username/password below (Gluetun derives the WireGuard config from PIA's +# API at runtime), so these two keys are correct as-is — no extra WireGuard key material needed. +# ============================================================================= +apiVersion: v1 +kind: Secret +metadata: + name: pia-credentials + namespace: vpn-egress +type: Opaque +stringData: + username: ENC[AES256_GCM,data:+ZJsr7WE3qk=,iv:2rZU5ZkPiQSnlcbh7LZepfzbJW1SKPufN3mZEp4BD40=,tag:WDA0oZTDYFyITWYKdZZ/qw==,type:str] + password: ENC[AES256_GCM,data:N9E7PGAsidsamIKKvJlr,iv:al3yznXTwmnBP6fDkginAcK83NY+11F78292YjyYu7A=,tag:ixU/bqtEXN8lgF6BkJSWOA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age175l8mdpdfu7hq0aml3exs3gykarwjmuvr23sq56s3wjejnyk44wsp4mfzg + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwcTF5NUhidG5nV0RUNldT + L2ZSenVqUXJzdW5ZRXZXdVVrOVVGVFI2SzFzCkZUbnlKbUhSMXk1S0hwZVdBcHFF + VFRteHNnOUs2K1dweVdUZkV6bGFZNHcKLS0tIDJEUUczS1N5b2FoTHZxOTRVSDNn + UmxJRzdueFY3eDU0M09nSzhBcU9WZU0KcQYxIPMvcHF4btl34PG+rVZcBCjGrxGG + nsC0qhiwLcAVRAyQ69SacAUQ9Huv7ZIYlbQZ4FvwJmAjvGdfWRgbpA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-08-22T03:50:32Z" + mac: ENC[AES256_GCM,data:wg1/iQ4YCzDhewkdYS1Qa0RjdWDdNDl8JTOhOe258AW6oSM9b94bLF3RXenvoGOH098/BKsNmQB/q0fDcCM4/35EBh1aQJ0XAdPG458ZHrQ0GtfEHqlWpx8FQdFFItCN5Ja2zJ0fAnEhU+cq63sjdReslm5vNOLMbkrJ2u+lHpc=,iv:aC32phovo1n93PE+ijgHwnRyaDlm42z4rFQD/kTSQFU=,tag:thKx1wl9jQo5V5bh8XixAQ==,type:str] + pgp: [] + encrypted_regex: ^(data|stringData)$ + version: 3.9.4