簡介:
電子郵件是因特網上最爲流行的應用之一。如同郵遞員分發投遞傳統郵件一樣,電子郵件也是異步的,也就是說人們是在方便的時候發送和閱讀郵件的,無須預先與別人協同。與傳統郵件不同的是,電子郵件既迅速,又易於分發,而且成本低廉。另外,現代的電子郵件消息可以包含超鏈接、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=<[email protected]>, 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=<[email protected]>, ctladdr=<[email protected]> (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=<[email protected]>, 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=<[email protected]>, ctladdr=<[email protected]> (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
這是很危險的。
所以我們需要安全的電子郵件傳輸