跳到主要内容

3. SMTP 过程: 概述 (The SMTP Procedures: An Overview)

本节概述 SMTP 操作, 包括会话启动, 邮件事务, 地址验证, 中继, 网关处理和会话终止.

3.1. 会话启动 (Session Initiation)

SMTP 会话由发送 SMTP (客户端) 与接收 SMTP (服务器) 建立双向传输信道而启动. 该信道完全异步, 没有数据流限制. TCP 连接完成后, 服务器通常发送 "220 Service ready" 响应. 客户端通常在收到该 greeting 后开始操作.

3.2. 客户端启动 (Client Initiation)

一旦传输服务提供初始化信道且服务器发送 220 service ready greeting, 客户端通常发送 EHLO 命令来标识自身, 并请求服务器告知任何可用服务扩展. 如果服务器不支持扩展, 它会以 500 错误响应 EHLO, 客户端应 fallback 到 HELO 命令.

EHLO 命令示例:

S: 220 smtp.example.com ESMTP Postfix
C: EHLO client.example.com
S: 250-smtp.example.com
S: 250-SIZE 52428800
S: 250-8BITMIME
S: 250-STARTTLS
S: 250 HELP

3.3. 邮件事务 (Mail Transactions)

邮件事务由一系列命令组成, 将消息从客户端传输到服务器. 邮件事务包含:

  1. MAIL command - 标识消息发起者
  2. 一个或多个 RCPT commands - 标识消息接收者
  3. DATA command - 传输消息内容

完整事务示例:

C: MAIL FROM:<[email protected]>
S: 250 Ok
C: RCPT TO:<[email protected]>
S: 250 Ok
C: RCPT TO:<[email protected]>
S: 250 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: From: [email protected]
C: To: [email protected]
C: Subject: Test message
C:
C: This is a test message.
C: .
S: 250 Ok: queued as 12345

MAIL 命令开始一个邮件事务. 该命令成功完成后, 接收方清除其所有缓冲区和状态表, 并准备接收 RCPT 命令.

RCPT 命令标识邮件的单个接收者. 对于给定消息, 可以发出多个 RCPT 命令. 成功的 RCPT 命令会把接收者添加到缓冲区.

DATA 命令使后续行被视为消息文本而不是命令. 消息以只包含一个句点 (.) 的行终止.

3.4. 用于地址修正或更新的转发 (Forwarding for Address Correction or Updating)

某些服务器可能希望把邮件转发到修正或更新后的地址, 而不是原始接收者地址. SMTP 为此提供响应代码 251 和 551. 这些代码允许服务器通知客户端用户地址已变更, 但服务器会尝试转发 (251), 或无法转发 (551) 该消息.

3.5. 地址调试命令 (Commands for Debugging Addresses)

3.5.1. 概述 (Overview)

SMTP 提供两个命令用于验证用户名和邮件列表:

  • VRFY - 验证用户名或邮箱
  • EXPN - 展开邮件列表

这些命令主要用于调试目的, 许多服务器出于安全和隐私原因会禁用或限制它们.

3.5.2. VRFY 正常响应 (VRFY Normal Response)

VRFY 命令的成功响应通常是代码 250, 后跟包含用户全名和邮箱地址的文本.

示例:

C: VRFY Jones
S: 250 Fred Jones <[email protected]>

3.5.3. VRFY 或 EXPN 成功响应的含义 (Meaning of VRFY or EXPN Success Response)

VRFY 和 EXPN 命令的成功响应并不保证该地址能够接收邮件或邮件一定会被投递. 它只表明服务器知道该地址且其语法有效.

3.5.4. EXPN 的语义和应用 (Semantics and Applications of EXPN)

EXPN 命令用于展开邮件列表或别名. 它返回列表中的所有地址.

示例:

C: EXPN staff
S: 250-Alice <[email protected]>
S: 250-Bob <[email protected]>
S: 250 Charlie <[email protected]>

