DKIM, DMARC, and SPF are the three main mechanisms maintaining the security of emails. The related protocols let you prevent unauthorized servers from sending as your domain and give recipients a way to verify emails really come from you.
In this guide we’ll explore what each technology does, why it’s needed, and what you should do to set it up. You’ll need all three pieces to maximize your email server’s deliverability and reputation.
We’ll take SPF first as it’s the simplest and oldest item on the list. SPF uses DNS records to define the server IP addresses that can send emails as a domain.
An SPF record typically looks like this:
v=spf1 ip4:22.214.171.124 ~all
If this record was set on
example.com, only the server at
126.96.36.199 would be able to send emails with a
FROM: email@example.com header. The
~all excludes all other IP addresses except those in the list.
SPF is enforced by the receiving email server. It’ll check the IP address of the sending server, the domain in the email’s
FROM header, and the list of permitted senders in that domain’s SPF DNS record. The delivery will be failed if the sending server’s IP isn’t in the list.
SPF distinguishes between “soft” and “hard” fails. Writing
~all in your header indicates a soft fail when an unauthorized sender is encountered;
-all instructs the receiving server to use a hard fail.
The email will be discarded entirely in a hard fail scenario. Soft fails may permit the email to be delivered to the recipient’s junk folder. Now DMARC is widely available, which we’ll see below, it’s generally recommended to use
~all (soft fail). This avoids false positives with legitimate emails, hands more control to DMARC, and can aid debugging in later verification stages.
Setting up SPF
It’s easy to configure SPF for your domain. Head to your domain’s control panel, find the section for setting DNS records, and add a new
TXT record. Write a valid SPF string as the value and save your record.
SPF records support several kinds of whitelist token:
ip4:188.8.131.52– Allow the specified IPv4 address.
ip6:abcd:1234:90ab:cdef:5678:90de:fabc– Allow the specified IPv6 address.
a:example.com– Allow the IP address given by the DNS
mx:example.com– Allow IP addresses given by one of the DNS
include:example.com– Query the SPF record of this domain too and use its whitelist in addition to your direct definitions. Simplifies integration of popular third-party email services.
redirect:example.com– Ignore other tokens and use the SPF record advertised by
You can combine several sources by adding multiple tokens to your header:
v=spf1 ip4:184.108.40.206 include:example.com ~all
DKIM stands for “DomainKeys Identified Mail.” Whereas SPF indicates whether a server can send as your domain, DKIM looks at the emails themselves. It’s a signing system that lets receiving servers trace emails back to their origin.
DKIM helps receiving email servers answer these questions:
- Have the email’s headers been modified since leaving the sender?
- Has the email’s body been tampered with since leaving the sender?
- Is the sending server authorized to send as this domain? (Overlaps with SPF)
The DKIM system offers a way to verify an email is authentic, unmodified, and actually sent by your server. When a DKIM check fails, the receiving server will treat the email as untrustworthy. It’s up to the server to decide what to do with the email. It’s likely it’ll end up in the recipient’s spam folder but it could be dropped entirely.
Setting up DKIM
DKIM uses encryption to enable server identity verification. Setting up DKIM requires generation of a public and private keypair. The public key is added to your domain’s DNS records.
The private key is kept secret and becomes part of your mail server’s configuration. The software will use this key to sign each email it sends. When a receiving server gets a new message, it’ll query the domain’s DKIM DNS record and use the public key to check whether the email’s been tampered with.
The exact steps for setting up DKIM will vary depending on the mail transfer agent you’re using. Here’s an example of how to get it working with Postfix:
# Install OpenDKIM implementation sudo apt install opendkim opendkim-tools # Add the Postfix user to the OpenDKIM group sudo gpasswd -a postfix opendkim
/etc/opendkim.conf and uncomment or add the following lines:
Canonicalization relaxed/simple Mode sv AutoRestart yes AutoRestartRate 5/1H SignatureAlgorithm rsa-sha256 UserID opendkim
This configures OpenDKIM for use as both a signer of outgoing mail and verifier of incoming messages. Here’s what you’re setting:
Canonicalization– Defines how strict OpenDKIM is when verifying whether an incoming email has been tampered with. The default is
simplewhich permits no modification. This usually results in legitimate emails going missing as messages which intermediary mail servers have slightly modified, such as by tweaking whitespace or line lengths, will be discarded.
relaxed/simpleallows more non-critical discrepancies.
Mode– Enable both signing (
s) and verification (
AutoRestartRate– Restart on failure, provided there are no more than five restarts in an hour.
SignatureAlgorithm– Encryption algorithm to use when signing outgoing messages.
Next add the following extra lines to the file:
# Maps domains to the keys used to sign emails KeyTable refile:/etc/opendkim/key.table SigningTable refile:/etc/opendkim/signing.table # Ignore these hosts when verifying incoming signatures ExternalIgnoreList /etc/opendkim/trusted.hosts # Internal hosts to enable outgoing mail signing for InternalHosts /etc/opendkim/trusted.hosts
Save and close the configuration file. Next create the mapping files referenced above:
sudo mkdir /etc/opendkim sudo mkdir /etc/opendkim/keys sudo chown -R opendkim:opendkim /etc/opendkim sudo chmod go-rw /etc/opendkim/keys
127.0.0.1 localhost *.example.com
This specifies that emails originating from local addresses or your domain are already trusted.
/etc/opendkim/signing.table and add the following content:
This instructs OpenDKIM that messages sent from any
example.com address should be signed with the
/etc/opendkim/key.table and add this content:
default._domainkey.example.com selector defined above is configured to use the private key at
/etc/opendkim/keys/example.com/default.private. We’ll generate this key next.
sudo opendkim-genkey -d example.com -D /etc/opendkim/keys/example.com -s default -v sudo chown opendkim:opendkim /etc/opendkim/keys/example.com/default.private sudo chmod 600 /etc/opendkim/keys/example.com/default.private
The key generation command will produce your public and private keys.
Next you need to add the public key as a DNS record on your domain. Open
/etc/opendkim/keys/example.com/default.txt. Copy everything after
TXT and paste it as the value of your DNS record. Use
default._domainkey as the DNS hostname as this is the name of the selector used throughout the commands above.
The final step is to connect OpenDKIM to Postfix. Open your OpenDKIM configuration file again and add the following line if it’s not there already:
This creates a TCP socket which Postfix will use to pass emails to OpenDKIM for signing and verification. Next open your Postfix configuration file,
milter_protocol = 2 milter_default_action = accept smtpd_milters = inet:localhost:8891 non_smtpd_milters = inet:localhost:8891
If the last two lines already exist with comma-separated values, you’ve already got some Postfix filters in use. Add the OpenDKIM filter to the end of the existing list instead of creating a new line. This will ensure OpenDKIM applies in addition to your existing filters.
Now you can restart Postfix (
service postfix restart) and benefit from DKIM-signed messages. You can check your key’s configured correctly using the
sudo opendkim-testkey -d example.com -s default -vvv
opendkim-testkey: using default configfile /etc/opendkim.conf opendkim-testkey: checking key 'default._domainkey.example.com' opendkim-testkey: key secure opendkim-testkey: key OK
To test an actual email, send a message to
firstname.lastname@example.org. Look for
DKIM check: pass in the results. If a failure’s indicated, inspect the Postfix log at
/etc/var/mail.log to look for signing errors.
========================================================== Summary of Results ========================================================== SPF check: pass DomainKeys check: neutral DKIM check: pass
DMARC is “Domain-Based Message Authentication, Reporting and Conformance.” It’s another protocol for preventing unauthorized use of domain names by sending email servers.
Unlike SPF and DKIM, DMARC gives domain owners a way to specify what happens when an email server receives a message without proper authentication. There are three supported actions:
none– The server can continue to deliver the message.
quarantine– Deliver the message to junk or spam.
reject– Reject and bounce the message.
DMARC also provides a reporting mechanism. You can specify a server endpoint that receiving mail servers will call when they get an email purporting to be from your domain. This gives you a cross-internet view of the servers that are sending as your domain.
Here’s an example DMARC DNS record. It should be added as a TXT record against the
v=DMARC1; p=none; rua=mailto:email@example.com
ptag tells mail servers what to do when an unauthenticated message arrives. Its value must be one of the actions named above.
ruatag instructs servers where to send reporting data to. In this case, it’ll be emailed to you. Reports are generally sent daily and let you monitor for unauthorized sending activity.
There are other supported DMARC tags too. These let you define a separate policy action for subdomains, vary the enforcement strictness for SPF and DKIM checks, and configure a percentage of emails which DMARC will apply to.
SPF, DKIM, and DMARC are three technologies which enforce security and trust in the email ecosystem. If you’re sending emails from your own server, you should use all three so recipients can verify you’re authorized to use your domain as a from address. This will reduce your risk of deliverability issues.
SPF and DMARC are simple DNS records. DKIM combines a public DNS record with a private key that’s handled by your email server. SPF is for limiting the servers that can send as your domain; DKIM is a newer alternative that includes verification of message integrity.
DMARC provides a way to define what happens when other checks fail. It also adds the previously missing reporting mechanism so domain owners can monitor authentication failures. It’s still relatively young and won’t be supported by all email servers. Nonetheless it is accepted by major providers and is worth setting up as another layer of protection.