OpenDMARC with multiple MX: correct setup for trust between servers
There are many tutorials on how to setup OpenDMARC on your favorite flavor of Linux, but they all focus on single server configurations. My goal was to keep backup secondary MX servers, but enforce RejectFailures true
for DMARC p=reject
to be actually satisfied.
This led to a problem: the example configuration has TrustedAuthservIDs HOSTNAME
for uptream SPF and DKIM sources. If this was used to list secondary MX servers, it would allow bypassing the OpenDMARC checks completely on the primary MX with a single forged header.
Authentication-Results: <HOSTNAME>;
dkim=pass (1024-bit key; unprotected) header.d=example.com [email protected];
How to configure trust between the primary and the secondary MX without this flaw?
This is a rewrite of another question on Security Stack Exchange for the scope of Server Fault.
In short:
- OpenDMARC can and should check SPF independently.
- OpenDKIM must validate the signature even if it's already "validated". (On a single MX, too!)
- Trust between the MX servers should not rely on the header, but on the SMTP connection.
How to configure this?
-
You can follow a tutorial for initial configuration of (SPF,) OpenDKIM and OpenDMARC.
(After this, Postfix has OpenDKIM and OpenDMARC configured as SMTP milters.)
-
OpenDMARC configuration changes for all MX servers
/etc/opendmarc.conf
:-
Use OpenDMARC milter for connection stage rejects (default is
false
):RejectFailures true
-
Do not trust external SPF checks from pypolicyd-spf or alternative. Perform own check:
SPFIgnoreResults true SPFSelfValidate true
-
-
OpenDKIM must be configured to add header even when it already exists.
/etc/opendkim.conf
:AlwaysAddARHeader yes
-
Once every MX has the #1-#3 configured, the OpenDMARC on the primary MX can trust the checks made by other MX servers; forged mail should be already rejected by the secondary MX. Do not list them on the
TrustedAuthservIDs
, because it's vulnerable to header forgery. There's anotheropendmarc.conf
option more suitable for this:IgnoreHosts
(string)Specifies the path to a file that contains a list of hostnames, IP addresses, and/or CIDR expressions identifying hosts whose SMTP connections are to be ignored by the filter. If not specified, defaults to
127.0.0.1
only.IgnoreHosts /etc/opendmarc-ignorehosts.conf
...and list the IP addresses for the secondary MX server(s) in that new configuration file.