一、网络协议概述
网络传输协议或简称为传送协议(Communications Protocol),是指计算机通信的共同语言。是目前最普及的计算机通信方式,所以"传送协议"一般都指计算机通信的传送协议,如:TCP/IP、NetBEUI等。然而,传送协议也存在于计算机的其他形式通信,例如:面向对象编程里面对象之间的通信;操作系统内不同程序之间的消息,都需要有一个传送协议,以确保传信双方能够沟通无间。
以下是TCP/IP体系结构中每层中包含的主要协议:(摘自维基百科)
网络协议 |
DHCP · DNS · FTP · Gopher · HTTP· IMAP4 · IRC · NNTP · XMPP ·POP3 · SIP · SMTP · SNMP · SSH ·TELNET · RPC · RTCP · RTP ·RTSP· SDP · SOAP · GTP · STUN · NTP· SSDP · BGP · RIP · 更多 |
Wi-Fi(IEEE 802.11) · WiMAX(IEEE 802.16) · ARP · RARP · ATM · DTM · 令牌环 · 以太网 ·FDDI · 帧中继 · GPRS · EVDO ·HSPA · HDLC · PPP · L2TP · ISDN· 更多 |
以太网 · 调制解调器 · 电力线通信(PLC) · SONET/SDH · G.709 · 光导纤维 · 同轴电缆 · 双绞线 · 更多 |
前段时间给公司一个老客户搭建了一个轻量级的邮件服务器,由于他们的需求很简单,负载也不大,于是使用了一个免费的邮件服务器hMailServer,可以在这里下载,数据库使用的MySQL。借这次机会,把网络协议系统学习一下,今天就从邮件协议SMTP开始。
简单邮件传输协议 (Simple Mail Transfer Protocol, SMTP) 是事实上的在Internet传输email的标准。
SMTP是一个相对简单的基于文本的协议。在其之上指定了一条消息的一个或多个接收者(在大多数情况下被确认是存在的),然后消息文本会被传输。
由于SMTP开始是基于纯ASCII文本的,它在二进制文件上处理得并不好。诸如MIME(多用途互联网邮件扩展)的标准被开发来编码二进制文件以使其通过SMTP来传输。今天,大多数SMTP服务器都支持8位MIME扩展,它使二进制文件的传输变得几乎和纯文本一样简单,此举大大方便了附件的放松。
SMTP是一个"推"的协议,它不允许根据需要从远程服务器上"拉"来消息。要做到这点,邮件客户端必须使用POP3或IMAP。另一个SMTP服务器可以使用ETRN在SMTP上触发一个发送。
协议分析将使用一款开源、免费的协议分析软件:WireShark,官方主页:http://www.wireshark.org/
其功能非常强大,可以自定义筛选规则,非常便于抓包、分析协议等。
推荐资源:
相关 RFC
- RFC 5321 - 简单邮件传输协议,在最近(2008.8)代替了RFC 2821
- RFC 2821 - 简单邮件传输协议,在最近(2001)代替了RFC 821,RFC 1869,RFC 974
- RFC 2822 - Internet(比如 e-mail)消息格式,代替了RFC 822
- RFC 3461 - SMTP的发送状态通知(DSN)扩展,代替了RFC 1891
二、SMTP传送阶段
SMTP报文的传送分为三个阶段:连接建立、邮件传送、连接终止。
2.1、连接建立
在端口25建立TCP连接后,就开始了连接阶段。
2.2、邮件传送
在SMTP客户端与服务器建立连接后,发件人就可以与一个或多个收件人交换单个的报文了。整个阶段分为8个步骤:
若收件人超过一个,则步骤3与步骤4将重复进行。
2.3、连接终止
在报文传送成功后,客户就终止连接,此时TCP连接也必须关闭。
三、命令与响应
SMTP使用命令与响应在客户端与服务器之间传递报文。
命令采用 【关键字 = 变量】 的格式:
关键字 | 变量 | |
必须 | HELO | 发送方的主机名 |
MAIL FROM | 发件人 | |
RCPT TO | 预期的收件人 | |
DATA | 邮件的主体 | |
QUIT | ||
可选 | RSET | |
VRFY | 需要验证的收件人名字 | |
NOOP | ||
不常用 | TURN | |
EXPN | 需要扩展的邮件发送清单 | |
HELP | 命令名 | |
SEND FROM | 预期的收件人 | |
SMOL FROM | 预期的收件人 | |
SMAL FROM | 预期的收件人 |
响应是三位十进制数字,后面可以添加附加的文本信息:
代码 | 说明 |
正面完成回答 | |
211 | 系统状态或求助回答 |
214 | 求助报文 |
220 | 服务就绪 |
221 | 服务关闭传输信道 |
250 | 请求命令完成 |
251 | 用户不是本地的;报文将被转发 |
正面中间回答 | |
354 | 开始邮件输入 |
过渡负面完成回答 | |
421 | 服务不可用 |
450 | 邮箱不可用 |
451 | 命令异常终止:本地差错 |
452 | 命令异常终止:存储器不足 |
永久负面完成回答 | |
500 | 语法差错,不能识别的命令 |
501 | 语法的参数或变量差错 |
502 | 命令未实现 |
503 | 命令序列不正确 |
504 | 命令暂时未实现 |
550 | 命令未执行;邮箱不可用 |
551 | 用户非本地的 |
552 | 所请求的动作异常终止 |
553 | 所请求的动作未发生 |
554 | 事务失败 |
四、使用代码发送邮件,并使用WireShark抓包分析
安装完WireShark后,打开,选择需要分析的网卡:
点击对应网卡的【Options】:
注意,如果用的笔记本的无线网卡,则需要取消"promiscuous mode"的选择,否则可能无法抓到包:
点击【Start】后就开始分析了:
可以看到显示的数据包非常多,所以必须要进行筛选,在【Filter】中输入:smtp后【Apply】,一般暂时是不会有SMTP的数据包的:
下面我们发送一封简单的测试邮件,来分析下SMTP协议。打开VS2010新建一个控制台项目,输入如下代码:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Net;
namespace SMTPDemo
{
class Program
{
private static void fnSMTPDemo()
{
SmtpClient mailClient = new SmtpClient( " smtp.qq.com " );
mailClient.Credentials = new NetworkCredential( " 214427358 " , " ****** " );
MailMessage message = new MailMessage( new MailAddress( " 214427358@qq.com " ), new MailAddress( " undead_47@163.com " ));
message.Body = " SMTP Demo! " ;
message.Subject = " SMTP Demo! " ;
Attachment att = new Attachment( @" G:\cnBlogs\Network\Protocol\SMTP.vsd " );
message.Attachments.Add(att);
mailClient.Send(message);
}
static void Main( string [] args)
{
Program.fnSMTPDemo();
}
}
}
F5运行后,在WireShark中就可以抓取到相应的数据包了:
如果你没有看到类似的数据包,请检查防火墙设置。
在收件箱中可以看到已发送和接受的邮件:
五、SMTP安全和垃圾邮件
最初的SMTP的局限之一在于它没有对发送方进行身份验证的机制。因此,后来定义了SMTP-AUTH扩展。
尽管有了身份认证机制,垃圾邮件仍然是一个主要的问题。但由于庞大的SMTP安装数量带来的网络效应,大刀阔斧地修改或完全替代SMTP被认为是不现实的。Internet Mail 2000就是一个替代SMTP的建议方案。
因此,出现了一些同SMTP工作的辅助协议。IRTF的反垃圾邮件研究小组正在研究一些建议方案,以提供简单、灵活、轻量级的、可升级的源端认证。最有可能被接受的建议方案是发送方策略框架协议。
小结:
SMTP主要用来发送邮件,是一种最基础的服务,各大邮件服务提供商都支持SMTP,连Windows也自带了SMTP Server。借助MIME,可以发送丰富的附件信息,方便了信息快速传递、分享。
接触WireShark等一类协议分析软件可以方便的分析各种协议,该软件功能很强大,更多用法请查阅官方文档。如果你对其实现原理感兴趣,请自行编译源代码。后续篇章将继续研究邮件的相关协议:POP3、IMAP等。