Skip to main content

2. The SMTP Model (SMTP模型)

2.1. Basic Structure (基本结构)

SMTP设计可以描述为:

                  +----------+                +----------+
+------+ | | | |
| User |<-->| | SMTP | |
+------+ | Client- |Commands/Replies| Server- |
+------+ | SMTP |<-------------->| SMTP | +------+
| File |<-->| | and Mail | |<-->| File |
|System| | | | | |System|
+------+ +----------+ +----------+ +------+
SMTP client SMTP server

当SMTP客户端有消息要传输时,它会与SMTP服务器建立双向传输通道。SMTP客户端的责任是将邮件消息传输到一个或多个SMTP服务器,或报告其失败。

邮件消息如何呈现给SMTP客户端,以及该客户端如何确定要将邮件消息传输到的域的标识符 ("名称"),是本地事务,本文档不涉及。在某些情况下,指定的域或SMTP客户端确定的域将标识邮件消息的最终目的地。在其他情况下,常见于与POP (RFC 937 [15], RFC 1939 [16]) 或IMAP (RFC 3501 [17]) 协议实现相关的SMTP客户端,或当SMTP客户端位于隔离的传输服务环境中时,确定的域将标识一个中间目的地,所有邮件消息都将通过该目的地中继。无论与单个消息关联的目标域如何,都传输所有流量的SMTP客户端,或者不维护用于重试最初无法完成的消息传输的队列的SMTP客户端,可能在其他方面符合本规范,但不被视为完全能力 (fully-capable) 的客户端。完全能力的SMTP实现,包括这些能力较弱的客户端使用的中继及其目的地,应支持本规范中讨论的所有队列、重试和备用地址功能。在许多情况和配置中,上述能力较弱的客户端应该 (SHOULD) 使用消息提交协议 (RFC 4409 [18]) 而不是SMTP。

SMTP客户端一旦确定了目标域,如何确定要将消息副本传输到的SMTP服务器的身份,然后执行该传输,本文档将涵盖这一点。为了实现到SMTP服务器的邮件传输,SMTP客户端与该SMTP服务器建立双向传输通道。SMTP客户端通过将目标域名解析为中间邮件交换器 (Mail eXchanger) 主机或最终目标主机来确定运行SMTP服务器的适当主机的地址。

SMTP服务器可以是最终目的地或中间"中继" (relay) (即它可以在接收消息后承担SMTP客户端的角色) 或"网关" (gateway) (即它可以使用SMTP以外的某些协议进一步传输消息)。SMTP命令由SMTP客户端生成并发送到SMTP服务器。SMTP应答从SMTP服务器发送到SMTP客户端以响应命令。

换句话说,消息传输可以在原始SMTP发送方和最终SMTP接收方之间的单个连接中发生,也可以通过中间系统的一系列跳跃发生。在任何一种情况下,一旦服务器在邮件数据结束时发出成功响应,就会发生消息责任的正式移交: 协议要求服务器必须 (MUST) 接受传递消息或正确报告失败的责任 (参见下面的第6.1, 6.2和7.8节)。

一旦建立了传输通道并完成了初始握手,SMTP客户端通常会启动邮件事务 (mail transaction)。这样的事务由一系列命令组成,用于指定邮件的发起者和目的地以及消息内容 (包括头部分中的任何行或其他结构) 本身的传输。当同一消息发送给多个收件人时,本协议鼓励仅为同一目标 (或中间中继) 主机的所有收件人传输一份数据副本。

服务器用应答响应每个命令; 应答可能表明命令已被接受、需要额外的命令、或存在临时或永久错误条件。指定发件人或收件人的命令可能包括服务器允许的SMTP服务扩展请求,如第2.2节所述。对话是有意的锁步式 (lock-step)、一次一个的,尽管这可以通过双方同意的扩展请求 (如命令流水线化, RFC 2920 [19]) 进行修改。

一旦传输了给定的邮件消息,客户端可以请求关闭连接或可以启动其他邮件事务。此外,SMTP客户端可以使用到SMTP服务器的连接来提供辅助服务,例如验证电子邮件地址或检索邮件列表订阅者地址。

