diff --git a/infrastructure/production/fleet/cert-manager/mail-certificate.yaml b/infrastructure/production/fleet/cert-manager/mail-certificate.yaml new file mode 100644 index 0000000..fd5bf7a --- /dev/null +++ b/infrastructure/production/fleet/cert-manager/mail-certificate.yaml @@ -0,0 +1,29 @@ +# TLS for mail.dezky.eu — issued in-cluster by cert-manager, consumed on the +# HOST by Stalwart: stalwart-cert-sync.timer (host/stalwart/cert-sync.sh) +# copies the mail/mail-tls secret to /opt/stalwart/etc/tls every 12h and +# reloads Stalwart when it changes. Until this Certificate is Ready, Stalwart +# serves the self-signed bootstrap cert and mail clients refuse the TLS +# handshake ("cannot verify account name or password" in Apple Mail). +# +# HTTP-01 works because Traefik owns :80 on the node and cert-manager's +# solver ingress answers /.well-known/acme-challenge for any Host. +# +# Apply by hand with the rest of the cert-manager layer (see RUNBOOK): +# kubectl apply -f mail-certificate.yaml +apiVersion: v1 +kind: Namespace +metadata: + name: mail +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: mail-dezky-eu + namespace: mail +spec: + secretName: mail-tls + dnsNames: + - mail.dezky.eu + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer diff --git a/infrastructure/production/host/stalwart/cert-sync.sh b/infrastructure/production/host/stalwart/cert-sync.sh index 8290a2a..a342c2f 100755 --- a/infrastructure/production/host/stalwart/cert-sync.sh +++ b/infrastructure/production/host/stalwart/cert-sync.sh @@ -7,6 +7,14 @@ # # Run by stalwart-cert-sync.timer (every 12h + on boot). Safe to run by hand. # +# v0.16 NOTE: Stalwart no longer reads TLS files directly from config.toml. +# A one-time x:Certificate object (management JMAP) points at these paths +# with the File variant: +# {"certificate":{"@type":"File","filePath":"/opt/stalwart/etc/tls/cert.pem"}, +# "privateKey":{"@type":"File","filePath":"/opt/stalwart/etc/tls/key.pem"}} +# Created 2026-06-10. With that in place this script's file update + reload +# keeps working for renewals exactly as designed. +# # Forward dependency: needs the fleet layer to have created the TLS secret # (default: namespace 'mail', secret 'mail-tls'). Until then this is a no-op and # Stalwart keeps using the self-signed bootstrap cert from install.sh.