简介:

电子邮件是因特网上最为流行的应用之一。如同邮递员分发投递传统邮件一样,电子邮件也是异步的,也就是说人们是在方便的时候发送和阅读邮件的,无须预先与别人协同。与传统邮件不同的是,电子邮件既迅速,又易于分发,而且成本低廉。另外,现代的电子邮件消息可以包含超链接、HTML格式文本、图像、声音甚至视频数据。我们将在本文中查看处于因特网电子邮件核心地位的协议。但在深入讨论这些协议之前,让我们先概览一下因特网邮件系统及其重要部件。

邮件服务器原理

邮件服务器构成了电子邮件系统的核心。每个收信人都有一个位于某个邮件服务器上的邮箱(mailbox)。Bob的邮箱用于管理和维护已经发送给他的邮件消息。一个邮件消息的典型旅程是从发信人的用户代理开始,游经发信人的邮件服务器,中转到收信人的邮件服务器,然后投递到收信人的邮箱中。当Bob想查看自己的邮箱中的邮件消息时,存放该邮箱的邮件服务器将以他提供的用户名和口令认证他。Alice的邮件服务器还得处理Bob的邮件服务器出故障的情况。如果Alice的邮件服务器无法把邮件消息立即递送到Bob的邮件服务器,Alice的服务器就把它们存放在消息队列(message queue)中,以后再尝试递送。这种尝试通常每30分钟左右执行一次:要是过了若干天仍未尝试成功,该服务器就把这个消息从消息队列中去除掉,同时以另一个邮件消息通知发信人(即Alice)。

术语:

1.协议

SMTP 简介

简单邮件传送协议(SMTP)是因特网电子邮件系统首要的应用层协议。它使用由TCP提供的可靠的数据传输服务把邮件消息从发信人的邮件服务器传送到收信人的邮件服务器。跟大多数应用层协议一样,SMTP也存在两个端:在发信人的邮件服务器上执行的客户端和在收信人的邮件服务器上执行的服务器端。SMTP的客户端和服务器端同时运行在每个邮件服务器上。当一个邮件服务器在向其他邮件服务器发送邮件消息时,它是作为SMTP客户在运行。当一个邮件服务器从其他邮件服务器接收邮件消息时,它是作为SMTP服务器在运行。

SMTP在RFC 821中定义,它的作用是把邮件消息从发信人的邮件服务器传送到收信人的邮件服务器。SMTP的历史比HTTP早得多,其RFC是在1982年编写的,而SMTP的现实使用又在此前多年就有了。尽管SMTP有许多奇妙的品质(它在因特网上的无所不在就是见证),但却是一种拥有某些“古老”特征的传统战术。例如,它限制所有邮件消息的信体(而不仅仅是信头)必须是简单的7位ASCII字符格式。这个限制在20世纪80年代早期是有意义的,当时因特网传输能力不足,没有人在电子邮件中附带大数据量酌图像、音频或视频文件。然而到了多媒体时代的今天,这个限制就多少显得局促了——它迫使二进制多媒体数据在文由SMTP传送之前首先编码成7位ASCII文本;SMTP传送完毕之后,再把相应的7位ASCII文本邮件消息解码成二进制数据。HTTP不需要对多媒体数据进行这样的编码解码操作。

把邮件消息从发送端邮件服务器 下面查看SMTP把邮件消息从发送端邮件服务器传送到接收端邮件服务器的具体过程。我们将看到,SMTP协议与人们用于面对面交互的礼仪之间有许多相似之处。首先,运行在发送端邮件服务器主机上的SMTP客户,发起建立一个到运行在接收端邮件服务器主机上的SMTP服务器端口号25之间的TCP连接。如果接收邮件服务器当前不在工作,SMTP客户就等待一段时间后再尝试建立该连接。这个连接建立之后,SMTP客户和服务器先执行一些应用层握手操作。就像人们在转手东西之前往往先自我介绍那样,SMTP客户和服务器也在传送信息之前先自我介绍一下。在这个SMTP握手阶段,SMTP客户向服务器分别指出发信人和收信人的电子邮件地址。彼此自我介绍完毕之后,客户发出邮件消息。SMTP可以指望由TCP提供的可靠数据传输服务把该消息无错地传送到服务器。如果客户还有其他邮件消息需发送到同一个服务器,它就在同一个TCP连接上重复上述过程;否则,它就指示TCP关闭该连接。

