邮件安全 SPF、DKIM、DMARC 是抵御域名伪造与钓鱼攻击的三道防线,本文通过 DNS 记录配置与 Postfix 集成实战,完整演示三项协议从原理到落地的全过程,帮助运维人员建立可验证的邮件信任体系。
适用场景
适用于自建邮件服务器(Postfix/Exim)或使用云邮箱(腾讯企业邮、阿里企业邮等)的企业域名。部署后对方邮箱可验证邮件发件人真实性,大幅降低被冒名发送钓鱼邮件、进入垃圾箱的概率。
前置条件
- 拥有域名的 DNS 管理权限(可添加 TXT 记录)
- 固定或可枚举的发件服务器 IP / 主机名
- 自建场景需 root 权限并安装 opendkim
原理说明
三项协议各司其职:SPF 在 DNS 中声明允许发件的 IP 范围,接收方校验发件 IP 是否在声明内;DKIM 用私钥对邮件签名,接收方通过 DNS 中的公钥验签,保证内容未被篡改;DMARC 汇总前两者结果,并规定未通过时的处置策略(none/quarantine/reject),同时将聚合报告发送到指定邮箱。
操作步骤
1. 配置 SPF 记录
在 DNS 管理面板为域名添加一条 TXT 记录:
记录类型: TXT
主机名: @ (或留空)
记录值: v=spf1 ip4:203.0.113.10 include:_spf.qq.com -all
关键参数说明:ip4 声明自有发件 IP,include 引入第三方邮箱服务商的 SPF,结尾 -all 表示未列出的一律拒绝(发布前可先用 ~all 软失败过渡)。
2. 配置 DKIM
# 生成密钥对 (选择器建议使用年份月份: 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
# 将公钥 202608.txt 中的 p= 值写入 DNS TXT 记录
记录类型: TXT
主机名: 202608._domainkey
记录值: v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GN...(完整公钥)
# 配置 opendkim 并集成 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. 配置 DMARC
记录类型: TXT
主机名: _dmarc
记录值: v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com; pct=100
策略建议分三步演进:先 p=none 观察报告 1~2 周,确认无误后升到 p=quarantine,最终收紧为 p=reject。rua 接收聚合报告,pct 控制策略生效比例。
配置验证
# 1. 校验 DNS 记录
dig TXT example.com +short
dig TXT 202608._domainkey.example.com +short
dig TXT _dmarc.example.com +short
# 2. 发送测试邮件后查看信头
# 期望出现:
# spf=pass / dkim=pass / dmarc=pass
grep -i "authentication-results" /var/log/mail.log
也可使用 mail-tester.com 发送测试邮件,获得三项协议的综合评分与缺失项提示;企业域名建议接入 Google Postmaster 或腾讯云邮件推送控制台持续观察送达率。
常见问题
Q1: SPF 记录提示查询次数超限(10 次限制)?
SPF 每次 include/redirect 都会增加 DNS 查询次数,超过 10 次 会返回 permerror。精简 include 链,删除冗余的第三方 include,必要时改用 ip4 直接声明 IP 段,避免层层嵌套。
Q2: DKIM 验签失败(dkim=neutral/fail)?
先确认选择器与公钥是否完全一致(注意 TXT 中 p= 值不能断行或被截断);再检查 opendkim 是否监听 8891 端口:ss -lntp | grep 8891,并用 opendkim-testmsg 本地验签排障;最后确认发件域名与签名域名一致。
Q3: 是否可以直接用 p=reject?
不建议。若第三方系统(如市场群发平台)未正确配置 SPF/DKIM,reject 会导致其邮件被直接丢弃。必须先以 p=none 观察 rua 报告 1~2 周,统计合法邮件通过率后再逐步收紧。
总结
SPF、DKIM、DMARC 三项协议共同构成邮件发件人身份认证体系:SPF 管「谁允许发」,DKIM 管「内容没被改」,DMARC 管「不合规怎么办」。本文的 DNS 记录与 Postfix 配置可直接套用,上线后务必保持 rua 报告监控,持续优化发件通道,才能让企业域名的邮件信任分稳定提升。