Introduction
Email spoofing — where attackers forge the sender address to impersonate your domain — is one of the most common attack vectors for phishing. Three DNS-based mechanisms work together to prevent this: SPF, DKIM, and DMARC.
SPF (Sender Policy Framework)
SPF tells the world which mail servers are authorized to send email from your domain. It's a DNS TXT record.
Creating an SPF Record
# Basic SPF record
example.com. IN TXT "v=spf1 mx a:mail.example.com include:_spf.google.com ~all"Breaking it down:
v=spf1— SPF version 1mx— allow your MX servers to senda:mail.example.com— allow this specific serverinclude:_spf.google.com— if using Google Workspace for email~all— soft fail anything else (use-allfor hard fail after testing)
Testing SPF
# Check your SPF record
dig TXT example.com | grep spf
# Test from command line
python3 -c "
import dns.resolver
result = dns.resolver.resolve('example.com', 'TXT')
for r in result:
if 'spf' in str(r).lower():
print(r)
"
# Online tools: mxtoolbox.com/spf.aspxDKIM (DomainKeys Identified Mail)
DKIM adds a cryptographic signature to outgoing emails. The receiving server verifies the signature using a public key in your DNS.
Generating DKIM Keys (Postfix + OpenDKIM)
# Install OpenDKIM
apt install opendkim opendkim-tools
# Generate key pair
mkdir -p /etc/opendkim/keys/example.com
opendkim-genkey -D /etc/opendkim/keys/example.com/ -d example.com -s mail
# Creates:
# mail.private (private key — keep on mail server)
# mail.txt (public key — put in DNS)
# Set permissions
chown -R opendkim:opendkim /etc/opendkim/keys/
chmod 600 /etc/opendkim/keys/example.com/mail.privateOpenDKIM Configuration
# /etc/opendkim.conf
Syslog yes
SyslogSuccess yes
LogWhy yes
Mode sv
SubDomains no
Domain example.com
KeyFile /etc/opendkim/keys/example.com/mail.private
Selector mail
Socket local:/var/spool/postfix/opendkim/opendkim.sockDNS Record for DKIM
The content of mail.txt goes in DNS:
mail._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GN..."DMARC (Domain-based Message Authentication, Reporting & Conformance)
DMARC ties SPF and DKIM together and tells receiving servers what to do when they fail.
DMARC Record
# Start with monitor mode (p=none) to see what's happening
_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com; ruf=mailto:dmarc@example.com; fo=1"
# After reviewing reports, move to quarantine
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; pct=50; rua=mailto:dmarc@example.com"
# Finally, reject unauthenticated emails
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"DMARC parameters:
p=none— monitor only, don't filterp=quarantine— send to spam folderp=reject— reject the email entirelypct=50— apply policy to 50% of emails (ramp up gradually)rua— aggregate report destinationruf— forensic report destination (individual failed emails)
Reading DMARC Reports
# DMARC reports arrive as XML in email, gzip compressed
# Use parsedmarc to analyze them
pip install parsedmarc
parsedmarc /path/to/dmarc-report.xml
# Shows which servers sent email, SPF/DKIM pass/fail ratesEmail Authentication Header
After implementing, check outgoing email headers:
Authentication-Results: mx.google.com;
dkim=pass header.i=@example.com header.s=mail header.b=AbCdEfGh;
spf=pass (google.com: domain of user@example.com designates 203.0.113.1 as permitted sender);
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.comAll three should show pass.
Implementation Checklist
[ ] Publish SPF record — start with ~all (soft fail)
[ ] Install and configure OpenDKIM
[ ] Publish DKIM public key in DNS
[ ] Publish DMARC with p=none and rua address
[ ] Wait 2 weeks and review aggregate reports
[ ] Fix any legitimate servers not covered by SPF/DKIM
[ ] Move DMARC to p=quarantine with pct=10, increase gradually
[ ] Move to p=reject when confident all legitimate mail is passingSummary
- SPF defines which servers can send email for your domain
- DKIM cryptographically signs emails — proves they weren't tampered with
- DMARC tells receivers what to do when SPF/DKIM fail, and sends you reports
- Always start with DMARC p=none and monitor before enforcing
- All three are required for good email deliverability and anti-spoofing
