SMTP — 简单邮件传输协议

邮件的『发送』协议:应用层,基于 TCP 25(提交用 587/465),由 RFC 5321 定义

1. 协议定位

项目信息
所属层应用层(Application Layer)
英文全称Simple Mail Transfer Protocol(简单邮件传输协议)
主要 RFCRFC 5321(SMTP 主标准,取代 RFC 2821/821);RFC 5322(邮件报文格式);RFC 3207(STARTTLS);RFC 4954(AUTH);RFC 6409(Message Submission,587);RFC 8314(隐式 TLS,465);RFC 2045–2049(MIME)
端口TCP 25(MTA 之间中继)、TCP 587(客户端提交 Submission,STARTTLS)、TCP 465(Submissions,隐式 TLS)
封装于TCP(面向连接、可靠、有序),文本行式命令,行结束符为 CRLF
典型应用邮件客户端投递邮件到自家服务器;邮件服务器之间投递邮件(如 QQ 邮箱 → Gmail)

2. 一句话理解

SMTP 是"推"协议,只管把邮件从发送方推到收件服务器;至于用户怎么把邮件"拉"下来看,那是 POP3 / IMAP 的事。

生活化类比

把 SMTP 想象成邮局的投递系统:你把写好的信塞进信封,在信封外面写上寄件人和收件人(这就是 SMTP 的信封 MAIL FROM / RCPT TO),然后交给邮局。邮局只负责一站一站地把信送到对方邮局的收发室,不负责替你开信箱取信

而信封上的地址和信纸里落款写的名字可以完全不一样——这正是伪造发件人显示名的原理,也是后来必须加装 SPF/DKIM/DMARC 这几把"防伪锁"的原因。

3. 它解决什么问题

为什么没有它,网络就"缺了一块":

早期互联网需要一个跨主机、跨组织的统一邮件投递机制。SMTP 用一套纯文本、可人工朗读的命令/响应对话解决了三件事:

  1. 谁发、发给谁:通过 MAIL FROM:RCPT TO: 建立"信封(Envelope)",与邮件正文里的 From: / To: 头部(Header)相互独立——这正是伪造发件人显示名的根源,也是 SPF/DKIM/DMARC 出现的原因。
  2. 内容怎么传DATA 命令后以 <CRLF>.<CRLF> 作为结束标记传输报文;二进制附件由 MIME 编码(Base64 / Quoted-Printable)成 7bit ASCII。
  3. 跨域怎么走:发送方通过 DNS 查询目标域的 MX 记录找到对方 MTA,逐跳中继(Relay),每跳追加一条 Received: 头,形成可追溯的投递路径。

4. 核心特征

  • 【文本行协议】:命令 4 个字母 + 参数,响应 3 位数字状态码 + 说明文字,可用 telnet/openssl s_client 手工敲完整会话。
  • 【状态码分级】2xx 成功、3xx 中间态(如 354 等待数据)、4xx 临时失败(会重试)、5xx 永久失败(退信)。4xx 与 5xx 的区分是排错第一要点。
  • 【ESMTP 扩展机制】:用 EHLO 替代 HELO,服务器以多行 250 响应回报支持的扩展(STARTTLSAUTHSIZE8BITMIMEPIPELININGDSN 等)。
  • 【存储转发】(Store and Forward):投递失败不会立刻丢弃,MTA 入队重试(典型重试窗口 4 小时提醒、4~5 天放弃),故邮件延迟可达数小时。
  • 【只发不收】:SMTP 服务器不提供"列出邮箱里的信"这类能力。
  • 【默认明文,安全靠叠加】:机密性由 STARTTLS/隐式 TLS 提供,身份真实性由 SMTP AUTH + SPF/DKIM/DMARC 提供。

5. 与其他协议的关系

相关协议关系
DNSSMTP 靠 MX 记录定位对端 MTA;无 MX 时回退到 A/AAAA 记录
TCPSMTP 的承载层,保证命令与报文按序可靠到达
TLS通过 STARTTLS(587/25)或隐式 TLS(465)加密整条会话
POP3 / IMAP互补而非竞争:SMTP 负责,POP3/IMAP 负责
MIME不是独立协议,而是邮件报文的内容格式扩展,让 SMTP 能携带附件与多语言字符

6. 本目录学习路线

  1. 01-原理与报文 — SMTP 命令集与响应码、信封与报文头的区别、MIME 结构、完整投递时序图。
  2. 02-实战与排错 — Wireshark 抓包过滤、telnet/openssl 手工发信、退信码解读、开放中继与鉴权失败排查、与 POP3/IMAP 对比速查。

学习建议:先手工用 telnet 敲一遍完整会话(EHLO → MAIL FROM → RCPT TO → DATA → .),比看十遍文档都管用。之后再理解 STARTTLS 与 AUTH 是如何"插进"这条会话的。

初学者最常踩的坑:把信封发件人MAIL FROM:)和报文头部 From: 当成同一个东西。它们相互独立,头部 From: 可以随便写,这才是钓鱼邮件能"显示成银行"的原因。另外别忘了 4xx 是临时失败会自动重试、5xx 才是永久退信,两者的处理方式完全不同。