邮件送达率:10 分钟讲清

邮件投递有两个彼此独立的结果:接收服务器可能接受了这封信,而它的过滤器仍然可能把信丢进垃圾箱。身份认证证明的是域名身份,它买不到收件箱位置。我的建议很直接:不要让营销邮件和密码重置走同一条发信通道。

🎙️ 发布并录制于: ·

01把事务邮件和营销邮件分成两条通道

事务邮件是由用户的动作触发的:密码重置、收据、安全提醒、账号通知。营销邮件是推广或者内容类的,必须很容易退订。两者在紧急程度、用户同意、发送量和投诉模式上都不一样。把它们放在不同的子域名和不同的发信通道上;等发送量大到值得上专用基础设施时,最好再把 IP 池也分开。

# One practical identity split
[email protected]   # transactional
[email protected]  # marketing

Return-Path: [email protected]
DKIM-Signature: ... d=notify.example.com; s=tx2026;

List-Unsubscribe: <https://example.com/unsubscribe/...>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
为什么这个拆分很重要

一次做得差的营销活动会招来投诉,进而拖累那条正被紧急登录邮件用着的信誉。把通道分开,就给信誉、限速、抑制规则和事故定位划出了边界。不要因为账号确实存在,就把每周的产品促销叫成「事务邮件」。

02SMTP 信封不是收件人看到的 From

SMTP 在传消息头之前,先传的是 envelope sender 和 envelope recipients。envelope sender 后面会体现为 Return-Path,它接收 bounce,也是 SPF 实际校验的那个身份。消息头里的 From 才是人看到的地址,也是 DMARC 保护的对象。这两个地址可以不一样,但它们的域名需要刻意做对齐。

S: 220 mx.receiver.test ESMTP
C: EHLO mail.notify.example.com
C: MAIL FROM:<[email protected]>
C: RCPT TO:<[email protected]>
C: DATA
C: From: Example Receipts <[email protected]>
C: To: Alex <[email protected]>
C: Subject: Your receipt

Envelope MAIL FROM → SPF and bounces
Header From        → visible identity and DMARC alignment

邮件被退回的时候,把 SMTP 应答、队列 ID、收件人、发信通道和服务商的 message ID 都留下来。一张写着「邮件发送失败」的截图,把唯一有用的证据丢干净了。

03SPF 授权的是 envelope sender

SPF 是发布在 envelope sender 域名上的一条 DNS TXT 策略。它说明哪些主机可以用这个域名发信。每个域名只发布一条 SPF 记录,把所有合法发信方都包含进去,保持在十次 DNS 查询的上限之内,并且用一个明确的策略结尾。SPF 本身并不校验收件人看到的 From 地址。

# DNS TXT at bounces.notify.example.com
v=spf1 include:spf.mail-provider.example -all

Received-SPF: softfail (domain of transitioning
[email protected] does not designate 192.0.2.44
as permitted sender) client-ip=192.0.2.44;
SPF softfail 的修法

第一:读 Return-Path,确认真正被检查的是哪个域名。第二:从 Received-SPF 里记下 client IP。第三:查这个域名确切的 TXT 记录,并把 include 展开。第四:加上服务商文档里给的 include 或者 IP,删掉已经不用的发信方,并且只保留一条 SPF 记录。第五:等 DNS 生效,再发一封新的信。不要在原来那条旁边再贴一条 v=spf1;多条记录会产生永久错误。

04DKIM 签的是实际到达的那封邮件

DKIM 给选定的消息头和正文加上一个密码学签名。签名里用 d 指出域名,用 s 指出 selector。接收方会去「selector 点 下划线 domainkey 点 签名域名」这个位置取公钥。条件允许时至少用 2048 位密钥,定期轮换 selector,并且在旧邮件还可能被验证的期间,保留旧密钥的记录。

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=notify.example.com; s=tx2026;
 h=from:to:subject:date:message-id; bh=...; b=...

Authentication-Results: mx.receiver.test;
 dkim=fail (DKIM signature verification failed)
 header.d=notify.example.com header.s=tx2026;
DKIM 验签失败的修法