如上所述,本协议提供了邮件传输的机制。从历史上看,当两个主机连接到同一传输服务时,此传输通常直接从发送用户的主机到接收用户的主机发生。当它们未连接到同一传输服务时,传输通过一个或多个中继SMTP服务器发生。当今互联网中一个非常常见的情况涉及将原始消息提交到中间"消息提交" (message submission) 服务器,该服务器类似于中继但具有一些附加属性; 此类服务器在第2.3.10节和RFC 4409 [18] 中有详细讨论。充当SMTP中继或充当进入某些其他传输环境的网关的中间主机通常通过使用域名服务 (DNS) 邮件交换器 (Mail eXchanger) 机制来选择。

通常,中间主机通过DNS MX记录确定,而不是通过显式"源"路由 (参见第5节和附录C及附录F.2)。

2.2. The Extension Model (扩展模型)

2.2.1. Background (背景)

在1990年开始的努力中,大约在RFC 821完成十年后,该协议使用"服务扩展"模型进行了修改,该模型允许客户端和服务器同意使用超出原始SMTP要求的共享功能。SMTP扩展机制定义了扩展SMTP客户端和服务器可以相互识别的方法,以及服务器可以向客户端通知其支持的服务扩展的方法。

现代SMTP实现必须 (MUST) 支持基本扩展机制。例如,即使服务器不实现任何特定扩展,也必须 (MUST) 支持EHLO命令,客户端应该 (SHOULD) 优先使用EHLO而不是HELO。(然而,为了与较旧的符合实现兼容,SMTP客户端和服务器必须 (MUST) 支持原始HELO机制作为后备。) 除非必须为互操作性目的识别HELO的不同特性,否则本文档仅讨论EHLO。

SMTP已被广泛部署,高质量的实现已被证明非常强大。然而,互联网社区现在认为某些服务是重要的,而这些服务在协议首次设计时并未预期到。如果要添加对这些服务的支持,则必须以允许较旧实现继续正常工作的方式进行。扩展框架包括:

  • SMTP命令EHLO,取代早期的HELO,

  • SMTP服务扩展的注册表,

  • SMTP MAIL和RCPT命令的附加参数, 以及

  • 可选地替换本协议中定义的命令,例如在非ASCII传输中替换DATA (RFC 3030 [20])。

SMTP的优势主要来自其简单性。许多协议的经验表明,选项少的协议往往普及,而选项多的协议往往不为人所知。

无论每个扩展的好处如何,都必须仔细审查其实现、部署和互操作性成本。在许多情况下,扩展SMTP服务的成本可能会超过其好处。

2.2.2. Definition and Registration of Extensions (扩展的定义和注册)

IANA维护SMTP服务扩展的注册表。每个扩展都与相应的EHLO关键字值相关联。向IANA注册的每个服务扩展必须 (MUST) 在正式的标准跟踪 (Standards-Track) 或IESG批准的实验协议文档中定义。定义必须 (MUST) 包括:

  • SMTP服务扩展的文本名称;

  • 与扩展相关联的EHLO关键字值;

  • 与EHLO关键字值相关联的参数的语法和可能值;

  • 与扩展相关联的任何附加SMTP动词 (附加动词通常但不要求与EHLO关键字值相同);

  • 扩展与MAIL或RCPT动词相关联的任何新参数;

  • 对扩展支持如何影响服务器和客户端SMTP行为的描述; 以及

  • 扩展使MAIL和/或RCPT命令的最大长度增加的增量,超过本标准中指定的长度。

此外,以大写或小写"X"开头的任何EHLO关键字值都指仅通过双边协议使用的本地SMTP服务扩展。以"X"开头的关键字禁止 (MUST NOT) 用于已注册的服务扩展。相反,在EHLO响应中呈现的不以"X"开头的关键字值必须 (MUST) 对应于向IANA注册的标准、标准跟踪或IESG批准的实验SMTP服务扩展。符合要求的服务器禁止 (MUST NOT) 提供未在已注册扩展中描述的非"X"前缀关键字值。

附加动词和参数名称受与EHLO关键字相同的规则约束; 具体而言,以"X"开头的动词是本地扩展,不得注册或标准化。相反,不以"X"开头的动词必须 (MUST) 始终注册。

2.2.3. Special Issues with Extensions (扩展的特殊问题)

