SPF, DMARC and DKIM - 3 pillars for email security
The SMPT protocol was invested without any security measures in place. Since then we have added multiple layers of security measures to ensure that emails are not tampered with and that the sender is who they say they are. The 3 most important security measures are SPF, DKIM and DMARC.
How are emails sent?
First let’s understand how emails are sent and how the sender is verified.
- The sending server establishes a connection with the receiving server. Over TCP - spoofing the IP address is not possible.
- The sending servers sends a HELO command to the receiving server with a domain. This domain is checked via SPF.
- The sending servers sends the envelope containing the Internet Message Format email to the receiving server.
- The envelope contains (among other things):
- Envelope From Header - this is not necessarily the same as the From header in the email.
- Envelope To Header - this is not necessarily the same as the To header in the email.
- The envelope contains (among other things):
- The receiving server verifies the Envelope From domain via SPF.
- The receiving server verifies the DKIM signature, the SPF alignment and the DKIM alignment.
- The receiving server evaluates the sender’s DMARC policy.
- The receiving server puts the email message (Internet Message Format) in the recipient’s inbox. Or quarantines or rejects it based on the DMARC policy.
- The email message has a different From header and To header than the envelope.
- This is what the user will see in the inbox.
SPF
The point of SPF is to authorize IPs to send email under your domain.
It basically says “I authorize these IPs to send email under my domain”. Example the following record says that IPs listed under _spf.google.com can send email everyone else should be rejected:
v=spf1 include:_spf.google.com -all
SPF needs to be defined for all subdomains that you want to use to send email. So if you set SPF for example.com it will not apply to sub.example.com.
DKIM
DKIM is a way to sign emails. The sending server signs the email with a private key and the receiving server verifies the signature with the public key.
The public key is published in a DNS TXT record. The private key is kept secret on the sending server. The emails is signed by the private key and the public key is marked in the email headers:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mailc.linkedin.com; s=d2048-202308-0c; t=1732040938; bh=1iqnC7YYUofxEvLWBjXP1+V6JS42cE67GcUxL+OZMhA=; h=From:Subject:MIME-Version:Content-Type:To:Date:X-LinkedIn-Class:
X-LinkedIn-Template:X-LinkedIn-fbl; b=F+P9LDNAWNSpRTJSAzD0CGIX4db6Iu3XhcOD1sZfwT11zXx7xQftrpm/8DpWmuDYT
The important part for us right now is the domain (d=) and the selector (s=). This is used to find the public key in the DNS record: {s}._domainkey.{d}
.
dig +short txt d2048-202308-0c._domainkey.mailc.linkedin.com
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuQ0dkp0bA39YHuhvJ8btSmmnNCb/ts5AJQXi4ljeza1CFfVLL8BlIXk4osyUOH3+or5mao5Y6ZnuXBNfvx8FM9D6PrR/QFheiNpqEM/nDhfY6WrhKqwt+n9InSMpR4laLYcBQKlkuT+xU3d3ZbvkPFijEp1rb2iU0/wUewC76dDS2uDEpBV+BoG42hXEbfymZ" "Zw5wXjWZ6Ci0oBIOByBFziiziqEv//nQ5TcTK0CN63JRyC/YDSeVQB83ileUlPzNNAbkwVQC+P00I9q73/E/LCiATXt5HY2VjoluS3wRAevQWBuy27xPpi2qp9+ykuEGi8iHESBfAbwVhPxQLwNCwIDAQAB"
The line also specifies the algorithm and the the headers that are signed. Some headers might change in transit and should not be signed.
DMARC
DMARC is a way to provide a policy for receiving servers on how to deal with your emails. It also increases security by enforcing alignment. A DMARC record looks like this (published as a txt record under _dmarc.yourdomain.com):
"v=DMARC1; p=reject; rua=mailto:[email protected]; ruf=mailto:[email protected]; fo=1"
v=DMARC1
- the version of the DMARC record.p=reject
- the policy to apply. It can benone
,quarantine
orreject
. - Basically you are saying that if you get any non-compliant emails from me, do this.rua
- the email address to send aggregate reports to.ruf
- the email address to send forensic reports to.fo
- the failure reporting options. 1 means that they should send a DMARC failure report if any underlying authentication mechanism (SPF or DKIM) produced something other than an aligned “pass” result.
If you define _dmarc.example.com it will apply to all subdomains such as something.something.example.com. Unless you define a different policy for the subdomain.
Alignment
As mentioned above, SPF only applies to the envelope from, the user sees the message from. While alignment was tested by servers before, DMARC formalized it, to allow senders to comply with a single set of rules instead of the varied requirements from different vendors. Alignment is basically matching the different domains to see if they are related.
SPF alignment
As mentioned SPF checks the envelope from domain. On the DMARC alignment it is going to check if the RFC5322.From (Message from) domain is either:
- The same as the Envelope From domain - strict alignment
aspf=s
- Has the same Organizational Domain - relaxed alignment
aspf=r
- Completly unrelated - alignment fails
There is an official definition in the RFC but the TLDR is that it is top level domain, i.e.:
a.b.c.d.example.com
and z.x.y.example.com
have the same Organizational Domain: example.com.
DKIM alignment
DKIM checks the domain in the d=
field. On the DMARC alignment it is going to check if the d=
domain is either:
- The same as the RFC5322.From domain - strict alignment
adkim=s
- Has the same Organizational Domain - relaxed alignment
adkim=r
- Completly unrelated - alignment fails
DMARC alignment
Always aligning SPF is a hard thing to achieve if you are using third party email services (marketing, transactional, etc).
To avoid blocks, you can strive for DKIM alignment. The idea is that the provider gives you a domain you CNAME to under your domain key, they publish the public key here and sign the emails with the private key.