第一:从失败的签名里抄出 d 和 s 的值。第二:检查 tx2026._domainkey.notify.example.com 上的 TXT 记录。第三:确认这个公钥和发信方实际用的私钥 selector 是配对的。第四:查一查有没有中继、签名档工具或者邮件列表,在签名之后改动了被签的消息头或者正文。第五:把签名放到所有改动之后,再发一封新的信。selector 名字写错,比密码学本身出问题常见得多。

05DMARC 要的是对齐,不是两个绿勾

DMARC 通过的条件是:要么 SPF 通过、并且 envelope 域名对齐,要么 DKIM 通过、并且签名域名对齐。对齐比的是这些域名和收件人看到的消息头 From 域名。宽松对齐允许同一个组织域名下的子域名,严格对齐要求完全一致。服务商那个跟你无关的 bounce 域名过了 SPF,对你的 DMARC 结果没有帮助。

From: [email protected]
Return-Path: [email protected]   # SPF pass, not aligned
DKIM-Signature: d=notify.example.com; ...   # DKIM pass, aligned relaxed

# Start by collecting reports; enforce after every sender is known.
_dmarc.example.com TXT
v=DMARC1; p=none; rua=mailto:[email protected]; pct=100

# Later: p=quarantine, then p=reject
550 5.7.26 This mail is unauthenticated, which poses a security risk
to the sender and users, and has been blocked. The sender must
authenticate with at least one of SPF or DKIM.
550 5.7.26 的修法

第一:拿一封失败的样本看 Authentication-Results,分别认清 SPF、DKIM 和 DMARC 的结果。第二:核对 Return-Path 域名的 SPF,以及那个确切 selector 的 DKIM DNS 记录。第三:让至少一个通过的身份,和消息头 From 的域名对齐。第四:从真实的生产发信通道重测,不要用后台的预览功能。第五:在报告显示所有合法发信源都清楚之前,DMARC 就留在监控档;把执行策略放松,并不能补上缺失的认证。

06PTR 和 HELO 必须描述发信主机

接收服务器看到的是连过来的 IP,以及 EHLO 或者 HELO 里声明的主机名。这个 IP 应该能通过 PTR 反解到一个真实的邮件主机名,而这个主机名要能正解回同一个 IP。PTR 得通过 IP 的所有者去设,通常是你的主机商或者邮件服务商。普通的 DNS 托管,没法给一个不属于你的地址创建反向解析。

192.0.2.44 PTR mail.notify.example.com.
mail.notify.example.com A 192.0.2.44
EHLO mail.notify.example.com

550 5.7.1 Client host rejected: cannot find your reverse hostname

# Verify both directions
dig -x 192.0.2.44 +short
mail.notify.example.com.
dig mail.notify.example.com A +short
192.0.2.44

遇到这种拒收,先从最早那条外部 Received 头里确认出口 IP。让 IP 提供方把 PTR 设好,建上对应的 A 记录,把邮件服务器的 HELO 配成这个主机名,然后重新连接。PTR 指向一个云厂商的通用名字,技术上能解析,但仍然是很差的身份。

07发信信誉跟的是行为,不是 DNS 配得多完美

身份认证回答的是这封信是谁发的。信誉问的是收件人到底想不想收这个域名和这个 IP 发来的邮件。complaint rate、hard bounce、垃圾陷阱、互动情况、发送量突增,还有内容的一致性,全都算在里面。一个全新的专用 IP 没有可用的信誉,要靠大家想收的邮件和稳定的日发量把它养起来。发送量小的时候,一个信誉不错的共享 IP 池,往往比你自己那个冷 IP 更安全。

# Watch trends by stream and mailbox provider
accepted rate      99.4%
temporary deferral  2.1%
hard bounce         0.6%
complaint            0.08%

421 4.7.0 Temporary System Problem. Try again later.
451 4.7.1 Please try again later

遇到临时的延迟投递,把原始应答留着,把发往这个目的地的速率降下来,用指数退避加抖动重试,同时查一查最近发送量或者投诉有没有变化。不要从好几台服务器上每分钟重试一次,那会把限流变成滥发行为。信誉恢复靠的主要是持续地少发那些没人想要的邮件。

