Beginning february Google and Yahoo start to require DMARC. They ramp this up slowly: first only temporary errors, then gradually increasing rejection rate (see Google documentation). Some requirements also only affect large senders with more than 5000 messages per day. Still DMARC is actually a good idea and it doesn't hurt to implement it.

What is DMARC?

First some background on DMARC: actually DMARC builds upon two other security mechanisms that you may already know:

DMARC is then a policy that defines what should happen if a message fails one of the two security mechanisms above. It has the nice feture that failing messages can be reported to a mail address of your choice.

There are also ARC headers that keep the authenticity chain for forwarded messages. Did not yet look too much into it, but maybe there's a follow-up blog post coming about this.

DKIM for Postfix

Signing messages is handled by OpenDKIM. For my configuration I followed the docs in Arch wiki and Debian.

After installing the package with yay -S opendkim, I configured the config files:

# /etc/opendkim/opendkim.conf
# Secure base cofiguration from
Selector                default
Socket                  local:/var/spool/postfix/opendkim/opendkim.sock
Syslog                  Yes
TemporaryDirectory      /run/opendkim
UMask                   002
UserID                  opendkim

# To tolerate tools that fiddle with headers
Canonicalization    relaxed/simple

# main domain
# Config based on
KeyTable                file:/etc/opendkim/KeyTable
SigningTable            refile:/etc/opendkim/SigningTable
ExternalIgnoreList      refile:/etc/opendkim/TrustedHosts
InternalHosts           refile:/etc/opendkim/TrustedHosts
# /etc/opendkim/KeyTable

Contrary to what the Arch wiki says, you dont need multiple line if you use the same key.

# /etc/opendkim/SigningTable
# /etc/opendkim/TrustedHosts
opendkim-genkey --restrict --selector default --domain --directory /etc/opendkim/keys/ --bits=2048 --verbose
chown -R opendkim:mail /etc/opendkim
cat /etc/opendkim/keys/

Then set in default._domainkey TXT in every domain to the output from default.txt (remove the brackets and quotes).

You can test that the DKIM config is correct with sudo -u opendkim opendkim-testkey -vv. Optionally you can also specify a domain with -d

As I run Postfix with a chroot, the socket file needs to be under /var/spool/postfix and therefore needed to create and fix the owner of the file: chown -R opendkim:postfix /run/opendkim/opendkim.sock

In my case I also needed to change the group, as Postfix didn't have he permissions to access the socket file:

# /etc/systemd/system/opendkim.service.d/override.conf
# Use the group "postfix", so the socket uses that group and postfix can access it

And then we can finally start OpenDKIM:

systemctl daemon-reload
systemctl start opendkim

To make Postfix communicate with OpenDKIM, we add config like this to

non_smtpd_milters = unix:/run/opendkim/opendkim.sock
smtpd_milters = unix:/run/opendkim/opendkim.sock
# Also run bounce through milters, so bounces are signed by DKIM
internal_mail_filter_classes = bounce

and systemctl restart postfix.


I used the DMARC wizard to generate my DMARC record. You could also do it manually if you want.

For the start I was conservative and used the most permissive policy (none = don't block anything): v=DMARC1; p=none;; Then set this record into TXT.

With multiple domains, you can use a reporting adress of the same domain (easier) or point all of them to the same address (then need whitelisting on the receiving domain).


Finally we also want to validate that DKIM and DMARC now work. The that was linked in the Debian docs is really easy to use: generate a mail address, send a test mail to it and see the score. the downside is, that you can only test 3 mails per day for free. Pro tip: Write a bit more that "Test" into your mail, otherwise you get warnings because pyzor thinks that it looks like spam.

It will probably tell you that the List-Unsubscribe header is missing, but this is not relevant if you don't operate a mailing list.

You could also configure to validate DMARC on incoming mail with OpenDMARC, but for now saved this for another weekend project.