cluster

Infrastructure files for Nordgedanken and Midnightthoughts.
git clone git://archive.git.mtrnord.blog/MTRNord/cluster.git
Log | Files | Refs | README

commit c48b88a8d39d5d7499d792b11e84061c5b9a4d6f
parent 3db6bebbf8ef01fc9a5f96290b4d45d6139be8b0
Author: MTRNord <MTRNord@users.noreply.github.com>
Date:   Mon, 23 Mar 2026 20:34:50 +0100

switch to stalwart

Signed-off-by: MTRNord <MTRNord@users.noreply.github.com>

Diffstat:
Mapps/talos_cluster/mailserver/routing.yaml | 221++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mapps/talos_cluster/stalwart/kustomization.yaml | 1+
Mapps/talos_cluster/stalwart/release.yaml | 7+++++++
Aapps/talos_cluster/stalwart/routing.yaml | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mapps/talos_cluster/stalwart/secret.yaml | 56++++++++++++++++++++++++++++----------------------------
5 files changed, 256 insertions(+), 138 deletions(-)

diff --git a/apps/talos_cluster/mailserver/routing.yaml b/apps/talos_cluster/mailserver/routing.yaml @@ -1,113 +1,114 @@ -apiVersion: gateway.networking.k8s.io/v1alpha2 -kind: TCPRoute -metadata: - name: mailserver-smtp - namespace: mailserver - annotations: - external-dns.alpha.kubernetes.io/hostname: mail.midnightthoughts.space -spec: - parentRefs: - - name: email-gateway - namespace: envoy-gateway - sectionName: smtp - rules: - - backendRefs: - - name: mailserver-docker-mailserver - port: 12525 ---- -apiVersion: gateway.networking.k8s.io/v1alpha2 -kind: TCPRoute -metadata: - name: mailserver-submissions - namespace: mailserver - annotations: - external-dns.alpha.kubernetes.io/hostname: mail.midnightthoughts.space -spec: - parentRefs: - - name: email-gateway - namespace: envoy-gateway - sectionName: submissions - rules: - - backendRefs: - - name: mailserver-docker-mailserver - port: 10465 ---- -apiVersion: gateway.networking.k8s.io/v1alpha2 -kind: TCPRoute -metadata: - name: mailserver-submission - namespace: mailserver - annotations: - external-dns.alpha.kubernetes.io/hostname: mail.midnightthoughts.space -spec: - parentRefs: - - name: email-gateway - namespace: envoy-gateway - sectionName: submission - rules: - - backendRefs: - - name: mailserver-docker-mailserver - port: 10587 ---- -apiVersion: gateway.networking.k8s.io/v1alpha2 -kind: TCPRoute -metadata: - name: mailserver-imap - namespace: mailserver - annotations: - external-dns.alpha.kubernetes.io/hostname: mail.midnightthoughts.space -spec: - parentRefs: - - name: email-gateway - namespace: envoy-gateway - sectionName: imap - rules: - - backendRefs: - - name: mailserver-docker-mailserver - port: 10143 ---- -apiVersion: gateway.networking.k8s.io/v1alpha2 -kind: TCPRoute -metadata: - name: mailserver-imaps - namespace: mailserver - annotations: - external-dns.alpha.kubernetes.io/hostname: mail.midnightthoughts.space -spec: - parentRefs: - - name: email-gateway - namespace: envoy-gateway - sectionName: imaps - rules: - - backendRefs: - - name: mailserver-docker-mailserver - port: 10993 ---- -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: mail-policy - namespace: mailserver -spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: TCPRoute - name: mailserver-imaps - - group: gateway.networking.k8s.io - kind: TCPRoute - name: mailserver-imap - - group: gateway.networking.k8s.io - kind: TCPRoute - name: mailserver-submission - - group: gateway.networking.k8s.io - kind: TCPRoute - name: mailserver-submissions - - group: gateway.networking.k8s.io - kind: TCPRoute - name: mailserver-smtp - proxyProtocol: - version: "V2" ---- +# --- docker-mailserver TCP routes (commented out after Stalwart cutover; uncomment to roll back) --- +# apiVersion: gateway.networking.k8s.io/v1alpha2 +# kind: TCPRoute +# metadata: +# name: mailserver-smtp +# namespace: mailserver +# annotations: +# external-dns.alpha.kubernetes.io/hostname: mail.midnightthoughts.space +# spec: +# parentRefs: +# - name: email-gateway +# namespace: envoy-gateway +# sectionName: smtp +# rules: +# - backendRefs: +# - name: mailserver-docker-mailserver +# port: 12525 +# --- +# apiVersion: gateway.networking.k8s.io/v1alpha2 +# kind: TCPRoute +# metadata: +# name: mailserver-submissions +# namespace: mailserver +# annotations: +# external-dns.alpha.kubernetes.io/hostname: mail.midnightthoughts.space +# spec: +# parentRefs: +# - name: email-gateway +# namespace: envoy-gateway +# sectionName: submissions +# rules: +# - backendRefs: +# - name: mailserver-docker-mailserver +# port: 10465 +# --- +# apiVersion: gateway.networking.k8s.io/v1alpha2 +# kind: TCPRoute +# metadata: +# name: mailserver-submission +# namespace: mailserver +# annotations: +# external-dns.alpha.kubernetes.io/hostname: mail.midnightthoughts.space +# spec: +# parentRefs: +# - name: email-gateway +# namespace: envoy-gateway +# sectionName: submission +# rules: +# - backendRefs: +# - name: mailserver-docker-mailserver +# port: 10587 +# --- +# apiVersion: gateway.networking.k8s.io/v1alpha2 +# kind: TCPRoute +# metadata: +# name: mailserver-imap +# namespace: mailserver +# annotations: +# external-dns.alpha.kubernetes.io/hostname: mail.midnightthoughts.space +# spec: +# parentRefs: +# - name: email-gateway +# namespace: envoy-gateway +# sectionName: imap +# rules: +# - backendRefs: +# - name: mailserver-docker-mailserver +# port: 10143 +# --- +# apiVersion: gateway.networking.k8s.io/v1alpha2 +# kind: TCPRoute +# metadata: +# name: mailserver-imaps +# namespace: mailserver +# annotations: +# external-dns.alpha.kubernetes.io/hostname: mail.midnightthoughts.space +# spec: +# parentRefs: +# - name: email-gateway +# namespace: envoy-gateway +# sectionName: imaps +# rules: +# - backendRefs: +# - name: mailserver-docker-mailserver +# port: 10993 +# --- +# apiVersion: gateway.envoyproxy.io/v1alpha1 +# kind: BackendTrafficPolicy +# metadata: +# name: mail-policy +# namespace: mailserver +# spec: +# targetRefs: +# - group: gateway.networking.k8s.io +# kind: TCPRoute +# name: mailserver-imaps +# - group: gateway.networking.k8s.io +# kind: TCPRoute +# name: mailserver-imap +# - group: gateway.networking.k8s.io +# kind: TCPRoute +# name: mailserver-submission +# - group: gateway.networking.k8s.io +# kind: TCPRoute +# name: mailserver-submissions +# - group: gateway.networking.k8s.io +# kind: TCPRoute +# name: mailserver-smtp +# proxyProtocol: +# version: "V2" +# --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: diff --git a/apps/talos_cluster/stalwart/kustomization.yaml b/apps/talos_cluster/stalwart/kustomization.yaml @@ -6,3 +6,4 @@ resources: - release.yaml - secret.yaml - ingress.yaml + - routing.yaml diff --git a/apps/talos_cluster/stalwart/release.yaml b/apps/talos_cluster/stalwart/release.yaml @@ -237,8 +237,15 @@ spec: tls: implicit: false allow-invalid-certs: true + mailman-lmtp: + type: relay + address: mailman.mailserver.svc.cluster.local + port: 8024 + protocol: lmtp strategy: route: + - if: "rcpt_domain == 'lists.midnightthoughts.space'" + then: "'mailman-lmtp'" - if: "rcpt_domain == 'phorge.mtrnord.blog'" then: "'phorge-relay'" - else: "'mx'" diff --git a/apps/talos_cluster/stalwart/routing.yaml b/apps/talos_cluster/stalwart/routing.yaml @@ -0,0 +1,109 @@ +apiVersion: gateway.networking.k8s.io/v1alpha2 +kind: TCPRoute +metadata: + name: stalwart-smtp + namespace: stalwart + annotations: + external-dns.alpha.kubernetes.io/hostname: mail.midnightthoughts.space +spec: + parentRefs: + - name: email-gateway + namespace: envoy-gateway + sectionName: smtp + rules: + - backendRefs: + - name: stalwart-mail + port: 25 +--- +apiVersion: gateway.networking.k8s.io/v1alpha2 +kind: TCPRoute +metadata: + name: stalwart-submissions + namespace: stalwart + annotations: + external-dns.alpha.kubernetes.io/hostname: mail.midnightthoughts.space +spec: + parentRefs: + - name: email-gateway + namespace: envoy-gateway + sectionName: submissions + rules: + - backendRefs: + - name: stalwart-mail + port: 465 +--- +apiVersion: gateway.networking.k8s.io/v1alpha2 +kind: TCPRoute +metadata: + name: stalwart-submission + namespace: stalwart + annotations: + external-dns.alpha.kubernetes.io/hostname: mail.midnightthoughts.space +spec: + parentRefs: + - name: email-gateway + namespace: envoy-gateway + sectionName: submission + rules: + - backendRefs: + - name: stalwart-mail + port: 587 +--- +apiVersion: gateway.networking.k8s.io/v1alpha2 +kind: TCPRoute +metadata: + name: stalwart-imap + namespace: stalwart + annotations: + external-dns.alpha.kubernetes.io/hostname: mail.midnightthoughts.space +spec: + parentRefs: + - name: email-gateway + namespace: envoy-gateway + sectionName: imap + rules: + - backendRefs: + - name: stalwart-mail + port: 143 +--- +apiVersion: gateway.networking.k8s.io/v1alpha2 +kind: TCPRoute +metadata: + name: stalwart-imaps + namespace: stalwart + annotations: + external-dns.alpha.kubernetes.io/hostname: mail.midnightthoughts.space +spec: + parentRefs: + - name: email-gateway + namespace: envoy-gateway + sectionName: imaps + rules: + - backendRefs: + - name: stalwart-mail + port: 993 +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: BackendTrafficPolicy +metadata: + name: stalwart-mail-policy + namespace: stalwart +spec: + targetRefs: + - group: gateway.networking.k8s.io + kind: TCPRoute + name: stalwart-smtp + - group: gateway.networking.k8s.io + kind: TCPRoute + name: stalwart-submissions + - group: gateway.networking.k8s.io + kind: TCPRoute + name: stalwart-submission + - group: gateway.networking.k8s.io + kind: TCPRoute + name: stalwart-imap + - group: gateway.networking.k8s.io + kind: TCPRoute + name: stalwart-imaps + proxyProtocol: + version: "V2" diff --git a/apps/talos_cluster/stalwart/secret.yaml b/apps/talos_cluster/stalwart/secret.yaml @@ -1,34 +1,34 @@ apiVersion: v1 kind: Secret metadata: - name: stalwart-secret - namespace: stalwart + name: stalwart-secret + namespace: stalwart type: Opaque stringData: - pg-user: ENC[AES256_GCM,data:2M2yBdjpFII=,iv:ixB2FyyZ28MK+EdpG2FWvlVTauy4XexeAkkMlrHyR2U=,tag:grgnCldASwOyfsagds7Gdg==,type:str] - pg-password: ENC[AES256_GCM,data:UJJQDB9C/1wZWG6bUb+72to/98IJb+EqevKnwaGfqaw70ZCTEJecrM+qzZpp0XTR1FflKqWc2kbsPEn2AEp3,iv:tUwiB50qe+3h6pVvqgc99pABS/6X6f882fzU4Q1lGyM=,tag:+nXaej6dkCsA0Hp2A8WLpQ==,type:str] - s3-access-key: ENC[AES256_GCM,data:cBUdiQixXubz6NfEt6HZ15GlYSs=,iv:TKfZRXizjGCQvSETs+kjciaPIbKmL7kxHi+UUadU+Qk=,tag:ZD4cjJOsp73EuKylmrXkGg==,type:str] - s3-secret-key: ENC[AES256_GCM,data:cwJtv65kgiKdq+qm1QJkjFlZ4xLsQQmAt24NsNqXnQHJz0N4xmQZWw==,iv:7Va/MdKN97W6zEBd9G9Gu1pPThWRyMJJOHfPbL0C0/c=,tag:XCMHXq28SLpxgowMitH+oA==,type:str] - ldap-bind-password: ENC[AES256_GCM,data:VNJjJPbDAv5MxaHe4I+RplmX8wPX9AjscPaKKGst5qhVq7+kPV5UinYGNfxSAocFYzwKvv7YNb/s1pF1E9y+,iv:KoItQlnlqR4poFXr4sr5UU4PVApxmShS0JpUZWazPdM=,tag:sGFbAoIA0L136Q0IKxvidw==,type:str] - admin-password: ENC[AES256_GCM,data:X4/ZCinPTvkp,iv:jO8RFUs07EaxL5B80TO+VCDheIotkvSK9OqrgZrp84Y=,tag:bDCuHqaQdKTuOSFFmAewYQ==,type:str] - metrics-password: ENC[AES256_GCM,data:tIcFtJ6mZENWXUYSltwF2BWfoKXugoPpV+JyeiKXLFQ2x7YYbkyHChrCiEVEPMB6frOgk7JCA0XPo9abB/e/,iv:iEeH3+khjpWf7zB2xxsYv8uqKLYZC339EPlKgRReJ0g=,tag:XZXc9vajrZIsAqEjXS0d9Q==,type:str] + pg-user: ENC[AES256_GCM,data:2M2yBdjpFII=,iv:ixB2FyyZ28MK+EdpG2FWvlVTauy4XexeAkkMlrHyR2U=,tag:grgnCldASwOyfsagds7Gdg==,type:str] + pg-password: ENC[AES256_GCM,data:UJJQDB9C/1wZWG6bUb+72to/98IJb+EqevKnwaGfqaw70ZCTEJecrM+qzZpp0XTR1FflKqWc2kbsPEn2AEp3,iv:tUwiB50qe+3h6pVvqgc99pABS/6X6f882fzU4Q1lGyM=,tag:+nXaej6dkCsA0Hp2A8WLpQ==,type:str] + s3-access-key: ENC[AES256_GCM,data:cBUdiQixXubz6NfEt6HZ15GlYSs=,iv:TKfZRXizjGCQvSETs+kjciaPIbKmL7kxHi+UUadU+Qk=,tag:ZD4cjJOsp73EuKylmrXkGg==,type:str] + s3-secret-key: ENC[AES256_GCM,data:cwJtv65kgiKdq+qm1QJkjFlZ4xLsQQmAt24NsNqXnQHJz0N4xmQZWw==,iv:7Va/MdKN97W6zEBd9G9Gu1pPThWRyMJJOHfPbL0C0/c=,tag:XCMHXq28SLpxgowMitH+oA==,type:str] + ldap-bind-password: ENC[AES256_GCM,data:VNJjJPbDAv5MxaHe4I+RplmX8wPX9AjscPaKKGst5qhVq7+kPV5UinYGNfxSAocFYzwKvv7YNb/s1pF1E9y+,iv:KoItQlnlqR4poFXr4sr5UU4PVApxmShS0JpUZWazPdM=,tag:sGFbAoIA0L136Q0IKxvidw==,type:str] + admin-password: ENC[AES256_GCM,data:X4/ZCinPTvkp,iv:jO8RFUs07EaxL5B80TO+VCDheIotkvSK9OqrgZrp84Y=,tag:bDCuHqaQdKTuOSFFmAewYQ==,type:str] + metrics-password: ENC[AES256_GCM,data:tIcFtJ6mZENWXUYSltwF2BWfoKXugoPpV+JyeiKXLFQ2x7YYbkyHChrCiEVEPMB6frOgk7JCA0XPo9abB/e/,iv:iEeH3+khjpWf7zB2xxsYv8uqKLYZC339EPlKgRReJ0g=,tag:XZXc9vajrZIsAqEjXS0d9Q==,type:str] sops: - kms: [] - gcp_kms: [] - azure_kv: [] - hc_vault: [] - age: - - recipient: age1esjyg2qfy49awv0ptkzvpk425adczjr38m37w2mmcahzc4p8n54sll2nzh - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuc3Y0OEpEVDFqdWE4QmRw - eDhMckNITmlQUWlKRHFxczBsdHgzMW5ydTEwCmNJRVhNODE0dVZzZThGUDVKWlp4 - SHVmSEF5TG9Hb1dtc0ladmx0M3BpRGMKLS0tIHBGUkM5Ri9QWFVTeXRhV3N3cGp2 - WGgwdjM0R3ZmUFBkVklCRENuMXZXMEkKMUC9tg/123WhsdCiB5gq/W1LIYPiXo8m - wwrag1l8VsHDhF8TpKSC0v3/5XY/OomZAUVz03+9kCBIERGTsR24SA== - -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-03-23T14:10:33Z" - mac: ENC[AES256_GCM,data:lxWrl7B78axl0rZ/dN9Ioxb4Hy1P6+LmreCmA5305mPUF56nmRFhs0yVH4gEoAoOAa52Nrx3Mzg7QBEE0XrY9Pit8tK5MMxIHqntTmq+7s2BGdvEDg5+vwF+DmkdXfNpAB0TFdLm2W6cjWMeVYo6k++f543C87/Fw81K2A/HEv0=,iv:HkndtOUxrxflkSzqC1QcPR4QWS6vg5spYiy2Vprz3FM=,tag:OmsRhWzxxRfUDsd1aJYgtw==,type:str] - pgp: [] - encrypted_regex: ^(apiKey|appUserPassword|otelUserPassword|harborAdminPassword|totpVaultKey|kimaiAppSecret|kimaiAdminPassword|GITHUB_CLIENT_ID|GITHUB_CLIENT_SECRET|GITHUB_PRIVATE_KEY|woosh|root_password|rspamd_password|pgdb_password|matrix_access_token|pgdb_remote_url|hmac_secret_key|adminPassword|adminEmail|jenkinsAdminEmail|securityRealm|gerrit.config|routing_key|DATABASE_URL|SMTP_PASSWORD|SECRET_KEY_BASE|admin_password|extraCommands|key|clickhouseDatabaseURL|databaseURL|client_id|client_secret|secret_key_base|otp_secret|private_key|public_key|primaryKey|deterministicKey|keyDerivationSalt|token|clientId|secretKey|installationId|installationKey|uriOverride|adminToken.value|password.value|sql_password|erlangCookie|AUTHENTICATION_PASSWORD|ROOM_API_SECRET_KEY|adminPassword|configPassword|adminUser|configUser|MAIL_PASSWORD|APP_KEY|api_key|api_secret|keys|livekit_key|livekit_secret|secret_key|admin_pass|admin_email|mariadbPassword|mariadbRootPassword|privateKey|data|stringData|PASSWD|password|pass|postgresPassword|smtp_auth_password|addresses|smtp_auth_username|authorization_credentials|postgresqlPassword|redminePassword|smtpPassword|registration_shared_secret|shared_secret|secret|admin_token|integrationKey|integration_key|rootPassword|adminPassword|adminUser|adminEmail|emailPassword|secretKey|appId|clientSecret|webhookSecret)$ - version: 3.9.1 + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1esjyg2qfy49awv0ptkzvpk425adczjr38m37w2mmcahzc4p8n54sll2nzh + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuc3Y0OEpEVDFqdWE4QmRw + eDhMckNITmlQUWlKRHFxczBsdHgzMW5ydTEwCmNJRVhNODE0dVZzZThGUDVKWlp4 + SHVmSEF5TG9Hb1dtc0ladmx0M3BpRGMKLS0tIHBGUkM5Ri9QWFVTeXRhV3N3cGp2 + WGgwdjM0R3ZmUFBkVklCRENuMXZXMEkKMUC9tg/123WhsdCiB5gq/W1LIYPiXo8m + wwrag1l8VsHDhF8TpKSC0v3/5XY/OomZAUVz03+9kCBIERGTsR24SA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-03-23T14:10:33Z" + mac: ENC[AES256_GCM,data:lxWrl7B78axl0rZ/dN9Ioxb4Hy1P6+LmreCmA5305mPUF56nmRFhs0yVH4gEoAoOAa52Nrx3Mzg7QBEE0XrY9Pit8tK5MMxIHqntTmq+7s2BGdvEDg5+vwF+DmkdXfNpAB0TFdLm2W6cjWMeVYo6k++f543C87/Fw81K2A/HEv0=,iv:HkndtOUxrxflkSzqC1QcPR4QWS6vg5spYiy2Vprz3FM=,tag:OmsRhWzxxRfUDsd1aJYgtw==,type:str] + pgp: [] + encrypted_regex: ^(apiKey|appUserPassword|otelUserPassword|harborAdminPassword|totpVaultKey|kimaiAppSecret|kimaiAdminPassword|GITHUB_CLIENT_ID|GITHUB_CLIENT_SECRET|GITHUB_PRIVATE_KEY|woosh|root_password|rspamd_password|pgdb_password|matrix_access_token|pgdb_remote_url|hmac_secret_key|adminPassword|adminEmail|jenkinsAdminEmail|securityRealm|gerrit.config|routing_key|DATABASE_URL|SMTP_PASSWORD|SECRET_KEY_BASE|admin_password|extraCommands|key|clickhouseDatabaseURL|databaseURL|client_id|client_secret|secret_key_base|otp_secret|private_key|public_key|primaryKey|deterministicKey|keyDerivationSalt|token|clientId|secretKey|installationId|installationKey|uriOverride|adminToken.value|password.value|sql_password|erlangCookie|AUTHENTICATION_PASSWORD|ROOM_API_SECRET_KEY|adminPassword|configPassword|adminUser|configUser|MAIL_PASSWORD|APP_KEY|api_key|api_secret|keys|livekit_key|livekit_secret|secret_key|admin_pass|admin_email|mariadbPassword|mariadbRootPassword|privateKey|data|stringData|PASSWD|password|pass|postgresPassword|smtp_auth_password|addresses|smtp_auth_username|authorization_credentials|postgresqlPassword|redminePassword|smtpPassword|registration_shared_secret|shared_secret|secret|admin_token|integrationKey|integration_key|rootPassword|adminPassword|adminUser|adminEmail|emailPassword|secretKey|appId|clientSecret|webhookSecret)$ + version: 3.9.1