diff --git a/adguardhome/k8s/cert-sync-rbac.yaml b/adguardhome/k8s/cert-sync-rbac.yaml deleted file mode 100644 index 084da9f..0000000 --- a/adguardhome/k8s/cert-sync-rbac.yaml +++ /dev/null @@ -1,92 +0,0 @@ -# Least-privilege RBAC for the adguard TLS cert sync CronJob (see cert-sync.yaml). -# -# The job runs as ServiceAccount `adguard-cert-sync` (namespace adguard) and needs: -# * namespace traefik: list/get pods (locate the running Traefik pod by label) -# and create pods/exec (read-only `cat` of /data/letsencrypt/acme.json). -# It never writes anything in namespace traefik. -# * namespace adguard: get/update/patch Secret `adguard-certs` (the only -# secret it may touch) and get/list/watch/patch Deployment -# `adguard-deployment` (`rollout restart` issues a patch, -# `rollout status` needs list+watch). -apiVersion: v1 -kind: ServiceAccount -metadata: - name: adguard-cert-sync - namespace: adguard - labels: - app: adguard ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: adguard-cert-sync - namespace: adguard - labels: - app: adguard -rules: - - apiGroups: [""] - resources: ["secrets"] - resourceNames: ["adguard-certs"] - verbs: ["get", "update", "patch"] - - apiGroups: ["apps"] - resources: ["deployments"] - resourceNames: ["adguard-deployment"] - verbs: ["get", "patch"] - # NOTE: list/watch cannot be combined with resourceNames (the API ignores - # the name filter for collection verbs, so the grant would be void). - # This rule is namespace-scoped to adguard, which holds a single - # Deployment; `rollout status` needs it to watch the rollout. - - apiGroups: ["apps"] - resources: ["deployments"] - verbs: ["list", "watch"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: adguard-cert-sync - namespace: adguard - labels: - app: adguard -subjects: - - kind: ServiceAccount - name: adguard-cert-sync - namespace: adguard -roleRef: - kind: Role - name: adguard-cert-sync - apiGroup: rbac.authorization.k8s.io ---- -# Read-only access to the Traefik pod (acme.json lives on its /data volume). -# The RoleBinding references a ServiceAccount from namespace adguard, -# which is allowed: the binding lives in namespace traefik and only -# grants rights inside namespace traefik. -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: adguard-cert-sync - namespace: traefik - labels: - app: adguard -rules: - - apiGroups: [""] - resources: ["pods"] - verbs: ["get", "list"] - - apiGroups: [""] - resources: ["pods/exec"] - verbs: ["create"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: adguard-cert-sync - namespace: traefik - labels: - app: adguard -subjects: - - kind: ServiceAccount - name: adguard-cert-sync - namespace: adguard -roleRef: - kind: Role - name: adguard-cert-sync - apiGroup: rbac.authorization.k8s.io diff --git a/adguardhome/k8s/cert-sync.yaml b/adguardhome/k8s/cert-sync.yaml deleted file mode 100644 index e8eaeaa..0000000 --- a/adguardhome/k8s/cert-sync.yaml +++ /dev/null @@ -1,135 +0,0 @@ -# AdGuard TLS cert sync: copy Traefik's public certificate for dns.forust.xyz -# (used by DNS-over-TLS on :853) from Traefik's acme.json into Secret -# `adguard-certs`, restarting the AdGuard Deployment only when it changed. -# -# Why this exists: cert-manager Certificate objects cannot be used here. -# Traefik's acme-http@internal router hijacks every HTTP-01 challenge path, -# so the prod ClusterIssuer can never complete an order for this host. -# Traefik itself keeps renewing the cert via its own ACME stack; this job -# mirrors the resulting public cert/key into the secret AdGuard mounts. -# -# Safety properties (all enforced by the script, not by convention): -# * selects the PROD resolver entry only (`.letsencrypt`), never staging; -# * matches by main domain OR SAN list (Traefik stores the bundled cert -# under the router's first domain, e.g. adguard.forust.xyz); -# * compares sha256 hashes and patches the Secret ONLY on change; -# * restarts the Deployment ONLY when the Secret was patched; -# * exits non-zero and touches nothing when Traefik has no cert yet, -# when the Secret is missing, or when the payload fails PEM checks. -# -# Manual apply: -# kubectl apply -f adguardhome/k8s/cert-sync-rbac.yaml -# kubectl apply -f adguardhome/k8s/cert-sync.yaml -# Force a run (safe: idempotent, read-only when already in sync): -# kubectl create job -n adguard --from=cronjob/adguard-cert-sync sync-now -apiVersion: batch/v1 -kind: CronJob -metadata: - name: adguard-cert-sync - namespace: adguard - labels: - app: adguard -spec: - schedule: "17 3 * * *" - concurrencyPolicy: Forbid - successfulJobsHistoryLimit: 2 - failedJobsHistoryLimit: 3 - jobTemplate: - spec: - activeDeadlineSeconds: 300 - template: - metadata: - labels: - app: adguard - spec: - serviceAccountName: adguard-cert-sync - restartPolicy: OnFailure - containers: - - name: cert-sync - image: dtzar/helm-kubectl:3.19.1 - imagePullPolicy: IfNotPresent - resources: - requests: - cpu: "50m" - memory: "64Mi" - limits: - cpu: "200m" - memory: "256Mi" - env: - - name: SYNC_DOMAIN - value: "dns.forust.xyz" - - name: SYNC_RESOLVER - value: "letsencrypt" - command: - - /bin/sh - - -c - - | - set -eu - DOMAIN="${SYNC_DOMAIN:?}" - RESOLVER="${SYNC_RESOLVER:?}" - NS="adguard" - SECRET="adguard-certs" - DEPLOY="adguard-deployment" - - echo "== 1. locate running traefik pod ==" - POD="$(kubectl get pods -n traefik -l app.kubernetes.io/name=traefik \ - --field-selector=status.phase=Running -o jsonpath='{.items[0].metadata.name}')" - if [ -z "${POD:-}" ]; then - echo "ERROR: no running traefik pod found, leaving secret untouched" - exit 1 - fi - echo "traefik pod: $POD" - - echo "== 2. fetch ${DOMAIN} cert/key from acme.json (resolver ${RESOLVER}) ==" - TMP="$(mktemp -d)" - trap 'rm -rf "$TMP"' EXIT INT TERM - kubectl exec -n traefik "$POD" -- cat /data/letsencrypt/acme.json > "$TMP/acme.json" - jq -r --arg r "$RESOLVER" --arg d "$DOMAIN" \ - '.[$r].Certificates // [] | map(select(.domain.main == $d or ((.domain.sans // []) | index($d))))' \ - "$TMP/acme.json" \ - | jq -r '.[0] // empty | .certificate // empty' > "$TMP/new.crt.b64" - jq -r --arg r "$RESOLVER" --arg d "$DOMAIN" \ - '.[$r].Certificates // [] | map(select(.domain.main == $d or ((.domain.sans // []) | index($d))))' \ - "$TMP/acme.json" \ - | jq -r '.[0] // empty | .key // empty' > "$TMP/new.key.b64" - if [ ! -s "$TMP/new.crt.b64" ] || [ ! -s "$TMP/new.key.b64" ]; then - echo "ERROR: no certificate for ${DOMAIN} under resolver ${RESOLVER} in acme.json." - echo "HINT: Traefik has not issued it (check HTTP-01 reachability and DNS records)." - echo "Leaving secret ${SECRET} untouched." - exit 1 - fi - base64 -d "$TMP/new.crt.b64" > "$TMP/new.crt" - base64 -d "$TMP/new.key.b64" > "$TMP/new.key" - grep -q "BEGIN CERTIFICATE" "$TMP/new.crt" || { echo "ERROR: payload is not a PEM certificate"; exit 1; } - grep -q "BEGIN .*PRIVATE KEY" "$TMP/new.key" || { echo "ERROR: payload is not a PEM private key"; exit 1; } - echo "fetched PEM cert/key for ${DOMAIN} (sanity checks passed)" - - echo "== 3. compare with live secret ${SECRET} ==" - if ! kubectl -n "$NS" get secret "$SECRET" >/dev/null 2>&1; then - echo "ERROR: secret $NS/${SECRET} does not exist, refusing to create it implicitly." - echo "HINT: bootstrap it once, then re-run this job." - exit 1 - fi - kubectl -n "$NS" get secret "$SECRET" -o jsonpath='{.data.tls\.crt}' \ - | base64 -d > "$TMP/live.crt" - kubectl -n "$NS" get secret "$SECRET" -o jsonpath='{.data.tls\.key}' \ - | base64 -d > "$TMP/live.key" - # Compare content digests only (never filenames: identical - # content under different paths must hash equal). - NEW_HASH="$(sha256sum "$TMP/new.crt" | cut -d' ' -f1)$(sha256sum "$TMP/new.key" | cut -d' ' -f1)" - LIVE_HASH="$(sha256sum "$TMP/live.crt" | cut -d' ' -f1)$(sha256sum "$TMP/live.key" | cut -d' ' -f1)" - if [ "$NEW_HASH" = "$LIVE_HASH" ]; then - echo "secret ${SECRET} already holds the current ${DOMAIN} cert, nothing to do" - exit 0 - fi - echo "cert differs, patching secret ${SECRET}" - - echo "== 4. update secret and restart ${DEPLOY} ==" - CRT_B64="$(base64 "$TMP/new.crt" | tr -d '\n')" - KEY_B64="$(base64 "$TMP/new.key" | tr -d '\n')" - kubectl -n "$NS" patch secret "$SECRET" --type=merge \ - -p '{"data":{"tls.crt":"'"$CRT_B64"'","tls.key":"'"$KEY_B64"'"}}' - echo "secret patched, restarting deployment" - kubectl -n "$NS" rollout restart "deploy/${DEPLOY}" - kubectl -n "$NS" rollout status "deploy/${DEPLOY}" --timeout=180s - echo "sync complete" diff --git a/adguardhome/k8s/certificate.yaml b/adguardhome/k8s/certificate.yaml new file mode 100644 index 0000000..2636938 --- /dev/null +++ b/adguardhome/k8s/certificate.yaml @@ -0,0 +1,12 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: adguard-certs + namespace: adguard +spec: + secretName: adguard-certs + dnsNames: + - dns.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/adguardhome/k8s/ingress.yaml b/adguardhome/k8s/ingress.yaml index c01fa15..0e101da 100644 --- a/adguardhome/k8s/ingress.yaml +++ b/adguardhome/k8s/ingress.yaml @@ -21,7 +21,7 @@ spec: - name: adguard-service port: 3000 tls: - certResolver: letsencrypt + secretName: adguard-certs --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/authentik/k8s/certificates.yaml b/authentik/k8s/certificates.yaml new file mode 100644 index 0000000..f9f7708 --- /dev/null +++ b/authentik/k8s/certificates.yaml @@ -0,0 +1,12 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: authentik-prod-tls + namespace: authentik +spec: + secretName: authentik-prod-tls + dnsNames: + - auth.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/authentik/k8s/ingress.yaml b/authentik/k8s/ingress.yaml index 991f0ea..6e06750 100644 --- a/authentik/k8s/ingress.yaml +++ b/authentik/k8s/ingress.yaml @@ -16,7 +16,7 @@ spec: - name: authentik-server-service port: 9000 tls: - certResolver: letsencrypt + secretName: authentik-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/checkmk/k8s/certificates.yaml b/checkmk/k8s/certificates.yaml new file mode 100644 index 0000000..d9dbf77 --- /dev/null +++ b/checkmk/k8s/certificates.yaml @@ -0,0 +1,12 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: checkmk-prod-tls + namespace: checkmk +spec: + secretName: checkmk-prod-tls + dnsNames: + - cmk.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/checkmk/k8s/ingress.yaml b/checkmk/k8s/ingress.yaml index ed756e4..28f2bbc 100644 --- a/checkmk/k8s/ingress.yaml +++ b/checkmk/k8s/ingress.yaml @@ -16,7 +16,7 @@ spec: - name: checkmk-service port: 5000 tls: - certResolver: letsencrypt + secretName: checkmk-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP diff --git a/converters/k8s/certificates.yaml b/converters/k8s/certificates.yaml new file mode 100644 index 0000000..c23fe42 --- /dev/null +++ b/converters/k8s/certificates.yaml @@ -0,0 +1,26 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: convertx-prod-tls + namespace: converters +spec: + secretName: convertx-prod-tls + dnsNames: + - forust.xyz + - www.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: bentopdf-prod-tls + namespace: converters +spec: + secretName: bentopdf-prod-tls + dnsNames: + - pdf.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/converters/k8s/ingress.yaml b/converters/k8s/ingress.yaml index 1e201af..88e36a5 100644 --- a/converters/k8s/ingress.yaml +++ b/converters/k8s/ingress.yaml @@ -14,7 +14,7 @@ spec: - name: convertx-service port: 3000 tls: - certResolver: letsencrypt + secretName: convertx-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute @@ -47,7 +47,7 @@ spec: - name: bentopdf-service port: 8080 tls: - certResolver: letsencrypt + secretName: bentopdf-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/dockmon/k8s/certificates.yaml b/dockmon/k8s/certificates.yaml new file mode 100644 index 0000000..6d434e1 --- /dev/null +++ b/dockmon/k8s/certificates.yaml @@ -0,0 +1,12 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: dockmon-prod-tls + namespace: dockmon +spec: + secretName: dockmon-prod-tls + dnsNames: + - dockmon.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/dockmon/k8s/ingress.yaml b/dockmon/k8s/ingress.yaml index bbaffeb..bbbd450 100644 --- a/dockmon/k8s/ingress.yaml +++ b/dockmon/k8s/ingress.yaml @@ -26,7 +26,7 @@ spec: port: 443 serversTransport: dockmon-transport tls: - certResolver: letsencrypt + secretName: dockmon-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/downtify/k8s/ingress.yaml b/downtify/k8s/ingress.yaml index 24026ea..25b5cf4 100644 --- a/downtify/k8s/ingress.yaml +++ b/downtify/k8s/ingress.yaml @@ -17,7 +17,7 @@ spec: - name: downtify-service port: 8000 tls: - certResolver: letsencrypt + secretName: downtify-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/gitea/k8s/certificates.yaml b/gitea/k8s/certificates.yaml new file mode 100644 index 0000000..f480d47 --- /dev/null +++ b/gitea/k8s/certificates.yaml @@ -0,0 +1,13 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: gitea-prod-tls + namespace: gitea +spec: + secretName: gitea-prod-tls + dnsNames: + - gcr.forust.xyz + - gitea.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/gitea/k8s/ingress.yaml b/gitea/k8s/ingress.yaml index de80195..28dba3d 100644 --- a/gitea/k8s/ingress.yaml +++ b/gitea/k8s/ingress.yaml @@ -24,7 +24,7 @@ spec: - name: gitea-service port: 3000 tls: - certResolver: letsencrypt + secretName: gitea-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/glance/k8s/certificates.yaml b/glance/k8s/certificates.yaml new file mode 100644 index 0000000..ae0bfb9 --- /dev/null +++ b/glance/k8s/certificates.yaml @@ -0,0 +1,13 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: glance-prod-tls + namespace: glance +spec: + secretName: glance-prod-tls + dnsNames: + - forust.xyz + - www.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/glance/k8s/ingress.yaml b/glance/k8s/ingress.yaml index 2fe4ad0..b84dfb4 100644 --- a/glance/k8s/ingress.yaml +++ b/glance/k8s/ingress.yaml @@ -16,7 +16,7 @@ spec: - name: glance-service port: 8080 tls: - certResolver: letsencrypt + secretName: glance-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/headscale/k8s/routing/certificates.yaml b/headscale/k8s/routing/certificates.yaml new file mode 100644 index 0000000..fb1f60b --- /dev/null +++ b/headscale/k8s/routing/certificates.yaml @@ -0,0 +1,25 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: headscale-prod-tls + namespace: headscale +spec: + secretName: headscale-prod-tls + dnsNames: + - hs.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: headplane-prod-tls + namespace: headscale +spec: + secretName: headplane-prod-tls + dnsNames: + - hp.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/headscale/k8s/routing/ingress.yaml b/headscale/k8s/routing/ingress.yaml index 8aa5534..baad830 100644 --- a/headscale/k8s/routing/ingress.yaml +++ b/headscale/k8s/routing/ingress.yaml @@ -38,7 +38,7 @@ spec: - name: headscale-server-external port: 9090 tls: - certResolver: letsencrypt + secretName: headscale-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute @@ -64,7 +64,7 @@ spec: - name: headplane-external port: 3000 tls: - certResolver: letsencrypt + secretName: headplane-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/homepages/k8s/certificates.yaml b/homepages/k8s/certificates.yaml new file mode 100644 index 0000000..2b64384 --- /dev/null +++ b/homepages/k8s/certificates.yaml @@ -0,0 +1,26 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: forust-homepage-prod-tls + namespace: homepages +spec: + secretName: forust-homepage-prod-tls + dnsNames: + - forust.xyz + - www.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: xdfnx-homepage-prod-tls + namespace: homepages +spec: + secretName: xdfnx-homepage-prod-tls + dnsNames: + - xdfnx.cfd + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/homepages/k8s/ingress.yaml b/homepages/k8s/ingress.yaml index 72fca1d..11e989b 100644 --- a/homepages/k8s/ingress.yaml +++ b/homepages/k8s/ingress.yaml @@ -17,7 +17,7 @@ spec: - name: forust-homepage-service port: 80 tls: - certResolver: letsencrypt + secretName: forust-homepage-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute @@ -53,7 +53,7 @@ spec: - name: xdfnx-homepage-service port: 80 tls: - certResolver: letsencrypt + secretName: xdfnx-homepage-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/kener/k8s/ingress.yaml b/kener/k8s/ingress.yaml index 01cfdef..56b0fb8 100644 --- a/kener/k8s/ingress.yaml +++ b/kener/k8s/ingress.yaml @@ -16,7 +16,7 @@ spec: - name: kener-service port: 3000 tls: - certResolver: letsencrypt + secretName: kener-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/metube/k8s/certificates.yaml b/metube/k8s/certificates.yaml new file mode 100644 index 0000000..3a9fe04 --- /dev/null +++ b/metube/k8s/certificates.yaml @@ -0,0 +1,12 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: metube-prod-tls + namespace: metube +spec: + secretName: metube-prod-tls + dnsNames: + - metube.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/metube/k8s/ingress.yaml b/metube/k8s/ingress.yaml index ffd0ac0..455c26d 100644 --- a/metube/k8s/ingress.yaml +++ b/metube/k8s/ingress.yaml @@ -15,7 +15,7 @@ spec: - name: metube-service port: 8081 tls: - certResolver: letsencrypt + secretName: metube-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/netronome/k8s/certificates.yaml b/netronome/k8s/certificates.yaml new file mode 100644 index 0000000..9c75d31 --- /dev/null +++ b/netronome/k8s/certificates.yaml @@ -0,0 +1,12 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: netronome-prod-tls + namespace: netronome +spec: + secretName: netronome-prod-tls + dnsNames: + - nm.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/netronome/k8s/ingress.yaml b/netronome/k8s/ingress.yaml index 9382ff4..ca8128c 100644 --- a/netronome/k8s/ingress.yaml +++ b/netronome/k8s/ingress.yaml @@ -16,7 +16,7 @@ spec: - name: netronome-service port: 7575 tls: - certResolver: letsencrypt + secretName: netronome-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/nextcloud/k8s/routing/certificates.yaml b/nextcloud/k8s/routing/certificates.yaml new file mode 100644 index 0000000..535ee50 --- /dev/null +++ b/nextcloud/k8s/routing/certificates.yaml @@ -0,0 +1,12 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: nextcloud-prod-tls + namespace: nextcloud +spec: + secretName: nextcloud-prod-tls + dnsNames: + - nextcloud.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/nextcloud/k8s/routing/ingress.yaml b/nextcloud/k8s/routing/ingress.yaml index 1f5c78f..1f4dbf0 100644 --- a/nextcloud/k8s/routing/ingress.yaml +++ b/nextcloud/k8s/routing/ingress.yaml @@ -18,7 +18,7 @@ spec: - name: nextcloud-apache port: 11000 tls: - certResolver: letsencrypt + secretName: nextcloud-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/portainer/k8s/certificates.yaml b/portainer/k8s/certificates.yaml new file mode 100644 index 0000000..a7f4418 --- /dev/null +++ b/portainer/k8s/certificates.yaml @@ -0,0 +1,12 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: portainer-prod-tls + namespace: portainer +spec: + secretName: portainer-prod-tls + dnsNames: + - portainer.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/portainer/k8s/ingress.yaml b/portainer/k8s/ingress.yaml index c928c2d..e0bd5d9 100644 --- a/portainer/k8s/ingress.yaml +++ b/portainer/k8s/ingress.yaml @@ -16,7 +16,7 @@ spec: - name: portainer-service port: 9000 tls: - certResolver: letsencrypt + secretName: portainer-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/prometheus-stack/k8s/certificates.yaml b/prometheus-stack/k8s/certificates.yaml new file mode 100644 index 0000000..e90f19d --- /dev/null +++ b/prometheus-stack/k8s/certificates.yaml @@ -0,0 +1,12 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: grafana-prod-tls + namespace: prometheus +spec: + secretName: grafana-prod-tls + dnsNames: + - grafana.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/prometheus-stack/k8s/ingress.yaml b/prometheus-stack/k8s/ingress.yaml index 1c7b3cf..8d712c4 100644 --- a/prometheus-stack/k8s/ingress.yaml +++ b/prometheus-stack/k8s/ingress.yaml @@ -16,9 +16,7 @@ spec: - name: prometheus-stack-grafana port: 80 tls: - certResolver: letsencrypt - domains: - - main: grafana.forust.xyz + secretName: grafana-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/searxng/k8s/certificates.yaml b/searxng/k8s/certificates.yaml new file mode 100644 index 0000000..eef650a --- /dev/null +++ b/searxng/k8s/certificates.yaml @@ -0,0 +1,13 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: searxng-prod-tls + namespace: searxng +spec: + secretName: searxng-prod-tls + dnsNames: + - s.forust.xyz + - search.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/searxng/k8s/ingress.yaml b/searxng/k8s/ingress.yaml index faa7a46..db223f1 100644 --- a/searxng/k8s/ingress.yaml +++ b/searxng/k8s/ingress.yaml @@ -16,7 +16,7 @@ spec: - name: searxng-service port: 8080 tls: - certResolver: letsencrypt + secretName: searxng-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/termix/k8s/certificates.yaml b/termix/k8s/certificates.yaml new file mode 100644 index 0000000..c1b4afe --- /dev/null +++ b/termix/k8s/certificates.yaml @@ -0,0 +1,12 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: termix-prod-tls + namespace: termix +spec: + secretName: termix-prod-tls + dnsNames: + - termix.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/termix/k8s/ingress.yaml b/termix/k8s/ingress.yaml index 4104519..bfbbfa8 100644 --- a/termix/k8s/ingress.yaml +++ b/termix/k8s/ingress.yaml @@ -16,7 +16,7 @@ spec: - name: termix-service port: 8080 tls: - certResolver: letsencrypt + secretName: termix-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/traefik/k8s/certificates.yaml b/traefik/k8s/certificates.yaml new file mode 100644 index 0000000..d1f5c71 --- /dev/null +++ b/traefik/k8s/certificates.yaml @@ -0,0 +1,12 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: dashboard-prod-tls + namespace: traefik +spec: + secretName: dashboard-prod-tls + dnsNames: + - traefik.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/traefik/k8s/ingress.yaml b/traefik/k8s/ingress.yaml index b4c6594..83b4717 100644 --- a/traefik/k8s/ingress.yaml +++ b/traefik/k8s/ingress.yaml @@ -17,7 +17,7 @@ spec: - name: api@internal kind: TraefikService tls: - certResolver: letsencrypt + secretName: dashboard-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/traefik/k8s/traefik-values.yaml b/traefik/k8s/traefik-values.yaml index 8fc0f8a..bdadaf5 100644 --- a/traefik/k8s/traefik-values.yaml +++ b/traefik/k8s/traefik-values.yaml @@ -121,14 +121,11 @@ persistence: size: 100Mi path: /data -certificatesResolvers: - letsencrypt: - acme: - email: bobrovod@national.shitposting.agency - storage: /data/letsencrypt/acme.json - caServer: https://acme-v02.api.letsencrypt.org/directory - httpChallenge: - entryPoint: web +# NOTE: no certificatesResolvers — public TLS is issued by cert-manager +# (see cert-manager/k8s/clusterissuer.yaml and per-service certificates.yaml). +# Traefik must not run its own ACME httpChallenge: its internal +# acme-http@internal router hijacks /.well-known/acme-challenge/ for every +# host and breaks external HTTP-01 solvers. volumes: - name: traefik-dynamic diff --git a/uptime-kuma/k8s/certificates.yaml b/uptime-kuma/k8s/certificates.yaml new file mode 100644 index 0000000..be2767d --- /dev/null +++ b/uptime-kuma/k8s/certificates.yaml @@ -0,0 +1,12 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: uptime-kuma-prod-tls + namespace: uptime-kuma +spec: + secretName: uptime-kuma-prod-tls + dnsNames: + - uptime.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/uptime-kuma/k8s/ingress.yaml b/uptime-kuma/k8s/ingress.yaml index fc5cc5c..c730da2 100644 --- a/uptime-kuma/k8s/ingress.yaml +++ b/uptime-kuma/k8s/ingress.yaml @@ -16,7 +16,7 @@ spec: - name: uptime-kuma-service port: 3001 tls: - certResolver: letsencrypt + secretName: uptime-kuma-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/vaultwarden/k8s/certificates.yaml b/vaultwarden/k8s/certificates.yaml new file mode 100644 index 0000000..b5a2119 --- /dev/null +++ b/vaultwarden/k8s/certificates.yaml @@ -0,0 +1,12 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: vaultwarden-prod-tls + namespace: vaultwarden +spec: + secretName: vaultwarden-prod-tls + dnsNames: + - vw.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/vaultwarden/k8s/ingress.yaml b/vaultwarden/k8s/ingress.yaml index 2133f6a..24c74e0 100644 --- a/vaultwarden/k8s/ingress.yaml +++ b/vaultwarden/k8s/ingress.yaml @@ -13,7 +13,7 @@ spec: - name: vaultwarden-service port: 80 tls: - certResolver: letsencrypt + secretName: vaultwarden-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/vpn/xui/k8s/certificates.yaml b/vpn/xui/k8s/certificates.yaml new file mode 100644 index 0000000..ec4bbe0 --- /dev/null +++ b/vpn/xui/k8s/certificates.yaml @@ -0,0 +1,12 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: xray-prod-tls + namespace: xui +spec: + secretName: xray-prod-tls + dnsNames: + - xray.forust.xyz + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/vpn/xui/k8s/ingress.yaml b/vpn/xui/k8s/ingress.yaml index a660489..f3b916e 100644 --- a/vpn/xui/k8s/ingress.yaml +++ b/vpn/xui/k8s/ingress.yaml @@ -58,7 +58,7 @@ spec: - name: xui-service port: 10000 tls: - certResolver: letsencrypt + secretName: xray-prod-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute