以监控模式发布 DMARC
在 From 地址所用域名的 _dmarc 下只添加一条 TXT 记录。p=none 不会改变投递,rua 会请求接收方发送汇总报告,显示哪些服务器以你的域名发送邮件,以及它们是否以对齐的方式通过 SPF 或 DKIM。如果报告发往另一个域名,该域名必须发布一条授权接收这些报告的记录。
; DMARC record for example.com, monitoring only
_dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"
; Only if rua points to another domain, for example rua=mailto:reports@example.net,
; example.net publishes:
example.com._report._dmarc.example.net. TXT "v=DMARC1"
先改为 quarantine,再改为 reject
当报告显示所有合法来源都能通过时,改为 p=quarantine,再次观察报告,然后改为 p=reject。RFC 7489 曾提供 pct,用于只对部分未通过的邮件应用策略。取代它的 RFC 9989 删除了 pct,因为部分比例的执行并不一致,并新增了 t=y,请求接收方按比已发布策略低一级的方式执行。仍遵循 RFC 7489 的接收方会忽略 t=y,因此测试期间请同时添加 pct=0,它会请求这些接收方同样按低一级的方式处理。正式执行时删除这两个标签。
; Publish one version at a time, in this order, after p=none
; 1. Quarantine in test mode (t=y, plus pct=0 for RFC 7489 receivers), then in full
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; t=y; pct=0; rua=mailto:dmarc-reports@example.com"
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com"
; 2. Reject in test mode, then in full
_dmarc.example.com. TXT "v=DMARC1; p=reject; t=y; pct=0; rua=mailto:dmarc-reports@example.com"
_dmarc.example.com. TXT "v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com"
每个域名只保留一条 SPF 记录
一个名称只能有一条以 v=spf1 开头的 TXT 记录;有两条时,SPF 会以永久错误失败。把所有发件方合并到一条记录中。include: 检查服务商自己的记录,redirect= 把整个策略交给另一个域名,适合多个域名共用一个策略的情况。如果记录中还有 all 项,redirect= 会被忽略。
; Before: two SPF records on one name (permerror)
example.com. TXT "v=spf1 include:_spf.mailhost.example ~all"
example.com. TXT "v=spf1 include:spf.newsletter.example ~all"
; After: one record
example.com. TXT "v=spf1 include:_spf.mailhost.example include:spf.newsletter.example ~all"
; Another domain that uses the same policy
example.org. TXT "v=spf1 redirect=example.com"
DNS 查询不超过十次
SPF 最多允许十个需要 DNS 查询的项(include、a、mx、ptr、exists 和 redirect),嵌套 include 中的项也计算在内。多出一个,SPF 就会以永久错误失败。删除不再使用的服务的 include,用你控制的 ip4 或 ip6 地址段代替 a 和 mx,去掉 ptr,并把群发服务移到拥有自己 SPF 记录的子域名。把服务商的地址直接复制到你的记录中也能减少查询,但服务商更换地址后,副本就会过时。此工具只统计顶层记录中的项。
; One lookup each: include, a, mx, ptr, exists, redirect (plus every lookup inside an include)
; No lookup: ip4, ip6, all
; Before: 4 lookups in the top-level record alone
example.com. TXT "v=spf1 a mx include:_spf.mailhost.example include:spf.oldtool.example ~all"
; After: fixed address, unused service removed, bulk mail on its own subdomain
example.com. TXT "v=spf1 ip4:192.0.2.10 include:_spf.mailhost.example ~all"
news.example.com. TXT "v=spf1 include:spf.newsletter.example ~all"
谨慎选择 ~all 或 -all
记录以 ~all(softfail)或 -all(fail)结尾,绝不要使用让任何服务器都通过的 +all。-all 是更严格的信号,但较早检查 SPF 的接收方可能会在 DMARC 看到有效 DKIM 签名之前拒收转发的邮件。已执行 DMARC 策略时,~all 会把决定交给 DMARC。不发送邮件的域名可以发布 v=spf1 -all。
; Choose one ending for example.com, not both
example.com. TXT "v=spf1 include:_spf.mailhost.example ~all"
example.com. TXT "v=spf1 include:_spf.mailhost.example -all"
; A domain that sends no mail
example.net. TXT "v=spf1 -all"
让 DKIM 与 From 域名对齐
当 SPF 或 DKIM 对一个与 From 地址对齐的域名通过时,DMARC 就会通过。许多服务默认用自己的域名签名,这样 DKIM 能通过,但对齐不通过。在每个服务中启用使用你自己域名的签名,让签名带有 d=example.com,并在其选择器下发布服务提供的密钥或 CNAME。默认的宽松对齐接受同一组织域名下的任何子域名;adkim=s 和 aspf=s 要求完全匹配。
; Key for a sending service, selector s1: a CNAME or a TXT record, as the service says
s1._domainkey.example.com. CNAME s1.dkim.mailhost.example.
s1._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOC..."
; Aligned signature in a delivered message: d= matches the From domain
From: news@example.com
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=s1; ...