POP3 协议

POP 协议(Post Office Protocol,邮局协议)是一种允许用户从邮件服务器收发邮件的协议。它有2种版本,即POP2和POP3,都具有简单的电子邮件存储转发功能。POP2与POP3本质上类似,都属于离线式工作协议,但是由于使用了不同的协议端口,两者并不兼容。与 SMTP协议相结合,POP3是目前最常用的电子邮件服务协议。 POP3除了支持离线工作方式外,还支持在线工作方式。在离线工作方式下,用户收发邮件时,首先通过POP3客户程序登录到支持POP3协议的邮件服务器,然后发送邮件及附件;接着,邮件服务器将为该用户收存的邮件传送给POP3客户程序,并将这些邮件从服务器上删除;最后,邮件服务器将用户提交的发送邮件,转发到运行SMTP协议的计算机中,通过它实现邮件的最终发送。在为用户从邮件服务器收取邮件时,POP3是以该用户当前存储在服务器上全部邮件为对象进行操作的,并一次性将它们下载到用户端计算机中。一旦客户的邮件下载完毕,邮件服务器对这些邮件的暂存托管即告完成。使用POP3,用户不能对他们贮存在邮件服务器上的邮件进行部分传输。离线工作方式适合那些从固定计算机上收发邮件的用户使用。 当使用POP3在线工作方式收发邮件时,用户在所用的计算机与邮件服务器保持连接的状态下读取邮件。用户的邮件保留在邮件服务器上。

pop2/pop3的端口号分别为109/110

IMAP协议

Internet Mail Access Protocol(交互式邮件存取协议)

IMAP是斯坦福大学在1986年开发的研发的一种邮件获取协议。它的主要作用是邮件客户端(例如MS Outlook Express)可以通过这种协议从邮件服务器上获取邮件的信息,下载邮件等。当前的权威定义是RFC3501。IMAP协议运行在TCP/IP协议之上,使用的端口是143。

IMAP的一个与POP3的区别是:IMAP它只下载邮件的主题,并不是把所有的邮件内容都下载下来,而是你邮箱当中还保留着邮件的副本,没有把你原邮箱中的邮件删除,你用邮件客户软件阅读邮件时才下载邮件的内容

IMAP协议的特点 与POP3协议类似,IMAP(Internet消息访问协议)也是提供面向用户的邮件收取服务。常用的版本是IMAP4。IMAP4改进了POP3的不足,用户可以通过浏览信件头来决定是否收取、删除和检索邮件的特定部分,还可以在服务器创建或更改文件夹或邮箱,它除了支持POP3协议的脱机操作模式外,还支持联机操作和断连接操作。它为用户提供了有选择的从邮件服务器接收邮件的功能、基于服务器的信息处理功能和共享信箱功能。IMAP4的脱机模式不同于POP3,它不会自动删除在邮件服务器上已取出的邮件,其联机模式和断连接模式也是将邮件服务器作为“远程文件服务器”进行访问,更加灵活方便。 IMAP协议功能

支持连接和断开两种操作模式。当使用POP3时,客户端只会连接在服务器上一段的时间,直到它下载完所有新信息,客户端即断开连接。在IMAP中,只要用户界面是活动的和下载信息内容是需要的,客户端就会一直连接在服务器上。对于有很多或者很大邮件的用户来说,使用IMAP4模式可以获得更快的响应时间。支持多个客户同时连接到一个邮箱。POP3协议假定邮箱当前的连接是唯一的连接。相反,IMAP4协议允许多个用户同时访问邮箱同时提供一种机制让客户能够感知其他当前连接到这个邮箱的用户所做的操作。

支持访问消息中的MIME部分和部分获取。几乎所有的Internet 邮件都是以MIME格式传输的。MIME允许消息包含一个树型结构,这个树型结构的叶子节点都是单一内容类型而非叶子节点都是多块类型的组合。

