Add postfix smarthost to the mail namespace
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/kubeconform Pipeline was successful

This commit is contained in:
2026-10-12 21:33:42 +11:00
parent 47fe9e085a
commit 7501dbca7d
10 changed files with 267 additions and 0 deletions
+16
View File
@@ -6,4 +6,20 @@ resources:
- cnpg_backup.yaml
- cnpg_cluster.yaml
- namespace.yaml
- smarthost-pdb.yaml
- smarthost-service.yaml
- smarthost-statefulset.yaml
- stalwart-blobs-bucket.yaml
configMapGenerator:
- name: smarthost-config
namespace: mail
options:
disableNameSuffixHash: true
files:
- smarthost/main.cf
- smarthost/master.cf
- smarthost/relay_domains
- smarthost/transport
- smarthost/gateways.cidr
- smarthost/milter.cidr
+11
View File
@@ -0,0 +1,11 @@
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: smarthost
namespace: mail
spec:
maxUnavailable: 1
selector:
matchLabels:
app.kubernetes.io/name: smarthost
+39
View File
@@ -0,0 +1,39 @@
---
apiVersion: v1
kind: Service
metadata:
name: smarthost
namespace: mail
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: smarthost
ports:
- name: smtp
port: 25
targetPort: smtp
- name: submission
port: 587
targetPort: submission
---
# Gateways and lab networks; Local keeps client IPs for the postfix CIDR checks.
apiVersion: v1
kind: Service
metadata:
name: smarthost-lb
namespace: mail
annotations:
purelb.io/addresses: 198.18.200.16
purelb.io/service-group: common
spec:
type: LoadBalancer
externalTrafficPolicy: Local
selector:
app.kubernetes.io/name: smarthost
ports:
- name: smtp
port: 25
targetPort: smtp
- name: submission
port: 587
targetPort: submission
+116
View File
@@ -0,0 +1,116 @@
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: smarthost
namespace: mail
annotations:
configmap.reloader.stakater.com/reload: "smarthost-config"
spec:
serviceName: smarthost
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: smarthost
template:
metadata:
labels:
app.kubernetes.io/name: smarthost
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app.kubernetes.io/name: smarthost
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: postfix
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/postfix:0.1.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 25
name: smtp
protocol: TCP
- containerPort: 587
name: submission
protocol: TCP
readinessProbe:
tcpSocket:
port: smtp
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
exec:
command: ["postfix", "status"]
initialDelaySeconds: 30
periodSeconds: 30
# postfix master runs as root and drops to the postfix user per service.
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
add:
- CHOWN
- DAC_OVERRIDE
- FOWNER
- SETUID
- SETGID
- NET_BIND_SERVICE
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
volumeMounts:
- name: spool
mountPath: /var/spool/postfix
- name: tls
mountPath: /etc/postfix/tls
readOnly: true
- name: config
mountPath: /etc/postfix/main.cf
subPath: main.cf
readOnly: true
- name: config
mountPath: /etc/postfix/master.cf
subPath: master.cf
readOnly: true
- name: config
mountPath: /etc/postfix/relay_domains
subPath: relay_domains
readOnly: true
- name: config
mountPath: /etc/postfix/transport
subPath: transport
readOnly: true
- name: config
mountPath: /etc/postfix/gateways.cidr
subPath: gateways.cidr
readOnly: true
- name: config
mountPath: /etc/postfix/milter.cidr
subPath: milter.cidr
readOnly: true
volumes:
- name: config
configMap:
name: smarthost-config
- name: tls
secret:
secretName: wildcard-unkin-net-tls
volumeClaimTemplates:
- metadata:
name: spool
spec:
accessModes: [ReadWriteOnce]
storageClassName: cephrbd-fast-delete
resources:
requests:
storage: 5Gi
+2
View File
@@ -0,0 +1,2 @@
# DMZ gateways (mx1/mx2) over WireGuard.
10.10.12.0/24 OK
+42
View File
@@ -0,0 +1,42 @@
compatibility_level = 3.5
myhostname = smarthost.unkin.net
myorigin = unkin.net
mydestination =
alias_maps =
local_recipient_maps =
inet_interfaces = all
inet_protocols = ipv4
maillog_file = /dev/stdout
message_size_limit = 52428800
# Pod CIDR (Stalwart) plus the lab networks from bind-internal acl-main/acl-common/acl-nomad-jobs.
pod_networks = 10.42.0.0/16
mynetworks = $pod_networks
10.10.12.200/32 198.18.1.10/32
198.18.2.160/27 198.18.2.192/27 198.18.21.160/27 198.18.21.192/27
198.18.13.0/24 198.18.14.0/24 198.18.15.0/24 198.18.16.0/24 198.18.17.0/24 198.18.18.0/24
198.18.19.0/24 198.18.20.0/24 198.18.21.0/24 198.18.22.0/24 198.18.23.0/24
198.18.25.0/24 198.18.26.0/24 198.18.27.0/24 198.18.28.0/24 198.18.29.0/24
198.18.64.0/24 198.18.65.0/24 198.18.66.0/24 198.18.67.0/24 198.18.68.0/24 198.18.69.0/24
relay_domains = texthash:/etc/postfix/relay_domains
transport_maps = texthash:/etc/postfix/transport
relayhost = [mx1.wg.unkin.net]:25
smtp_fallback_relay = [mx2.wg.unkin.net]:25
smtpd_relay_restrictions = permit_mynetworks, reject_unauth_destination
unverified_recipient_reject_code = 550
milter_default_action = tempfail
rspamd_milter = inet:rspamd.mail.svc:11332
# Referenced from master.cf per listener.
inbound_client_restrictions = permit_mynetworks, check_client_access cidr:/etc/postfix/gateways.cidr, reject
inbound_recipient_restrictions = permit_mynetworks, reject_unverified_recipient
submission_client_restrictions = permit_mynetworks, reject
smtpd_tls_security_level = may
smtpd_tls_cert_file = /etc/postfix/tls/tls.crt
smtpd_tls_key_file = /etc/postfix/tls/tls.key
smtpd_tls_received_header = yes
smtp_tls_security_level = may
lmtp_tls_security_level = none
+38
View File
@@ -0,0 +1,38 @@
# inbound-relay: gateways (no milter) and Stalwart's outbound relay (pod CIDR, rspamd milter).
25 inet n - n - - smtpd
-o syslog_name=postfix/inbound-relay
-o mynetworks=$pod_networks
-o smtpd_client_restrictions=$inbound_client_restrictions
-o smtpd_recipient_restrictions=$inbound_recipient_restrictions
-o smtpd_milters=
-o smtpd_milter_maps=cidr:/etc/postfix/milter.cidr
# submission-internal: lab networks and pods, always through rspamd.
587 inet n - n - - smtpd
-o syslog_name=postfix/submission-internal
-o smtpd_client_restrictions=$submission_client_restrictions
-o smtpd_milters=$rspamd_milter
pickup unix n - n 60 1 pickup
cleanup unix n - n - 0 cleanup
qmgr unix n - n 300 1 qmgr
tlsmgr unix - - n 1000? 1 tlsmgr
rewrite unix - - n - - trivial-rewrite
bounce unix - - n - 0 bounce
defer unix - - n - 0 bounce
trace unix - - n - 0 bounce
verify unix - - n - 1 verify
flush unix n - n 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - n - - smtp
relay unix - - n - - smtp
-o syslog_name=postfix/$service_name
showq unix n - n - - showq
error unix - - n - - error
retry unix - - n - - error
discard unix - - n - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - n - - lmtp
anvil unix - - n - 1 anvil
scache unix - - n - 1 scache
postlog unix-dgram n - n - 1 postlogd
+1
View File
@@ -0,0 +1 @@
10.42.0.0/16 inet:rspamd.mail.svc:11332
+1
View File
@@ -0,0 +1 @@
unkin.net OK
+1
View File
@@ -0,0 +1 @@
unkin.net lmtp:[stalwart.mail.svc.cluster.local]:24