邮件收发流程解析
    本文打算详细分析一封邮件从发件人发出邮件到收件人收到邮件的过程,讲述该过程涉及到的各种知识,为初步接触邮件系统的系统管理员深入学习邮件服务器配置和反垃圾邮件软件或者硬件的配置打下扎实的基础。
1) SMTP 会话
a. 发件人在自己的邮件客户端(比如outlookfoxmail等等,称之为MUA【邮件用户  代理】)写邮件,完成后,按“发送”按钮;
b.
发件人邮件客户端根据发件人先前的配置(SMTP 服务器【发件人公司邮局服务器】 域名或者IP地址,如果发送邮件需要身份验证的话,还有发件人用来向SMTP服务器  表明身份的用户名和密码),建立到发件人公司邮局服务器25号端口的TCP连接;
c.
发件人邮件客户端向发件人公司邮局服务器发送命令 HELO <发件人主机名> 或者   EHLO <发件人主机名>,向发件人公司邮局服务器表明自己的身份;
d.
发件人公司邮局服务器响应发件人邮件客户端,如果该邮件服务器配置了SMTP身份 验证的话,还会把自己支持的身份验证加密算法返回给发件人邮件客户端;
     
注意:邮件服务器可以通过两种方式来限定能够通过它发送邮件的邮件客户端, 防止自己被当成开放中转(open relay),被用来发送垃圾邮件:
       
一种是通过 IP 地址来限定,比如把该邮件服务器负责发送邮件的客户端电脑的IP地址段写到邮件服务器的相应配置文件里;
   
另外一种就是通过配置SMTP身份验证来限制,只有通过身份验证的客户端才能通过它来发送邮件;
e. 如果邮件服务器使用SMTP身份验证来限制邮件客户端,那么发件人邮件客户端向发件人公司邮局服务器发送命令 AUTH <发件人邮件客户端选择的加密算法>,把自己选择的算法发送给发件人公司邮局服务器,否则,转到步骤k
f. 发件人公司邮局服务器响应发件人邮件客户端,并用双方协商的加密算法加密响应数据;
g. 发件人邮件客户端向发件人公司邮局服务器发送命令 USER <发件人用户名>,并用双方协商的加密算法加密命令;
h. 发件人公司邮局服务器响应发件人邮件客户端,并用双方协商的加密算法加密响应数据;
i. 发件人邮件客户端向发件人公司邮局服务器发送命令 PASS <发件人密码>,并用双方协商的加密算法加密命令;
j. 发件人公司邮局服务器响应发件人邮件客户端,告诉发件人邮件客户端身份验证的结果;
k. 发件人邮件客户端向发件人公司邮局服务器发送命令 MAIL FROM: <发件人邮箱>,告诉邮局服务器发件人的邮箱地址;
l. 发件人公司邮局服务器响应发件人邮件客户端;
m. 发件人邮件客户端向发件人公司邮局服务器发送命令 RCPT TO: <收件人邮箱>,告诉邮局服务器收件人的邮箱地址;
n. 发件人公司邮局服务器判断邮件客户端是否位于自己负责为其转发邮件的IP地址段内,或者客户端是否通过了SMTP身份验证,如果该客户端在自己负责的IP地址段内,或者通过SMTP身份验证,那么允许该客户端发送外部邮件,反之如果该客户端既不在自己负责的IP地址段内,又没有通过SMTP身份验证,那么发件人公司邮局服务器会认为该发件人邮件客户端是一台外部邮件服务器,试图通过它发送邮件,那么它会判断RCPT TO 命令的参数收件人邮箱是否是本地邮箱,如果是,则允许发送,如果是外部邮箱,则拒绝发送,并用判断的结果响应发件人邮件客户端;
o. 发件人邮件客户端向发件人公司邮局服务器发送命令 DATA,要求发送邮件;
p. 发件人公司邮局服务器响应发件人邮件客户端;
q. 发件人邮件客户端向发件人公司邮局服务器发送邮件;
      r. 发件人公司邮局服务器响应发件人邮件客户端,告诉其邮件已经接收了,然后关闭连接。
     
 
2) SMTP 会话
a.
发件人公司邮件服务器分析刚收到的邮件,取出其“收件人邮箱”部分(比如, [email]zoukj@sinogrid.com[/email]),并分离出收件人邮箱的域名sinogrid.com)
b.
发件人公司邮件服务器执行DNS查询,查询类别为MX,查找sinogrid.com 这个域的 邮件服务器的IP地址(可以用nslookup命令模拟:nslookup –type=mx sinogrid.com);
c.
收件人公司的DNS服务器将本公司的邮件服务器列表都返回给发件人公司邮件服务器;
d.
发件人公司邮件服务器分析获得的收件人公司邮件服务器列表,找出优先级最高的 邮件服务器,试图与其建立TCP连接,如果优先级最高的邮件服务器有多个,那么就轮流使用,如果不能与优先级高的邮件服务器建立连接,则跟优先级次高的服务器 建立连接,以此类推。
  
