RFC 5321 – 简单邮件传输协议
为什么存在这份RFC
SMTP是驱动电子邮件的最古老和最基础的协议。其血统可以追溯到RFC 821,由Jon Postel在1982年发布。RFC 5321发布于2008年,是当前的权威规范。它将数十年的扩展、澄清和运营经验整合为一份权威文件。
从RFC 821到5321的主要演变包括:ESMTP(扩展SMTP)的正式化、对中继与提交行为的澄清、对DNS MX查询的更严格要求、地址字面量和IPv6规则的更新,以及退信处理的要求。这份RFC是其他每份电子邮件RFC都建立其上的基础。
工作原理
SMTP事务是两台服务器通过TCP连接(传统上使用端口25)之间的结构化对话。该协议是基于文本且面向行的——每条命令和响应都是可读的ASCII。
SMTP模型
SMTP定义了三个角色:
- SMTP客户端(发送方-SMTP):启动连接以传输消息的系统。
- SMTP服务器(接收方-SMTP):接受连接并接收消息的系统。
- SMTP中继:接收消息并将其转发到最终目的地的服务器,既充当客户端也充当服务器。
客户端连接,使用EHLO标识自己,指定信封发送者(MAIL FROM),一个或多个收件人(RCPT TO),然后传输消息数据(DATA)。服务器用三位数状态码响应每条命令。
SMTP命令
| 命令 | 用途 |
|---|---|
EHLO |
标识客户端并请求扩展功能。替代了较早的HELO。 |
MAIL FROM:<addr> |
指定信封发送者(退信的返回路径)。 |
RCPT TO:<addr> |
指定收件人。每个收件人发出一次。 |
DATA |
开始消息内容传输。以单独一行的.结束。 |
RSET |
中止当前事务并重置状态。 |
VRFY |
验证用户是否存在(很少支持,因为容易被滥用)。 |
EXPN |
展开邮件列表(很少支持)。 |
NOOP |
无操作;保持连接活跃。 |
QUIT |
关闭连接。 |
回复码
每条服务器响应都以三位数代码开头。第一位数字告诉客户端发生了什么:
- 2xx——成功。请求的操作已完成。
-
3xx——中间。服务器需要更多输入(在
DATA后使用)。 - 4xx——临时失败。客户端应稍后重试。示例:邮箱满(452)、服务器忙(421)。
- 5xx——永久失败。不要重试。示例:用户未知(550)、语法错误(500)、中继被拒(553)。
第二位数字缩小分类:x0x = 语法、x1x = 信息、x2x = 连接、x5x = 邮件系统。RFC 3463进一步使用增强状态码进行扩展,如5.1.1(错误目标邮箱)。
关键技术细节
信封与首部
SMTP中的一个关键区别是信封和消息首部之间的区别。信封(MAIL FROM和RCPT TO)控制路由——它告诉服务器在哪里传递消息。消息首部(From:、To:、Subject:)是在DATA期间传输的消息正文的一部分,是收件人看到的内容。这些可以不同,在邮件列表、密送和转发等情况下合法地不同。
MX查询过程
当客户端需要传递到user@example.com时,它会查询DNS以获取example.com的MX记录。RFC 5321定义的过程:
- 查询域的MX记录。按优先级排序(数字越小=优先级越高)。
- 如果不存在MX记录,回退到域本身的A或AAAA记录。
- 如果MX记录指向
.(根据RFC 7505的"空MX"),该域不接受邮件。 - 按优先级顺序尝试每个MX主机。如果服务器返回4xx错误,尝试下一个主机。
行长度和数据透明度
SMTP要求消息中的行长度不超过998个字符(不包括CRLF),建议限制为78个字符。数据结束标记是仅包含句点(.)的一行。如果消息正文中的一行以句点开头,客户端必须通过在前面添加额外的句点来"填充点",服务器必须将其剥离。
超时
RFC 5321指定了客户端必须遵守的最小超时:
- 初始问候:5分钟
- MAIL命令:5分钟
- RCPT命令:5分钟
- DATA启动:2分钟
- 数据块:3分钟
-
DATA结束(最后的
.):10分钟
这些慷慨的超时存在是因为接收服务器可能在响应最后一个点之前执行昂贵的检查(垃圾邮件过滤、病毒扫描)。
SMTP示例
传递消息的完整SMTP事务:
常见错误
-
混淆信封和首部地址。
MAIL FROM信封地址与From:首部不同。SPF检查信封发送者;DKIM对首部进行签名。弄错这一点会导致身份验证失败。 -
忽视4xx与5xx的区别。
450表示"稍后重试"——你应该排队并使用指数退避重试。550表示"永远不会成功"——继续重试会产生不必要的流量,并可能损害你的发送者信誉。 -
不处理多行响应。像
250-(带连字符)这样的响应表示后面还有更多行。只有250(带空格)表示最后一行。 -
不发送EHLO。使用旧的
HELO命令而不是EHLO意味着你将无法发现服务器扩展,如STARTTLS、SIZE或PIPELINING。始终使用EHLO。 - 超过行长度限制。超过998个字符的行违反规范,可能导致消息损坏。对长内容使用MIME编码。
-
忽视空发送者。退信消息(DSN)使用空的
MAIL FROM:<>。拒绝空发送者会破坏退信循环防止机制。 -
未实现点填充。如果消息正文有以
.开头的行,服务器将解释为数据结束,除非你加倍该点。
可交付性影响
RFC 5321合规性直接影响你的电子邮件是否到达收件箱:
- 正确的EHLO主机名。你的EHLO主机名应该在DNS中可解析(正向和反向)。许多接收服务器检查EHLO名称是否有有效的A/AAAA记录,以及你的IP的反向DNS是否匹配。不匹配是垃圾邮件信号。
- 退信处理。RFC 5321要求发送者处理退信。如果你忽视DSN,你将继续发送到无效地址,这会破坏你的发送者信誉。邮箱提供商密切跟踪你的退信率。
- 重试行为。针对4xx错误使用指数退避的适当重试逻辑显示你是一个行为良好的发送者。积极的重试行为可能会触发速率限制或列入黑名单。
- 连接行为。打开太多与单个MX的同时连接,或在被拒后太快重新连接,是与垃圾邮件相关的模式。尊重连接限制并适当地进行限流。
-
信封对齐。SPF和DMARC依赖
MAIL FROM域。确保你的信封发送者域与你的From:首部域对齐对于通过身份验证检查至关重要。