IMAP4协议允许客户端获取任何独立的MIME部分和获取信息的一部分或者全部。 这些机制使得用户无需下载附件就可以浏览消息内容或者在获取内容的同时浏览。支持在服务器保留消息状态信息。通过使用在IMAP4协议中定义的标志客户端可以跟踪消息状态,例如邮件是否被读取,回复,或者删除。这些标识存储在服务器,所以多个客户在不同时间访问一个邮箱可以感知其他用户所做的操作。支持在服务器上访问多个邮箱。IMAP4客户端可以在服务器上创建,重命名,或删除邮箱(通常以文件夹形式显现给用户)。支持多个邮箱还允许服务器提供对于共享和公共文件夹的访问。支持服务器端搜索。IMAP4提供了一种机制给客户使客户可以要求服务器搜索符合多个标准的信息。在这种机制下客户端就无需下载邮箱中所有信息来完成这些搜索。支持一个定义良好的扩展机制。吸取早期Internet协议的经验,IMAP的扩展定义了一个明确的机制。很多对于原始协议的扩展已被提议并广泛使用。无论使用POP3还是IMAP4来获取消息,客户端使用SMTP协议来发送。邮件客户可能是POP客户端或者IMAP客户端,但都会使用SMTP.

多媒体文件格式MIME 最早的HTTP协议中,并没有附加的数据类型信息,所有传送的数据都被客户程序解释为超文本标记语言HTML 文档,而为了支持多媒体数据类型,HTTP协议中就使用了附加在文档之前的MIME数据类型信息来标识数据类型。

MIME意为多功能Internet邮件扩展,它设计的最初目的是为了在发送电子邮件时附加多媒体数据,让邮件客户程序能根据其类型进行处理。然而当它被HTTP协议支持之后,它的意义就更为显著了。它使得HTTP传输的不仅是普通的文本,而变得丰富多彩。

每个MIME类型由两部分组成,前面是数据的大类别,例如声音audio、图象p_w_picpath等,后面定义具体的种类。

2.系统 电子邮件系统组成的5部分:MTA,MSA,MUA,MDA,MAA

MUA(MAIL USER AGENT):

电子邮件系统的构成之一,接受用户输入的各种指令,将用户的邮件发送至MTA或者通过POP3、IMAP协议将邮件从MTA取到本机。在windows系统上,常见的MUA有Foxmail,Outlook Express等邮件客户端程序。在linux/Unix系统上,常见的MUA有字符界面下的mail,mutt以及图形界面下的thunderbird,evolution等邮件客户端程序。

MTA(Mail Transfer Agent)

用于收发Mail的程序一般统称为邮件用户代理MUA(Mail User Agent)。将来自MUA的信件转发给指定的用户的程序一般被称之为因特网邮件传送代理MTA。在linux/Unix系统上,最著名的MTA有sendamil、postfix、qmail等程序。在windows系统上,最著名的MTA有exchange系列,MDaemon等程序。

MDA(MAIL DELIVERY AGENT)

邮件投递代理从MTA接收邮件并进行适当的本地投递,可以投递个一个本地用户,一个邮件列表,一个文件或是一个程序。Linux下常用的MDA是mail.local,smrsh和procmail

MAA (Mail Access Agent,MAA)

邮件访问代理用于将用户连接到系统邮件库,使用POP或IMAP协议收取邮件。Linux下常用的MAA有UW-IMAP,Cyrus-IMAP,COURIER-IMAP等邮件中继:就是当邮件向目的地址传输时,一旦源地址和目的地址都不是本地系统,那么本地系统就是邮件的中继(中转站)

MSA(Mail Submmission Agent,MSA)

MSA邮件提交代理负责消息有MTA发送之前必须完成的所有准备工作和错误检测,MSA就像在MUA和MTA之间插入了一个头脑清醒的检测员对所有的主机名,从MUA得到的信息头等信息进行检测。
案例 企业网中邮件服务器的搭建

拓扑图

搭建过程如下:

[root@mail ~]# mount /dev/cdrom /mnt/cdrom

