There are plenty of tutorials out there how to get DKIM1, SPF2 and DMARC3 working, but it still took me a couple of hours to get everything right, because each and every one of them lacks something to actually work.
I also recommend reading another tutorial: https://www.skelleton.net/2015/03/21/how-to-eliminate-spam-and-protect-your-name-with-dmarc/
It’s covering the topic a bit better than this entry of mine.
Note: mail servers are not hard, just complex
I’ve seen a lot of bragging these days that mail servers are hard; that the Big Services greylists and trust-lists are getting impenetrable.
That is not true, but you need to keep a few things in mind:
- Do not try to run a massive newsletter server; that will always raise a warning flag. There are services out there for you to handle this.
- Make sure you can accept and send mails via TLS; this is crucial. DKIM, SPF and DMARC are not yet a must, but TLS is.
- Double check your mail server with external services; there are good and useful services out there, like:
- Forwarding mails is getting tricky due to the SPF and DMARC. Try to avoid that, if possible. If you need to do it anyway, make sure that at least you clear all DKIM headers from the mail, so you avoid bogus DKIM signatures.
- DMARC and SPF can break mailing lists for the same reasons as forwarding. Keep that in mind.
Let’s get started
The domain I’m setting this up for is
domain.com; replace it with your own. To test the result, use https://www.mail-tester.com/.
WARNING If DKIM, SPF and DMARC are set in the DNS but not actually working, so mail is not signed, etc., it’ll do more harm than good. Leave all the required DNS entries to the very end, after you’re sure all mails are fine!
This is relatively easy and straightforward; add the following to your DNS record:
*.domain.com. 1800 IN TXT "v=spf1 mx ip4:YOUR_MX_IP -all" domain.com. 1800 IN TXT "v=spf1 mx ip4:YOUR_MX_IP -all"
YOUR_MX_IP is the IP address of your mail server. If there is more, add more
ip4:IP entries separated by spaces.
-all means that mails should only be accepted from the IPs listed.
DKIM key for your domain
You’ll need to generate a DKIM private key. The fastest way to do this
opendkim-genkey -b 2048 -d domain.com -s domain.com.dkim
This will output 2 files:
.private is your key; keep it safe. The
.txt contains the DNS entry you’ll need.
OpenDKIM7 is a useful software, but it’s picky and it lacks proper error handling. This means that if you misconfigure it, or set
AutoRestart yes, it will still act like it was fine, but it won’t sign your mails.
So, my config ( it’s combined with postfix ):
Socket local:/var/spool/postfix/private/opendkim Syslog yes UMask 002 UserID postfix Selector mail Mode sv SubDomains yes AutoRestart yes Background yes Canonicalization relaxed/relaxed DNSTimeout 5 SignatureAlgorithm rsa-sha256 X-Header yes Logwhy yes InternalHosts /etc/internalhosts KeyTable /etc/opendkim/keytable SigningTable refile:/etc/opendkim/signtable OversignHeaders From
The important part is the Selector mail - this will be what you need to set in the DNS and in the KeyTable.
your.domain.com domain.com 192.168.0.0/255.255.255.0
DNS for DKIM
Remember the Selector entry in the opendkim.conf? You need that in from of
_domainkey.domain.com to work; in our case,
mail._domainkey.domain.com. 1800 IN TXT "what's in your domain.com.dkim.txt file between the double quotes"
DNS for DMARC
You’ll then need to add another TXT record to your DNS to get DMARC working.
_dmarc.domain.com. 1800 IN TXT "v=DMARC1; p=none; rua=mailto:firstname.lastname@example.org"
none indicates that the remove server should not drop the mails, even if they are not coming from the servers listed in the SPF record. Once you’re sure everything is fine, change the
There is also the option to “cc” a service, by adding more
rua entries. For example, you can include agari8, like this:
_dmarc.domain.com. 1800 IN TXT "v=DMARC1; p=reject; rua=mailto:email@example.com,mailto:firstname.lastname@example.org; ruf=mailto:email@example.com,mailto:firstname.lastname@example.org"
This will not drop any mail, so this is only the initial setup; later change none to reject, but do be careful.
Note: the Debian init script hardcodes the username/group; you have to change it there as well. Also, OpenDMARC seems to be buggy and somewhat unreliable; test it well before relying on it.
AuthservID mail.domain.com PidFile /var/run/opendmarc.pid RejectFailures false Syslog true SyslogFacility mail TrustedAuthservIDs mail.domain.com IgnoreHosts /etc/opendmarc/ignore.hosts UMask 002 UserID postfix:postfix TemporaryDirectory /tmp Socket local:/var/spool/postfix/private/opendmarc FailureReportsSentBy email@example.com FailureReportsBcc firstname.lastname@example.org FailureReports false AutoRestart true PublicSuffixList /etc/effective_tld_names.dat HistoryFile /var/log/opendmarc.log
localhost 127.0.0.0/8 192.168.0.0/24
This is not my complete postfix config, just the required lines for OpenDKIM and OpenDMARC to be effective.
smtpd_milters = unix:private/opendkim unix:private/opendmarc non_smtpd_milters = unix:private/opendkim unix:private/opendmarc
Working DNS example
This is how it should look like in the end, with a current, working example, for my
$ORIGIN petermolnar.net. $TTL 1800 petermolnar.net. IN SOA ns1.digitalocean.com. hostmaster.petermolnar.net. 1471376771 10800 3600 604800 1800 petermolnar.net. 1800 IN NS ns1.digitalocean.com. petermolnar.net. 1800 IN NS ns2.digitalocean.com. petermolnar.net. 1800 IN NS ns3.digitalocean.com. petermolnar.net. 1800 IN A 188.8.131.52 petermolnar.net. 1800 IN MX 10 mail.petermolnar.eu. *.petermolnar.net. 1800 IN A 184.108.40.206 petermolnar.net. 1800 IN TXT "v=spf1 mx ip4:220.127.116.11 ip4:18.104.22.168/29 -all" *.petermolnar.net. 1800 IN TXT "v=spf1 mx ip4:22.214.171.124 ip4:126.96.36.199/29 -all" _dmarc.petermolnar.net. 1800 IN TXT "v=DMARC1; p=reject; rua=mailto:email@example.com,mailto:firstname.lastname@example.org; ; ruf=mailto:email@example.com,mailto:firstname.lastname@example.org" mail._domainkey.petermolnar.net. 1800 IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFBnAcF/qUPAdpdPxYISnS0XrzS/GWIKa7r8Xh6lNTE4/tBfSiFLFkHguOxoT6+JWJiKjjsvM9cXhLa2yKf1R5EjGuOoVQokcIqZJ2oeJRwJSRQBy6KX9cFuPD/ZUYJiFFMPL1dqdD+G8FCnF1FjPddRaOgfokcT4KEB+JhbFuWwIDAQAB" hello._pka.petermolnar.net. 1800 IN TXT "v=pka1;fpr=AADDEF2263C9E5B52B4DE59C1E8898416C1F051F;uri=https://petermolnar.eu/pgp.asc/" petermolnar.net. 1800 IN TXT dnslink="/ipns/QmZhKarpdPZi5pgAsnoqQvX6dEAK4EDTcs96qGf4w38Td9"