Skip to content
Poshan Bhandari
← All Articles
Email Security

Email Security: SPF, DKIM, and DMARC

February 2, 2023·6 min read

Email is still the primary delivery channel for both malware and social-engineering attacks. Verizon's 2019 Data Breach Investigations Report put the share of malware delivered by email at 94%. SPF, DKIM, and DMARC are the three DNS-based controls that decide whether a spoofed message ever reaches an inbox, and most organizations have at most one of them configured correctly.

SPF: is this server allowed to send mail for this domain?

SPF (RFC 7208) is a DNS TXT record listing every server authorized to send mail on behalf of a domain. When server A sends mail to server B, server B checks the return-path domain, looks up its SPF record, and checks whether server A's IP is in it. A match passes the check; no match means the message gets rejected or spam-foldered, depending on policy.

dns
; authorizes a specific IP and a third-party sender
v=spf1 ip4:203.0.113.10 include:thirdparty.example ~all

; authorizes the domain's own mail servers (MX records)
v=spf1 mx ~all
  • v=spf1: marks the record as SPF; every SPF record starts with this string.
  • ip4 / ip6: authorizes a specific IP or CIDR range to send mail.
  • include: authorizes a third-party domain's SPF record to send on this domain's behalf.
  • mx: authorizes the IPs listed in the domain's own MX records.
  • a: authorizes the IP in the domain's A record.
  • ~all (softfail): anything not matched above gets sent to spam.
  • -all (hardfail): anything not matched above gets rejected outright.

DKIM: proving the message wasn't altered in transit

DKIM signs outbound mail with a digital signature tied to the sending domain, so the receiving server can verify both authenticity and integrity. On send, the server hashes the relevant headers and body, signs the hash, and attaches it as a DKIM-Signature header. On receipt, the recipient server pulls the sender's public key from DNS (using the domain and selector named in the signature), decrypts the signature, and compares it against its own hash of the message. A match means the message is authentic and unmodified; a mismatch means it was tampered with, and it gets treated accordingly.

text
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
  s=selector1; d=example.com; h=From:Date:Subject:To:Message-ID;
  bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
  b=iHeFQ+7rCiSQs3DPjR2eUSZSv4i/Kp+sipURfVH7BGf+SxcwOkX7X8R1RVDE1ODH...
  • v: the DKIM version.
  • a: the signing algorithm, e.g. rsa-sha256.
  • c: the canonicalization used to prepare the message for signing. Relaxed tolerates minor whitespace and line-wrapping changes; simple tolerates none.
  • s / d: the selector and domain used together to look up the correct public key in DNS.
  • h: the list of header fields that were included in the signature.
  • bh: the hash of the message body.
  • b: the signature itself, computed over the headers and body.

DMARC: deciding what happens when SPF or DKIM fail

DMARC (RFC 7489) needs at least SPF or DKIM already configured to be useful. It's a DNS TXT record that tells receiving servers what to do when a message fails those checks, and it adds a reporting mechanism that shows who is sending mail using the domain, which is how domain spoofing and phishing campaigns using a brand's name typically get noticed.

dns
; flag failures, send them to spam
v=DMARC1; p=quarantine;

; reject failures outright, and email a report
v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com;
  • p=none: no enforcement action; used to observe traffic before turning on enforcement.
  • p=quarantine: sends messages that fail SPF/DKIM to spam.
  • p=reject: refuses to deliver messages that fail SPF/DKIM at all.
SPF says who is allowed to send. DKIM proves the message wasn't altered. DMARC decides what happens when either one fails.
Email SecuritySPFDKIMDMARCDNS