电子邮件的生命周期
从你点击"发送"到消息出现在某人的收件箱中——每一跳、每一个协议、每一个沿途的决定。
参与者
互联网邮件架构 (RFC 5598) 定义了参与邮件递送的角色。理解这些角色至关重要,因为同一软件通常扮演多个角色,它们之间的边界对于理解邮件如何流动很重要。
| 角色 | 名称 | 功能 |
|---|---|---|
| MUA | 邮件用户代理 | 你用来撰写和阅读电子邮件的应用程序。Outlook、Thunderbird、Gmail 的网页界面、Apple Mail、你手机的邮件应用。 |
| MSA | 邮件提交代理 | 接受来自你的 MUA 的传出电子邮件的服务器。在端口 587 (STARTTLS) 或 465 (隐式 TLS) 上监听。需要身份验证。 |
| MTA | 邮件传输代理 | 在组织之间路由电子邮件的服务器。在端口 25 上使用 SMTP。处理队列、重试和中继决策。 |
| MX | 邮件交换器 | 接收 MTA,由 MX DNS 记录标识。接受来自某个域的传入邮件。 |
| MDA | 邮件递送代理 | 将消息存入收件人的邮箱。应用过滤器、排序规则和垃圾邮件分类。 |
| MRA | 邮件检索代理 | 通过 IMAP 或 POP3 向 MUA 提供邮箱。 |
在实践中,这些角色通常被合并。Gmail 的基础设施同时是 MSA、MTA、MX、MDA 和 MRA。Postfix 可以同时充当 MSA 和 MTA。但逻辑角色保持不同,理解它们有助于调试递送问题。
第一阶段:撰写 (MUA)
生命周期始于用户在其邮件客户端中撰写消息,或应用程序以编程方式生成消息(通过 API 或 SMTP 库)。
MUA 根据 RFC 5322 (互联网消息格式) 构造消息:
To: Bob <bob@example.net>
Subject: 项目更新
Date: Tue, 11 Mar 2026 09:15:00 -0400
Message-ID: <a1b2c3@example.com>
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="boundary42"
--boundary42
Content-Type: text/plain; charset=utf-8
Hi Bob, here is the latest on the project...
--boundary42
Content-Type: text/html; charset=utf-8
<p>Hi Bob, here is the latest on the project...</p>
--boundary42--
此阶段的关键决定:
From:标头向收件人标识作者(这是 DMARC 检查对齐的内容)。Message-ID:被生成——此特定消息的全局唯一标识符。- 应用 MIME 编码:附件进行 Base64 编码,如果需要,正文被构造为多部分。
- MUA 不添加
Received:标头。这些由处理消息的每个服务器添加。
第二阶段:提交 (MUA → MSA)
MUA 连接到 MSA (RFC 6409) 来移交消息。这是 提交 步骤。
220 smtp.example.com ESMTP ready
EHLO alices-laptop.local
250-smtp.example.com
250-STARTTLS
250-AUTH PLAIN LOGIN
250 SIZE 52428800
STARTTLS
220 Ready to start TLS
# TLS 握手完成
EHLO alices-laptop.local
250-smtp.example.com
250-AUTH PLAIN LOGIN
250 SIZE 52428800
AUTH PLAIN AGFsaWNlAHMzY3IzdA==
235 Authentication successful
MAIL FROM:<alice@example.com>
250 OK
RCPT TO:<bob@example.net>
250 OK
DATA
354 Start mail input
[message content]
.
250 OK: queued as ABC123
MSA 在收到消息时所做的工作:
- 验证发送者。 MUA 必须提供有效凭证(通过 AUTH 的用户名/密码)。这就是防止随意他人使用你的邮件服务器作为开放中继的方式。
- 验证信封。 MSA 可能会检查 MAIL FROM 域是否与已验证用户的域相匹配。
- 添加 Received: 标头。 这记录了第一跳:谁提交了消息、何时以及来自哪个 IP。
- 可能会添加或修复标头。 MSA 可以添加缺失的
Date:标头、生成 MUA 未生成的Message-ID:,并添加DKIM-Signature标头。 - 为递送队列消息。 消息进入 MTA 的出站队列。
API 提交路径
使用事务性电子邮件服务(如 Mailer To Go)时,你的应用通常通过 HTTP API 而不是 SMTP 提交。API 服务器接受消息、构建 SMTP 信封和标头、应用 DKIM 签名,并将消息注入 MTA 队列。API 调用替换了 MUA 和 MUA 到 MSA 的 SMTP 事务,但下游的一切保持不变。
第三阶段:路由和传输 (MTA → MTA)
发送 MTA 现在必须将消息递送到收件人的域。这是 中继 阶段,由 RFC 5321 (SMTP) 管理。
DNS 解析
MTA 查找收件人域的 MX 记录:
10 mx1.example.net.
20 mx2.example.net.
它尝试优先级最低的 MX。如果该服务器无法访问,则回退到下一个。有关完整算法的详细信息,请参见 DNS 和邮件路由,包括回退到 A/AAAA 记录和 Null MX 处理。
传输
220 mx1.example.net ESMTP
EHLO sender.mailertogo.com
250-mx1.example.net
250-STARTTLS
250-SIZE 26214400
250 ENHANCEDSTATUSCODES
STARTTLS
220 Ready to start TLS
# TLS 握手——连接现已加密
EHLO sender.mailertogo.com
250-mx1.example.net
250 ENHANCEDSTATUSCODES
MAIL FROM:<alice@example.com>
250 OK
RCPT TO:<bob@example.net>
250 OK
DATA
354 End data with <CR><LF>.<CR><LF>
[message with additional Received: header]
.
250 OK: queued as DEF456
在此阶段:
- STARTTLS 加密连接。 在没有 MTA-STS 或 DANE 的情况下,如果 TLS 协商失败,发送 MTA 将回退到明文。这是一个安全风险——活跃攻击者可以从连接中剥离 TLS。
- 不使用身份验证 (AUTH)。 端口 25 上的服务器到服务器 SMTP 不需要凭证。接收服务器依靠 IP 地址、SPF、DKIM 和 DMARC 来验证发送者。
- 添加另一个 Received: 标头。 每个 MTA 在前面加上一个 Received: 标头,构建一条链来记录消息的路径。
- 消息可能通过多个 MTA。 大型组织内的内部路由、转发规则和邮件列表可以添加额外的跳转。
队列和重试
如果接收 MX 返回 4xx 临时错误(服务器忙碌、灰名单、速率限制),发送 MTA 将消息排队并稍后重试。重试计划通常使用指数退避:15 分钟、30 分钟、1 小时、2 小时等。如果在重试期间(通常为 4-5 天)无法递送消息,MTA 会生成 退信消息 (DSN) 并将其发送回信封发送者。
第四阶段:接收 (MX)
接收 MX(为收件人的域接收传入邮件的 MTA)是大多数过滤发生的地方。这是守门人。
在连接时,在任何消息内容到达之前:
- IP 信誉检查。 接收 MX 根据其内部信誉数据库和外部 黑名单 检查连接 IP。
- 反向 DNS 检查。 IP 应该有一个有效的 PTR 记录,可以解析回相同的 IP。
- 速率限制。 来自同一 IP 的过多连接可能会被限制。
在信封阶段:
- 收件人验证。 邮箱是否存在?如果不存在:
550 5.1.1 User unknown。 - SPF 检查。 MAIL FROM 域根据其 SPF 记录 进行检查,以验证发送 IP 是否被授权。
在 DATA 之后(收到完整消息):
- DKIM 验证。 DKIM 签名 根据 DNS 中的公钥进行验证。
- DMARC 评估。 SPF 和 DKIM 结果针对 DMARC 对齐 与 From: 标头进行检查。
- 内容过滤。 消息通过 垃圾邮件过滤器 进行处理:内容分析、URL 检查、贝叶斯分类、机器学习模型。
- 添加 Authentication-Results 标头。 MX 在 Authentication-Results 标头 中记录所有身份验证检查的结果。
第五阶段:递送 (MDA)
邮件递送代理将通过过滤的消息添加到收件人的邮箱。在许多系统中,MDA 集成到 MX 服务器中,而不是一个单独的过程。
MDA 的职责:
- 邮箱选择。 根据 RCPT TO 地址、别名和路由规则,确定哪个邮箱(用户账户)接收消息。
- 文件夹放置。 基于垃圾邮件过滤器的决定和用户定义的规则,消息转到收件箱、垃圾箱/垃圾邮件文件夹、特定标签 (Gmail) 或自定义文件夹 (Sieve 规则)。
- Sieve 过滤。 许多邮件系统支持 Sieve (RFC 5228),这是一种用户定义的邮件过滤规则语言。规则可以将消息文件保存到文件夹、转发、拒绝或触发假期自动回复。
- 配额强制。 如果邮箱超过配额,MDA 可能会用
452 4.2.2 Mailbox full或552 5.2.2 Mailbox full拒绝消息。 - 通知。 MDA 可能会向用户的设备触发推送通知(新邮件提醒)。
此时,消息 静止 在收件人的邮件存储中。SMTP 事务完成。发送 MTA 的责任在从接收 MX 收到 250 OK 时结束。
第六阶段:检索 (MRA → MUA)
收件人的邮件客户端使用以下三个协议之一从邮件存储中检索消息:
IMAP (RFC 9051)
主要的邮件访问协议。IMAP 将消息保留在服务器上并同步状态(已读/未读、标志、文件夹)跨多个客户端。客户端首先下载消息标头,按需获取完整正文。在一个客户端上所做的更改(标记为已读、移动到文件夹)会反映在所有客户端上。
POP3 (RFC 1939)
较旧的、更简单的协议。POP3 将消息下载到客户端并(默认情况下)从服务器删除它们。它不在客户端之间同步状态。在很大程度上被 IMAP 取代,但仍在某些场景中使用。
网页和 API 访问
网页邮件界面(Gmail、Outlook.com)和移动应用通过专有 API 或 JMAP (RFC 8620) 访问邮件存储,完全绕过 IMAP/POP3。消息永远不会离开提供商的服务器——客户端通过网页请求显示它。
事情出错的地方:每个阶段的失败模式
提交失败
身份验证失败(密码错误、令牌过期)、MSA 拒绝消息(超过大小限制、政策违反)或连接超时。用户立即看到错误。
路由失败
DNS 解析失败(无 MX 记录、DNS 超时)、所有 MX 主机无法访问或每个 MX 返回永久错误。重试耗尽后,发送者收到 退信 (DSN)。
接收时拒绝
接收 MX 在 SMTP 时拒绝消息:黑名单 IP (550)、身份验证失败 (550 5.7.1)、未知收件人 (550 5.1.1) 或内容拒绝 (554)。发送 MTA 生成退信通知到信封发送者。
接受后过滤
MX 接受了消息 (250 OK),但 MDA 基于内容分析和 信誉评分 将其路由到垃圾文件夹。发送者不会收到退信——消息在技术上被"递送"了——但收件人永远看不到。这是最常见且最难诊断的可递送性问题。
邮箱已满
收件人的邮箱已超过配额。根据实现情况,这要么在 RCPT TO 时被拒绝,要么在 DATA 接受后生成退信。
标头讲述故事
生命周期的每个阶段都会向消息添加标头。从下到上阅读标头来重建旅程:
Received: from sender.mailertogo.com (198.51.100.42)
by mx1.example.net with ESMTPS id DEF456
for <bob@example.net>;
Tue, 11 Mar 2026 13:15:02 +0000
Authentication-Results: mx1.example.net;
spf=pass smtp.mailfrom=example.com;
dkim=pass header.d=example.com;
dmarc=pass header.from=example.com
# 由发送 MTA/MSA 添加(第一跳,标头底部)
Received: from alices-laptop.local (192.0.2.10)
by smtp.example.com with ESMTPSA id ABC123
for <bob@example.net>;
Tue, 11 Mar 2026 13:15:00 +0000
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=mtg; ...
Received: 标头是面包屑。每一个都记录发送主机、接收主机、使用的协议(ESMTP、用于 TLS 的 ESMTPS、用于已验证+TLS 的 ESMTPSA)、队列 ID 和时间戳。有关完整指南,请参见 电子邮件标头的解剖。
事务性电子邮件路径
当应用程序通过 Mailer To Go 等服务发送电子邮件时,生命周期略有不同:
- 应用调用 API。 你的应用发送带有消息内容、收件人和元数据的 POST 请求。
- 服务构造消息。 它构建 MIME 结构、添加必需的标头(Date、Message-ID、List-Unsubscribe,如适用)并使用你的域密钥应用 DKIM 签名。
- 服务的 MTA 发送消息。 消息从服务的 IP 通过端口 25 上的 SMTP 发送到收件人的 MX,并带有 STARTTLS。
- 其余的相同。 MX 接收、身份验证检查、内容过滤、MDA 递送和客户端检索都按上述方式进行。
关键区别:你的应用从不直接与 SMTP 通信。API 抽象了整个提交层。但消息仍然通过相同的基础设施,经历相同的身份验证检查,并由相同的垃圾邮件过滤器评估。
关键要点
- 电子邮件有六个不同的阶段: 撰写、提交、传输、接收、递送和检索。每个阶段涉及不同的协议和不同的参与者。
- 信封和消息是分离的。 MAIL FROM / RCPT TO(信封)可以与 From: / To: 标头(消息)不同。这个区别对于身份验证、退信和密件抄送很重要。
- 大多数过滤发生在接收阶段。 接收 MX 是评估身份验证、信誉和内容的地方。这是决定收件箱 vs. 垃圾邮件的阶段。
- 250 OK 意味着接受,而不是递送到收件箱。 接收 MX 仍可能将消息路由到垃圾邮件,或 MDA 可能稍后拒绝(邮箱已满、Sieve 规则)。
- Received: 标头记录了旅程。 从下到上阅读它们以追踪消息的路径。它们是用于递送问题的单一最有用的调试工具。
- 每一跳都增加延迟和风险。 更多跳转意味着更多失败、延迟或内容修改的机会(可能会破坏 DKIM 签名)。