feat(postfix): deploy postfix MTA and rspamd spam filter

- postfix namespace with Deployment + HPA (2-6 replicas)
- rspamd Deployment + HPA (2-6 replicas) with milter interface
- postfix configured to relay inbound mail to stalwart via transport maps
- rspamd milter on port 11332 for spam scanning and DKIM signing
- DKIM keys stored in Vault at kubernetes/namespace/postfix/default/dkim-keys
- TLS cert via cert-manager (vault-issuer) for mail.main.unkin.net
- rspamd web UI exposed via Traefik Gateway at rspamd.k8s.syd1.au.unkin.net
- postfix external LoadBalancer service for inbound MX on port 25
- artifactapi: add boky/postfix and rspamd/rspamd to dockerhub cache
This commit is contained in:
2026-05-24 00:43:56 +10:00
parent cbc2c1cb9f
commit 1cf08dd5c1
20 changed files with 514 additions and 0 deletions
@@ -0,0 +1,30 @@
# Relay domains - mail for these domains is forwarded to Stalwart
relay_domains = main.unkin.net unkin.net
# Transport map (texthash: reads plain text without postmap)
transport_maps = texthash:/etc/postfix/transport
# rspamd milter
smtpd_milters = inet:rspamd:11332
non_smtpd_milters = inet:rspamd:11332
milter_default_action = accept
milter_protocol = 6
milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}
# Message size limit (50 MiB)
message_size_limit = 52428800
# TLS for inbound connections
smtpd_tls_cert_file = /etc/postfix/tls/tls.crt
smtpd_tls_key_file = /etc/postfix/tls/tls.key
smtpd_use_tls = yes
smtpd_tls_security_level = may
smtpd_tls_loglevel = 1
# TLS for outbound delivery
smtp_tls_security_level = may
smtp_tls_loglevel = 1
# Queue settings
maximal_queue_lifetime = 5d
bounce_queue_lifetime = 1d
@@ -0,0 +1,2 @@
main.unkin.net smtp:[stalwart.stalwart.svc.cluster.local]:25
unkin.net smtp:[stalwart.stalwart.svc.cluster.local]:25
@@ -0,0 +1,13 @@
enabled = true;
selector = "mail";
domain {
main.unkin.net {
privkey = "/etc/rspamd/dkim/private_key";
selector = "mail";
}
unkin.net {
privkey = "/etc/rspamd/dkim/private_key";
selector = "mail";
}
}
@@ -0,0 +1,2 @@
extended_spam_headers = true;
use = ["x-spam-status", "x-spam-score", "authentication-results"];
@@ -0,0 +1,7 @@
milter = yes;
bind_socket = "*:11332";
upstream "local" {
default = yes;
self_scan = yes;
}