允许更改SMTP操作相当基本属性的扩展。本文档其他部分中的文本必须 (MUST) 在该上下文中理解。特别是,扩展可以更改第4.5.3节中指定的最小限制,可以更改上述ASCII字符集要求,或者可以引入某些可选的消息处理模式。

特别是,如果扩展暗示传递路径通常支持该扩展的特殊功能,并且中间SMTP系统发现下一跳不支持所需的扩展,它可以 (MAY) 根据特定扩展和情况选择重新排队消息并稍后重试和/或尝试备用MX主机。如果采用此策略,回退到未扩展格式 (如果可用) 的超时应该 (SHOULD) 小于作为不可传递而反弹的正常超时 (例如,如果正常超时为三天,则在尝试传输不带扩展的邮件之前的重新排队超时可能为一天)。

2.3. SMTP Terminology (SMTP术语)

2.3.1. Mail Objects (邮件对象)

SMTP传输邮件对象 (mail object)。邮件对象包含信封 (envelope) 和内容 (content)。

SMTP信封作为一系列SMTP协议单元 (在第3节中描述) 发送。它由发起者地址 (originator address, 错误报告应指向该地址)、一个或多个收件人地址以及可选的协议扩展材料组成。从历史上看,反向路径 (发起者) 地址规范命令 (MAIL) 的变体可用于指定备用传递模式,例如立即显示; 这些变体现已弃用 (参见附录F和附录F.6)。

SMTP内容在SMTP DATA协议单元中发送,并具有两个部分: 头部分 (header section) 和正文 (body)。如果内容符合其他当代标准,头部分由头字段集合组成,每个头字段由头名称、冒号和数据组成,结构如消息格式规范 (RFC 5322 [4]) 中所示; 如果正文是结构化的,则根据MIME (RFC 2045 [21]) 定义。内容本质上是文本的,使用US-ASCII字符集 [6] 表示。虽然SMTP扩展 (如"8BITMIME", RFC 1652 [22]) 可以放宽对内容正文的此限制,但内容头字段始终使用US-ASCII字符集编码。两个MIME扩展 (RFC 2047 [23] 和RFC 2231 [24]) 定义了一种算法,用于表示US-ASCII字符集之外的头值,同时仍使用US-ASCII字符集对其进行编码。

2.3.2. Senders and Receivers (发送方和接收方)

在RFC 821中,参与SMTP事务的两个主机被描述为"SMTP发送方" (SMTP-sender) 和"SMTP接收方" (SMTP-receiver)。本文档已更改以反映当前行业术语,因此分别将它们称为"SMTP客户端" (SMTP client 或有时只是"客户端") 和"SMTP服务器" (SMTP server 或只是"服务器")。由于给定主机在中继情况下可能同时充当服务器和客户端,因此在需要清晰时仍使用"接收方" (receiver) 和"发送方" (sender) 术语。

2.3.3. Mail Agents and Message Stores (邮件代理和消息存储)

在RFC 821发布后,附加的邮件系统术语变得普遍,并且在方便时在本规范中使用。特别是,SMTP服务器和客户端提供邮件传输服务,因此充当"邮件传输代理" (Mail Transfer Agents, MTAs)。"邮件用户代理" (Mail User Agents, MUAs或UAs) 通常被认为是邮件的源和目标。在源处,MUA可能收集要从用户传输的邮件并将其交给MTA; 最终 ("传递") MTA将被认为是将邮件交给MUA (或至少将责任转移给它,例如,通过将消息存入"消息存储" (message store))。然而,虽然这些术语在其他环境中至少看起来具有很高的精确性,但MUA和MTA之间隐含的边界通常无法准确匹配互联网邮件的常见和符合实践。因此,读者应该谨慎地推断如果这些术语在其他地方使用可能会暗示的强关系和责任。

2.3.4. Host (主机)

就本规范而言,主机 (host) 是连接到互联网 (或在某些情况下连接到专用TCP/IP网络) 并支持SMTP协议的计算机系统。主机由名称标识 (参见下一节); 它们不应该 (SHOULD NOT) 通过数字地址标识,即通过第4.1.2节中描述的地址文字标识。

2.3.5. Domain Names (域名)

