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: ~all

If this record was set on, only the server at would be able to send emails with a FROM: 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: – Allow the specified IPv4 address.
  • ip6:abcd:1234:90ab:cdef:5678:90de:fabc – Allow the specified IPv6 address.
  • – Allow the IP address given by the DNS A record for
  • – Allow IP addresses given by one of the DNS MX records for
  • – 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.
  • – 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: ~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

Open /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 simple which 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/simple allows more non-critical discrepancies.
  • Mode – Enable both signing (s) and verification (v) modes.
  • AutoRestart and 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

Create /etc/opendkim/trusted.hosts first:


This specifies that emails originating from local addresses or your domain are already trusted.

Open /etc/opendkim/signing.table and add the following content:


This instructs OpenDKIM that messages sent from any address should be signed with the key.

Now open /etc/opendkim/key.table and add this content:

The selector defined above is configured to use the private key at /etc/opendkim/keys/ We’ll generate this key next.

sudo opendkim-genkey -d -D /etc/opendkim/keys/ -s default -v
sudo chown opendkim:opendkim /etc/opendkim/keys/
sudo chmod 600 /etc/opendkim/keys/

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/ 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:

Socket      inet:8891@localhost

This creates a TCP socket which Postfix will use to pass emails to OpenDKIM for signing and verification. Next open your Postfix configuration file, /etc/postfix/

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 opendkim-testkey command:

sudo opendkim-testkey -d -s default -vvv
opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key ''
opendkim-testkey: key secure
opendkim-testkey: key OK

To test an actual email, send a message to 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 hostname.

v=DMARC1; p=none;
  • p=none – The p tag tells mail servers what to do when an unauthenticated message arrives. Its value must be one of the actions named above.
  • rua=mailto... – The rua tag 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.

Profile Photo for James Walker James Walker
James Walker is a contributor to How-To Geek DevOps. He is the founder of Heron Web, a UK-based digital agency providing bespoke software development services to SMEs. He has experience managing complete end-to-end web development workflows, using technologies including Linux, GitLab, Docker, and Kubernetes.
Read Full Bio »