如何为发件域名配置 SPF、DKIM 和 DMARC

Hacker News Top 工具

摘要

本分步指南介绍如何为发件域名设置 SPF、DKIM 和 DMARC DNS 记录,确保自动邮件不落入垃圾邮件箱,并通过 Gmail 的发件人验证要求。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/10/01 20:12

# SPF、DKIM 和 DMARC 配置,一步步来 来源:https://mailfully.com/blog/spf-dkim-dmarc-setup 设置自动化邮件时,忽视邮件认证的情况实在太常见了。你接入邮件服务商,发送一封测试邮件,结果它进了垃圾箱。或者 Gmail 直接退信,报一个 `550 5.7.26` 的"发件人未认证"错误。本指南会说明发件域名是如何进行认证的,这有助于让你的邮件不被投递到垃圾箱。邮件安全的三大关键组件是 SPF、DKIM 和 DMARC。它们让收件邮件服务器可以检查一封邮件是否被授权使用你的域名,而且三者协同工作:SPF 授权发送服务器的 IP 地址,DKIM 添加加密签名以证明邮件完整性,DMARC 则利用这两项结果来检查是否与可见发件地址一致,并执行你的策略。\[1 (https://developers.cloudflare.com/dmarc-management/security-records/?ref=mailfully),2 (https://redsift.com/guides/difference-among-spf-dkim-and-dmarc-explained-for-msps?ref=mailfully)\] 正确配置这三项并不能保证邮件一定进入收件箱,但记录缺失会让普通邮件都送不达。密码重置和发票发送与通讯稿一样需要通过这些检查。Gmail 的[发件人指南](https://support.google.com/mail/answer/81126?hl=en&ref=mailfully)要求即便是小规模发件人也必须配置 SPF 或 DKIM,而每天向个人 Gmail 账户发送约 5,000 封邮件的发件人,则要求三者全部配置。我们建议你在接入域名时就立即把它们配置好。这里我们会以 Mailfully 的域名配置为例来演示整个流程。如果你使用其他服务商,记录的值会有所不同,但你要做的检查是一样的:这些记录是否正确发布,以及通过你的应用发送的邮件是否真的通过了验证。 ## 你要配置的是什么 当你的邮件到达时,收件邮件服务器会提出三个问题。每条记录回答其中一个: - **SPF(发件人策略框架):**投递这封邮件的服务器是否被允许代表该域名发送邮件? - **DKIM(域名密钥识别邮件):**这封邮件确实来自该域名吗?而且是否在传输过程中未被篡改? - **DMARC(基于域的消息认证、报告与合规性):**上述检查结果是否适用于收件人在 From 行看到的地址?如果不是,应该对这封邮件怎么处理? 这三者都是 DNS 记录:由你所在的 DNS 服务商(如 Cloudflare)发布的一小段文本,任何邮件服务器都可以查询。下面的图示展示了你的邮件服务商到收件服务器之间一封邮件的完整流程。它显示了每项检查读取消息的哪个部分,服务器为此查询哪条 DNS 记录,以及 DMARC 通过或失败时会发生什么。 图示:mail.example.com 发送了一封带签名的邮件。收件服务器针对 Return-Path 域名检查 SPF,针对签名中的 d= 域名检查 DKIM,针对 From 域名检查 DMARC,所依据的是公共 DNS 记录。DMARC 通过则继续正常投递;失败则按域名策略处理:none(不处理)、quarantine(隔离)或 reject(拒收)。 注意,每项检查读取的是同一封邮件中不同的域名。SPF 使用 Return-Path,DKIM 使用签名中的 `d=` 域名,DMARC 使用 From 地址。大多数配置问题都出在这三个域名中的某个并不是你所预期的那一个。下表把同样的信息汇总在一起: | 记录 | 检查内容 | 检查的域名 | 发布位置 | |---|---|---|---| | SPF | 发送服务器在允许列表中 | Return-Path(信封发件人) | Return-Path 域名下的 TXT 记录 | | DKIM | 邮件带有有效签名 | 签名中的 `d=` 域名 | `._domainkey.` 下的记录 | | DMARC | SPF 或 DKIM 通过,且域名与 From 一致 | 可见 From 地址中的域名 | `_dmarc.` 下的 TXT 记录 | ### SPF:哪些服务器可以代表你发送邮件 SPF 是一个允许代表某域名发送邮件的服务器列表,以 DNS TXT 记录的形式发布。当一封邮件到达时,收件服务器会将投递它的 IP 地址与该列表进行比对。如果地址在列表中,SPF 通过。如果不在,SPF 会失败或软失败,具体取决于记录末尾的写法。 针对主机 `example.com` 的 SPF 示例: ``` v=spf1 include:_spf.google.com ~all ``` 容易被忽略的部分是 SPF 到底检查哪个域名。它不看收件人看到的 From 地址,而是检查信封发件人,也就是 MAIL FROM 或称 Return-Path。这是后台使用的一个单独地址,主要用途是让退信邮件有地方可退。收件人除非打开原始邮件,否则看不到它;而邮件服务商通常默认将其设置为自己的域名。 可以把它想象成一封装在信封里的信。邮政系统使用信封上的回邮地址;读者看到的是信笺上的抬头。SPF 检查的是信封,而不是信笺抬头。 SPF 还与交出邮件的服务器绑定。当邮件被转发时,转发服务器就成为投递方,而它通常不在你的列表中,因此转发之后 SPF 往往会失败。 ### DKIM:证明邮件属于你的签名 DKIM 的工作方式类似于防篡改封条。当你的服务商发送邮件时,它会用一把只有服务商持有的私钥对邮件进行签名,并将签名作为邮件头添加进去。对应的公钥发布在你的 DNS 中,因此任何收件服务器都可以查询它并验证签名。 针对主机 `s1._domainkey.example.com` 的 DKIM 示例: ``` v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu3Xk...IDAQAB ``` 如果签名验证通过,收件方就知道两件事:这封邮件由控制该域名密钥的人签名,且被签名的部分在传输过程中没有变化。被签名的部分包括正文以及一组始终包含 From、通常也包含 Subject 的邮件头。其中任何一项在传输途中被修改,验证就会失败。 每个签名都会在其 `d=` 字段中注明它所签名的域名。这就是收件方查询的域名,也是 DMARC 之后用来与你的 From 地址进行比对的域名。一封邮件可以携带多个 DKIM 签名,每个签名对应不同的域名。 ### DMARC:把这一切与 From 地址关联起来 SPF 和 DKIM 单独使用时存在一个漏洞:两者都不检查收件人看到的 From 地址。垃圾邮件发送者可以通过自己的服务器发送邮件,让 SPF 对其自己的 Return-Path 域名通过,再为自己域名添加 DKIM 签名,同时却在 From 行填上你的域名。两项检查都会通过——只不过针对的是错误的域名。 DMARC 通过把检查结果与可见 From 地址中的域名关联起来,堵住了这个漏洞。要让一封邮件通过 DMARC,SPF 和 DKIM 至少要有一项通过*并且*使用的域名与 From 域名一致。这种一致性称为对齐(alignment)。 针对主机 `_dmarc.example.com` 的 DMARC 示例: ``` v=DMARC1; p=quarantine; rua=mailto:[email protected]; adkim=s; aspf=r; pct=100 ``` 对齐并不意味着域名完全相同。在默认的宽松(relaxed)规则下,任何共享同一组织级域名的两个域名都视为对齐。组织级域名是指你从注册商那里购买的那部分,例如 `example.com`。因此 `mail.example.com` 和 `send.mail.example.com` 彼此对齐,但它们都与 `example.net` 不对齐。 例如,一封来自 `[email protected]` 的邮件,可以通过 `send.mail.example.com` 上的 SPF 来通过 DMARC 检查。而邮件服务商自身域名上的 SPF 通过是不行的。DKIM 也是一样:来自不相关服务商域名的有效签名,无法通过 DMARC 为你的 From 地址完成认证。 这就解释了那个令人困惑的结果:SPF 和 DKIM 都说"通过",但 DMARC 说"失败"。这两项检查是针对错误的域名通过的。 DMARC 还会告诉收件方如何处理认证失败的邮件(`p=none`、`p=quarantine` 或 `p=reject`),并且可以要求收件方向你发送报告,通过这种方式你就能发现那些被遗忘的发件人。第 3 步会同时涵盖这两点。 ## 在打开你的 DNS 设置之前 选择一个你将用于发送的域名。对于应用邮件,`mail.example.com` 这样的子域名是一个不错的起点。它让你有独立的空间来配置发件,而不会把这些记录混进你用于员工邮件的配置中。关于这一选择的讨论请参见[从子域名发送事务性邮件](https://mailfully.com/blog/send-transactional-mail-from-a-subdomain)。本指南始终以 `mail.example.com` 为例。请替换为你自己的发件域名,并从你的服务商那里复制实际的记录值。 下面列出的 DKIM 选择器只是示例;照搬发布并不能验证你的域名。 你需要有权限访问托管你 DNS 的服务。它可能是你的域名注册商,也可能是 Cloudflare 或其他服务商。如果不确定,可以用下面这条命令查看你域名的 DNS 服务器: ``` bash dig NS example.com +short ``` 在 [Mailfully](https://mailfully.com/) 中,从 Domains 页面添加你的域名。你会得到一份记录列表,每条记录都有一个复制按钮和一个状态标记。在你操作 DNS 设置期间,请保持该页面打开。 如果你的 DNS 托管在 Cloudflare 上,Mailfully 可以替你添加这些记录;详情请参见文末的[如果你的 DNS 在 Cloudflare 上](https://mailfully.com/blog/spf-dkim-dmarc-setup#if-your-dns-is-on-cloudflare)。 Mailfully 域名页面列出了一个发件域名的 DKIM、MAIL FROM 和 DMARC 记录,每条记录都带有复制按钮。 ## 第 1 步:添加 DKIM 记录 Mailfully 会提供三条 DKIM CNAME 记录。每条都指向由 Mailfully 托管的公钥,这意味着密钥轮换时你这边不需要再进行一轮 DNS 修改。 | 类型 | Name | Value | |---|---|---| | CNAME | `k7qz2._domainkey.mail.example.com` | `k7qz2.dkim.mailfully.com` | | CNAME | `m4tr9._domainkey.mail.example.com` | `m4tr9.dkim.mailfully.com` | | CNAME | `p2xw8._domainkey.mail.example.com` | `p2xw8.dkim.mailfully.com` | 请注意 Name 或 Host 字段。有些 DNS 服务商需要填写完整名称;另一些会自动为你拼接区域名称。如果你正在编辑 `example.com` 区域,而表单会自动附加 `example.com`,那么请输入 `k7qz2._domainkey.mail`。在这类表单中输入完整名称可能会产生这样的结果: ``` k7qz2._domainkey.mail.example.com.example.com ``` 这确实是一个可以发布记录的合法位置,但没有任何收件服务器会到那里去查找你的 DKIM 公钥。在等待验证之前,请检查已保存记录的完整名称。 如果你使用的是 Cloudflare,请将这些 CNAME 设置为 **DNS only**(仅 DNS),表现为灰色云朵图标。代理功能是针对 Web 流量的,它会阻止 CNAME 按预期解析到 DKIM 目标地址。 使用控制面板中的选择器,逐条检查已保存的记录: ``` bash dig CNAME k7qz2._domainkey.mail.example.com +short ``` 返回结果应与目标值一致。如果结果为空,请先检查已保存的名称和记录类型。DNS 变更可能还需要一些时间才能通过你的 DNS 服务商生效。 ## 第 2 步:在 return path 上配置 SPF 除非你配置了自定义地址,否则许多邮件服务商会为 Return-Path 使用自己的域名。在这种配置下 SPF 可以通过,但无法与你的 From 域名对齐。你的邮件仍然可以通过对齐的 DKIM 来通过 DMARC;配置自定义 MAIL FROM 则为它提供了多一条通过的途径。 例如,Mailfully 默认使用 `send.` 前缀。对于我们的发件域名,MAIL FROM 域名就是 `send.mail.example.com`。你需要在这个名称下添加一条 MX 记录和一条 TXT 记录: | 类型 | Name | Value | Priority | |---|---|---|---| | MX | `send.mail.example.com` | `feedback-smtp.us-east-1.amazonses.com` | 10 | | TXT | `send.mail.example.com` | `v=spf1 include:_spf.mailfully.com ~all` | | MX 记录将退信邮件路由回发送服务。TXT 记录授权通过 `_spf.mailfully.com` 列出的服务器代表该域名发送邮件。 请使用控制面板中显示的值,包括 MX 目标中的区域信息。这些记录应放在 `send.mail.example.com` 下。你不需要替换 Google Workspace 或 Microsoft 365 在 `example.com` 下使用的 SPF 记录。SPF 记录适用于发布它们的那个名称;子域名不会继承它。一个域名只能有一条 SPF 记录。如果你在同一个名称下发布两条以 `v=spf1` 开头的 TXT 记录,收件方会返回 `permerror`(永久错误)。当多个服务需要代表同一个名称发送邮件时,它们的授权必须合并到一条 SPF 记录中。 评估期间还有 10 次 DNS 查询的上限,包括由嵌套的 `include:` 条目引起的查询,因此即使是单条记录,过长的服务商列表也可能带来麻烦。 Mailfully 的记录以 `~all` 结尾,这会对未列出的发件人产生 SPF 软失败(softfail)。你可能会看到其他指南推荐 `-all`,那会产生硬失败(fail)。两者都不是无条件地把邮件放进垃圾箱或拒收的指令;收件方还会考虑 DMARC 以及自己的过滤规则。除非有明确的理由需要修改,否则请使用服务商提供的记录。 检查这两条记录: ``` bash dig TXT send.mail.example.com +short dig MX send.mail.example.com +short ``` TXT 查询结果中应当恰好只有一条 SPF 记录。其他 TXT 记录没问题。如果你看到两条以 `v=spf1` 开头的独立记录,请先修正再继续。 ## 第 3 步:添加 DMARC 并跟踪报告 首先,检查你的域名是否已经存在 DMARC 策略。不要仅仅为了照搬本示例,就用 `none` 去替换已有的 `quarantine` 或 `reject` 策略。 如果你不发布 `_dmarc.mail.example.com`,收件方会回退到 `_dmarc.example.com` 下的策略,包括其中(如果存在)的 `sp=` 子域名策略。单独的记录让你能够独立管理发件子域名,但请先检查继承到的策略,以免无意中削弱它。 对于全新的配置且不存在任何策略,先从这条开始: | 类型 | Name | Value | |---|---|---| | TXT | `_dmarc.mail.example.com` | `v=DMARC1; p=none;` | `p=none` 要求收件方不要*仅仅因为你的 DMARC 策略*而隔离或拒收邮件。他们仍然可以因为其他原因对邮件进行过滤。这给了你一个机会,在要求收件方拦截失败邮件之前,先找出那些尚未对齐的合法发件人。 要了解当前的实际情况,请添加一个用于聚合报告的地址: ``` v=DMARC1; p=none; rua=mailto:[email protected] ``` 在发布记录之前,先创建好该邮箱或别名。 参与的收件方通常会每天发送 XML 报告,展示他们观察到的发件 IP 以及认证结果。这些文件用肉眼阅读并不友好,因此当报告开始到来后,使用 DMARC 报告服务或解析工具会很有帮助。 发送到不同组织级域名的报告通常需要在目标域名侧添加一条授权记录;报告服务应当会给出相关说明。 给报告留出足够的时间以覆盖你正常的发送活动。对于一个每天都在发邮件的应用来说,两周左右可能就够了;但对于一个每月只发一次的账单系统来说,这点时间说明不了什么。请检查密码重置、邀请函、收据、客服工具,以及任何其他使用该 From 域名的发送方。 当这些发件人都通过验证后,将策略改为 `p=quarantine` 并继续观察。这会要求收件方将失败的邮件视为可疑,通常会放入垃圾箱。 当你确信合法邮件都已被覆盖后,再切换到 `p=reject`,要求收件方直接拒收失败的邮件。 即使配置正确,也要预料到仍会出现一些失败。未授权的发件人正是你要寻找的对象。关键问题是:这些失败里,有没有属于你实际在用的服务?在收紧策略之前,先修好这些。 ## 第 4 步:发送一封真实邮件并进行检查 新记录通常几分钟内就会生效,但缓存和 DNS 服务商可能会让等待时间更长。Mailfully 会对照实时 DNS 检查记录,并标出常见问题:**名称错误**(域名重复)、**位于代理之后**(被代理的 CNAME),以及**未找到**(找不到记录)。 Mailfully 的 DNS 检查显示每条记录都处于 Published(已发布)状态,而 DKIM 和 Mail From 的验证状态仍是 Pending(待处理)。 记录验证通过后,通过你的应用在生产环境将要使用的同一条路径发送一封邮件。从个人邮箱发送的测试邮件无法告诉你你的应用服务商是否正确地为邮件签名。例如,把它发送到一个 Gmail 账户……

相似文章

薛定谔的电子邮件

Lobsters Hottest

文章详细介绍了作者因SPF、DKIM、DMARC等认证协议导致的电子邮件转发挑战,并描述了使用Outlook规则和Cloudflare服务等工具解决该问题的各种尝试。