域名 (domain name 或通常只是"域") 由一个或多个组件组成,如果出现多个组件,则用点分隔。在电子邮件地址中单独使用的顶级域的情况下,使用单个字符串而不带任何点。这使得下面更详细描述的要求特别重要,即只有完全限定的域名 (fully-qualified domain names) 出现在公共互联网上的SMTP事务中,特别是涉及顶级域的地方。这些组件 (DNS术语中的"标签", RFC 1035 [2]) 对于SMTP目的被限制为由从ASCII字符集 [6] 中提取的字母、数字和连字符序列组成。域名用作主机名称和域名层次结构中其他实体的名称。例如,域可以指别名 (CNAME RR的标签) 或用于传递邮件而不是表示主机名的邮件交换器 (Mail eXchanger) 记录的标签。参见RFC 1035 [2] 和本规范的第5节。

本文档和RFC 1035 [2] 中描述的域名是整个完全限定的名称 (通常称为"FQDN")。不是FQDN形式的域名不过是本地别名。本地别名禁止 (MUST NOT) 出现在任何SMTP事务中。

当在SMTP中使用域名时,只允许可解析的完全限定域名 (FQDNs)。换句话说,允许可以解析为MX RR或地址 (即A或AAAA) RR (如第5节所述) 的名称,以及其目标可以依次解析为MX或地址RR的CNAME RR。禁止 (MUST NOT) 使用本地昵称或非限定名称。要求FQDN的规则有两个例外:

  • 在EHLO命令中给出的域名必须 (MUST) 是主主机名 (解析为地址RR的域名) 或,如果主机没有名称,则是地址文字,如第4.1.3节所述并在第4.1.4节的EHLO讨论中进一步讨论。

  • 保留的邮箱名称"postmaster"可以 (MAY) 在RCPT命令中使用而无需域限定 (参见第4.1.1.3节),并且如果这样使用,则必须 (MUST) 被接受。

2.3.6. Buffer and State Table (缓冲区和状态表)

SMTP会话是有状态的,双方都仔细维护当前状态的公共视图。在本文档中,我们通过服务器上的虚拟"缓冲区" (buffer) 和"状态表" (state table) 来建模此状态,客户端可以使用它们,例如,"清除缓冲区"或"重置状态表",导致缓冲区中的信息被丢弃,状态返回到某个先前的状态。

2.3.7. Commands and Replies (命令和应答)

SMTP命令以及除非由服务扩展更改的消息数据,通过传输通道以"行" (lines) 的形式从发送方传输到接收方。

SMTP应答 (reply) 是通过传输通道以"行"的形式从接收方发送到发送方的确认 (肯定或否定),用于响应命令。应答的一般形式是数字完成代码 (表示失败或成功),通常后跟文本字符串。代码供程序使用,文本通常供人类用户使用。RFC 3463 [25] 指定了应答字符串的进一步结构,包括使用补充和更具体的完成代码 (另见RFC 5248 [26])。

2.3.8. Lines (行)

行 (lines) 由零个或多个数据字符组成,以ASCII字符"CR" (十六进制值0D) 后立即跟随ASCII字符"LF" (十六进制值0A) 的序列终止。此终止序列在本文档中表示为<CRLF>。符合要求的实现禁止 (MUST NOT) 将任何其他字符或字符序列识别或生成为行终止符。服务器可以 (MAY) 对行长度施加限制 (参见第4节)。

此外,在文本中出现"裸" (bare) "CR"或"LF"字符 (即,没有另一个字符) 在邮件实现和使用邮件系统作为工具的应用程序中有很长的引起问题的历史。SMTP客户端实现禁止 (MUST NOT) 传输这些字符,除非它们旨在作为行终止符,并且如上所述,必须 (MUST) 仅将它们作为<CRLF>序列传输。

2.3.9. Message Content and Mail Data (消息内容和邮件数据)

术语"消息内容" (message content) 和"邮件数据" (mail data) 在本文档中可互换使用,用于描述在接受DATA命令后和传输数据结束指示之前传输的材料。消息内容包括消息头部分 (message header section) 和可能的结构化消息正文 (message body)。MIME规范 (RFC 2045 [21]) 提供了结构化消息正文的标准机制。

2.3.10. Originator, Delivery, Relay, and Gateway Systems (发起、传递、中继和网关系统)

