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:
parent
516657bf6a
commit
ab3346d187
4 changed files with 69 additions and 5 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -39,9 +39,11 @@ the relay regexp) for a MAS receiving domain:
|
|||
- pipe to `mas-gateway`;
|
||||
- optional authenticated relay with a send cap;
|
||||
- null-sender discard;
|
||||
- sender authentication: OpenDKIM (verify) + OpenDMARC milters with
|
||||
`RemoveARFrom` for the host's authserv-id, annotate-only (from
|
||||
MAS-WP-0005 T11; spec §14 item 10).
|
||||
- sender authentication: OpenDKIM (verify) + OpenDMARC milters,
|
||||
annotate-only. Forged A-R headers for the host's authserv-id are
|
||||
stripped with a Postfix `header_checks` IGNORE rule, because OpenDKIM's
|
||||
`RemoveARFrom` did not work in testing. The milters run in the
|
||||
foreground (MAS-WP-0005 T11; spec §14 item 10).
|
||||
Explain each setting and say why the stock config fails.
|
||||
|
||||
## Probe the profile
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ and case-insensitive ids. Repeat the IONOS forward test with
|
|||
|
||||
```task
|
||||
id: MAS-WP-0005-T11
|
||||
status: progress
|
||||
status: done
|
||||
priority: medium
|
||||
```
|
||||
|
||||
|
|
@ -368,6 +368,27 @@ claiming that authserv-id are removed (`RemoveARFrom`). Annotate only;
|
|||
never reject on DMARC failure. Milter failure means accept
|
||||
(`milter_default_action = accept`).
|
||||
|
||||
- 2026-10-18 done (verified in a local container; live in T13):
|
||||
- Image packages: opendkim, opendmarc, publicsuffix. OpenDKIM runs in
|
||||
verify mode; OpenDMARC with `SPFSelfValidate`, `RejectFailures false`
|
||||
and `TrustedAuthservIDs` set to the domain.
|
||||
- **Forged A-R stripping is done by Postfix, not OpenDKIM.**
|
||||
`RemoveARFrom` and `RemoveARAll` did not remove forged
|
||||
`Authentication-Results: mas.coulomb.social; dmarc=pass` headers. A
|
||||
`header_checks` regexp IGNORE rule does, and it leaves the milters'
|
||||
own headers alone, because header_checks do not apply to
|
||||
milter-added headers. Verified for a forged pass, an upper-case
|
||||
variant and a foreign id (foreign ids are kept; the gateway ignores
|
||||
them).
|
||||
- Daemonized, OpenDKIM died on its first connection ("can't read
|
||||
SMFIC_OPTNEG reply"), so both milters now run with `-f` in the
|
||||
background.
|
||||
- Result for a spoofed `From: test@coulomb.social` sent directly:
|
||||
`spf=fail`, `dmarc=fail (p=none)`. Our A-R headers sit above our
|
||||
`Received:` line; anything forged sits below it.
|
||||
- Note for MAS-WP-0004: use header_checks for A-R stripping and
|
||||
foreground milters.
|
||||
|
||||
## Gateway verdict and reply gating
|
||||
|
||||
```task
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue