Extend LE *.unkin.net wildcard to arrstack + authentik (reflect into gitea) (#418)

## Why

#417 stood up the central Let's Encrypt `*.unkin.net` wildcard (Certificate `wildcard-unkin-net` in `cert-manager`, secret `wildcard-unkin-net-tls`, emberstack-reflected). This wires the remaining single-label public hosts onto that publicly-trusted leaf instead of the internal Vault-PKI CA.

A `*.unkin.net` wildcard matches **single-label** subdomains only, so cluster hostnames under `*.k8s.syd1.au.unkin.net` are deliberately left on `vault-issuer`.

> Note: PR #417 already merged to `main`, so this is no longer stacked — it targets `main` directly.

## How

- **cert-manager**: reflect `wildcard-unkin-net-tls` into `arrstack`, `authentik`, `gitea` (appended to both reflector namespace lists → `cheeztv,arrstack,authentik,gitea`).
- **arrstack**: repoint the public `arrproxy` gateway listener (`arrstack.unkin.net`) `certificateRefs` → `wildcard-unkin-net-tls`; drop its `cert-manager.io/*` vault-issuer annotations.
- **authentik**: repoint the `identity.unkin.net` https listener → `wildcard-unkin-net-tls`. The `identity.k8s.syd1.au.unkin.net` listeners keep `authentik-tls` (vault-issuer), so the gateway `common-name` is retargeted to that cluster host. `authentik-ldap` gateway untouched.
- **gitea**: secret **reflected only**; `git.unkin.net` cutover deferred (no manifest change), same deferred pattern as fafflix.

## Validation

- `kustomize build` OK for cert-manager / arrstack / authentik / gitea overlays.
- `kubeconform` all valid (0 invalid, 0 errors) across the four overlays.
- Verified no `*.k8s.syd1.au.unkin.net` listener lost its vault-issuer wiring.

Reviewed-on: #418
Co-authored-by: unkin-agent <unkin-agent@unkin.net>
Co-committed-by: unkin-agent <unkin-agent@unkin.net>
This commit was merged in pull request #418.
This commit is contained in:
2026-08-25 21:48:54 +10:00
committed by BenVincent
parent 48632eb9f9
commit 5da12e398d
5 changed files with 93 additions and 32 deletions
+7 -8
View File
@@ -1,9 +1,11 @@
--- ---
# External (DMZ) front for the arrstack, served on arrstack.unkin.net via the # External (DMZ) front for the arrstack, served on arrstack.unkin.net via the
# external Traefik (LB VIP 198.18.199.0). cert-manager mints arrproxy-gateway-tls # external Traefik (LB VIP 198.18.199.0). The apex arrstack.unkin.net A record
# (CN arrstack.unkin.net) off the internal Vault-PKI CA. The apex arrstack.unkin.net # lives in the bind-operator unkin.net zone (bind-internal/authoritative), NOT
# A record lives in the bind-operator unkin.net zone (bind-internal/authoritative), # external-dns, so no external-dns annotation here. Public TLS is terminated with
# NOT external-dns, so no external-dns annotation here. # the real Let's Encrypt *.unkin.net wildcard, centrally minted once in the
# cert-manager namespace (Certificate wildcard-unkin-net) and reflected into this
# namespace by the emberstack reflector as wildcard-unkin-net-tls, not Vault PKI.
apiVersion: gateway.networking.k8s.io/v1 apiVersion: gateway.networking.k8s.io/v1
kind: Gateway kind: Gateway
metadata: metadata:
@@ -11,9 +13,6 @@ metadata:
traefik.io/instance: external traefik.io/instance: external
annotations: annotations:
argocd.argoproj.io/sync-wave: "2" argocd.argoproj.io/sync-wave: "2"
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: arrstack.unkin.net
cert-manager.io/private-key-size: "4096"
name: arrproxy name: arrproxy
namespace: arrstack namespace: arrstack
spec: spec:
@@ -38,4 +37,4 @@ spec:
certificateRefs: certificateRefs:
- group: "" - group: ""
kind: Secret kind: Secret
name: arrproxy-gateway-tls name: wildcard-unkin-net-tls
+33 -10
View File
@@ -1,19 +1,22 @@
--- ---
# External (DMZ) front for public identity.unkin.net, served via the external
# Traefik (LB VIP 198.18.199.0). The apex identity.unkin.net A record lives in
# the bind-operator unkin.net zone (bind-internal/authoritative), NOT
# external-dns, so no external-dns annotation here. Public TLS is terminated with
# the real Let's Encrypt *.unkin.net wildcard, centrally minted once in the
# cert-manager namespace (Certificate wildcard-unkin-net) and reflected into this
# namespace by the emberstack reflector as wildcard-unkin-net-tls, not Vault PKI.
apiVersion: gateway.networking.k8s.io/v1 apiVersion: gateway.networking.k8s.io/v1
kind: Gateway kind: Gateway
metadata: metadata:
labels: labels:
traefik.io/instance: internal traefik.io/instance: external
annotations: annotations:
cert-manager.io/cluster-issuer: vault-issuer argocd.argoproj.io/sync-wave: "2"
cert-manager.io/common-name: identity.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: identity.unkin.net,identity.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.4
name: authentik name: authentik
namespace: authentik namespace: authentik
spec: spec:
gatewayClassName: traefik-internal gatewayClassName: traefik-external
listeners: listeners:
- allowedRoutes: - allowedRoutes:
namespaces: namespaces:
@@ -33,20 +36,40 @@ spec:
certificateRefs: certificateRefs:
- group: "" - group: ""
kind: Secret kind: Secret
name: authentik-tls name: wildcard-unkin-net-tls
mode: Terminate mode: Terminate
---
# Cluster hostname variant, identity.k8s.syd1.au.unkin.net. Internal Traefik,
# external-dns at 198.18.200.4. Own leaf from the Vault PKI issuer via the
# cert-manager gateway-shim; the common-name keys off this cluster host.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
labels:
traefik.io/instance: internal
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: identity.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: identity.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.4
name: authentik-internal
namespace: authentik
spec:
gatewayClassName: traefik-internal
listeners:
- allowedRoutes: - allowedRoutes:
namespaces: namespaces:
from: Same from: Same
hostname: identity.k8s.syd1.au.unkin.net hostname: identity.k8s.syd1.au.unkin.net
name: http-internal name: http
port: 80 port: 80
protocol: HTTP protocol: HTTP
- allowedRoutes: - allowedRoutes:
namespaces: namespaces:
from: Same from: Same
hostname: identity.k8s.syd1.au.unkin.net hostname: identity.k8s.syd1.au.unkin.net
name: https-internal name: https
port: 443 port: 443
protocol: HTTPS protocol: HTTPS
tls: tls:
+49 -10
View File
@@ -7,16 +7,11 @@ metadata:
spec: spec:
hostnames: hostnames:
- identity.unkin.net - identity.unkin.net
- identity.k8s.syd1.au.unkin.net
parentRefs: parentRefs:
- group: gateway.networking.k8s.io - group: gateway.networking.k8s.io
kind: Gateway kind: Gateway
name: authentik name: authentik
sectionName: http sectionName: http
- group: gateway.networking.k8s.io
kind: Gateway
name: authentik
sectionName: http-internal
rules: rules:
- filters: - filters:
- type: RequestRedirect - type: RequestRedirect
@@ -36,16 +31,60 @@ metadata:
spec: spec:
hostnames: hostnames:
- identity.unkin.net - identity.unkin.net
- identity.k8s.syd1.au.unkin.net
parentRefs: parentRefs:
- group: gateway.networking.k8s.io - group: gateway.networking.k8s.io
kind: Gateway kind: Gateway
name: authentik name: authentik
sectionName: https sectionName: https
- group: gateway.networking.k8s.io rules:
kind: Gateway - backendRefs:
name: authentik - group: ""
sectionName: https-internal kind: Service
name: authentik-server
port: 80
weight: 1
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: authentik-http-redirect-internal
namespace: authentik
spec:
hostnames:
- identity.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: authentik-internal
sectionName: http
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: authentik-internal
namespace: authentik
spec:
hostnames:
- identity.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: authentik-internal
sectionName: https
rules: rules:
- backendRefs: - backendRefs:
- group: "" - group: ""
@@ -16,9 +16,9 @@ spec:
type: A type: A
ttl: 600 ttl: 600
values: values:
# traefik-internal gateway VIP; the authentik Gateway serves the # traefik-EXTERNAL (DMZ) gateway VIP; the authentik Gateway serves the
# identity.unkin.net hostname there. # identity.unkin.net hostname there.
- 198.18.200.4 - 198.18.199.0
--- ---
# PRODUCTION CUTOVER RECORD — intentionally commented out. # PRODUCTION CUTOVER RECORD — intentionally commented out.
# git.unkin.net currently resolves to the LIVE VM forge (HAProxy VRRP VIP # git.unkin.net currently resolves to the LIVE VM forge (HAProxy VRRP VIP
@@ -14,9 +14,9 @@ spec:
secretTemplate: secretTemplate:
annotations: annotations:
reflector.v1.k8s.emberstack.com/reflection-allowed: "true" reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "cheeztv" reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "cheeztv,arrstack,authentik,gitea,watchstate"
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true" reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "cheeztv" reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "cheeztv,arrstack,authentik,gitea,watchstate"
privateKey: privateKey:
size: 4096 size: 4096
dnsNames: dnsNames: