SMTP(Simple Mail Transfer Protocol)简单邮件传输协议是一种提供可靠且有效电子邮件传输的协议。 SMTP 是建模在 FTP 文件传输服务上的一种邮件服务,主要用于传输系统之间的邮件信息并提供来信有关的通知。SMTP 独立于特定的传输子系统,且只需要可靠有序的数据流信道支持。SMTP 重要特性之一是其能跨越网络传输邮件,即“ SMTP 邮件中继”。通常,一个网络可以由公用互联网上TCP可相互访问的主机、防火墙分隔的TCP/IP 网络上TCP 可相互访问的主机,及其它LAN/WAN 中的主机利用非TCP 传输层协议组成。使用 SMTP ,可实现相同网络上处理机之间的邮件传输,也可通过中继器或网关实现某处理机与其它网络之间的邮件传输。在这种方式下,邮件的发送可能经过从发送端到接收端路径上的大量中间中继器或网关主机。域名服务系统(DNS)的邮件交换服务器可以用来识别出传输邮件的下一跳IP地址。
163 smtp_SMTP -协议原理
SMTPSMTP-简单邮件传输协议(SimpleMailTransferProtocol),是定义邮件传输的协议,它是基于TCP服务的应用层协议,由RFC0821所定义。SMPT协议规定的命令是以明文方式进行的。为了说明SMTP的工作原理,我们以向163发送邮件为实例进行说明。
在linux环境下,使用"telnetsmtp.163.com 25"连接smtp.163.com的25号端口(SMTP的标准服务端口);在windows下使用telnet程序,远程主机指定为smtp.163.com,而端口号指定为25,然后连接smtp.163.com:交互过程如下:
[lix@nslix]$telnet smtp.163.com 25
220 163.com Anti-spam GT forCoremailSystem (163com[071018])
helosmtp.163.com
250 OK
auth login
334 dXNlcm5hbWU6
USERbase64加密后的用户名
334 UGFzc3dvcmQ6
PASS base64加密后的密码
235 Authentication successful
MAILFROM:XXX@163.COM
250 Mail OK
RCPTTO:XXX@163.COM
250 Mail OK
DATA
354 End data with .
QUIT
250 Mail OK queued as smtp5,D9GowLArizfIFTpIxFX8AA==.41385S2 1211766217
SMTP
HELO是客户向对方邮件服务器发出的标识自己的身份的命令,这里假设发送者为ideal;MAILFROM命令用来表示发送者的邮件地址;RCPTTO:标识接收者的邮件地址,这里表示希望发送邮件给XXX@163.COM,如果邮件接收者不是本地用户,例如RCPTTO:ideal@btamail.net.cn,则说明希望对方邮件服务器为自己转发(Relay)邮件,若该机器允许转发这样的邮件,则表示该邮件服务器是OPENRELAY的,否则说明该服务器不允许RELAY;DATA表示下面是邮件的数据部分,输入完毕以后,以一个"."开始的行作为数据部分的结束标识;QUIT表示退出这次会话,结束邮件发送。
这就是一个简单的发送邮件的会话过程,其实当使用outlookexpress等客户软件发送时,后台进行的交互也是这样的,当然,SMTP协议为了处理复杂的邮件发送情况如附件等等,定义了很多的命令及规定,具体可以通过阅读RFC821来获得。
当你的一个朋友向你发送邮件时,他的邮件服务器和你的邮件服务器通过SMTP协议通信,将邮件传递给你邮件地址所指示的邮件服务器上(这里假设你的本地邮件服务器是Linux系统),若你通过telnet协议直接登录到邮件服务器上,则可以使用mail等客户软件直接阅读邮件,但是若你希望使用本地的MUA(MailUserAgent,如outlookexpress等客户软件)来阅读邮件,则本地客户端通过POP3或IMAP协议与邮件服务器交互,将邮件信息传递到客户端(如:win98系统)。而如果你向你的朋友回复一封信件时,你所使用的MUA也是通过SMTP协议与邮件服务(一般为发送邮件地址对应的email地址)器通信,指示其希望邮件服务器帮助转发一封邮件到你朋友的邮件地址指定的邮件服务器中。若本地邮件服务器允许你通过它转发邮件,则服务器通过SMTP协议发送邮件到对方的邮件服务器。这就是接受和发送邮件的全部过程。
163 smtp_SMTP -MailRelay
邮件服务器一般具有一个或若干个域名(这些域名应该出现在某个配置文件内),邮件服务器在运行时将监听25号端口,等待远程的发送邮件的请求。网络上其他的mail服务器或者请求发送邮件的MUA(MailUserAgent,如outlookexpress、foxmail等等)会连接邮件服务器的25号端口,请求发送邮件,SMTP会话过程一般是从远程标识自己的身份开始,过程如下:
HELOremote.system.domainname
250qmailserver.domain
MAILFROM:user@somewherer.net
250OK
RCPTTO:user1@elsewhere.net
邮件的接收者user1@elsewhere.net中的域名并不一定是邮件接受服务器的所具有的本地域名,也就是说邮件目的可能不是上面协议交互中的接收方,而是邮件发送者希望接收邮件服务器帮助其转发邮件。这时候本地系统可能有两种回答,接受它:
250OK
或者拒绝接受它:
553 sorry,.thatdomainisnotinmydomainlistofallowedrecphosts
第一种情况下,本地邮件服务器是允许relay的,它接收并同意传递一个目的地址不是本地的邮件;而第二种情况则不接收非本地邮件。
不能配置邮件服务器为openrelay的原因
如果系统管理员将自己的邮件服务器设置为openrelay,将会导致一些垃圾邮件发送者将你的邮件服务器作为转发自圾邮件的中继站,这将使垃圾邮件的接收者将矛头对准你,可能会导致报复性的邮件炸弹;垃圾邮件还能消耗你大量的资源,占用你的带宽。更为糟糕的事情可能是你的名字可能会上了黑名单,成为其他邮件接收者共同抵制的目标,你的邮件将被这些接收者所拒绝。
163 smtp_SMTP -协议程序实现
用socket连接邮件服务器实现SMTP协议的PHP程序:
<?php
<?php
class smtp
{
public $bd;
public $cntid;
public $host;
public $port = 25;
public $errno;
public $message = array();
private $user;
private $pass;
function __construct(&$bd)
{
$this->bd = $bd;
}
function sendData($order,$bool)
{
fputs($this->cntid,$order."n");
if($bool)return fgets($this->cntid,1024).'<hr />';
else return true;
}
function mail($from,$to,$message,$user,$pass,$host,$port=25,$timeout = 30)
{
if($from)$this->from = $from;
if($to)$this->to = $to;
if($user)$this->user =base64_encode($user);
if($pass)$this->pass = base64_encode($pass);
if($host)$this->host = $host;
if($port)$this->port = $port;
if(!$this->host)
{
$this->errno = 1;
return false;
}
if(!function_exists('fsockopen'))
{
$this->errno = 2;
return false;
}
$this->cntid = @fsockopen($this->host,$this->port,$errno,$errstr,$timeout);
$back = $this->sendData('helo '.$this->host);
if(substr($back,0,3)!=250)
{
$this->errno = 3;
return false;
}
if($this->user)
{
$back = $this->sendData('auth login');
if(substr($back,0,3)!=334)
{
$this->errno = 4;
return false;
}
$back = $this->sendData('user '.$this->user);
if(substr($back,0,3)!=334)
{
$this->errno = 4;
return false;
}
$back = $this->sendData('user '.$this->user);
if(substr($back,0,3)!=235)
{
$this->errno = 4;
return false;
}
}
$back = $this->sendData('mail from: <'.$this->from.'>');
if(substr($back,0,3)!=250)
{
$this->errno = 5;
return false;
}
if(is_array($this->to))
{
foreach($this->to as $p)
{
$back = $this->sendData('rcpt to: <'.$p.'>');
if(substr($back,0,3)!=250)
{
$this->errno = 6;
return false;
}
}
}
else
{
$back = $this->sendData('rcpt to: <'.$this->to.'>');
if(substr($back,0,3)!=250)
{
$this->errno = 6;
return false;
}
}
$back = $this->sendData('data');
if(substr($back,0,3)!=354)
{
$this->errno = 7;
return false;
}
$this->sendData('Content-Type: text/plain; chaRSet="'.HE.'"'."n".'MIME-Version: 1.0',false);
if(is_array($this->to))
{
foreach($this->to as $p)
{
$this->sendData('to:<'.$p.'>',false);
}
}
else $this->sendData('to:<'.$this->to.'>',false);
$this->sendData('from:'.$user.'<'.$this->to.'>',false);
if($this->message['subject'])$this->sendData('subject:'.$this->message['subject'],false);
if($this->message['body'])
{
$this->sendData('');
$this->sendData('');
$this->sendData($this->message['body'],false);
}
$back = $this->sendData('quit');
{
$this->errno = 8;
return false;
}
}
}
$smtp = new smtp;
smtp->mail($from,$to,$message,$user,$pass,$host,$port=25,$timeout );
?>
163 smtp_SMTP -通讯模型
SMTPSMTP协议是TCP/IP协议族中的一员,主要对如何将电子邮件从发送方地址传送到接收方地址,也即是对传输的规则做了规定。SMTP协议的通信模型并不复杂,主要工作集中在发送SMTP和接收SMTP上:首先针对用户发出的邮件请求,由发送SMTP建立一条连接到接收SMTP的双工通讯链路,这里的接收SMTP是相对于发送SMTP而言的,实际上它既可以是最终的接收者也可以是中间传送者。发送SMTP负责向接收SMTP发送SMTP命令,而接收SMTP则负责接收并反馈应答。
SMTP协议的命令和应答
从前面的通讯模型可以看出SMTP协议在发送SMTP和接收SMTP之间的会话是靠发送SMTP的SMTP命令和接收SMTP反馈的应答来完成的。在通讯链路建立后,发送SMTP发送MAIL命令指令邮件发送者,若接收SMTP此时可以接收邮件则作出OK的应答,然后发送SMTP继续发出RCPT命令以确认邮件是否收到,如果接收到就作出OK的应答,否则就发出拒绝接收应答,但这并不会对整个邮件操作造成影响。双方如此反复多次,直至邮件处理完毕。SMTP协议共包含10个SMTP命令,列表如下:
SMTP命令命令说明
HELLO<domain><CRLF>识别发送方到接收SMTP的一个HELLO命令
MAILFROM:<reverse-path><CRLF><reverse-path>为发送者地址。此命令告诉接收方一个新邮件发送的开始,并对所有的状态和缓冲区进行初始化。此命令开始一个邮件传输处理,最终完成将邮件数据传送到一个或多个邮箱中。
RCPTTO:<forward-path><CRLF><forward-path>标识各个邮件接收者的地址
DATA<CRLF>
接收SMTP将把其后的行为看作邮件数据去处理,以<CRLF>.<CRLF>标识数据的结尾。
REST<CRLF>退出/复位当前的邮件传输
Noop<CRLF>要求接收SMTP仅做OK应答。(用于测试)
QUIT<CRLF>要求接收SMTP返回一个OK应答并关闭传输。
VRFY<string><CRLF>验证指定的邮箱是否存在,由于安全因素,服务器多禁止此命令。
EXPN<string><CRLF>验证给定的邮箱列表是否存在,扩充邮箱列表,也常禁止使用。
HELP<CRLF>查询服务器支持什么命令
163 smtp_SMTP -安全
sendmail是在Unix环境下使用最广泛的实现邮件发送/接受的邮件传输代理程序。由于Sendmail邮件服务器的特点是功能强大而复杂,因此为保证Sendmail的安全性,需要作以下一些工作。
1、设置Sendmail使用"smrsh"
smrsh程序的目的是作为在mailer中为sendmail定义的"/bin/sh"的替代shell。smrsh是一种受限shell工具,它通过"/
SMTPetc/smrsh"目录来明确指定可执行文件的列表。简而言之smrsh限制了攻击者可以执行的程序集。当它与sendmail程序一起使用的时候,smrsh有效的将sendmail可以执行的程序的范围限制在smrsh目录之下。
第一步:
决定smrsh可以允许sendmail运行的命令列表。缺省情况下应当包含以下命令,但不局限于这些命令:
"/bin/mail"(如果在你的系统中安装了的话)
"/usr/bin/procmail"(如果在你的系统中安装了的话)
注意:不可在命令列表里包括命令解释程序,例如sh(1),CSH(1),perl(1),uudecode(1)及流编辑器sed(1)。
第二步:
在"/etc/smrsh"目录中创建允许sendmail运行的程序的符号连接。
使用以下命令允许mail程序"/bin/mail"运行:
[root@deep]#cd/etc/smrsh
[root@deep]#ln-s/bin/mailmail
用以下命令允许procmail程序"/usr/bin/procmail"运行:
[root@deep]#cd/etc/smrsh
[root@deep]#ln-s/usr/bin/procmailprocmail
这将允许位于".forward"和"aliases"中的用户采用"|program"语法来运行mail及procmail程序。
第三步
配置sendmail使之使用受限shell。mailer程序在sendmail的配置文件"/etc/sendmail.cf"中仅有一行。必须修改"sendmail.cf"文件中"Mprog"定义的那一行。将"/bin/sh"替换为"/usr/sbin/smrsh"。
编辑"sendmail.cf"文件(vi/etc/sendmail.cf)并改动下面这一行:
例如:
Mprog,P=/bin/sh,F=lsDFMoqeu9,S=10/30,R=20/40,D=$z:/,T=X-Unix,A=sh-c$u
应该被改为:
Mprog,P=/usr/sbin/smrsh,F=lsDFMoqeu9,S=10/30,R=20/40,D=$z:/,T=X-Unix,A=sh-c$u
现在用以下命令手工重起sendmail进程:
[root@deep]#/etc/rc.d/init.d/sendmailrestart
2、"/etc/aliases"文件
如果没有加以正确和严格的管理的话,别名文件被用来获取特权。例如,很多发行版本在别名文件中带有"decode"别名。现在这种情况越来越少了。
这样做的目的是为用户提供一个通过mail传输二进制文件的方便的方式。在邮件的发送地,用户把二进制文件用"uuencode"转换成ASCII格式,并把结果邮递给接收地"decode"别名。那个别名通过管道把邮件消息发送到"/usr/bin/uuencode"程序,由这个程序来完成从ASCII转回到原始的二进制文件的工作。
删除"decode"别名。类似的,对于所有用于执行没有被放在smrsh目录下的程序的别名,你都要仔细的检查,可能它们都值得怀疑并应当删除它们。要想使你的改变生效,需要运行:
[root@deep]#/usr/bin/newaliases
编辑别名文件(vi/etc/aliases)并删除以下各行:
#Basicsystemaliases--theseMUSTbepresent.
MAILER-DAEMON:postmaster
postmaster:root
#Generalredirectionsforpseudoaccounts.
bin:root
daemon:root
games:root??删除这一行
ingres:root??删除这一行
nobody:root
system:root??删除这一行
toor:root??删除这一行
uucp:root??删除这一行
#Well-knownaliases.
manager:root??删除这一行
dumper:root??删除这一行
operator:root??删除这一行
#trapdecodetocatchsecurityattacks
decode:root??删除这一行
#Personwhoshouldgetroot'smail
#root:marc
最后应该运行"/usr/bin/newaliases"程序使改动生效
3、避免你的Sendmail被未授权的用户滥用
最新版本的Sendmail(8.9.3)加入了很强的防止欺骗的特性。它们可以防止你的邮件服务器被未授权的用户滥用。编辑你的"/etc/sendmail.cf"文件,修改一下这个配置文件,使你的邮件服务器能够挡住欺骗邮件。
编辑"sendmail.cf"文件(vi/etc/sendmail.cf)并更改下面一行:
OPrivacyOptions=authwarnings
改为:
OPrivacyOptions=authwarnings,noexpn,novrfy
设置"noexpn"使sendmail禁止所有SMTP的"EXPN"命令,它也使sendmail拒绝所有SMTP的"VERB"命令。设置"novrfy"使sendmail禁止所有SMTP的"VRFY"命令。这种更改可以防止欺骗者使用"EXPN"和"VRFY"命令,而这些命令恰恰被那些不守规矩的人所滥用。
4、SMTP的问候信息
当sendmail接受一个SMTP连接的时候,它会向那台机器发送一个问候信息,这些信息作为本台主机的标识,而且它所做的第一件事就是告诉对方它已经准备好了。
编辑"sendmail.cf"文件(vi/etc/sendmail.cf)并更改下面一行:
OSmtpGreetingMessage=$jSendmail$v/$Z;$b
改为:
OSmtpGreetingMessage=$jSendmail$v/$Z;$bNOUCEC=xxL=xx
现在手工重起一下sendmail进程,使刚才所做的更改生效:
[root@deep]#/etc/rc.d/init.d/sendmailrestart
以上的更改将影响到Sendmail在接收一个连接时所显示的标志信息。你应该把"`C=xxL=xx"条目中的"xx"换成你所在的国家和地区代码。后面的更改其实不会影响任何东西。但这是"news.admin.net-abuse.email"新闻组的伙伴们推荐的合法做法。
5、限制可以审核邮件队列内容的人员
通常情况下,任何人都可以使用"mailq"命令来查看邮件队列的内容。为了限制可以审核邮件队列内容的人员,只需要在"/etc/sendmail.cf"文件中指定"restrictmailq"选项即可。在这种情况下,sendmail只允许与这个队列所在目录的组属主相同的用户可以查看它的内容。这将允许权限为0700的邮件队列目录被完全保护起来,而我们限定的合法用户仍然可以看到它的内容。
编辑"sendmail.cf"文件(vi/etc/sendmail.cf)并更改下面一行:
OPrivacyOptions=authwarnings,noexpn,novrfy
改为:
OPrivacyOptions=authwarnings,noexpn,novrfy,restrictmailq
现在我们更改邮件队列目录的权限使它被完全保护起来:
[root@deep]#chmod0700/var/spool/mqueue
注意:我们已经在sendmail.cf中的"PrivacyOptions="行中添加了"noexpn"和"novrfy"选项,现在在这一行中我们接着添加"restrictmailq"选项。
任何一个没有特权的用户如果试图查看邮件队列的内容会收到下面的信息:
[user@deep]$/usr/bin/mailq
Youarenotpermittedtoseethequeue
SMTP6、限制处理邮件队列的权限为"root"
通常,任何人都可以使用"-q"开关来处理邮件队列,为限制只允许root处理邮件队列,需要在"/etc/sendmail.cf"文件中指定"restrictqrun"。
编辑"sendmail.cf"文件(vi/etc/sendmail.cf)并更改下面一行:
OPrivacyOptions=authwarnings,noexpn,novrfy,restrictmailq
改为:
OPrivacyOptions=authwarnings,noexpn,novrfy,restrictmailq,restrictqrun
任何一个没有特权的用户如果试图处理邮件队列的内容会收到下面的信息:
[user@deep]$/usr/sbin/sendmail-q
Youdonothavepermissiontoprocessthequeue
7、在重要的sendmail文件上设置不可更改位
可以通过使用"chattr"命令而使重要的Sendmail文件不会被擅自更改,可以提高系统的安全性。具有"+i"属性的文件不能被修改:它不能被删除和改名,不能创建到这个文件的链接,不能向这个文件写入数据。只有超级用户才能设置和清除这个属性。
为"sendmail.cf"文件设置不可更改位:
[root@deep]#chattr+i/etc/sendmail.cf
为"sendmail.cw"文件设置不可更改位:
[root@deep]#chattr+i/etc/sendmail.cw
为"sendmail.mc"文件设置不可更改位:
[root@deep]#chattr+i/etc/sendmail.mc
为"null.mc"文件设置不可更改位:
[root@deep]#chattr+i/etc/null.mc
为"aliases"文件设置不可更改位:
[root@deep]#chattr+i/etc/aliases
为"access"文件设置不可更改位:
[root@deep]#chattr+i/etc/mail/access
qmail安全
qmail有一个名为rcpthosts(该文件名源于RCPTTO命令)的配置文件,其决定了是否接受一个邮件。只有当一个RCPTTO命令中的接收者地址的域名存在于rcpthosts文件中时,才接受该邮件,否则就拒绝该邮件。若该文件不存在,则所有的邮件将被接受。当一个邮件服务器不管邮件接收者和邮件接收者是谁,而是对所有邮件进行转发(relay),则该邮件服务器就被称为开放转发(openrelay)的。当qmail服务器没有rcpthosts时,其是开放转发的。
设置自己服务器为非openrelay的最简单的办法就是将你的邮件服务器的所有域名(若DNS的MX记录指向该机器,也应该包括该域名。例如你的机器有三个域名mail.linxuaid.com.cn、mail1.linuxaid.com.cn,而且linuxaid.com.cn的MX指向mail.linuxaid.com.cn,则qmail的rcphosts的应该包括mail.linuxaid.com.cn、mail1.linuxaid.com.cn和linuxaid.com.cn)。
但是这将导致你的本地客户也被拒绝使用你的服务器转发邮件,而要支持客户使用MUA来发送邮件,必须允许客户使用服务器转发邮件。qmail-smtpd支持一种有选择性的忽略rcpthosts文件的方法:若qmail-smtpd的环境变量RELAYCLIENT被设置,则rcpthost文件将被忽略,relay将被允许。但是如何识别一个邮件发送者是否是自己的客户呢?qmail并没有采用密码认证的方法,而是判断发送邮件者的源IP地址,若该IP地址属于本地网络,则认为该发送者为自己的客户。
这里就要使用ucspi-tcp软件包。在这里我们要使用该软件包的tcpserver程序。该程序的功能类似于inetd-监听进入的连接请求,为要启动的服务设置各种环境变量,然后启动指定的服务。
tcpserver的配置文件是/etc/tcp.smtp,该文件定义了是否对某个网络设置RELAYCLIENT环境变量。例如,本地网络是地址为192.168.10.0/24的C类地址,则tcp.smtp的内容应该设置如下:
127.0.0.1:allow,RELAYCLIENT=""
192.168.10.:allow,RELAYCLIENT=""
:allow
这几个规则的含义是指若连接来自127.0.0.1和192.168.10则允许,并且为其设置环境变量RELAYCLIENT,否则允许其他连接,但是不设置RELAYCLIENT环境变量。这样当从其他地方到本地的25号连接将会被允许,但是由于没有被设置环境变量,所以其连接将会被qmail-smptd所拒绝。
但是tcopserver并不直接使用/etc/tcp.smtp文件,而是需要先将该文件转化为cbd文件:
[lix@mail/etc]$#tcprulestcp.smtp.cdbtcp.smtp.temp<tcp.smtp
然后再回头看在/service/qmail-smtpd目录下的run文件中有
/usr/local/bin/tcpserver-v-p-x/etc/tcp.smtp.cdb
可以看到,tcpserver利用了/etc/smtp.cbd文件。若本地有多个网络,则需要这些网络都出现在/etc/tcp.smtp文件中。
这样就实现了允许本地客户relay邮件,而防止relay被滥用。
163 smtp_SMTP -在X.25上的应用
1
SMTP.本备忘录的状态
本备忘录讲述了一种基于CCITT的X.25标准提供的虚电路业务的SMTP标准。
本备忘录的发布不受任何限制。
2.简介
在RFC821("SIMPLEMAILTRANSPORTPROTOCOL",SMTP,简单邮件传输协议)
的附录D中提到了直接将SMTP置于X.25虚电路(ISO第3层)上的可能性。并建议“利
用一种类似于TCP可靠的端到端协议在X.25的连接上”。在1981年时,考虑到psdns的
总体的可靠性,这毫无疑问是可行的。这一业务现在(1989年)已经非常可靠,它允许直
接将其置于虚电路业务上。
在包括22个不同的国家的24个PSDN网的许多产品,证明了这种方法是成功的,结
果证明,即使使用在一些花费比较昂贵的PSDN中,这种方法还是十分经济的,在X.25专
网和X.25局域网中,这种方法也是成功。
每一个SMTP会话必须打开一条X.25虚电路(VirtualCircuit,VC),SMTP会话将
使用由VC提供的全双工通道。通常,VC是由发起呼叫的一方关闭的。
3.协议ID和呼叫用户数据
呼叫用户数据区的前4个字节应该是0xC0F7,0000(十六进制),十进制是19224700。
这个字段通常用来标识一个协议ID,或者PRID。
但是在实际的操作中,应该有能力在基本前缀地址上配置呼叫用户数据,包括协议ID
字段。
4.数据流
在发送端通常把SMTP数据分成许多数据包,相应地,在数据包封装的时候应该置M
位(表示有后续数据包)。数据包的总长度可以达到2048个字节。
通常我们建议SMTP命令和响应应在一个数据包发送出去,或者只有一个后续数据包。
只要对调试协议方便即可。但这并不要求是必须的。
5.识别数据
Q比特被置位的分组和中断分组是没有用的。如果收到了,应该被忽略掉。
6.电路复位
如果收到了一个3层的电路复位指示,这条VC应该清除,SMTP连接应该重新建立。
重新建立会带来一些时延,也可能是不同的呼叫业务。
7.呼叫业务
任何被X.25呼叫请求业务选择的协商特征都可以使用。使用时应有能力为每一个被叫
地址指定业务。
8.字符编码
X.25使用的字符编码是完整的8位ASCII码,没有任何遗漏和修改。一行应该以CRLF
(十进制:1310)结尾,也可以仅仅以LF(十进制:10)来标识一行的结束。
9.关闭连接
跟TCP协议不同,在清除请求的过程中,X.25不提供数据的同步传送;当清除虚电
路时,就丢弃所有正在传送的数据包。因此,当收到“服务关闭”消息时,主叫的一边关闭
SMTP会话层(在X.25上),这种消息要么是QUIT命令的响应,或者是因为服务必须中止。
10.超时
SMTP通常不提供超时会话,在X.25,以下几项是有效的:
10.1呼叫请求
如果在100秒内没有收到“呼叫接受”信息,或者在120秒(另外)内没有收到“服
务准备好”信息,那么应该清除这次呼叫,然后重试。
10.2已经建立的呼叫
当协议会话建立之后,在10分钟内如果没有收到任何响应,那么就应该清除这条虚
电路。
10.3关闭
执行QUIT命令后,超时时间缩短为20秒。这可能会导致不经意地退出,但它不会影
响已经完成的SMTP业务。
10.4清除
当X.25“清除请求”发出时,这条虚电路将在X.25协议指定的时间内超时。
11.其他特性
X.25的其他特性,如永久虚电路和D比特的选择,都没有用到。
163 smtp_SMTP -服务扩展
SMTP提供一种可靠的有效的传送机制,它用于传送电子邮件。虽然十几年来,它的作用已经有目共睹,可是对它功能的扩充也是必不可少的。对SMTP服务的扩展我们介绍一下:在SMTP转发的邮件中包括信封和内容这两种东西。我们写信也写信封和信皮,我们可以借生活中的信件来帮助理解。
(1)SMTP信封比较容易理解,它被作为一系列的SMTP协议单元传送,它包括发送者地址,传送模式,还有一个或多个接收者地址。如果有不清楚的地方,请参阅《SMTP协议标准》。
(2)至于内容,它是由两部分组成的,一部分是信头,一部分是信体,信头是由一个个的域/值对(一个域,一个值)组成的,如果信体有结构的话,它的结构是以MIME构造的。内容从根本上来说是文本的,一般也是由ASCII码构成的,但是由于使用了MIME,所以这个限制应该也是没有了,但信头却不行,一般都应该使用ASCII码表示。虽然SMTP协议是一个不错的协议,可是对它的扩展还是不可避免,本文主要说明了一种扩展方法,使用这种扩展方法,服务器和用户之间可以相互知道对方使用了扩展,使用了多少,如果进行通信。
这里我们希望让大家知道网络协议中的一个经验:参数越多,死得越快;参数越少,越能持久。参数太多了,根本不利于使用,无法推广,早晚会被别的协议取代。这也符合科学的基础原理,简单。这说明在实现时一定要小心,如果不小心会便得到的远远小于付出的,有时根本不能提供任何益处。
下面我们看一下EHLO命令,支持SMTP服务扩展的客户应该以EHLO命令开始SMTP会话,而不是通常的HELO命令。如果服务器也支持,那就返回确认响应,如果不支持就返回失败响应。因为引入了EHLO命令,因此会话开始的第一条命令可以是HELO或EHLO。
因此引入了新的参数,所以SMTP的MAILFROM和RCPTTO命令行长度也能再是512字节了,但是引入新参数的长度必须加以说明,以便实现者准备缓冲区。
命令格式如下:
ehlo-cmd::="EHLO"SPdomainCRLF
在命令成功是,服务器返回代码250,如果失败返回代码550,如果出错,返500,501,502,504或421。对比《SMTP协议标准》,EHLO命令可以出现在任何HELO命令出现的地方,在成功发送一个HELO或EHLO命令后再次发送它会使服务器返回503。客户这时不能缓存服务器返回的任何信息。这里一定要注意的是,每次开始SMTP扩展服务会话的时候必须发送EHLO命令。如果服务器能够处理EHLO命令,它会返回代码250。这样,服务器和客户就处于初始状态了,也就是说,所有的状态表和缓冲区已经准备完毕。通常这种响应是多行的,每行响应包括一个关键字,如果有的话,还有一个或多个参数,响应的语法如下:
ehlo-ok-rsp::="250"domain[SPgreeting]CRLF
/("250-"domain[SPgreeting]CRLF
*("250-"ehlo-lineCRLF)
"250"SPehlo-lineCRLF)
greeting::=1*
ehlo-line::=ehlo-keyword*(SPehlo-param)
ehlo-keyword::=(字母/数字)*(字母/数字/"-")
ehlo-param::=1*
ALPHA::=
DIGIT::=
CR::=
LF::=
SP::=
虽然EHLO关键字可以是大写,小写,大小写混合的,但是对它的处理是大小写敏感的,这是与原来规定不同的。IANA支持SMTP服务扩展注册,相对于每个扩展都有一个相应的EHLO关键字值,每个在IANA注册的服务扩展必须在一个RFC中定义。如果一个关键字以X开头,它指的是这个服务扩展是双方约定的,不是标准的。
如果出于某种原因,服务器不能列出它所支持的服务扩展,就返回代码554。在接收到这个代码后,客户要么发送HELO,要么发送QUIT命令。有时候服务器接收到EHLO命令,可是命令参数不可接受,它就返回代码501。如果服务器识别了EHLO,但对服务器扩展未实现,则返回代码502。
如果服务器不再提供服务扩展,则返回代码421。在接收到这个代码后,客户要么发送HELO,要么发送QUIT命令。如果服务器不支持服务扩展,则返回500,服务器保持现有状态,在接收到这个代码后,客户要么发送HELO,要么发送QUIT命令。
有时候,SMTP服务器会在接收到EHLO命令后因为某种原因关闭连接,这种情况在原来的SMTP协议标准中未涉及。为了处理这种情况,客户必须能够确认服务器是否能够工作,它可以重新连接并发送HELO或EHLO命令。有些服务器在接收到一个EHLO命令后会拒绝接收新的HELO命令,这时可以利用RSET命令重新启动,然后再发送HELO。如果客户不注意这样的小细节,会收到失败代码。
下面我们来看一下MAILFROM和RCPTTO参数。许多服务扩展是在MAILFROM和RCPTTO命令后加入一些参数来实现的。下面我们看一下这两个命令的格式:
esmtp-cmd::=inner-esmtp-cmd[SPesmtp-parameters]CRLF
esmtp-parameters::=esmtp-parameter*(SPesmtp-parameter)
esmtp-parameter::=esmtp-keyword["="esmtp-value]
esmtp-keyword::=(字母/数字)*(字母/数字/"-")
esmtp-value::=1*
inner-esmtp-cmd::=("MAILFROM:"返回路径)/("RCPTTO:"转发路径)
如果服务器不能识别或实现一个或多个MAILFROM或RCPTTO参数,它应该返回代码555。如果这种情况只是暂时的,服务器返回代码455。其它返回代码请查阅相关资料,这里不再详述了。服务器以服务扩展处理时,它处理的任何信息都应该在包头上加上“服务扩展标记”以示区别。
下面是一个例子:
(1)双方交互:S是服务器,C是客户。
S:
C:
S:220dbc.mtview.ca.usSMTPserviceready
C:EHLOymir.claremont.edu
S:250dbc.mtview.ca.ussayshello
...
(2)下面也是一个例子:
S:
C:
S:220dbc.mtview.ca.usSMTPserviceready
C:EHLOymir.claremont.edu
S:250-dbc.mtview.ca.ussayshello
S:250-EXPN
S:250-HELP
S:250-8BITMIME
S:250-XONE
S:250XVRB
...
这说明服务器实现了服务扩展EXPN和HELP,这两个是标准的服务扩展,另外两个以X开头的是非标准的。
SMTP(3)最后,我们来看看服务器不支持服务扩展时的情况:
S:
C:
S:220dbc.mtview.ca.usSMTPserviceready
C:EHLOymir.claremont.edu
S:500Commandnotrecognized:EHLO
...
代码500表示服务器不支持服务扩展。
163 smtp_SMTP -参考资料
中国协议分析网: http://www.cnpaf.net/