我将在这里介绍sendmail的使用方法。还将写出加密的邮件传输。(利用ssl)

sendmail 在linux中默认安装。所以就不需要安装了。查看是否安装

[root@localhost ~]# service sendmail status
sendmail (pid 2944) 正在运行...

[root@localhost ~]# cd /etc/mail/
[root@localhost mail]# ll
总计 244
-rw-r--r-- 1 root root 355 2006-11-28 access //中继文件
-rw-r----- 1 root root 12288 08-11 22:56 access.db
-rw-r--r-- 1 root root 0 2006-11-28 domaintable
-rw-r----- 1 root root 12288 08-11 22:56 domaintable.db
-rw-r--r-- 1 root root 5521 2006-11-28 helpfile
-rw-r--r-- 1 root root 64 2006-11-28 local-host-names
-rw-r--r-- 1 root root 0 2006-11-28 mailertable
-rw-r----- 1 root root 12288 08-11 22:56 mailertable.db
-rw-r--r-- 1 root root 1048 2006-11-28 Makefile
-rw-r--r-- 1 root root 58205 08-11 22:56 sendmail.cf
-rw-r--r-- 1 root root 7209 2006-11-28 sendmail.mc
-r--r--r-- 1 root root 41286 2006-11-28 submit.cf
-rw-r--r-- 1 root root 940 2006-11-28 submit.mc
-rw-r--r-- 1 root root 127 2006-11-28 trusted-users
-rw-r--r-- 1 root root 0 2006-11-28 virtusertable
-rw-r----- 1 root root 12288 08-11 22:56 virtusertable.db

红色字体的需要我们进行关注。access 与access.db,sendmail.cf与sendmail.mc 功能一样

我们需要对sendmail进行配置。实际上我们需要配置sendmail.cf 文件,但其文件中语法晦涩难懂。我们可以配置sendmail.mc 。实际上就是配置sendmail.cf 。但我们需要

sendmail-cf-版本号 的包安装。它的功能就是把配置sendmail.mc文件时使sendmail.cf 生效。我们还需要安装m4-版本号 的包安装。它的作用是sendmail.mc自动转换成sendmail.cf。m4默认已经安装。

[root@localhost mail]# yum install sendmail-cf

[root@localhost mail]# vim sendmail.mc