08bounce 和投诉是控制信号

hard bounce 表示这个地址永久无法投递,应该立刻抑制。soft bounce 是临时的,可以带上限地重试。complaint 表示收件人把这封信标成了垃圾邮件;要立刻在对应的营销通道上把这个收件人抑制掉。把服务商推来的事件解析成原因、增强状态码、收件人、活动,以及永久还是临时这个分类。

550 5.1.1 The email account that you tried to reach does not exist.
552 5.2.2 Mailbox full
421 4.4.2 Connection timed out

5.1.1 → hard bounce → suppress address now
5.2.2 → policy-dependent retry, then suppress after limit
4.4.2 → retry with backoff; preserve attempt history
complaint event → suppress immediately; audit source and campaign
别把这些区别抹平

很多系统把所有失败都存成「bounced」,运营就此变成瞎子。第一:保留原始的 SMTP 诊断信息。第二:解析增强状态码。第三:分清永久失败、临时失败、投诉和策略拦截。第四:套用按通道区分的抑制规则。第五:把原因暴露给客服,但不要把收件人数据大范围暴露出去。

09名单卫生从用户同意开始

地址质量重要的时候就用二次确认订阅,记录来源和同意时间,在录入环节就校验明显的格式错误,并且只发当初承诺的那类邮件。按一份写下来的策略,清掉 hard bounce、投诉,以及长期不互动的收件人。绝对不要买名单。买来的东西里全是失效地址、垃圾陷阱,以及根本没打算听你说话的人。

# Minimum subscription audit record
address: [email protected]
source: pricing-page-form
consented_at: 2026-07-25T10:42:13Z
confirmed_at: 2026-07-25T10:44:02Z
policy_version: marketing-v3

# Every marketing message
visible unsubscribe link
one-click unsubscribe headers
working preference endpoint
suppression applied before queueing

不要单纯为了让打开率的图表好看一点,就把不互动的人删掉;也不要一直给他们发下去。按你自己的发信节奏,定一个逐步停发的流程。另外,对打开率要保守看待,因为隐私代理会把它抬高;点击、回复、购买和用户明确表达的偏好,才是更强的信号。

10邮件头要从接收方往回读

对于已经投递的邮件,先把原始信源下载下来。Received 头要从最下面往上读,才能还原出这封信走过的路径。找到接收方加上的 Authentication-Results,然后对比消息头 From、Return-Path、DKIM 的 d 和 s、Message-ID、Date,以及退订相关的头。对于被拒收的邮件,从 SMTP 应答开始看,因为可能根本没有最终的消息头。

# Header triage
Authentication-Results: spf=pass; dkim=pass; dmarc=pass
From: visible domain used for DMARC
Return-Path: envelope domain used for SPF and bounces
DKIM-Signature: d= signing domain; s= selector
Received: route, timestamps, connecting identities
Message-ID: stable correlation key

# Fix order
1. Capture raw SMTP reply or raw received message
2. Identify stream, provider message ID, recipient, and timestamp
3. Verify PTR ↔ A and HELO for the outbound IP
4. Verify one SPF record for the Return-Path domain
5. Verify DKIM selector DNS and post-signing modifications
6. Verify SPF or DKIM alignment with header From
7. Check bounce, complaint, volume, and reputation trends
8. Send a new test; old messages do not re-authenticate

# Meaning of common results
550 5.7.26 unauthenticated → repair SPF/DKIM and alignment
SPF softfail → actual IP not authorized for envelope domain
DKIM signature failed → key mismatch or message changed
550 5.1.1 → suppress nonexistent recipient
421 / 451 → defer and retry with controlled backoff

我的顺序是:身份第一,信誉第二,内容最后。如果服务器说的是 SPF softfail,那么改标题就是迷信。如果认证都通过了,但某一家邮箱服务商在限流你的活动,就去查那边的受众质量、投诉和发送量。送达率是一个持续运转的运营反馈回路,不是一次配完就结束的 DNS 任务。

Tell me what missed

A correction is more useful than a compliment. This goes straight to the person who writes SwiftGrasp.

Was this page useful?
0/1000

Please do not include passwords, private keys, or personal information.