MAS-WP-0005-T11: OpenDKIM+OpenDMARC milters; forged A-R stripped by header_checks

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 252470@bnt-lap001
Assistant-Session: ad628c8f-4be2-4979-94c9-76c7ed6f8241
This commit is contained in:
tegwick 2026-10-18 22:38:43 +02:00
parent 516657bf6a
commit ab3346d187
4 changed files with 69 additions and 5 deletions

View file

@ -2,7 +2,7 @@
# Build from the repo root: docker build -f deploy/railiance/Dockerfile .
FROM debian:bookworm-slim
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
postfix libsasl2-modules python3 python3-jsonschema ssl-cert ca-certificates && rm -rf /var/lib/apt/lists/*
postfix libsasl2-modules opendkim opendmarc publicsuffix python3 python3-jsonschema ssl-cert ca-certificates && rm -rf /var/lib/apt/lists/*
RUN useradd -r -s /usr/sbin/nologin mas
COPY mas_core /app/mas_core
COPY mas_gateway /app/mas_gateway

View file

@ -67,6 +67,47 @@ if [ -n "$MAS_RELAY" ] && [ -s /etc/mas-relay/username ]; then
else
postconf -e "default_transport=error:5.7.1 outbound mail disabled"
fi
# Sender authentication (spec 14 item 10). The MTA does SPF/DKIM/DMARC, since
# they need DNS; the gateway only reads Authentication-Results carrying our
# authserv-id. Postfix header_checks drop incoming A-R headers claiming that
# id; header_checks do not see milter-added headers, so only the milters'
# own results survive and a sender cannot forge a pass. (OpenDKIM's
# RemoveARFrom did not remove them in testing.) Annotate only: never reject,
# and accept mail if a milter is down. Loopback (the ticket service's
# replies) is skipped. Both milters run in the foreground: daemonized,
# OpenDKIM died on its first connection in this container.
mkdir -p /run/opendkim /run/opendmarc
chown opendkim:opendkim /run/opendkim && chown opendmarc:opendmarc /run/opendmarc
printf '127.0.0.1\n' > /etc/opendkim-peers
cat > /etc/opendkim.conf <<CONF
Mode v
Socket inet:8891@127.0.0.1
AuthservID $DOMAIN
PeerList /etc/opendkim-peers
UserID opendkim
PidFile /run/opendkim/opendkim.pid
Syslog no
CONF
cat > /etc/opendmarc.conf <<CONF
Socket inet:8893@127.0.0.1
AuthservID $DOMAIN
TrustedAuthservIDs $DOMAIN
SPFSelfValidate true
SPFIgnoreResults true
RejectFailures false
PublicSuffixList /usr/share/publicsuffix/public_suffix_list.dat
UserID opendmarc
PidFile /run/opendmarc/opendmarc.pid
Syslog false
CONF
opendkim -f -x /etc/opendkim.conf &
opendmarc -f -c /etc/opendmarc.conf &
printf '/^Authentication-Results:[[:space:]]*%s([[:space:];]|$)/ IGNORE\n' "$DOMAIN_RE" \
> /etc/postfix/ar_strip.regexp
postconf -e "header_checks=regexp:/etc/postfix/ar_strip.regexp" "smtpd_milters=inet:127.0.0.1:8891,inet:127.0.0.1:8893" "non_smtpd_milters=" \
"milter_default_action=accept" "milter_protocol=6"
cat >> /etc/postfix/master.cf <<CF
mas unix - n n - - pipe
flags=Rq user=mas argv=/usr/local/bin/mas-gateway