SMTP报文格式
现在我们来分析SMTP的报文格式。如图三,一个合法的SMTP报文由信封和正文这两部分所组成。在传递过程中,邮件每经过一台SMTP服务器,该服务器就会在信封这一部分上留下转发的痕迹(转发时间,服务器IP地址等等)。正文(既SMTP DATA命令后所做的输入)部分由信头和信体组成,信头中包含发件人和收件人地址以及其他的一些信息,信体为邮件的具体内容。
信封上有发件人和收件人地址,不同的是,信封上的发件人收件人地址由MAIL FROM和RCPT TO命令写入,是用来给邮件服务器进行信件传送的,而信头上的发件人收件人是用来显示在Outlook中的。这两组地址,是可以不相同的!我们跟传统的书信比较一下:当给女朋友写情书的时候,大家一般都在信封上写她的真实姓名,而在信纸的开头冠以“亲爱的。。。”之类的亲切称呼。情书在被邮局投递时,工作人员会在信封上敲邮戳,以反映投递的过程。
信封和信体上的地址可以不相同,这有什么好处呢?我们举一个简单的例子。当我们采用BCC的方式发一封邮件给A,B,C三个人时,BCC的特点就要求隐藏邮件的收件人。这时,Exchange就会把原来的邮件拆分成三封独立的邮件,然后分别生成SMTP报文,在发给每个人的信封中,写入他的地址,在正文的信头中,把收件人表示为空。这样,每个收件人都回收到BCC的邮件,但是都无法知道这封信还BCC了哪些其他人。
图三:SMTP的报文格式
我们可能已经注意到,在RFC 821和1869中,我们定义了SMTP中用于建立连接和传输报文的命令字。在DATA命令后,我们可以传送由ASCII字符组成的数据流(即前面所提到的正文部分)到远端的SMTP主机,可这远远不能满足日常email通信的要求。邮件发送者往往需要在信件中使用非ASCII字符(例如,中文和其他非罗马字母语言),还需要插入各种类型的附件。为了能通过email发送非ASCII数据,IETF定义了多用途Internet邮件扩充MIME(Multipurpose Internet Mail Extension)标准。MIME并非为了改动SMTP或者取代它,而是允许使用ASCII码对任意数据进行编码,然后使用SMTP的DATA命令进行传送。
我们可以通过如下的例子来深入了解MIME编码在邮件中的作用。如图四,如果邮件中包含由MIME编码的数据,一般会在信头中指定MIME版本和分隔符(例子中的boundary=98766789,通过此分隔符来分隔不同的MIME内容)。当信件正文中有图文混排,或者中英文交叉在一起的情况,就需要把不同的内容分别进行MIME编码。下图中所表示的邮件由一段文本和一张jpeg图片组成,所以就会生成两段独立的MIME编码。每段MIME编码起始位置,都会指明这段编码所代表的数据类型和使用的编码算法,以方便客户端软件进行解码。我们可以在Outlook软件中把邮件另存为以EML为扩展名的文件,然后用写字板打开,这样可以看到所有的邮件结构和MIME编码。
图四:MIME编码在邮件中的作用
至此我们简单的介绍了SMTP协议的传输命令和其编码方式,正如我们在开篇所提到的,SMTP协议是随着Internet的发展和用户的需求逐渐完善和优化的,其标准的形成经历了一定的过程,下面简单的列出了跟SMTP有关的几个RFC标准。
标准定义时间 | RFC编号 | 作用 |
1982年8月 | 821 | 简单邮件传送协议和基本的SMTP命令字 |
1982年8月 | 822 | 邮件报文的确切格式,定义了信封加正文的结构 |
1986年1月 | 974 | 邮件选路和域名系统的关系 |
1986年2月 | 976 | 用于UNIX UUCP的邮件系统标准 |
1993年9月 | 1521 | MIME标准,包括信头说明语法,内容类型和编码算法 |
1993年9月 | 1522 | 为非ASCII文本定义了MIME信头的扩充 |
1994年3月 | 1590 | 描述了新MIME内容和编码类型的登记过程 |
1995年11月 | 1869 | 扩展SMTP标准 |
Exchange传输引擎架构
在花了大量篇幅讨论过SMTP协议的细节之后,我们来看一看微软是如何设计Exchange的传输模块,使其既满足SMTP协议的规则,又能够在微软的特定系统架构环境下高效地工作。Exchange Server是一个非常复杂的大型软件,它涉及到了活动目录、高性能数据库、各种类型的网络协议(MAPI、RPC、HTTP、SMTP、NNTP等等)以及很多Windows底层的技术,做为传输模块核心的SMTP服务,需要在实现自身功能的基础上,跟上述模块紧密、高效、安全的运行在一起,这是微软的Exchange开发者所面临的巨大挑战。
在微软发布Exchange 2000之前,SMTP协议的实现作为IIS 5.0的一部分,已经随着Windows 2000一起发布了。Windows中的SMTP服务是严格按照RFC标准所开发的,实现了其中的绝大部分要求。但是对于Exchange Server来说,这个版本的SMTP还需要进一步的增强,以实现跟微软Exchange相关的邮件数据库和活动目录的接口。Exchange Server的SMTP是在Windows SMTP的基础之上进行了一定的扩展和增强。从图一中我们可以看出来,SMTP是运行在IIS的进程空间(inetinfo.exe)的,在安装Exchange Server时,安装程序接管Windows SMTP,并对其进行改造。首先,安装程序把SMTP的工作目录转移到“\Exchsrvr\mailroot\vsi 1”下面,并且重新设置这些目录的若干属性;然后,安装程序注册了一些COM组件(DLL文件),这些组件作为Exchange SMTP的扩展,将扩展和覆盖Windows SMTP原有的模块,并和IIS无缝的集成在一起进行邮件的传输工作。概括来说,Exchange对Windows SMTP一共做了如下五个方面的扩展:
1. 高级队列引擎(Advanced Queuing Engine,下文简称AQE)。作为传输模块的心脏,高级队列引擎控制着SMTP服务器上邮件的处理流程,所有提交到SMTP服务器的邮件,都无一例外的要经过AQE的处理。
2. 增强型邮件分类器(Enhanced Categorizer)。邮件分类器负责邮件的收件人地址解析。在Windows SMTP中,Windows在其自带的CAT.DLL中实现了邮件分类器的基本功能,但是这个功能在Windows下默认是关闭的。Exchange安装时,安装程序激活了邮件分类器,并且使用其自带的PHATCAT.DLL来接管CAT.DLL实现Exchange SMTP邮件分类器的功能。PHATCAT.DLL由<, FONT face="Times New Roman">Exchange开发小组编写,有更加复杂的功能,并且与活动目有很好的集成。
3. 链路状态协议(Link State Protocol)。链路状态协议用于Exchange组织中的路由信息更新。Exchange服务器、路由组和路由组连接器的任何状态变化,都由链路状态协议负责在整个组织环境中进行广而告之。这些功能也是由Exchange SMTP来协助实现的,服务器使用特定的X-LINK2STATE命令字来传送路由表的变化。
4. 数据库驱动程序接口(Information Store Driver)。数据库驱动程序接口允许SMTP中的组件对Exchange数据库中的邮件进行直接的读取,这在进行邮件的本地投递和获取邮件属性时非常有用。
5. Exchange SMTP专用命令字(Extended Command Verbs)。为了满足自身的要求,微软在SMTP命令字的基础上,增加了X-LINK2STATE、Chunking和Pipelining等等特殊的关键字,以实现服务器间通信和特定的性能优化。
Exchange的SMTP之所以建立在Windows SMTP的基础之上,除了为了接管Windows SMTP原有的功能之外,另一个重要的原因是为了获得IIS所提供的安全、高效的网络通信平台。在IIS中,用户身份认证,底层网络通信这些模块已经完成并且技术成熟度也很高,因此不需要Exchange的开发者再重新花力气去另起炉灶。图五显示了SMTP在IIS和整个Windows平台中的位置。SMTP可以同时响应很多并发的连接,其中一个很重要的原因就是SMTP借助了IIS所提供的异步线程队列技术(Asynchronous Thread Queue),该技术允许并发连接可以被系统以平行、异步的方式高速的处理,在Windows平台上尽最大的可能性提高了系统的吞吐量。
图五:SMTP在IIS和整个Windows平台中的位置
前文所提到的Exchange SMTP扩展模块,是采用COM组件和Event Sink技术来完成的。当IIS中的线程运行SMTPSVC.DLL中的SMTP协议处理代码,或者运行PHATQ.DLL中的SMTP传输过程处理代码时,被传送的邮件会经历一个又一个的“事件”。SMTP使用微软服务器扩展对象(Server Extension Object,SEO.DLL)这个COM组件来触发这一系列的事件,并且随后使用COM激活技术去实例化跟这些事件所关联的相应代码(调用Event Sink)。SMTP常常用事件来表示一个SMTP命令的提交(如客户端发送一个EHLO命令给服务器),也用事件表示把一封邮件提交给传输子系统。一些诸如SMTP协议扩展、邮件分类器、路由引擎的模块,这些都是微软所开发的Event Sink,他们分别注册并跟SMTP中相应的事件相关联。Event和Event Sink是互相关联的,Event被触发后,事先注册好的Event Sink中的代码就会被调用。Event触发与调用Event Sink和编程技术中的回调函数是同样的道理。值得一提的是,Exchange的Event Sink接口技术是公开的,也就是说任何开发者都可以编写自己的事件响应代码,来扩展SMTP的功能。(常见的在邮件结尾自动添加公司保密声明、邮件自动归档、邮件查毒过滤、垃圾邮件判别等等功能,都是通过二次开发的Event Sink来实现的)。在进一步讨论之前,我们来看一看SMTP中事件的种类和他们相应的作用。如下图,SMTP触发的事件一般分为4个大类别。
图六:SMTP触发的事件类别
1. SMTP协议事件(SMTP protocol events)。
这些事件针对SMTP协议本身,其注册的事件响应代码(Event Sink)通过修改、禁用或增加一些特殊的命令字,来改变SMTP协议引擎对标准SMTP命令字的响应行为。举例来说,进行X-LSA链路状态协议(此协议用于更新服务器路由拓扑)处理的Event Sink会针对其自定义的X-LINK2STATE这一SMTP命令字做出响应,执行相应的路由更新操作。SMTP协议事件的Event Sink也能够更改标准SMTP和ESMTP命令字的回应和处理过成功,例如,当用户提交MAIL FROM命令时,预先定义的Event Sink可以检查FROM字段中的邮件地址是否在黑名单中,如果是,可以采取屏蔽操作。
2. SMTP存储事件(SMTP store events)。
这些存储事件允许其Event Sink(通常在数据库驱动中被实现)去获取在数据库或者文件系统中的邮件内容。传输子系统使用此Event Sink来完成邮件的本地投递工作。(邮件最终目的地就是当前SMTP服务器时,SMTP执行本地投递,把信件保存到数据库中)
3. SMTP传输事件(SMTP transport events)。
当邮件到达服务器、在传输系统中被处理、投递给收件人或向外转发时,都会触发一连串的SMTP传输事件。在Exchange 2003中,微软使用SMTP传输事件来调用邮件的分类器和路由组件(这两部分会在下一期的文章中进行非常细致的讨论)。
4. SMTP系统事件(SMTP system events)。
与此事件相关联的Event Sink负责进行日志记录等工作,该Event Sink往往以异步的方式被触发,执行Event Log和SMTP诊断日志的记录工作。
我们再从全局的角度看一下Exchange的传输模块。如图七,Exchange邮件传输流程大致可以从这张图上反映出来。
图七:Exchange邮件传输流程
邮件可以从两个来源进入传输模块,通过SMTP协议引擎(前文图二中的2、3、4,当使用Outlook Express的SMTP/POP3方式收发邮件时,属于这种情况)或者通过数据库(Web Storage System)直接向传输模块提交(前文图二中的1,当使用Outlook MAPI方式,或者OWA发信时,属于这种情况)。需要注意的是,当信件由数据库引擎提交时,它是不经过SMTP协议模块处理的,而是直接放入到分类器的队列里面了。因此,一般的反垃圾邮件和反病毒程序,都不会去通过注册Event Sink来监听SMTP协议事件来工作,因为这样会漏掉通过数据库直接提交的邮件,这种类型的程序,往往注册监听AQ中分类器所产生的事件。请牢记,只有高级队列中的分类器是Exchange系统中传送邮件时唯一的一个必经之路,其它模块都有可能在特定的情况下被跳过。
邮件经过分类器和路由引擎进行处理,来分析收件人地址并进行下一跳(next hop)的投递路由判断和选择,然后就会交给SMTP向外投递。当下一跳的目的地恰好是本地服务器时,SMTP调用Store Driver中定义的Local Delivery把邮件投递到数据库中,当下一跳目的地是其他远程服务器时,根据目的地服务器的类型,邮件依次被放置到不同的远程队列中进行投递处理,此时,SMTP承担图二中5、6的角色,以SMTP Client的身份,向远程SMTP主机发起会话请求。邮件就是这样在一台台的服务器间被传递,直到被Local Delivery到目标数据库中(或者被退信)。
总结和下期介绍:
本文介绍了SMTP协议的工作方式,基本命令字和MIME的基础知识,同时也阐明了Exchange Server SMTP模块的组成方式。作为连载,笔者会在下一篇文章中从邮件投递过程的动态角度,深入地讨论Exchange是如何在内部处理邮件传输的。下期要目如下:
1.基于事件触发机制的邮件传输过程
2.Exchange Categorizer
3.队列和MailMsg对象
参考文档:
1.本文部分插图取自微软Technet网站。
2.用TCP/IP进行网际互联第一卷:原理、协议与结构,Douglas Comer著。
3.Microsoft Support Knowledge Base,微软知识库文档。
作者简介:
喻勇,曾任微软产品技术支持工程师和CTEC课程讲师。对Exchange Server,SharePoint Server,IIS,.NET开发等微软产品和技术有丰富的实践经验。他的电子邮件信箱是yy@yuyong.net,读者可以在他的网站www.yuyong.net下载Exchange相关的课程讲义。
P.S:如果对本文有任何意见,请到Exchange Server 论坛以下地址参与讨论:
http://www.5dmail.net/bbs/Announce/Announce.asp?BoardID=35&ID=136288
自由广告区 |
分类导航 |
邮件新闻资讯: IT业界 | 邮件服务器 | 邮件趣闻 | 移动电邮 电子邮箱 | 反垃圾邮件|邮件客户端|网络安全 行业数据 | 邮件人物 | 网站公告 | 行业法规 网络技术: 邮件原理 | 网络协议 | 网络管理 | 传输介质 线路接入 | 路由接口 | 邮件存储 | 华为3Com CISCO技术 | 网络与服务器硬件 操作系统: Windows 9X | Linux&Uinx | Windows NT Windows Vista | FreeBSD | 其它操作系统 邮件服务器: 程序与开发 | Exchange | Qmail | Postfix Sendmail | MDaemon | Domino | Foxmail KerioMail | JavaMail | Winwebmail |James Merak&VisNetic | CMailServer | WinMail 金笛邮件系统 | 其它 | 反垃圾邮件: 综述| 客户端反垃圾邮件|服务器端反垃圾邮件 邮件客户端软件: Outlook | Foxmail | DreamMail| KooMail The bat | 雷鸟 | Eudora |Becky! |Pegasus IncrediMail |其它 电子邮箱: 个人邮箱 | 企业邮箱 |Gmail 移动电子邮件:服务器 | 客户端 | 技术前沿 邮件网络安全: 软件漏洞 | 安全知识 | 病毒公告 |防火墙 攻防技术 | 病毒查杀| ISA | 数字签名 邮件营销: Email营销 | 网络营销 | 营销技巧 |营销案例 邮件人才:招聘 | 职场 | 培训 | 指南 | 职场 解决方案: 邮件系统|反垃圾邮件 |安全 |移动电邮 |招标 产品评测: 邮件系统 |反垃圾邮件 |邮箱 |安全 |客户端 |