第28章 SMTP: 简单邮件传送协议
28.2 SMTP协议
两个M TA之间用NVT ASCII进行通信。客户向服务器发出命令,服务器用数字应答码和可选的人可读字符串进行响应。这与上一章的 F T P类似。
客户只能向服务器发送很少的命令:不到 1 2个(相比较而言, F T P超过4 0个)。我们用简单的例子说明发送邮件的工作过程,并不仔细描述每个命令。
28.2.1 简单例子
我们将发送一个只有一行的简单邮件,并观察 S M T P连接。我们用 -v 标志调用用户代理,它被传送给邮件传送代理(本例中是 S e n d m a i l)。当设置该标志时,该 M TA显示在S M T P连接上发送和接收的内容。以 > > >开始的行是S M T P客户发出的命令,以 3位数字的应答码开始的行是从S M T P服务器来的。以下就是交互会话:
只有5个S M T P命令用于发送邮件:H E L O,M A I L,R C T P,D ATA和Q U I T。我们键入m a i l启动用户代理,然后键入主题( s u b j e c t)的提示;键入后,再键入报文的正文。在一行上键入一个句点结束报文,用户代理把邮件传给 M TA,由M TA进行交付。
客户主动打开T C P端口2 5。返回时,客户等待从服务器来的问候报文(应答代码为 2 2 0)。该服务器的应答必须以服务器的完全合格的域名开始:本例中为 n o a o . e d u(通常,跟在数字应答后面的文字是可选的。这里需要域名。以 S e n d m a i l打头的文字是可选的)。
下一步客户用 H E L O命令标识自己。参数必须是完全合格的的客户主机名: s u n . t u c .n o a o . e d u。
M A I L命令标识出报文的发起人。下一个命令, R C P T,标识接收方。如果有多个接收方,可以发多个R C P T命令。邮件报文的内容由客户通过 D ATA命令发送。报文的末尾由客户指定,是只有一个句点的一行。最后的命令Q U I T,结束邮件的交换。
图2 8 - 2是在发送方S M T P(客户端)与接收方S M T P(服务器)之间的一个S M T P连接。我们键入到用户代理的数据是一行报文(“1,2,3”),但在报文段1 2中共发送了3 9 3字节的数据。下面的1 2行组成了客户发送的3 9 3字节数据:
前三行,Received: 和M e s s a g e - I d: 由M TA加上;下一行由用户代理生成。
28.2.2 SMTP命令
最小S M T P实现支持 8种命令。我们在前面的例子中遇到 5个:H E L O,M A I L,R C P T,D ATA和Q U I T。
R S E T命令异常中止当前的邮件事务并使两端复位。丢掉所有有关发送方、接收方或邮件的存储信息。
V R F Y命令使客户能够询问发送方以验证接收方地址,而无需向接收方发送邮件。通常是系统管理员在查找邮件交付差错时手工使用的。我们将在下一节中给出这方面的例子。
N O O P命令除了强迫服务器响应一个 O K应答码(2 0 0)外,不做任何事情。还有附加和可选命令。 E X P N扩充邮件表,与 V R F Y类似,通常是由系统管理员使用的。
事实上,许多S e n d m a i l的版本都把这两者等价地处理。4.4BSD 中的S e n d m a i l版本8不再将两者等同处理。 V R F Y不扩充别名也不接受.forward文件。
T U R N命令使客户和服务器交换角色,无需拆除 T C P连接并建立新的连接就能以相反方向发送邮件(S e n d m a i l不支持这个命令)。其他还有三个很少被实现的命令( S E N D、S O M L和S A M L)取代M A I L命令。这三个命令允许邮件直接发送到客户终端(如果已注册)或发送到接收方的邮箱。
28.2.3 信封、首部和正文
电子邮件由三部分组成:
- 信封(e n v e l o p e)是M TA用来交付的。在我们的例子中信封由两个 S M T P命令指明:
MAIL From: <rstevens@sun.tuc.noao.edu>
RCPT To: <estevens@noao.edu>
RFC 821指明了信封的内容及其解释,以及在一个 T C P连接上用于交换邮件的协议。
2) 首部由用户代理使用。在我们的例子中可以看到 9个首部字段: R e c e i v e d、M e s s a g e - I d、F r o m、D a t a、R e p l y - T o、X - P h o n e、X - M a i l e r、T o和S u b j e c t。每个首部字段都包含一个名,紧跟一个冒号,接着是字段值。 RFC 822指明了首部字段的格式的解释(以X-开始的首部字段是用户定义的字段,其他是由 RFC 822定义的)。长首部字段,如例
子中的R e c e i v e d,被折在几行中,多余行以空格开头。
3) 正文(b o d y)是发送用户发给接收用户报文的内容。 RFC 822 指定正文为NVT ASCII文字行。当用D ATA命令发送时,先发送首部,紧跟一个空行,然后是正文。用 D ATA命令发送的各行都必须小于1 0 0 0字节。
用户接收我们指定为正文的部分,加上一些首部字段,并把结果传到 M TA。M TA加上一些首部字段,加上信封,并把结果发送到另一个 M TA。
内容(c o n t e n t)通常用于描述首部和正文的结合。内容是客户用 D ATA命令发送的。
28.2.4 中继代理
在我们的例子中本地M TA的信息输出的第1行是:“Connecting to mailhost via ether”(即“通过以太网连接到邮件主机”)。这是因为作者的系统已被配置成把所有非本地的向外的邮件发送到一台中继机上进行转发。
这样做的原因有两个。首先,简化了除中继系统 M TA外的其他所有M TA的配置(所有曾使用过S e n d m a i l的人都能证明,配置一个 M TA并不简单)。第二,它允许某个机构中的一个系统作为邮件集线器,从而可能把其他所有系统隐藏起来。
在这个例子中,中继系统在本地域( . t u c . n o a o . e d u)中有一个m a i l h o s t的主机名,而其他所有系统都被配置成把它们的邮件发往该主机。我们可以执行 h o s t命令来看看在D N S中这个名是如何定义的:
sun % host mailhost
mailhost.tuc.noao.edu CNAME noao.edu 规范名
noao.edu A 140.252.1.54 它的真实I P地址
如果将来用于中继的主机改变了,只需改变它的 D N S名—其他所有单个系统的邮箱配置都无需改变。
目前许多机构都采用中继系统。图 2 8 - 3是修改后的I n t e r n e t邮件图(图2 8 - 2),考虑发送主机和最后的接收主机都可能使用中继主机。
在这种情况下,在发送方和接收方之间有 4个M TA。发送方主机上的本地 M TA只把邮件交给它自己的中继M TA(该中继M TA可能在该机构的域中有一个 m a i l h o s t的主机名)。这个通信就在该机构的本地互联网上用 S M T P。然后,发送方机构的中继 M TA就在I n t e r n e t上把邮件发送到接收方机构的中继 M TA上,而这个中继 M TA就通过与接收方主机上的本地 M TA通信,
把邮件交给接收方主机。尽管可能存在其他协议,但这个例子中所有 M TA均使用S M T P协议。
28.2.5 NVT ASCII
S M T P的一个特色是它用NVT ASCII表示一切:信封、首部和正文。正如我们在 2 6 . 4节中谈到的,这是一个7 bit的字符码,以8 bit字节发送,高位比特被置为 0。 在2 8 . 4节中,我们讨论了 I n t e r n e t邮件的一些新特性、允许发送和接收诸如音频和视频数据的扩充S M T P和多媒体邮件(M I M E)。我们将看到,M I M E和NVT ASCII一起表示信封、首部和正文,只需对用户代理作一些改变。
28.2.6 重试间隔
当用户把一个新的邮件报文传给它的 M TA时,通常立即试图交付。如果交付失败, M TA必须把该报文放入队列中以后再重试。
Host Requirements RFC推荐初始时间间隔至少为 3 0分钟。发送方至少4 ~ 5天内不能放弃。而且,因为交付失败通常是透明的(接收方崩溃或临时网络连接中断),所以当报文在队列中等待的第1个小时内,尝试两次连接是有意义的。