116 DAEMON_OPTIONS(`Port=smtp,Addr=0.0.0.0, Name=MTA')dnl //使服务器能为广大用户服务 后dnl表示去掉括号里多余的空格 前dnl代表注释

Connect:localhost.localdomain RELAY
Connect:localhost RELAY
Connect:127.0.0.1 RELAY
sh.zz.com RELAY //对sh.zz.com地区的邮件进行中继
bj.zz.com ok //对bj.zz.com地区的邮件无条件转发

[root@mail mail]# vim local-host-names //添加如下

bj.zz.com //本地的域名
mail.bj.zz.com //本地的邮件服务器

[root@localhost mail]# service sendmail restart

[root@localhost ~]# tail -f /var/log/maillog //查看日志

Aug 12 17:41:15 localhost sendmail[14730]: alias database /etc/aliases rebuilt by root
Aug 12 17:41:15 localhost sendmail[14730]: /etc/aliases: 76 aliases, longest 10 bytes, 765 bytes total
Aug 12 17:41:16 localhost sendmail[14735]: starting daemon (8.13.8): SMTP+queueing@01:00:00
Aug 12 17:41:16 localhost sm-msp-queue[14743]: starting daemon (8.13.8): queueing@01:00:00

这样我们就可以进行以下操作。

telnet 192.168.145.100 25进行邮件发送了。

安装dovecot 软件包。它利用pop3协议对邮件进行接收。

[root@mail mail]# yum install dovecot

dovecot配置文件默认的就可以了。启动dovecot。

[root@mail mail]# service dovecot start

[root@mail ~]# chkconfig dovecot on

修改服务器域名。

[root@localhost ~]# vim /etc/sysconfig/network

NETWORKING=yes
NETWORKING_IPV6=yes
HOSTNAME=mail.bj.zz.com

[root@localhost ~]# vim /etc/hosts

127.0.0.1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6

我们还需要安装dns服务器对域名进行解析。

[root@localhost ~]# yum install bind

[root@localhost ~]# yum install bind-chroot

[root@localhost ~]# yum install caching-nameserver

[root@localhost named]# cd /var/named/chroot/etc

[root@localhost etc]# cp -p named.caching-nameserver.conf named.conf

[root@localhost etc]# vim named.conf

options {
15 listen-on port 53 { any; };
16 listen-on-v6 port 53 { ::1; };
17 directory "/var/named";
18 dump-file "/var/named/data/cache_dump.db";
19 statistics-file "/var/named/data/named_stats.txt";
20 memstatistics-file "/var/named/data/named_mem_stats.txt";
27 allow-query { any; };
28 allow-query-cache { any; };
29 };
30 logging {
31 channel default_debug {
32 file "data/named.run";
33 severity dynamic;
34 };
35 };
36 view localhost_resolver {
37 match-clients { any; };
38 match-destinations { any; };
39 recursion yes;
40 include "/etc/named.rfc1912.zones";

[root@localhost etc]# vim named.rfc1912.zones 添加如下

20
21 zone "bj.zz.com" IN {
22 type master;
23 file "bj.zz.com.zone";
24 allow-update { none; };
25 };

[root@localhost etc]# cd ../var/named/

[root@localhost named]# cp -p localhost.zone bj.zz.com.zone

[root@localhost named]# vim bj.zz.com.zone

[root@localhost named]# service named start
启动 named: [确定]
[root@localhost named]# chkconfig named on

[root@mail ~]# vim /etc/resolv.conf

nameserver 192.168.145.100
search localdomain

[root@localhost named]# init 6 //重启机器使修改生效

[root@mail ~]# service named start

[root@mail ~]# useradd user1

[root@mail ~]# useradd user2

[root@mail ~]# passwd user1

[root@mail ~]# passwd user2 //用户密码均为123

利用windows的系统进行邮件传输测试。这里是利用outlook。

客户端地址设为192.168.145.11

dns服务器设为192.168.145.100

outlook设置如下:具体设置这里就不多说了。

在服务器上查看日志文件可以看到邮件已经发送。

Aug 12 19:16:52 mail sendmail[4468]: q7CBGqCg004468: from=, size=1241, class=0, nrcpts=1, msgid=<000801cd8ef2$9b7e7c00$0b91a8c0@zzuce090d72288>, proto=SMTP, daemon=MTA, relay=[192.168.145.11]
Aug 12 19:16:52 mail sendmail[4469]: q7CBGqCg004468: to=, ctladdr= (500/501), delay=00:00:00, xdelay=00:00:00, mailer=local, pri=31414, dsn=2.0.0, stat=Sent

同时服务器还具有邮件群发的功能

[root@mail ~]# vim /etc/aliases

user3: user1,user2

[root@mail ~]# service sendmail restart

当我们发送邮件给user3时,实际上发给了user1 和user2了。

[root@mail ~]# mail user3
Subject: 3333
333333333333333333333333333
.
Cc:

我们可以可以看一下user1和user2是否收到邮件

这里需要特别注意别名的使用,不要与公司的用户冲突。

下面进行sh.zz.com 的邮件服务器搭建

这里是利用的虚拟机克隆

如果实际环境中需要进行如上一步的操作。

首先修改IP地址

[root@mail ~]# service network restart

[root@mail ~]# cd /var/named/chroot/etc

[root@mail etc]# vim named.rfc1912.zones

zone "sh.zz.com" IN {
type master;
file "sh.zz.com.zone";
allow-update { none; };
};

[root@mail etc]# cd ../var/named/

[root@mail named]# mv bj.zz.com.zone sh.zz.com.zone

[root@mail named]# vim sh.zz.com.zone

[root@mail ~]# vim /etc/resolv.conf

nameserver 192.168.145.101
search localdomain

[root@mail named]# cd /etc/mail
[root@mail mail]# vim access

Connect:localhost.localdomain RELAY
Connect:localhost RELAY
Connect:127.0.0.1 RELAY
bj.zz.com RELAY
sh.zz.com ok
[root@mail mail]# vim local-host-names

# local-host-names - include all aliases for your machine here.
sh.zz.com
mail.sh.zz.com

[root@mail mail]# vim /etc/sysconfig/network

NETWORKING=yes
NETWORKING_IPV6=yes
HOSTNAME=mail.sh.zz.com

修改完毕,重启机器。

由于原来的系统启动时,dns,sendmail,dovecot都已经设为开机启动。这里就不用启动了。

注意我们上一台机器的定义的别名user3。这里影响实验,必须删除。

[root@mail ~]# userdel -r user1
[root@mail ~]# userdel -r user2

[root@mail ~]# useradd user3
[root@mail ~]# useradd user4

[root@mail ~]# passwd user3

[root@mail ~]# passwd user4 //密码设为123

不同域名的邮件服务器进行邮件转发。由于是企业内部的私有域名。我们需要利用dns的转发功能

在dns服务器上进行邮件转发。

在bj.zz.com服务器上

[root@mail ~]# vim /var/named/chroot/etc/named.conf

allow-query { any; };
allow-query-cache { any; };
forwarders { 192.168.145.101; };

[root@mail ~]# rndc reload

在sh.zz.com服务器上

[root@mail ~]# vim /var/named/chroot/etc/named.conf

allow-query { any; };
allow-query-cache { any; };
forwarders { 192.168.145.101; };

[root@mail ~]# rndc reload

然后我们可以进行邮件传输了

sh.zz.com区域的客户端ip地址设为192.168.145.12

dns 服务器设为192.168.145.101

outlook添加账户user3 ,user4

测试如下

解析域名

当user1 向user3 发送邮件时

查看日志可以看到邮件已经发送。

Aug 12 20:59:35 mail sendmail[3977]: q7CCxZTW003977: from=, size=1377, class=0, nrcpts=1, msgid=<002f01cd8f00$f47d8090$0b91a8c0@zzuce090d72288>, proto=SMTP, daemon=MTA, relay=[192.168.145.11]
Aug 12 20:59:35 mail sendmail[3979]: q7CCxZTW003977: to=, ctladdr= (500/501), delay=00:00:00, xdelay=00:00:00, mailer=esmtp, pri=121377, relay=mail.sh.zz.com. [192.168.145.101], dsn=2.0.0, stat=Sent (q7CCxZG6004793 Message accepted for delivery)

我们可以感觉到传递很慢

我们需要做dns反向地址解析

在bj.zz.com区域服务器上

[root@mail ~]# cd /var/named/chroot/etc/
[root@mail etc]# vim named.rfc1912.zones //添加如下:

zone "145.168.192.in-addr.arpa" IN {
type master;
file "192.168.145.zone";
allow-update { none; };
};

[root@mail etc]# cd ../var/named/

[root@mail named]# cp -p named.local 192.168.145.zone

[root@mail named]# vim 192.168.145.zone

[root@mail named]# rndc reload

在sh.zz.com区域服务器上

[root@mail ~]# cd /var/named/chroot/etc/
[root@mail etc]# vim named.rfc1912.zones //添加如下:

zone "145.168.192.in-addr.arpa" IN {
type master;
file "192.168.145.zone";
allow-update { none; };
};

[root@mail etc]# cd ../var/named/

[root@mail named]# cp -p named.local 192.168.145.zone

[root@mail named]# vim 192.168.145.zone

[root@mail named]# rndc reload

我们这使用的服务器地址都是一个网段的。我们的区域文件应该一样。但在真实的应用中区域文件应该如上所写。

我们的区域文件这时候需要改为一样。两台dns服务器修改如下:

这样简单的电子邮件转发就可以实现了

但是这样传输的邮件都是明文传输。别人通过抓包就可以知道用户的用户名和密码以及邮件内容

[root@mail ~]# yum install wireshark

[root@mail ~]# tshark -ni eth0 -R "tcp.dstport eq 110"

48.975186 192.168.145.11 -> 192.168.145.100 POP Request: USER user2
48.976226 192.168.145.11 -> 192.168.145.100 POP Request: PASS 123