Blog

Tips, guides, and privacy advice

← Back to Blog
指南

SPF、DKIM 和 DMARC 通俗讲解(附示例)

作者 Khaja Hussain·2026年10月15日·7 min read

邮件为什么需要这些东西

先说一个有点扎心的事实:电子邮件是在 20 世纪 80 年代初设计的,当时只服务于一个彼此信任的小网络。在默认情况下,任何人都可以发出一封声称来自 [email protected] 的邮件。基本协议里没有任何机制能阻止他们。

SPF、DKIM 和 DMARC 是后来为了解决这个问题才加上的。三者配合,能让收件方(比如 Gmail、Outlook 或 Yahoo)回答一个问题:这封邮件真的来自它声称的那个域名吗?如果答案是否定的,这封邮件就会进垃圾箱,或者直接被拒收。反过来,如果你自己的域名没有配置好这些,你发出的真邮件也可能被当成假的。

打个比方会更好理解:

  • SPF 是宾客名单:哪些服务器可以代表你的域名发邮件。
  • DKIM 是火漆封印:一个签名,证明邮件在途中没有被改动过。
  • DMARC 是给门口保安的指示:邮件没通过检查时该怎么处理,以及该通知谁。

SPF:宾客名单

SPF(Sender Policy Framework,发件人策略框架)是你发布在域名 DNS 里的一行文本。它列出了允许代表你发送邮件的服务器和服务。当 Gmail 收到一封来自你域名的邮件时,它会去查这份名单,看看发信的服务器在不在上面。

一条典型的 SPF 记录长这样:

v=spf1 include:_spf.google.com include:sendgrid.net ~all

从左往右读:

  • v=spf1:“这是一条 SPF 记录”。
  • include:_spf.google.com:Google Workspace 可以代表我发信。
  • include:sendgrid.net:SendGrid 也可以(比如用来发我的应用邮件)。
  • ~all:其他的大概率不是我,请保持怀疑。(-all 的意思是“肯定不是我,直接拒收”。)
最常见的两个 SPF 错误:同一个域名上有两条 SPF 记录(必须合并成一行),以及漏掉了某个服务。如果你的邮件营销工具或客服系统以你的域名发信,它也得在名单里。

另外,一条 SPF 记录里最多只能有 10 次 DNS 查询。每个 include: 都算一次,它们内部嵌套的 include 也算。如果你用了很多服务,可能不知不觉就超了上限,到时候所有邮件的 SPF 都会失败。

DKIM:火漆封印

SPF 检查的是邮件从哪里来。DKIM(DomainKeys Identified Mail,域名密钥识别邮件)检查的是邮件本身有没有被篡改。你的邮件服务会用一把只有它自己知道的私钥,给每封外发邮件签名。你把配对的公钥发布在 DNS 里,收件服务器就用这把公钥来验证签名。

如果有人在途中改了邮件,哪怕只改了正文里的一个词,签名也就对不上了。这就像旧时书信上的火漆封印:封印一旦破了,你就知道有人拆过。

DKIM 记录发布在一个特殊的名称下,比如 google._domainkey.yourdomain.com,它的值大致长这样:

v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1...

好消息是:这个你永远不用自己写。邮件服务商会帮你生成,你只要把它复制到 DNS 里就行。._domainkey 前面的那个词(这里是 google)叫作选择器(selector)。它的作用很简单,就是让你可以有多把密钥,每个服务一把。

DMARC:给门口保安的指示

SPF 和 DKIM 给收件服务器提供的是事实。DMARC(Domain-based Message Authentication, Reporting and Conformance,基于域名的消息认证、报告与一致性)则告诉它拿这些事实怎么办。它还加了一条重要规则,叫作对齐(alignment):通过 SPF 或 DKIM 检查的域名,必须和读者在“发件人”(From)一栏里实际看到的域名一致。没有这条规则的话,骗子完全可以用自己的域名通过 SPF,同时在发件人里显示你的域名。

DMARC 记录放在 _dmarc.yourdomain.com 下,长这样:

v=DMARC1; p=none; rua=mailto:[email protected]
  • p=none:只观察,暂时什么都不拦。非常适合刚起步的时候。
  • p=quarantine:把没通过检查的邮件送进垃圾箱。
  • p=reject:直接拒收没通过检查的邮件。最强的保护。
  • rua=mailto:...:收件方每天把汇总报告发到这个地址。

