SPF, DKIM and DMARC: the what, the why and the how
I’ve recently been sorting out my email setup on a couple of domains that I run for my personal use, and I struggled to find good resources to explain the concepts and basic implementation of SPF, DKIM and DMARC for beginners. This guide is aimed at people with small, simple email setups on their own domain. If you have a more complex setup e.g. for a large organisation, this isn’t the guide for you.
Why you’d want to implement SPF, DKIM and/or DMARC
- genuine emails from your domain are being marked as spam
- you’ve become aware of (or want to prevent) emails being sent out, claiming to be from your domain
We’ll need to cover a few basics of how email works before moving on to SPF, DKIM and DMARC.
When a server is sending an email to, say, email@example.com, it looks up the MX record for that domain (example.com) in the DNS. The MX record will have either an IP address or another domain name. If you use Google Apps or Microsoft for your email, you’ll put their details in here, so your incoming emails will come to your Google or Microsoft inbox. The record looks something like this:
example.com. IN MX 10 aspmx.l.google.com.
This works pretty well and ensures that emails get to the right place. Just like the regular postal service, I can be pretty sure that a letter sent in the post to my address will arrive to me. (I’ll refer to this analogy throughout — email is built on the analogy of sending regular post, so it works pretty well).
The problem of spam
Email is really cheap to send, and that means that a lot of spam email is sent out. Perhaps 45% of emails sent are spam, though estimates vary widely. The emails you see in your Spam folder are just the tip of the iceberg. Most spam emails are blocked without you ever seeing them. Email providers have sophisticated spam filtering processes in place to reduce this to a manageable level, but this isn’t a perfect process.
Generally speaking, spammers don’t want an email landing in your inbox from firstname.lastname@example.org. That’ll make it easier for receivers and email providers to spot their emails. So spammers often spoof email addresses to make it appear that emails have come from a legitimate domain. Without any mitigations, the basic standards of email allow a sender to claim that the email has come from any address.
Now, if I own example.com, I really don’t want spam emails coming from email@example.com, because:
- it’ll give me a bad reputation with my users if they see dodgy emails appearing to come from me
- spam filters from email providers will start to mark emails from example.com — including legitimate ones — as spam
- when spam senders send out emails, including to invalid addresses, I’ll get ‘bounce back’ emails to my inbox — because the bounce back emails will go to the server listed in my MX record. This is known as ‘backscatter spam’ and will quickly get very annoying.
The problem of identifying senders
It’s fairly easy to get an email to its intended recipient, but it’s much more difficult to identify whether it was sent from who it claims to be.
This applies to letters too, so let’s go back to our analogy. If I send a letter, it’s quite hard for the recipient to tell if the letter really came from me. I might put a return address on the envelope, so that undelivered email can be returned to me.
It turns out that emails have something pretty similar called the ‘envelope sender’ or ‘Return-Path’. This is the place where undelivered notifications will be sent. In many normal circumstances, the envelope sender is the same as the ‘From’ address. But there’s nothing to prove that this was the case. In the letter analogy, I could put someone else’s return address on an envelope.
SPF — Sender Policy Framework
SPF is a mechanism for checking that the ‘envelope sender’ or ‘Return-Path’ email address on an email matches with the server that the email is sent from. It uses another DNS record to list the valid servers that an email should be sent from
Having a valid SPF record, and making sure any emails you send pass SPF, means that your emails will be less likely to be marked as spam.
SPF is the easiest of the three to implement. All you need to do is to add a TXT record at the root of your domain (example.com) which says something like this:
example.com. IN TXT "v=spf1 include:amazonses.com ~all"
This example is for Amazon’s SES — you’ll need to put in the appropriate information for whatever email provider you’re using. If you’re using multiple providers (for example, Google Apps and SES) you’ll need to add both in the same record.
One limitation to be aware of is that automated email forwarding breaks SPF — for example if someone has their work emails forwarded to a personal address. Email forwarding is pretty common, and it will break SPF completely.
DKIM — DomainKeys Identified Mail
DKIM is a much more robust way of validating that an email came from the place it claims to. It uses public key cryptography to do this — I won’t go into detail of what public key cryptography is, but one of the things it allows me to do is to validate, using a ‘public key’ that you publish, that you ‘signed’ a message using a ‘private key’, without me seeing the ‘private key’.
In the case of DKIM, the ‘public key’ is published in the DNS. The ‘private key’ is kept secure and used to ‘sign’ each email.
Again for DKIM, you’re going to find the information you need for the DNS records from your email provider. But these will be specific to you, unlike the generic details used for SPF. They also won’t go at the root of your domain but instead at somewhere specified. They’ll look something like this:
w4brt6yt8k4lb7lvevow._domainkey.example.com IN CNAME w4brt6yt8k4lb7lvevow.dkim.amazonses.com
Note that each email provider will work a bit differently, so check with your provider to find the exact records you need to add.
When an email is sent out, your email provider will declare in the email which of these keys it has used to sign your email. You can have many different DKIM public keys for a single domain.
Again, a DKIM pass will mean your email is less likely to be marked as spam.
DMARC — Domain-based Message Authentication, Reporting and Conformance
While SPF and DKIM will both mean your legitimate emails are less likely to be marked as spam, DMARC allows you to set out a policy with explicit instructions for how you want emails claiming to be from your domain to be treated.
DMARC roughly follows the following algorithm:
- Check DKIM. If DKIM passes, DMARC passes. If DKIM fails or is not present, continue.
- Check SPF. If SPF fails, DMARC fails. If SPF passes, continue.
- Does the domain of the ‘envelope sender’/’Return-Path’ (the return address in our analogy) matches the domain of the ‘From’ address (the ‘From’ email is what appears in your email inbox)? If it matches, DMARC passes. Otherwise, DMARC fails.
In the simplest case where the ‘envelope sender’/’Return-Path’ has the same domain as the ‘From’ address, DMARC is basically checking whether the email passes at least one of SPF or DKIM. If either pass, that’s a DMARC pass. Checking the domain of the ‘From’ address is pretty crucial, since that’s what appears in people’s inboxes — and this is one of the big steps up from SPF to DMARC.
The remainder of the DMARC policy is about what the sender wants receivers to do with the emails they receive. This is really handy, because you’re able to indicate what email providers should expect from emails from your domain. For example, once you’re confident that all the emails you send are DKIM signed, you can tell email providers to discard all other emails claiming to be from your domain.
You’ll need to add a TXT record at a subdomain of your domain — if your domain is example.com, you’d add it at _dmarc.example.com. Here’s an example:
_dmarc.example.com IN TXT "v=DMARC1;p=none;pct=100;rua=mailto:firstname.lastname@example.org;"
Breaking down each of the sections in this record:
Should always be v=DMARC1;
This refers to the ‘policy’ that you want applied to emails that don’t pass the DMARC check.
p:none; does nothing, proceed as before
p:quarantine; put emails in Spam
p:reject; discard emails
What percentage of emails you want the policy to be applied to — anything from 0 to 100.
Where you want aggregate reports to be sent. Receivers will send you reports telling you what emails have been sent, whether they’ve passed SPF and DKIM, and whether they’ve pass DMARC.
Not all receivers implement DMARC, so you won’t get reports from everyone you send emails to. I’ve had reports from Google, Microsoft (Outlook) and Amazon (SES).
(There are some other optional fields you can include in a DMARC record as well.)
The easiest way of making sure your legitimate emails always pass DMARC is to implement DKIM. Then, you won’t be affected by SPF being broken by forwarding. At least one major bank in the UK is currently sending out emails with a DMARC quarantine policy, but not signing emails with DKIM. This means that any emails that go through automated forwarding are ending up in spam.
The best way to implement DMARC is in a phased way. Start off with p=none, send some test emails, look at the reports to make sure that everything’s working okay, then upgrade your policy to p=quarantine or p=reject.
SPF, DKIM and DMARC are great tools in making sure that your emails arrive to their intended recipients and spam emails are stopped in their tracks. They really ought to be a standard part of any responsible sender’s email setup — and nowadays, they’re relatively easy to set up.
DMARCIAN has some great tools for working with SPF, DKIM and DMARC. The SPF Inspector and DMARC Inspector are great ways to look at the policy on your domain and see if it’s doing what you expect.
Google’s guidance on implementing SPF, DKIM and DMARC is pretty good, even if you don’t use Google Workspace for your emails.