第28章 SMTP: 简单邮件传送协议
28.3 SMTP的例子
上面我们说明了普通邮件发送,在这里我们将说明 M X记录如何用于邮件发送,以及V R F Y和E X P N命令的用法。
28.3.1 MX记录:主机非直接连到Internet
在1 4 . 6节中我们提到D N S中的一种资源记录类型是邮件交换记录,称为 M X记录。在下面的例子中我们将说明如何用 M X记录向不直接连到 I n t e r n e t的主机发送邮件。 RFC 974[Partridge 1986 ] 描述了M TA对M X记录的处理。
主机m l f a r m . c o m不是直接连到I n t e r n e t的,但是有一个M X记录指向I n t e r n e t上的一个邮件转发器。
有两个M X记录,各有不同的优先级。我们希望 M TA从优先级数值低的开始。
从输出中我们看到, M TA发现目的主机有一个 M X记录,并使用具有低优先级数值的 M X记录。
在主机s u n运行这个例子之前,它被配置成不使用本地中继主机,所以我们会看到与目的主机的邮件交换。主机 s u n还被配置成可使用主机 n o a o . e d u(通过拨号S L I P链路)上的域名服务器,所以我们能用 t c p d u m p捕获在S L I P链路上进行的邮件发送和 D N S通信。图2 8 - 4显示了t c p d u m p输出的开始部分。
在第1行,M TA向它的域名服务器查询 m l f a r m . c o m的M X记录。跟在2后面的加号“+”意思是设置要求递归的标志位。第 2行的响应置位授权比特(跟在 2后面的星号“*”),并包含两个回答R R(两个M X主机名),0个授权R R,以及两个附加的R R(两个主机的I P地址)。 第3 ~ 5行与主机m e r c u r y . h s i . c o m上的S M T P建立了一个T C P连接。服务器的初始响应2 2 0显示在第6行。
由于某种原因,主机m e r c u r y . h s i . c o m必须把这个邮件报文交付给目的地,m l f a r m . c o m。对于没有连接到I n t e r n e t上与它的M X站点交换邮件的系统,U U C P协议是一种常用的办法。在这个例子中,M TA要求一个M X记录,得到一个肯定的结果,然后发送邮件。但不幸的是,M TA与D N S之间的交互随不同的实现而不同。 RFC 974指定M TA必须首先要求M X记录, 如果没有,就尝试提交给目的主机(也就是说,向 D N S要主机的记录和I P地址)。M TA也必须处理D N S中的C N A M记录(规范的名)。
作为一个例子,如果我们从一个 B S D / 3 8 6 主机上向 r s t e v e n s @ m a i l h o s t .t u c . n o a o . e d u发送邮件,则M TA(S e n d m a i l)执行以下步骤:
- Sendmail 向D N S询问主机m a i l h o s t . t u c . n o a o . e d u的C N A M E记录。我们看到存在一个C N A M E记录:
sun % host -t cname mailhost.tuc.noao.edu
mailhost.tuc.noao.edu CNAME noao.edu
- 发布一个要求n o a o . e d u的C N A M E记录的D N S查询,回答是不存在。
- Sendmail向D N S寻求n o a o . e d u的M X记录并得到一个记录:
sun % host -t mx noao.edu
noao.edu M X n o a o . e d u
- Sendmail 向D N S查询n o a o . e d u的A记录(I P地址),并得到返回值1 4 0 . 2 5 2 . 1 . 5 4(这个A记录大概是由域名服务器为 n o a o . e d u返回的,作为第3步中M X应答的一个附加的R R)。
- 启动一个到1 4 0 . 2 5 2 . 1 . 5 4的S M T P连接并发送邮件。C N A M E查询不是为M X记录(n o a o . e d u)中返回的数据做的。M X记录中的数据不能是别名—必须是具有一个A记录的主机名。与只用DNS 的SunOS 4.1.3一起发布的Sendmail版本查询MX记录,并且如果没有找到MX记录就放弃。
28.3.2 MX记录:主机出故障
M X记录的另一个用途是在目的主机出故障时可提供另一个邮件接收器。如果看一下主机s u n的D N S入口,我们就会看到它有两个 M X记录:
最低优先级的M X记录表明应该首先尝试直接发送到主机本身,下一个优先级是把邮件发送到主机n o a o . e d u。
在下面的描述中,在关掉目的S M T P服务器后,我们从主机v a n g o g h . c s . b e r k e l e y . e d u向位于主机s u n . t u c . n o a o . e d u的我们自己发送邮件。当端口2 5上的连接请求到达时,T C P应该响应一个RST,因为没有被动打开的进程为等待该端口而挂起。
第1行v a n g o g h向s u n的第1个I P地址140.252.1.29 的端口25 发送一个S Y N。在第2行它被拒绝。然后,v a n g o g h上的S M T P客户尝试s u n的第2个I P地址1 4 0 . 2 5 2 . 1 3 . 3 3(第3行),也产生一个R S T的返回(第4行)。
S M T P客户不区分第1行它主动打开时所返回的不同差错,而这是导致它在第 2行尝试其他I P地址的原因。如果第 1次的差错是类似“host unreachable(主机不可达)”,那么第2次尝试或许可行。
如果S M T P客户的主动打开失败的原因是因为服务器主机出故障了,我们将看到客户会向I P地址1 4 0 . 2 5 2 . 1 . 2 9重传S Y N总共7 5秒(类似于图1 8 - 6)。然后客户向I P地址1 4 0 . 2 5 2 . 1 3 . 3 3发送另一个7 5秒的其他3个S Y N。1 5 0秒后客户会移到下一个具有更高优先级的 M X记录。
28.3.3 VRFY和EXPN命令
V R F Y命令无需发送邮件而验证某个接收方地址是否 O K。E X P N的目的是无需向邮件表发送邮件就可以扩充该表。许多 S M T P实现(如S e n d m a i l)把两者看成一个,但我们提到新的S e n d m a i l区分这两者。
作为一个简单测试,我们可以连到一个新的 S e n d m a i l版本,并看到不同之处(已经删除了无关的Te l n e t客户输出)。
首先注意到我们故意在H E L O命令中键入错误的主机名: b s d i,而不是s u n。许多S M T P服务器得到客户的I P地址,完成一个D N S指针查询(1 4 . 5节)并比较主机名。这样允许服务器基于I P地址注册到客户的连接,而不是基于用户可能错误键入的名。某些服务器会用幽默的报文回答,如“你是一个骗子”,或“为什么叫你自己……”。在这个例子中我们看到,这个服务器通过指针查询只打印出我们的真实域名以及我们的 I P地址。
然后我们用一个无效的名字键入 V R F Y命令,服务器就响应 5 5 0差错。下一步我们键入一个有效的名字,服务器用本地主机上的用户名回答。然后我们试试 E X P N命令,并得到一个不同的回答。E X P N命令决定到该用户的邮件是否被转发,并打印出转发的地址。
许多站点禁止V R F Y和E X P N命令,有时是因为隐私,有时因为相信这是安全漏洞。例如,我们可以向白宫的S M T P服务器试试下面的命令: