Phase 5: full outbound Postfix relay (465/587 SASL+TLS, sender binding, milters)
Generate the relay config from the environment at container start (build/postfix-config.sh, run from entrypoint.sh): - smtps 465 (implicit TLS) primary + optional submission 587 (STARTTLS), chroot=n so smtpd reaches the sasldb2/sender map under /data. - Cyrus SASL against the panel-maintained sasldb2; realm left implicit so the authenticated name equals the bare login in smtpd_sender_login_maps. - reject_sender_login_mismatch + relay/recipient restrictions with no permit_mynetworks: credentials-only, open relay impossible (spec 5, 5.1). - TLS cert/key from TLS_CERT_FILE/TLS_KEY_FILE; daily postfix reload picks up renewed certs (postfix-cert-reload.sh under supervisord, spec 5.2). - anvil level-1 rate limit from env (spec 5 p.5). - Milter chain with per-milter action: OpenDKIM strict (tempfail), journal fail-open (accept) so monitoring never blocks the relay (spec 7.3). Two integration fixes found on the server: - postconf -F '*/*/chroot=n': Debian's chrooted delivery agent can't read /etc/resolv.conf, so MX lookups failed and mail never left. - entrypoint sets /run/opendkim and /run/selfpost to group selfpost + setgid, and the journal stub chmods its socket 0660, so postfix can connect to both milter sockets (strict OpenDKIM was milter-rejecting all mail otherwise). Verified on selfpost.mixfed.ru: gofmt/vet/test green, image builds; container e2e — 465 auth+send DKIM-signed (d=domain,s=selfpost), 587 STARTTLS auth, cross-domain sender 553, list-mode per-address binding, unauth relay 554, real outbound delivery reaching the recipient MX over TLS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
# Periodic `postfix reload` so refreshed TLS certificates are picked up (spec
|
||||
# 5.2 p.4). The reverse-proxy renews the PEM files in the read-only mount every
|
||||
# few months; Postfix only re-reads them on reload. A simple daily reload is
|
||||
# more than enough (a day of staleness is harmless) and far simpler than an
|
||||
# inotify watcher — the spec explicitly prefers this.
|
||||
#
|
||||
# Runs under supervisord as root, so it can reload Postfix directly. It sleeps
|
||||
# first, then reloads in a loop: no reload at container start (the wrapper is
|
||||
# still bringing Postfix up then) and none until at least one interval has
|
||||
# passed. A reload is harmless when nothing changed.
|
||||
set -eu
|
||||
|
||||
INTERVAL="${TLS_RELOAD_INTERVAL_SECONDS:-86400}"
|
||||
|
||||
while true; do
|
||||
sleep "${INTERVAL}"
|
||||
if postfix reload; then
|
||||
echo "cert-reload: postfix reloaded (periodic TLS refresh)"
|
||||
else
|
||||
# Never exit non-zero: a transient reload failure must not trip the
|
||||
# crashexit listener and take the container down. Log and retry next cycle.
|
||||
echo "cert-reload: postfix reload failed, will retry after ${INTERVAL}s" >&2
|
||||
fi
|
||||
done
|
||||
Reference in New Issue
Block a user