wildduck: fix cert renewal
This commit is contained in:
89
wildduck/cert-reconciler.yaml
Normal file
89
wildduck/cert-reconciler.yaml
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
---
|
||||||
|
# WildDuck and ZoneMTA read the mounted wildduck-tls cert into an in-memory
|
||||||
|
# TLS cache at startup and never re-read it, so after cert-manager renews the
|
||||||
|
# secret, long-lived pods keep serving the boot-time cert until restarted
|
||||||
|
# (IMAP/submission served an expired cert on 2026-07-21). Haraka watches the
|
||||||
|
# cert files and reloads on its own, but is stamped too for a uniform
|
||||||
|
# guarantee.
|
||||||
|
#
|
||||||
|
# This CronJob stamps a hash of the current cert onto the pod templates:
|
||||||
|
# unchanged hash is a no-op (k8s only rolls when the template changes), a
|
||||||
|
# changed cert triggers a rollout. Idempotent and self-healing.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: wildduck-cert-reconciler
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: Role
|
||||||
|
metadata:
|
||||||
|
name: wildduck-cert-reconciler
|
||||||
|
rules:
|
||||||
|
# Enough to patch the pod template annotation on the mail-server deployments.
|
||||||
|
- apiGroups: ["apps"]
|
||||||
|
resources: ["deployments"]
|
||||||
|
verbs: ["get", "patch"]
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: RoleBinding
|
||||||
|
metadata:
|
||||||
|
name: wildduck-cert-reconciler
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: Role
|
||||||
|
name: wildduck-cert-reconciler
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: wildduck-cert-reconciler
|
||||||
|
namespace: wildduck
|
||||||
|
---
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: CronJob
|
||||||
|
metadata:
|
||||||
|
name: wildduck-cert-reconciler
|
||||||
|
spec:
|
||||||
|
# cert-manager renews ~30 days before expiry; daily is plenty to pick up.
|
||||||
|
schedule: "17 3 * * *"
|
||||||
|
successfulJobsHistoryLimit: 1
|
||||||
|
failedJobsHistoryLimit: 3
|
||||||
|
concurrencyPolicy: Forbid
|
||||||
|
jobTemplate:
|
||||||
|
spec:
|
||||||
|
backoffLimit: 2
|
||||||
|
ttlSecondsAfterFinished: 86400
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
serviceAccountName: wildduck-cert-reconciler
|
||||||
|
restartPolicy: OnFailure
|
||||||
|
containers:
|
||||||
|
- name: reconcile
|
||||||
|
image: mirror.gcr.io/library/alpine:3.19
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -euc
|
||||||
|
- |
|
||||||
|
apk add --no-cache curl >/dev/null
|
||||||
|
CERT_HASH=$(sha256sum /cert/tls.crt | cut -c1-16)
|
||||||
|
echo "Cert content hash: $CERT_HASH"
|
||||||
|
APISERVER=https://kubernetes.default.svc
|
||||||
|
SA=/var/run/secrets/kubernetes.io/serviceaccount
|
||||||
|
KTOKEN=$(cat "$SA/token")
|
||||||
|
for DEP in wildduck zonemta haraka; do
|
||||||
|
curl -fsS --cacert "$SA/ca.crt" \
|
||||||
|
-H "Authorization: Bearer $KTOKEN" \
|
||||||
|
-H "Content-Type: application/strategic-merge-patch+json" \
|
||||||
|
-X PATCH \
|
||||||
|
"$APISERVER/apis/apps/v1/namespaces/wildduck/deployments/$DEP" \
|
||||||
|
--data '{"spec":{"template":{"metadata":{"annotations":{"k-space.ee/wildduck-tls-hash":"'"$CERT_HASH"'"}}}}}' \
|
||||||
|
>/dev/null
|
||||||
|
echo " stamped $DEP (rolls only if hash changed)"
|
||||||
|
done
|
||||||
|
echo "done"
|
||||||
|
volumeMounts:
|
||||||
|
- name: cert
|
||||||
|
mountPath: /cert
|
||||||
|
readOnly: true
|
||||||
|
volumes:
|
||||||
|
- name: cert
|
||||||
|
secret:
|
||||||
|
secretName: wildduck-tls
|
||||||
@@ -4,6 +4,7 @@ kind: Kustomization
|
|||||||
namespace: wildduck
|
namespace: wildduck
|
||||||
|
|
||||||
resources:
|
resources:
|
||||||
|
- ./cert-reconciler.yaml
|
||||||
- ./certificate.yaml
|
- ./certificate.yaml
|
||||||
- ./clamav.yaml
|
- ./clamav.yaml
|
||||||
- ./dns.yaml
|
- ./dns.yaml
|
||||||
|
|||||||
Reference in New Issue
Block a user