← News
/PLAYBOOK · 2026-08-10

Email Security: Hands-on SPF, DKIM, and DMARC Against Spoofing

End-to-end SPF, DKIM, and DMARC setup: DNS records, opendkim key generation and Postfix integration, DMARC policy rollout and report monitoring. Includes verification commands and FAQ.

SPF, DKIM, and DMARC are three defenses against domain spoofing and phishing. This guide covers DNS records and Postfix integration from mechanism to production so operators can build a verifiable mail trust chain.

Scope

Self-hosted mail (Postfix/Exim) or cloud mail (Tencent Exmail, Alibaba Enterprise Mail, etc.) on a company domain. Recipients can verify sender authenticity, cutting spoofed phishing and spam-folder placement.

Prerequisites

Mechanism

Each protocol has a job: SPF publishes allowed sender IPs in DNS; the receiver checks the connecting IP. DKIM signs mail with a private key; the receiver verifies with the public key in DNS so the body was not altered. DMARC combines both results, sets fail policy (none/quarantine/reject), and sends aggregate reports to a mailbox you name.

Procedure

1. Configure the SPF record

Add a TXT record for the domain in the DNS panel:

Record type: TXT
Hostname:    @ (or blank)
Value:       v=spf1 ip4:203.0.113.10 include:_spf.qq.com -all

Key params: ip4 declares your sending IP; include pulls a third-party ESP's SPF; trailing -all rejects anything not listed (use `~all` softfail during rollout).

2. Configure DKIM

# Generate key pair (selector recommended as year-month: 202608)
sudo apt install -y opendkim opendkim-tools
sudo mkdir -p /etc/opendkim/keys/example.com
sudo opendkim-genkey -b 2048 -s 202608 -d example.com   -D /etc/opendkim/keys/example.com -v
# Write the p= value from public key 202608.txt into a DNS TXT record
Record type: TXT
Hostname:    202608._domainkey
Value:       v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GN... (full public key)
# Configure opendkim and integrate with Postfix
sudo tee /etc/opendkim.conf <<'EOF'
Mode                sv
Socket              inet:8891@localhost
Selector            202608
Domain              example.com
KeyFile             /etc/opendkim/keys/example.com/202608.private
EOF
sudo systemctl restart opendkim
sudo postconf -e "milter_default_action = accept"
sudo postconf -e "smtpd_milters = inet:localhost:8891"
sudo postconf -e "non_smtpd_milters = inet:localhost:8891"
sudo systemctl restart postfix

3. Configure DMARC

Record type: TXT
Hostname:    _dmarc
Value:       v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com; pct=100

Roll out in three steps: p=none and watch reports 1–2 weeks, then p=quarantine, then p=reject. rua receives aggregate reports; pct is the percent of mail the policy applies to.

Verification

# 1. Verify DNS records
dig TXT example.com +short
dig TXT 202608._domainkey.example.com +short
dig TXT _dmarc.example.com +short

# 2. After sending a test email, inspect headers
# Expect:
#   spf=pass / dkim=pass / dmarc=pass
grep -i "authentication-results" /var/log/mail.log

Or send a test via mail-tester.com for a combined score and missing-item hints. Enterprise domains should watch delivery in Google Postmaster or the Tencent Cloud email console.

FAQ

Q1: SPF lookup limit exceeded (10 lookups)?

Each include/redirect counts as a DNS lookup; over 10 returns permerror. Shorten the include chain, drop unused third-party includes, and declare IP ranges with `ip4` instead of nested includes.

Q2: DKIM verify fails (dkim=neutral/fail)?

Confirm selector and public key match exactly (the TXT p= value must not wrap or truncate). Check opendkim is listening on 8891: `ss -lntp | grep 8891`, then verify locally with `opendkim-testmsg`. Confirm the From domain matches the signing domain.

Q3: Can I start with p=reject?

No. If a third-party system (e.g. a marketing blast platform) lacks SPF/DKIM, reject drops that mail. Start with p=none, watch rua reports 1–2 weeks, measure pass rate on legitimate mail, then tighten.

Summary

SPF, DKIM, and DMARC form sender authentication: SPF is who may send, DKIM is the body was not changed, DMARC is what to do on fail. The DNS records and Postfix config here can be applied as-is. After go-live, keep watching rua reports and tighten sending paths so the domain's mail trust score rises.