本规范根据SMTP系统在传输电子邮件中扮演的角色,对四种类型的SMTP系统进行了区分。"发起" (originating) 系统 (有时称为SMTP发起者) 将邮件引入互联网或更广泛地引入传输服务环境。"传递" (delivery) SMTP系统是从传输服务环境接收邮件并将其传递给邮件用户代理或将其存入邮件用户代理应随后访问的消息存储中的系统。"中继" (relay) SMTP系统 (通常仅称为"中继") 从SMTP客户端接收邮件并将其传输到另一个SMTP服务器以进行进一步中继或传递,除了添加跟踪信息外,不对消息数据进行修改。

"网关" (gateway) SMTP系统 (通常仅称为"网关") 从一个传输环境中的客户端系统接收邮件并将其传输到另一个传输环境中的服务器系统。网关两侧传输环境之间的协议或消息语义的差异可能要求网关系统对消息执行SMTP中继系统不允许的转换。就本规范而言,重写地址的防火墙应被视为网关,即使它们的两侧都使用SMTP (参见RFC 2979 [27])。

2.3.11. Mailbox and Address (邮箱和地址)

如本规范中所用,"地址" (address) 是标识将向其发送邮件的用户或将在其中存放邮件的位置的字符串。术语"邮箱" (mailbox) 指该存放处。这两个术语通常可互换使用,除非放置邮件的位置 (邮箱) 与对它的引用 (地址) 之间的区别很重要。地址通常由用户和域规范组成。标准邮箱命名约定定义为"local-part@domain"; 当代用法允许比简单的"用户名"更广泛的应用集。因此,由于当中间主机试图通过修改它们来优化传输时存在很长的问题历史,local-part必须 (MUST) 仅由地址的domain部分中指定的主机解释和分配语义。

2.4. General Syntax Principles and Transaction Model (一般语法原则和事务模型)

SMTP命令和应答具有严格的语法。所有命令都以命令动词 (command verb) 开头。所有应答都以三位数字代码开头。在某些命令和应答中,动词或应答代码后需要参数。某些命令不接受参数 (在动词之后),某些应答代码后跟自由形式文本 (有时是可选的)。在这两种情况下,出现文本的地方,它与动词或应答代码由空格字符分隔。命令和应答的完整定义出现在第4节中。

动词和参数值 (例如,RCPT命令中的"TO:"或"to:"和扩展名称关键字) 不区分大小写,本规范中唯一的例外是邮箱local-part (SMTP扩展可能明确指定区分大小写的元素)。也就是说,命令动词、除邮箱local-part之外的参数值和自由形式文本可以 (MAY) 以大写、小写或大写和小写的任何混合编码,而不会影响其含义。邮箱的local-part必须 (MUST) 被视为区分大小写。因此,SMTP实现必须 (MUST) 注意保留邮箱local-part的大小写。特别是,对于某些主机,用户"smith"与用户"Smith"不同。然而,利用邮箱local-part的大小写敏感性会妨碍互操作性,因此不鼓励这样做。邮箱域遵循正常的DNS规则,因此不区分大小写。

少数SMTP服务器违反本规范 (和RFC 821) 要求客户端以大写编码命令动词。实现可以 (MAY) 希望采用此编码以适应这些服务器。

参数子句由以行尾结束的可变长度字符串组成,即以字符序列<CRLF>结束。接收方在接收到此序列之前不会采取任何操作。

每个命令的语法在该命令的讨论中显示。常见元素和参数在第4.1.2节中显示。

命令和应答由ASCII字符集 [6] 中的字符组成。当传输服务提供8位字节 (八位组) 传输通道时,每个7位字符在八位组中右对齐传输,高位清零。更具体地说,未扩展的SMTP服务提供7位传输通道。在这种情况下,顶级比特禁止 (MUST NOT) 由发送SMTP传输,并且当由接收SMTP检测到时应该 (SHOULD) 被清零或可以 (MAY) 被拒绝为协议违规。

命令和应答的语法规则在第4节中详细说明。SMTP的语法在原则上利用行为基本通信单元。在命令和应答中,可以出现几行; 当行是命令或应答的一部分时,关键字或数字代码 (如适用) 必须 (MUST) 出现在每行的开头。

发送SMTP等待来自接收SMTP的成功完成应答代码或错误应答代码的确认,然后再发送下一个命令。如前所述,可以使用服务扩展 (如RFC 2920 [19]) 修改此行为。