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.

  1. The sending server establishes a connection with the receiving server. Over TCP - spoofing the IP address is not possible.
  2. The sending servers sends a HELO command to the receiving server with a domain. This domain is checked via SPF.
  3. 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.
  4. The receiving server verifies the Envelope From domain via SPF.
  5. The receiving server verifies the DKIM signature, the SPF alignment and the DKIM alignment.
  6. The receiving server evaluates the sender’s DMARC policy.
  7. 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.



graph LR A[Sending Server] -->|1. Establishes connection| E[Receiving Server] C -->|Receives Envelope| D[Message with Headers] E -->|The Internet Message Format email is put in the inbox| F[Recipient's Inbox] subgraph H[Internet Message Format] I[Message From] J[Message To] K[Message Subject] L[Message Body] end subgraph C[SMTP Envelope] D B[SMTP From Header] G[SMTP To Header] H end A -->|2. Sends Envelope| C[SMTP Envelope] C -->|3. Receives Envelope| E[Receiving Server]

SPF

The point of SPF is to authorize IPs to send email under your domain.

SPF only applies to the envelope from domain. It does not apply to the From header in the email, which is what the user sees.

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 be none, quarantine or reject. - 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.
DMARC policy is inherited by subdomains.
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
What is an Organizational Domain?
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.