About

Domain-based Message Authentication, Reporting and Conformance (DMARC) is an enhancement to existing mail systems that relies on Sender Policy Framework (SPF) and Domain Keys Identified Mail (DKIM) and performs additional checks by combining the two.

Requirements

SPF and DKIM must be implemented for DMARC to work correctly and the following pages offer the guidelines necessary for implementing them:

Adding DNS Record

DMARC requires an additional DNS TXT record to be added next to the SPF and DKIM ones. Just like the former, the TXT record for DMARC has a specific format with various options.

Given a mail server with a domain:

  • mydomain.tld

the TXT record would be created:

_dmarc.mydomain.tld

with the following configuration:

v=DMARC1; p=reject; rua=mailto:dmarc@mydomain.tld; ruf=mailto:dmarc@mydomain.tld; fo=1; adkim=s; aspf=s; rf=afrf; pct=100; rl=86400; sp=reject"

where:

  • v=DMARC1 is the DMARC version (currently v1 makes sense),
  • p=reject indicates the policy and suggests to the destination mail server to reject any mails that do not pass the DMARC check. Possible options are none and quarantine (treat mails that fail the DMARC check as suspicious).
  • rua=mailto:dmarc@mydomain.tld specifies an address to which DMARC aggregate reports should be sent to.
  • ruf=mailto:dmarc@mydomain.tld specifies an address to which forensic reports should be sent. These reports contained detailed information about failed DMARC verifications.
  • fo=1 indicates that failure reports should be generated if either SPF or DKIM verification failed. Other possible values are:
    • 0 - generate a report if both SPF and DKIM tests failed
    • s - generate a report if the SPF verification failed
    • d - generate a report if the DKIM test failed
  • adkim=s tells DMARC to be strict about interpreting DKIM results. The other possible value passed to adkim can be r for relaxed verification.
  • aspf=s similar to the antecedent check for DKIM, but for SPF.
  • rf=afrf the report format currently set to "Authentication Failure Reporting Format"; other possible value is "Accident Object Description Exchange Format"
  • pct=100 the percentage of mail from the mydomain.tld that should be checked by other mail servers (the default, if omitted is 100%, all mail is going to be checked).
  • rl=86400 the time interval in seconds for report generation (the default, if omitted is 86400, one day).
  • sp=reject similar to p=reject, sp is the policy for subdomains of mydomain.tld.

Setting up OpenDMARC

On Debian, opendmarc is an implementation of DMARC and can be installed with:

aptitude install opendmarc

and then configured by editing /etc/opendmarc.conf.

The defaults are safe, but a good addition would be an IgnoreHosts configuration parameter:

## Ignore hostnames and networks
IgnoreHosts /etc/opendmarc-ignore.hosts

that allows all hosts, subnets and IP addresses listed in the file /etc/opendmarc-ignore.hosts to be exempt from any DMARC checks - this can be useful in settings where mydomain.tld would be a relay for a different mail server.

The contents of /etc/opendmarc-ignore.hosts could possibly be:

localhost
192.168.0.0/24

in order to exclude localhost and the 192.168.0 local network (this could be set to the trusted internal network).

Finally, /etc/default/opendmarc and enable a socket configuration key, for instance:

SOCKET=inet:12345@localhost

where:

  • 12345 is the port to listen on,
  • localhost is the address to listen on.

It is a good idea to specify localhost in the socket configuration in case the mail server and OpenDMARC reside on the same server in order to prevent unauthorized connections.

Ignoring Authenticated Clients

In order to prevent opendmarc to verify authenticated clients, add to /etc/opendmarc.conf:

## Skip authenticated clients.
IgnoreAuthenticatedClients true

such that any authenticated user does not have to pass DMARC verfications.

Configuring Postfix

With OpenDMARC configured, the last step is to tell Postfix to use OpenDMARC as a milter. In order to accomplish that, edit /etc/postfix/main.cf and locate the smtpd_milters and non_smtpd_milters that were used whilst setting up DKIM.

There should be a configuration along the lines of:

smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

to which the DMARC milter should be appended, like so:

smtpd_milters = inet:localhost:8891,inet:localhost:12345
non_smtpd_milters = inet:localhost:8891,inet:localhost:12345

where the milters will be called in-order: first DKIM and then DMARC.

Finally, reload or restart Postfix, for instance by issuing:

/etc/init.d/postfix reload

Debian Workarounds

The OpenDMARC package is broken on Debian and does not read /etc/default/opendmarc. As a workaround, edit /lib/systemd/system/opendmarc.service and replace by the following:

[Unit]
Description=OpenDMARC Milter
Documentation=man:opendmarc(8) man:opendmarc.conf(5)
After=network.target nss-lookup.target 
 
[Service]
Type=forking
PIDFile=/var/run/opendmarc/opendmarc.pid
User=opendmarc
PermissionsStartOnly=true
ExecStartPre=/usr/bin/install -d -o opendmarc -g opendmarc -m 0750 /var/run/opendmarc
ExecStart=/usr/sbin/opendmarc -p inet:12345@127.0.0.1  -u opendmarc -P /var/run/opendmarc/opendmarc.pid
Restart=on-failure
ExecReload=/bin/kill -USR1 $MAINPID
 
[Install]
WantedBy=multi-user.target

the added directives are:

  • PermissionsStartOnly - makes ExecStartPre run as root.
  • ExecStartPre - in order to make sure that /var/run/opendmarc directory is created,
  • -p inet:12345@127.0.0.1 is the socket to listen on corresponding to /etc/default/opendmarc since the latter is not being read properly under Debian.

Forwarding Issues and Policy Choice

When mail is forwarded by upstream servers, it is possible for the sever that forwards the mail to also modify its content. If the headers are modified, then upstream servers or the destination server may perform DMARC verifications that may fail.

[ server ] --> [ server ] -- forward --> [ server ]
    ^              +                         ^
    |              | DMARC?                  | DMARC?
    +--------------+-------------------------+

There is no definite solution to this problem - except to either send the mail to the destination server directly or to relax the DMARC policy by setting sp=quarantine (or sp=none) instead of sp=reject.

Testing DMARC

The easiest way is to write an E-mail from the mail server being set up to an external mailbox and then check the raw message to see all the headers. Amongst the other headers, there should be a dmarc=pass in the Authentication-Results header:

smtp.mailfrom=me@mydomain.tld;
       dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=mydomain.tld

networking/postfix/domain-based_message_authentication_reporting_and_conformance.txt ยท Last modified: 2022/04/19 08:27 by 127.0.0.1

Access website using Tor Access website using i2p Wizardry and Steamworks PGP Key


For the contact, copyright, license, warranty and privacy terms for the usage of this website please see the contact, license, privacy, copyright.