入门指南
SPF、DKIM、DMARC:三个记录各证明什么,2026 年标准改了什么
按 2026 年 5 月发布的 RFC 9989 与 Gmail 的两套发件人要求,拆开三个 DNS 记录的职责、对齐的判定方式、pct 的退场,以及一份能照着验收的上线顺序。
三个记录证明的是域名身份,不是邮件能不能进收件箱。

先看答案
- 适合谁
- 用自己的域名发收据、登录邮件和订阅邮件的人
- 照着教程加了 DMARC 记录,却说不清它到底拦了什么的人
- 被服务商要求「配置 SPF/DKIM/DMARC」的一人公司
- 你会获得
- 先把三个记录各自证明什么分开,再决定 p 值该收紧到哪一步。
- 发布时间
- 实质更新
- 发布
- AOPC 编辑部
60 秒结论
一分钟看懂这篇文章
三个记录证明的是域名身份,不是邮件能不能进收件箱。
人负责
- 决定哪些发信源必须保留
- 决定什么时候收紧策略
AI 负责
- 逐条比对 DNS 记录与实际发信源
- 把失败项写成可复查的记录
- 盘发送源
- 配三记录
- 收报告
- 再收紧
直接答案
三个记录回答的是三个不同的问题:
- SPF:这封信是从「被这个域授权」的 IP 发出来的吗?
- DKIM:这封信确实由这个域签过名,且内容在传输中没有被改过吗?
- DMARC:当上面两项与
From:头里的域对不上时,我希望接收方怎么做?顺便,把报告发给我。
三件事都做完,说明你的域名身份更难被冒用;它不说明邮件一定进收件箱——Gmail 的官方措辞是「可能被标为垃圾邮件,或以 5.7.26 错误拒收」,而不是「配了就送达」。
2026 年有一件多数教程还没更新的事:DMARC 的参考文本在 2026 年 5 月从 RFC 7489 换成了 RFC 9989(标准轨道,取代 7489 与 9091)。这次换版删掉了 pct、rf、ri 三个标签,新增 np、psd、t,并且明确写出:面向普通用户、会往邮件列表发信的域,SHOULD NOT 直接发布 p=reject。
所以本文按「三个记录各自的职责 → 两套 Gmail 门槛 → 对齐怎么判定 → 2026 年改了什么 → 上线顺序 → 验收清单」来写。所有事实性表述都对应文末来源;属于编辑判断的地方会单独标出。
一、三个记录,三种证明
| 记录 | 放在哪 | 它证明什么 | 它不证明什么 |
|---|---|---|---|
| SPF | 域名的 TXT 记录(example.com) |
某个 IP 被这个域授权发信;校验对象是 SMTP 会话里的 MAIL FROM 身份 | 不校验 From: 头里的域,也不管正文有没有被改 |
| DKIM | <selector>._domainkey.example.com 的 TXT |
域所有者签过名;接收方用公钥验证签名,Cloudflare 的表述还包括「验证内容在传输中未被改动」 | 不证明这封信是本人想发的,也不证明内容可信 |
| DMARC | _dmarc.example.com 的 TXT |
声明「SPF/DKIM 必须与 From: 域对齐」,以及失败时希望接收方怎么做;并请求聚合报告 |
它本身不「拦截」任何东西,只是一份偏好声明加报告地址 |
三者的定位,官方页面写得很直白:
- Google:「SPF prevents spammers from sending unauthorized messages that appear to be from your domain.」并且「The SPF record for your domain should include all email senders for your domain.」——漏掉一个发送方,那个来源就更容易被标为垃圾邮件。
- Cloudflare:SPF 确认「邮件来自你的域授权的 IP 或域」;DKIM 用密码学签名认证发件域、并验证内容未被改动;DMARC 把两者绑起来,告诉接收方校验失败时是拒收、隔离还是不动作。
- Google 对 DMARC 的一句话定义:「DMARC tells receiving servers what to do with your messages that don’t pass SPF or DKIM.」
最后一句值得停一下:DMARC 的动作对象是「没通过 SPF 或 DKIM 的邮件」,而「通过」在 DMARC 语境里还要求对齐——这正是下一节的内容。
二、对齐:认证通过 ≠ 可以用这个域名
Google 把 DMARC 通过的条件写成了两句:
To pass DMARC authentication, messages must be authenticated by SPF or DKIM, or both. The authenticating domain must be the same domain that appears in the message From: header.
翻译成可操作的判断:先有 SPF 或 DKIM 的 pass,再要求「通过的那个域」与 From: 头里的域对得上。少任何一半,DMARC 都不算过。
RFC 9989 把「对得上」分成两档:
- relaxed(宽松):只要同属一个组织域即可。
mail.example.com与example.com算对齐。 - strict(严格):必须完全相同。
adkim(管 DKIM)与 aspf(管 SPF)的默认值都是 r,也就是默认宽松。这意味着大多数人不需要显式写这两个标签;但如果你在排查「为什么明明 SPF pass 了 DMARC 还 fail」,就要看对齐模式。
两处最容易踩空的细节:
- SPF 对齐看的是 MAIL FROM 域,不是
From:头。 RFC 9989 明确「DMARC relies solely on SPF validation of the MAIL FROM identity」。很多邮件服务商用自己的 bounce 域做 MAIL FROM(例如bounce.provider.com),于是 SPF 是 pass 的,但那个域和你的From:域不对齐——DMARC 仍然 fail。 - DKIM 对齐看签名里的
d=域。 服务商默认可能用共享域签名,那就对不上;要让它用你的域(或你的子域)签。
所以「配置 DKIM」和「配置对 DMARC 有用的 DKIM」不是同一件事。验收时要看 d=,不是看有没有签名。
三、Gmail 的两套门槛,别混成一套
Google 的页面把要求分成两层,且上层不是下层的替代:
Important: If you send more than 5,000 messages per day to Gmail accounts, follow the Requirements for sending 5,000 or more messages per day.
| 要求 | 所有发件人(2024-02-01 起) | 每天 5,000 封以上 |
|---|---|---|
| 认证 | SPF 或 DKIM | SPF 和 DKIM |
| DMARC | 不要求 | 要求,但「Your DMARC enforcement policy can be set to none」 |
| 正反 DNS(PTR) | 要求 | 要求 |
| 传输加密 | TLS | TLS |
| 垃圾率(Postmaster Tools) | 低于 0.3% | 低于 0.30%(同一个门槛,页面写法不同) |
| 报文格式 | RFC 5322 | RFC 5322 |
冒用 Gmail 的 From: |
禁止 | 禁止 |
| 对齐 | 本节未写 | 「must be aligned with either the SPF domain or the DKIM domain」 |
| 一键退订 | 本节未写 | 营销与订阅邮件必须支持,且正文有可见退订链接 |
三个结论:
- 小量发件人也要配。 「我才发几百封」不构成豁免;只是不必满足 5,000+ 那一层的 DMARC 与一键退订。
- DMARC 不要求 reject。 5,000+ 那一层也只说「可以设为 none」。把「必须 p=reject」写成硬要求,是常见误读。
- 一键退订有具体头部格式。 页面给的是
List-Unsubscribe-Post: List-Unsubscribe=One-Click与List-Unsubscribe: <https://…>两个头,收件人点击后你会收到一个 POST 请求。
另外一条只写在 DKIM 小节、但很容易漏的硬约束:发往个人 Gmail 账户的 DKIM 密钥必须是 1024 位或更长,官方建议 2048 位。
四、2026 年 5 月:标准换版,删了三个标签
这是本文与多数中文教程最不一样的地方。
RFC 7489 发布于 2015 年 3 月,文档类型是 Informational,走 Independent Submission 流;Datatracker 页面上原话是「This RFC is not endorsed by the IETF and has no formal standing in the IETF standards process」。它被 RFC 9989(Proposed Standard,2026 年 5 月) 取代,同时被取代的还有 RFC 9091。
RFC 9989 的附录 C 列了与 7489 的差异,其中标签层面的变化是:
| 变化 | 标签 | 说明 |
|---|---|---|
| 新增 | np |
针对不存在的子域声明策略(从 RFC 9091 引入) |
| 新增 | psd |
声明该域是否为 Public Suffix Domain |
| 新增 | t |
测试模式,替代 pct 的一部分功能 |
| 删除 | pct |
不再按百分比施加策略 |
| 删除 | rf |
失败报告格式 |
| 删除 | ri |
聚合报告间隔 |
pct 为什么被删,附录 A.6 给了运营层面的理由:除 0 和 100 之外,这个标签通常没有被准确执行,不同实现之间的偏差很大;而 pct=0 还被一些中间件当成「改写 From: 头」的信号。换句话说,「先 pct=25,再慢慢加到 100」这条流传很广的渐进路径,在新标准里不再是可依赖的机制。
替代它的是 t:
- 默认
n,即按p/sp/np声明的策略执行; - 设成
y是请求接收方不要执行该策略,而是降一级处理:quarantine按none处理,reject按quarantine处理; - 它不影响报告生成,对
p=none也没有作用。
还有两处细节值得记住:
p从 REQUIRED 变成 RECOMMENDED。 7489 里p是「REQUIRED for policy records」;9989 写的是「RECOMMENDED」。如果记录里没有有效的p,但rua合法,接收方 MUST 按p=none处理;两者都没有,则不施加 DMARC 处理。np补的是子域这个缺口。 伪造者常用「你根本没建过的子域」(invoice.example.com)发信;np让你对这类不存在子域单独声明策略。没有np时,回落到sp,再回落到p。
编辑判断:如果你现在用的是 pct=,不必惊慌——它不会让邮件立刻失效,接收方多半仍按老实现处理;但它已经不是可以写进新配置的东西,迁移时用 t=y 加分阶段改 p 更稳妥。
五、为什么「加了 DMARC 记录」挡不住伪造
三种常见情形,原因各不相同:
① p=none 只是「不表达处置偏好」。 RFC 9989 对 none 的定义是「The Domain Owner offers no expression of preference.」——报告照收,失败邮件照投。很多人加了记录、看到报告,就以为「已经防住伪造了」,其实只是从「不知情」变成了「知情」。
② 就算写了 p=reject,接收方也不一定照做。 RFC 9989 第 7.4 节明确:接收方 MUST NOT 仅凭发件域的 p=reject 就拒收;在缺乏其它判断依据时,必须按 p=quarantine 处理。这是为了保护邮件列表与转发场景。所以「声明 reject」与「一定被拒」之间隔着接收方的判断。
③ DMARC 只认证域,不认证人,也不认证内容。 RFC 9989 的原话是:认证机制「only validate the usage of a DNS domain in an email message. They do not validate the local-part of any email address identifier found in that message, nor do such validations carry an explicit or implicit value assertion about that message or about the Domain Owner.」显示名冒充、相似域名(examp1e.com)、被盗的邮箱账号,都不在 DMARC 的射程内。
再补一个现实约束:Cloudflare 的 DMARC Management 页面对自己的定位是「track every source that is sending emails from your domain and review DMARC reports for each source」——它的用途是看来源、收报告,不是替你拦住伪造。记录本身才是策略,报告只是反馈。
六、p=reject 不是默认答案
这一节是 2026 版标准里最容易被忽略、但对一人公司最实用的一段。
RFC 9989 第 7.4 节对「有普通用户、可能往 Internet 邮件列表发信」的域写得很清楚:
It is therefore critical that domains that host users who might post messages to mailing lists SHOULD NOT publish Domain Owner Assessment Policies of “p=reject”.
并且给了收紧的顺序:先 p=none 至少一个月,再 p=quarantine 同样长的时间,比较两者的处置结果,确认影响后再考虑 reject。第 5.1.7 节也提醒:取决于发信节奏,可能要消费好几个月的聚合报告才能确认「所有邮件都被正确认证」。
还有一条硬约束:发布 p=reject 的域 MUST NOT 只靠 SPF 来保证 DMARC 通过,必须给邮件加有效 DKIM 签名。原因是转发场景会改掉 SMTP 路径(SPF 失效),而 DKIM 签名通常还能活下来。
对一人公司,可以这样落地(以下是编辑判断,不是 RFC 原文):
- 只发事务邮件(收据、登录、密码重置、交付通知),且全部经同一个服务商、DKIM 稳定:收紧到
quarantine的风险主要来自用户转发,reject可以更晚再评估。 - 有客服邮箱、让用户直接回信:这就是「普通用户发信」的场景,按 9989 的建议不要上
p=reject。 - 跑邮件列表或 newsletter:先把列表软件的
From:处理方式弄清楚(有的会改写 From,有的不会),再决定;这条比任何 p 值都重要。
七、六步上线顺序(可照抄)
第 0 步:盘发送源。 把替你发信的东西列全:交易邮件服务商、表单通知、发票系统、域名注册商、客服工单、监控告警、WordPress/建站工具、日历邀请。漏一个,SPF 就少一条授权。
第 1 步:先发 SPF。 一条 TXT,包含所有发送方。Google 的原话是「should include all email senders for your domain」,并提示漏掉的发送方更容易被标为垃圾邮件。
第 2 步:再配 DKIM,并确认 d=。 每个发送源一个 selector;密钥 1024 位起步、2048 位更好;确认签名域与 From: 域对齐(relaxed 下同组织域即可)。
第 3 步:DMARC 先用 p=none + rua。 例:v=DMARC1; p=none; rua=mailto:dmarc@example.com。这一步的目标不是拦,是看清谁在替你发信。
第 4 步:逐源核对报告。 看三件事:报告里出现了哪些你没列过的 IP/域;哪些来源 SPF 或 DKIM 是 fail;哪些 pass 了但没对齐。第 2、4 步通常要来回改几轮。
第 5 步:改 p=quarantine,再观察。 用 t=y 可以先「试运行」——请求接收方降一级执行,同时报告照收。
第 6 步:只在确认无转发/列表依赖后才考虑 reject。 有普通用户发信、或跑着邮件列表,就按 9989 留在 quarantine。
回滚:DNS 改动的生效速度由 TTL 决定(编辑判断:收紧前先把 _dmarc 的 TTL 调低,给自己留一条快速退回 p=none 的路)。
八、验收清单
三条查询(把 example.com、selector 换成你自己的):
dig TXT example.com +short # SPF
dig TXT selector._domainkey.example.com +short # DKIM 公钥
dig TXT _dmarc.example.com +short # DMARC
然后逐项打勾:
- SPF 只有一条 TXT(多条会一起失效),且覆盖了第 0 步列出的所有发送源。
- DKIM 公钥能解析出来,密钥长度 ≥1024 位;签名域
d=与From:域对齐。 - DMARC 记录以
v=DMARC1开头,且有rua=(否则你收不到任何报告)。 -
p=的值与当前阶段一致(先none,再quarantine,reject另行评估)。 - 如果用了子域发信,确认
sp/np的行为符合预期(缺省时回落到p)。 - 对齐模式是你以为的那个(
adkim/aspf默认r;要严格就显式写s)。 - 用真实邮箱往 Gmail 发一封,打开「显示原始邮件」,在
Authentication-Results里能看到 spf/dkim/dmarc 三行结果。 - 营销或订阅邮件:如果每天超过 5,000 封,确认两个
List-Unsubscribe*头都在。
九、四种误读
- 「加了 DMARC 记录就挡住伪造了。」
p=none不表达处置偏好,只收报告;要拦,得收紧p,而且要接受转发场景的代价。 - 「SPF pass 就说明
From:域没问题。」 DMARC 要的是对齐;MAIL FROM 域和From:域可以完全不同。 - 「DMARC 必须
p=reject。」 Gmail 对 5,000+ 发件人明写「可以设为 none」;RFC 9989 对有普通用户的域写的是 SHOULD NOT 直接 reject。 - 「用
pct慢慢放开就行。」pct已在 RFC 9989 中删除;渐进改用t=y与分阶段p。
十、这周可以做的五件事
- 把第 0 步的发送源清单写出来,逐个标「有没有 SPF 授权、有没有 DKIM 签名」。
- 查一次
_dmarc记录:现在到底是none、quarantine还是reject,有没有rua。 - 找一个真实收件箱,发一封测试邮件,看
Authentication-Results里 dmarc 是 pass 还是 fail。 - 如果还是
p=none,先确认rua指向一个你真的会看的邮箱——报告没人看,等于没配。 - 把「改 DNS 前先降 TTL」写进你的发布检查表。
边界说明:本文不提供任何送达率、进箱率或「配置后提升多少」的数字——Google 与 Cloudflare 的页面都没有给出这类数字,本文也不替它们估算。文中标注为「编辑判断」的段落是运营建议,不是标准或厂商文档的结论。
来源
以下页面均于 2026-10-26 逐条访问并验证为 HTTP 200;字节数为当日抓取的实际大小。
- Email sender guidelines – Gmail Help核查于 2026/10/26(200,1 646 422 B):2024-02-01 起所有发件人的要求(SPF 或 DKIM、PTR、TLS、垃圾率低于 0.3%、RFC 5322、不得冒用 Gmail 的 From);5,000+/天 的额外要求(SPF 和 DKIM、DMARC 且「can be set to none」、垃圾率 0.30%、对齐、一键退订与两个
List-Unsubscribe*头);DKIM 密钥 ≥1024 位、建议 2048 位;未认证邮件「might be marked as spam or rejected with a 5.7.26 error」。 - Cloudflare DMARC Management – Overview核查于 2026/10/26(200,97 780 B):SPF/DKIM/DMARC 三种机制的定义;DMARC Management 用于追踪发信来源、查看每家来源的报告;页面标注 Beta,且「available to all Cloudflare customers with Cloudflare DNS」。
- RFC 9989核查于 2026/10/26(200,186 641 B):Proposed Standard,2026 年 5 月,取代 RFC 7489 与 9091;
p为 RECOMMENDED、缺省按p=none处理;adkim/aspf默认r;np/psd/t新增,pct/rf/ri删除及理由;第 7.4 节对p=reject的 SHOULD NOT 与「先 none 一个月、再 quarantine 同样长」的顺序;p=reject不得只靠 SPF、必须有效 DKIM;接收方不得仅凭p=reject拒收;认证只验证域、不验证 local-part。 - RFC 7489 – IETF Datatracker核查于 2026/10/26(200,261 674 B):文档类型为 Informational(2015 年 3 月)、Independent Submission 流、「not endorsed by the IETF and has no formal standing」;页面标注 Obsoleted by RFC 9989、RFC 9990、RFC 9991。