这些报告其实是个隐藏的宝藏。它们会列出所有在用你的域名发邮件的服务器,包括你早就忘了的服务,以及任何想冒充你的人。

一步步完成配置

假设你拥有 myshop.com,邮箱用的是 Google Workspace,订单确认邮件用的是 SendGrid 或 Mailgun 之类的服务。如果是我,会按这个顺序来:

  1. 列出所有以你的域名发信的东西:邮箱服务商、网站或应用、邮件营销工具、客服系统、开票软件。这是大家最容易跳过的一步,也是后来大多数问题的根源。
  2. 创建一条 SPF 记录:在 DNS 里(myshop.com 上的一条 TXT 记录)把它们全部包含进去,最后以 ~all 结尾。
  3. 在每个服务里开启 DKIM。每个服务都会给你一条要复制到 DNS 的记录。然后在该服务里点“验证”或“开始认证”。
  4. 添加一条 p=none 的 DMARC 记录,带上接收报告的地址,放在 _dmarc.myshop.com 下。
  5. 等一到两周,然后看看报告。把那些本该通过却失败了的正常邮件修好。
  6. 等你确信所有真实邮件都能通过后,收紧策略,改成 p=quarantine,之后再改成 p=reject。
DNS 的改动要在各处生效,可能需要几分钟到几个小时不等。如果你刚加完记录检查就失败了,先别急着改动,稍等一会儿再说。

如何在收到的邮件里查看它们

不需要任何工具,你的邮件应用已经把结果显示出来了:

  • Gmail:打开邮件,点击三个点,然后选择显示原始邮件。在顶部你会看到类似 SPF: PASS、DKIM: PASS 和 DMARC: PASS 的几行。
  • Outlook:打开邮件,依次选择查看和查看邮件详细信息(或邮件源),然后找到 Authentication-Results 这个邮件头。
  • Apple 邮件:依次选择显示、邮件、所有邮件头。

一个真实的邮件头大概是这样的:

Authentication-Results: mx.google.com;
  dkim=pass header.d=myshop.com;
  spf=pass smtp.mailfrom=myshop.com;
  dmarc=pass (p=QUARANTINE) header.from=myshop.com

三个都通过,而且域名一致:这封邮件是真的。如果你看到 fail,或者域名和你看到的发件人对不上,就要小心了。这也是我在如何识别钓鱼邮件里讲到的危险信号之一。

如果你正在配置自己的域名,有个快速的测试方法:发一封邮件到临时邮箱和一个 Gmail 地址,然后查看 Gmail 那份的邮件头。两分钟就能搞定,还能让你清楚看到外界眼中的邮件是什么样子。

常见问题与快速解决办法

  • “SPF: softfail”或“neutral”:发信的服务器不在你的 SPF 记录里。把该服务提供的 include: 加进去。
  • “SPF permerror”:通常是有两条 SPF 记录,或者查询次数超过了 10 次。合并成一条记录,并删掉不再使用的服务。
  • 修改模板后出现“DKIM: fail”:邮件在签名之后被什么东西改写了(一些转发服务和邮件页脚功能会这么做)。直接发送,再测一次。
  • SPF 通过了,DMARC 却失败:是对齐的问题。SPF 通过的是发信服务的域名,而不是你的域名。在该服务里用你自己的域名开启 DKIM,或者设置一个自定义的 Return-Path 域名。
  • 全部通过,邮件却还是进了垃圾箱:身份验证证明的是你是谁,而不是别人想收你的邮件。内容、发信信誉和投诉率同样重要。关于这一点,我在为什么应用邮件会进垃圾箱里写得更详细。

三个真的都需要吗?

需要。从 2024 年起,Gmail 和 Yahoo 要求大批量发信的发件人必须配置 SPF、DKIM 和 DMARC 记录;即使是小发件人,三者齐全后邮件的送达率也会好得多。更重要的是,设置了 p=reject 的 DMARC,才能真正阻止骗子以你的名义给你自己的客户发假邮件。

配置只需要一个下午。之后,它会每天默默守护你的域名。如果你有域名,却一直拖着没弄,那就把这篇文章当作提醒吧。今天先从 p=none 开始,以后再慢慢收紧。