注意:MX 查询的返回值,形如 sinogrid.com   MX preference = 20mail exchanger  = mail.sinogrid.com  其中的那个数值越低,则该记录对应的邮件服务器的优先级就越高。
e.
如果收件人公司邮件服务器配置了根据发件邮件服务器的IP地址来过滤垃圾邮件,那么它会将发件人公司邮件服务器的IP地址跟自己的黑白名单进行匹配,如果发件人公司邮件服务器的IP在黑名单里面,那么它可能会拒绝发件人公司邮件服务器的连接;
f.
发件人公司邮件服务器向收件人公司邮件服务器发送命令 HELO <发件人公司邮件服务器域名> 或者EHLO <发件人公司邮件服务器域名>,表明自己的身份;
g.
收件人公司邮件服务器响应;
h.
发件人公司邮件服务器取出试图发送的邮件的“发件人邮箱”,向收件人公司邮件服务器发送命令 MAIL FROM: <发件人邮箱>
i.
收件人公司邮件服务器如果配置了DNS反向查询验证,那么它会这样做:
 
首先他执行一个 PTR 类型的DNS查询(根据IP查找域名),查找出发件人公司邮件服务器的域名,然后执行一个 MX 类型的DNS查询(根据域名查找负责该域的邮件服务器列表),查找出负责“发件人邮箱”所在域的邮件的邮件服务器列表,判断发件人公司邮件服务器的域名是否在这个列表里面。如果PTR 类型的DNS查询失败了(例如我们没有配置DNS反向查询,这个需要向ISP申请,由他们来做),或者域名不在列表里面,那么收件人公司邮件服务器会拒绝接收邮件,终止会话。反之,如果两个条件都满足了,那么以“OK”响应发件人公司邮件服务器。
j.
发件人邮件服务器向收件人公司邮局服务器发送命令 RCPT TO: <收件人邮箱>,告诉收件人邮件服务器收件人的邮箱地址;
k.
收件人公司邮局服务器判断该“收件人邮箱”地址(比如[email]zoukj@sinogrid.com[/email])是否属于自己负责投递的域的邮箱地址(这些域在配置邮件服务器的时候写到相应配置文件里面),如果收件人公司邮件服务器配置了收件人地址验证的话,它还会去验证该地址是否存在,如果不是自己负责的域或者地址不存在,那么它会提示发件人公司邮件服务器。反之,以“OK”响应发件人公司邮件服务器。
l.
发件人公司邮件服务器向收件人公司邮件服务器发送命令 DATA 命令,请求发送邮件;
m.
收件人公司邮局服务器响应发件人公司邮件服务器;
n.
发件人公司邮件服务器向收件人公司邮件服务器发送邮件;
o.
收件人公司邮局服务器响应发件人公司邮件服务器发送命令 QUIT,终止会话。
 
 
3) POP3/IMAP 会话
通常情况下,邮件服务器软件,比如sendmailqmailpostfix,称之为MTA(邮件发送代理),只负责为本地邮件用户向外发送邮件和接收外部发给本地邮件用户的邮件并将外来邮件投递到本地邮件用户的邮箱里面,并不包含让用户通过邮件客户端软件读取自己在邮件服务器上的邮箱里面的邮件的功能,即POP3或者IMAP服务。用户只能通过命令行,在邮件服务器上查看自己邮箱里面的邮件,很不方便。所以,在搭建邮件服务器的时候,我们需要另外安装POP3或者IMAP服务器,以方便用户通过邮件客户端方便地收发邮件;
邮件接收流程如下:
a.
收件人点击邮件客户端的“接收”按钮;
b.
邮件客户端根据发件人先前的配置(POP3/IMAP 服务器【收件人公司邮局服务器】 域名或者IP地址,和收件人用来向POP3/IMAP服务器表明身份的用户名和密码),建立到收件人公司邮局服务器110号端口(POP3)或者445端口(IMAP)的TCP连接;
c. 收件人公司邮局服务器响应收件人邮件客户端,表明自己已经准备就绪,可以接收命令。
d. 收件人邮件客户端向收件人公司邮局服务器发送命令 USER <用户名>
e. 收件人公司邮局服务器响应收件人邮件客户端,请求发送密码;
f. 收件人邮件客户端向收件人公司邮局服务器发送命令 PASS <密码>
g. 收件人公司邮局服务器验证收件人邮件客户端发送的用户名和密码,并把验证结果通知收件人邮件客户端,如果验证失败,则断开连接;
          通常情况下,我们可以将邮件服务器配置为根据邮件服务器本机上的帐户来验证用户身份,或者根据外部用户数据库来验证,比如LDAP等等。
h. 收件人邮件客户端向收件人公司邮局服务器发送邮件操作命令,比如STATUIDLLIST
i. 收件人邮件客户端向收件人公司邮局服务器发送命令 QUIT,中止会话;
 
4)总结
        一台配置得当的邮件服务器,本身已经包含了多种防垃圾邮件技术。一旦我们理解并掌 握了邮件收发的整个流程,不管是配置邮件服务器,还是配置防垃圾邮件网关,我们都能够做到不但知道要做什么,而且知道为什么要那样做。