3.6. 中继和邮件路由 (Relaying and Mail Routing)

3.6.1. 源路由和中继 (Source Routes and Relaying)

源路由, 即显式指定经过中间主机的路径, 在现代 SMTP 中已被弃用. 邮件路由应依赖 DNS MX 记录.

3.6.2. Mail eXchange 记录和中继 (Mail eXchange Records and Relaying)

DNS MX (Mail eXchanger) 记录系统用于识别负责接受某个域邮件的邮件服务器. 投递邮件时:

  1. 查询目标域的 MX 记录
  2. 按优先级排序 (数字越小优先级越高)
  3. 按优先级顺序尝试投递到服务器
  4. 如果所有 MX 记录失败, 尝试直接投递到 A/AAAA 记录

DNS MX 记录示例:

example.com.  IN MX 10 mail1.example.com.
example.com. IN MX 20 mail2.example.com.
example.com. IN MX 30 mail3.example.com.

3.6.3. 作为中继的消息提交服务器 (Message Submission Servers as Relays)

消息提交代理 (Message Submission Agents, MSAs) 充当专门的 relay:

  • 从 Mail User Agents (MUAs) 接收邮件
  • 执行提交策略
  • 添加必需头部
  • 认证发送者
  • 转发到适当的 MTAs

3.7. 邮件网关 (Mail Gatewaying)

邮件网关连接 SMTP 基础设施与其他邮件系统 (例如 X.400, UUCP). 网关在协议和格式之间进行转换.

3.7.1. 网关中的头部字段 (Header Fields in Gatewaying)

网关必须保留必要头部字段, 并可以添加网关特定字段. 转换应尽可能保持语义等价.

3.7.2. 网关中的 Received 行 (Received Lines in Gatewaying)

网关必须添加 Received 头部字段以跟踪消息路径, 包括:

  • 网关标识
  • 时间戳
  • 协议信息

3.7.3. 网关中的地址 (Addresses in Gatewaying)

地址转换复杂且依赖具体网关. 网关应:

  • 保留原始地址信息
  • 提供双向地址映射
  • 记录转换规则

3.7.4. 网关中的其他头部字段 (Other Header Fields in Gatewaying)

网关必须适当处理各种头部字段:

  • From, To, Cc, Bcc (地址字段)
  • Subject, Keywords (文本字段)
  • Date (时间戳转换)
  • Message-ID (唯一标识符保留)

3.7.5. 网关中的 Envelope (Envelopes in Gatewaying)

SMTP envelope (MAIL FROM 和 RCPT TO) 可能不同于头部地址. 网关必须正确处理二者.

3.8. 终止会话和连接 (Terminating Sessions and Connections)

SMTP 会话通过 QUIT 命令终止:

C: QUIT
S: 221 smtp.example.com closing connection

发送 221 响应后, 服务器关闭 TCP 连接. 客户端应等待 221 响应再关闭, 但必须准备好处理服务器先关闭连接的情况.

异常终止: 如果发生严重错误, 任一方都可以立即关闭连接. 服务器可在关闭前使用响应代码 421 表示服务不可用.

3.9. 邮件列表和别名 (Mailing Lists and Aliases)

3.9.1. 别名 (Alias)

别名是一个邮箱名称, 解析后指向一个或多个其他邮箱名称. 别名展开对发送者透明.

示例: [email protected] 可能是 [email protected] 的别名

3.9.2. 列表 (List)

邮件列表类似于别名, 但通常:

  • 由列表管理软件管理
  • 允许订阅/退订
  • 可以修改消息 (添加头部, footer)
  • 维护订阅者数据库

当邮件发送到列表时, 列表会展开并投递给所有订阅者. 列表软件通常:

  • 添加列表特定头部 (List-ID, List-Unsubscribe)
  • 可能要求 moderation
  • 处理 bounce
  • 维护归档