SMTP 协议原始命令码和工作原理
是工作在两种情况下:一是电子邮件从客户机传输到服务器;二是从某一个服务器
传输到另一个
服务器
是个请求/响应协议,命令和响应都是基于 ASCII 文本,并以 CR 和 LF 符结束。响
应包括一个表示返
回状态的三位数字代码
在 TCP 协议 25 号端口监听连接请求
4.连接和发送过程:
a.建立 TCP 连接
b.客户端发送 HELO 命令以标识发件人自己的身份,然后客户端发送 MAIL 命令
服务器端正希望以 OK 作为响应,表明准备接收
c.客户端发送 RCPT 命令,以标识该电子邮件的计划接收人,可以有多个 RCPT 行
服务器端则表示是否愿意为收件人接受邮件
d.协商结束,发送邮件,用命令 DATA 发送
e. 以.表示结束输入内容一起发送出去
f.结束此次发送,用 QUIT 命令退出。
5.另外两个命令:
VRFY---用于验证给定的用户邮箱是否存在,以及接收关于该用户的详细信息。
EXPN---用于扩充邮件列表。
6.邮件路由过程:
SMTP 服务器基于‘域名服务 DNS 中计划收件人的域名来路由电子邮件。SMTP 服务器基于
DNS 中的 MX 记录
来路由电子邮件,MX 记录注册了域名和相关的 SMTP 中继主机,属于该域的电子邮件都应
向该主机发送。
若 SMTP 服务器 收到一封信要发到 shuser@:
请 求 DNS 给 出 主 机 的 CNAME 记 录 , 如 有 , 假 若 CNAME 到
,则再次
请求 的 CNAME 记录,直到没有为止
b. 假 定 被 CNAME 到 , 然 后 sendmail 请 求 @ 域 的 DNS 给 出
的 MX 记录,
shmail MX 5
10
c. Sendmail 最后请求 DNS 给出 的 A 记录,即 IP 地址,若返回值为
d. Sendmail 与 连接,传送这封给 shuser@ 的信到 这台服务器的
SMTP 后台程序
基本命令集:
命令 描述
------------------------------
HELO 向服务器标识用户身份
发送者能欺骗,说谎,但一般情况下服务器都能检测到。
MAIL 初始化邮件传输
mail from:
RCPT 标识单个的邮件接收人;常在 MAIL 命令后面
可有多个 rcpt to:
DATA 在单个或多个 RCPT 命令后,表示所有的邮件接收人已标识,并初始化数据传输,
以.结束。
VRFY 用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令
EXPN 验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用
HELP 查询服务器支持什么命令
NOOP 无操作,服务器应响应 OK
QUIT 结束会话
RSET 重置会话,当前传输被取消
--------------------------------
8. MAIL FROM 命令中指定的地址是称作 envelope from 地址,不需要和发送者自己的地址
是一致的。
RCPT TO 与之等同,指明的接收者地址称为 envelope to 地址,而与实际的 to:行是什么无
关。
9.为什么没有 RCPT CC 和 RCPT BCC:?
所有的接收者协商都通过 RCPT TO 命令来实现,如果是 BCC,则协商发送后在对方接收时
被删掉信封接收者
10.邮件被分为信封部分,信头部分和信体部分
envelope from, envelope to 与 message from:, message to:完全不相干。
evnelope 是由服务器主机间 SMTP 后台提供的,而 message from/to 是由用户提供的。有无
冒号也是区别。
11. 怎样由信封部分检查是否一封信是否是伪造的?
a. received 行的关联性。
现在的 SMTP 邮件传输系统,在信封部分除了两端的内部主机处理的之个,考虑两个公司
防火墙之间
的部分,若两台防火墙机器分别为A和B,但接收者检查信封 received:行时发现经过了
C.则是伪造的。
b. received:行中的主机和 IP 地址对是否对应如:
Receibed: from ( [] by mail .....
c. 被人手动添加在最后面的 received 行:
Received: from ([]) by mail . ()
Received: from by ()
Received: from by ()
--------------------------------------------------------------------------------
SMTP 服务对命令流水的扩展
1.摘要
本文主要定义了一种 SMTP 服务扩展,使用这种服务扩展服务器可以说明它在一个 TCP 发
送操作中可以接收多少个指令。在一个 TCP 发送指令中使用多个操作可以大大提高系统的
运行效率。
2. 介绍
虽然 SMTP 服务已经广泛使用了,效果也不错,但是对它的扩展也是不可少的。如果某个
网络需要很长时间进行连接,那 SMTP 运行的效果可就比较差了。SMTP 的时间就费在等待
一个个的命令上了。如果能够使 SMTP 客户端进行命令流水,也就是一次发送许多指令,
就会提高运行效率。但以前的协议中没有说明这一条,客户无法知道服务器能够同时接收多
少指令。因此产生了如下的一些问题:
连接过程中连接失控或缓冲区满;
在 SMTP 命令失败时清除 TCP 输入缓冲区,有时这是没有必要的;
对一些命令会不讲道理地判断它为失败,例如一些服务器如果在上一个 REPT TO 失败后会
再不接收 DATA 命令,而不管 RCPT TO 之前的命令是不是成功,而有些服务器则可以在
RCPT TO 命令失败后接收 DATA 命令。
3. 命令流水扩展框架
它的定义如下:
此服务扩展的名称为流水(Pipelining);
与 EHLO 相关联的扩展值是 PIPELINING;
PIPELINING EHLO 不再参数;
MAIL FROM 或 RCPT TO 命令不附加其它参数;
没有附加其它 SMTP 命令;
4. 流水服务扩展
当客户机希望使用流水时,它会发送 EHLO 命令到服务器,如果服务器以 250 响应(其中
的响应包括 PIPELINING)就表明服务器支持 SMTP 服务流水。
. 客户使用流水
在客户知道服务器可以支持流水的时候,客户可以传输多个命令(称为命令组)到服务器,
不用发送一条等待一下然后再发一条,特别的 RSET,MAIL FROM,SEND FROM,SOML
FROM ,SAML FROM 和 RCPT TO 可以出现在命令组的任何地方。EHLO ,DATA ,
VRFY,EXPN,TURN,QUIT 和 NOOP 只能出现在命令组中的最后位置,因为它们成功与
否将改变 SMTP 命令所处的状态。由其它 SMTP 扩展产生的命令只能出现在组中的最后位
置。实际传送的命令可以是组中的第一个命令。
客户 SMTP 必须检查与组中据有相关的状态。如果 RCPT TP 接收地址未被接受,客户端必
须检查 DATA 的状态,客户端不能假设因为没有 RCPT TO 是成功的所以 DATA 就会失败。
如果 DATA 命令被正确拒绝,客户端可以发出 RSET,如果 DATA 命令没有被正确拒绝,
客户端要发出一个点(dot)。命令所产生的状态必须和分别发出每个命令时相同,必须支持
多行(Multiline)响应。客户 SMTP 可以选择在非阻塞状态运行,它在接收到服务器的响应
时立即处理,即使还有数据需要发送也不能推迟对响应的处理。如果不支持非阻塞状态,客
户端必须检查 TCP 窗口的大小,TCP 窗口的大小必须大于命令组的大小。窗口大小经常是
4K,如果不能进行这样的检查,可能会导致死锁。
. 服务器对流水的支持
服务器应该提供下面的服务扩展:
在任何情况下不行将 TCP 输入缓冲区的内容丢弃;
当且仅当接收到一个或多个有效的 RCPT TO 命令时,才对 DATA 命令应该主动发出响应;
因为 DATA 命令没有合法的接收者,结果接收到空信息时,不要再发出消息给任何人(当
然对 DATA 命令还要做一个响应);
对成组的 RSET,MAIL FROM,SEND FROM,SOML FROM,SAML FROM 和 RCPT TO
命令的响应先保存起来,然后一起发送;
不允许缓存对 EHLO,DATA,VRFY,EXPN,TURN,QUIT 和 NOOP 的响应;
不允许缓冲不可识别命令的响应;
在本地 TCP 输入缓冲区为空时必须将据有未发出的响应全部发出;
不允许对未接收到的命令进行猜测;或假设它的存在;
在响应的文本信息中应该表时这是对哪个命令进行的响应;
5. 例子
下面是一个不支持流水的 SMTP 会话:其中 S 代表服务器,C 代表客户端;
S: <等待打开连接>;
C: <打开连接>;
S: 220 SMTP service ready
C: HELO
S: 250
C: MAIL FROM:<mrose@>;
S: 250 sender <mrose@>; OK
C: RCPT TO:<ned@>;
S: 250 recipient <ned@>; OK
C: RCPT TO:<dan@>;
S: 250 recipient <dan@>; OK
C: RCPT TO:<kvc@>;
S: 250 recipient <kvc@>; OK
C: DATA
S: 354 传输邮件内容,并以一个只有”.”的行结束邮件
...
C: .
S: 250 message sent
C: QUIT
S: 221 goodbye
在上例中客户需要 9 次等待服务器的响应,下面我们来看看在支持流水的情况下是什么样子:
其中 S 代表服务器,C 代表客户端;
S: <等待打开连接>;
C: <打开连接>;
S: 220 SMTP service ready
C: EHLO
S:
S: 250 PIPELINING
C: MAIL FROM:<mrose@>;
C: RCPT TO:<ned@>;
C: RCPT TO:<dan@>;
C: RCPT TO:<kvc@>;
C: DATA
S: 250 sender <mrose@>; OK
S: 250 recipient <ned@>; OK
S: 250 recipient <dan@>; OK
S: 250 recipient <kvc@>; OK
S: 354 传输邮件内容,并以一个只有”.”的行结束邮件
...
C: .
C: QUIT
S: 250 message sent
S: 221 goodbye
现在等待的次数由 9 次变为了 4 次,下面我们看一下当据有接收者均被拒绝时会是什么情况:
S: <等待打开连接>;
C: <打开连接>;
S: 220 SMTP service ready
C: EHLO
S:
S: 250 PIPELINING
C: MAIL FROM:<mrose@>;
C: RCPT TO:<nsb@>;
C: RCPT TO:<galvin@>;
C: DATA
S: 250 sender <mrose@>; OK
S: 550 remote mail to <nsb@>; not allowed
S: 550 remote mail to <galvin@>; not allowed
S: 554 no valid recipients given //未给出合法的接收者
C: QUIT
S: 221 goodbye
客户端也等待了 4 次,如果服务器在接收 DATA 命令当不检查接收者的合法性,则是下面
的情况:
S: <等待打开连接>;
C: <打开连接>;
S: 220 SMTP service ready
C: EHLO
S:
S: 250 PIPELINING
C: MAIL FROM:<mrose@>;
C: RCPT TO:<nsb@>;
C: RCPT TO:<galvin@>;
C: DATA
S: 250 sender <mrose@>; OK
S: 550 remote mail to <nsb@>; not allowed
S: 550 remote mail to <galvin@>; not allowed
S: 354 传输邮件内容,并以一个只有”.”的行结束邮件
C: .
C: QUIT
S: 554 no valid recipients //未给出合法的接收者
S: 221 goodbye