天天看點

SMTP協定分析

SMTP協定分析

第1章.     SMTP概述

1.1.  SMTP在郵件通信中的位置

SMTP,即簡單郵件傳送協定,所相應RFC文檔為RFC821。同http等多數應用層協定一樣,它工作在C/S模式下,用來實作網際網路上的郵件傳送。SMTP在整個電子郵件通信中所處的位置如圖 1所看到的。

圖 1電子郵件的通信過程

能夠看出,SMTP是用來将客戶機上的郵件傳送到server上。這裡的客戶機是指某次連接配接中的發送方,server是指對應的接收方。在解說發送郵件的整個通信過程前,先解釋一以下幾個術語。

1.2.  幾個術語

1.2.1.  郵件

郵件是一種消息的格式,由信封、首部和正文組成。

信封上最重要的是收信人的位址。郵件server用這個位址将郵件發送到收信人所在的郵件server上。

首部是由使用者代理或郵件server加入的一些資訊。包含Received、Message-ID、From、Data、Reply-To、X-Phone、X-Mailer、To和Subject等字段。

正文是是發送使用者發給接收使用者封包的内容。RFC 822 規定正文為NVT ASCII文字行。

更為具體的說明,請參考RFC821和RFC822等協定。

1.2.2.  使用者代理

使用者代理UA(User Agent)是使用者與電子郵件系統的互動接口,一般來說它就是我們PC機上的一個程式。Windows上常見的使用者代理是Foxmail和Outlook Express。

使用者代理提供一個好的使用者界面,它提取使用者在其界面填寫的各項資訊,生成一封符合SMTP等郵件标準的郵件,然後採用SMTP協定将郵件發送到發送端郵件server。

1.2.3.  郵件server

郵件server是電子郵件系統的核心,它用來發送和接收郵件。郵件server不同于普通PC的是它差點兒是全天工作的,是以它能夠在不論什麼時候為使用者提供服務,後面将提到這正是為什麼須要郵件server的一個重要原因。非常多ISP都提供免費的郵件server,如126提供smtp.126.com郵件server。

郵件server向其他郵件server轉發郵件也是採用SMTP協定。

1.3.  郵件的收發過程

普通情況下,一封郵件的發送和接收步驟例如以下。

1)        發信人在使用者代理裡編輯郵件,包含填寫發信人郵箱、收信人郵箱和郵件标題等等。

2)        使用者代理提取發信人編輯的資訊,生成一封符合郵件格式标準(RFC822)的郵件。

3)        使用者代理用SMTP将郵件發送到發送端郵件server(即發信人郵箱所相應的郵件server)。

4)        發送端郵件server用SMTP将郵件發送到接收端郵件server(即收信人郵箱所相應的郵件server)。

5)        收信人調用使用者代理。使用者代理用POP3協定從接收端郵件server取回郵件。

6)        使用者代了解析收到的郵件,以适當的形式呈如今收信人面前。

第2章.     SMTP具體解釋

2.1.  通信過程

一個詳細的SMTP通信(如發送端郵件server與接收端server的通信)的步驟例如以下。

1)        發送端郵件server(下面簡稱client)與接收端郵件server(下面簡稱server)的25号port建立TCP連接配接。

2)        client向server發送各種指令,來請求各種服務(如認證、指定發送人和接收人)。

3)        server解析使用者的指令,做出對應動作并傳回給client一個響應。

4)        2)和3)交替進行,直到全部郵件都發送完或兩者的連接配接被意外中斷。

從這個過程看出,指令和響應是SMTP協定的重點,以下将予以重點講述。

2.2.  指令和響應

2.2.1.  格式

SMTP的指令不多(14個),它的一般形式是:COMMAND  [Parameter] <CRLF>。當中COMMAND是ASCII形式的指令名,Parameter是對應的指令參數,<CRLF>是回車換行符(0DH, 0AH)。

SMTP的響應也不複雜,它的一般形式是:XXX  Readable Illustration。XXX是三位十進制數;Readable Illustration是可讀的解釋說明,用來表明指令是否成功等。XXX具有例如以下的規律:以2開頭的表示成功,以4和5開頭的表示失敗,以3開頭的表示未完畢(進行中)。

2.2.2.  一個樣例

指令和響應的格式是文法,各指令和響應的意思則是語義,各指令和各響應在時間上的關系則是同步。以下将通過一個簡單的SMTP通信過程來說明協定的這三個要素。

C:telnet smtp.126.com 25   /* 以telnet方式連接配接126郵件server */

S:220 126.com Anti-spam GT for Coremail System (126com[071018]) /* 220為響應數字,其後的為歡迎資訊,會應server不同而不同*/

C:HELO smtp.126.com /* HELO 後用來填寫傳回域名(詳細含義請參閱RFC821),但該指令并不檢查後面的參數 */

S:250 OK

C: MAIL FROM: [email protected] /* 發送者郵箱 */

S:250 … ./* “…”代表省略了一些可讀資訊 */

C:RCPT TO: [email protected] /* 接收者郵箱 */

C:DATA  /* 請求發送資料 */

S:354 Enter mail, end with "." on a line by itself

C:Enjoy Protocol Studing

C:.

S:250 Message sent

C:QUIT /* 退出連接配接 */

S:221 Bye

分析上面的過程可參考凝視進行,這裡要補充例如以下幾點。

1)        “C:”開頭的行(不包含"C:")是client的輸入,而以“S:”開頭的行(不包含"S:")則是server的輸出。

2)        上述的指令并不一定會一次性成功,server會傳回錯誤響應,client應該依照協定規定的時序,來輸入興許的指令(或反複運作失敗的指令,或重置會話,或退出會話等等)。

2.2.3.  經常使用指令

SMTP指令不區分大寫和小寫,但參數區分大寫和小寫,有關這方面的具體說明請參考RFC821。經常使用的指令例如以下。

HELO <domain> <CRLF>。向server辨別使用者身份發送者能欺騙,說謊,但普通情況下server都能檢測到。

MAIL FROM: <reverse-path> <CRLF>。<reverse-path>為發送者位址,此指令用來初始化郵件傳輸,即用來對全部的狀态和緩沖區進行初始化。

RCPT TO:<forward-path> <CRLF>。 <forward-path>用來标志郵件接收者的位址,經常使用在MAIL FROM後,能夠有多個RCPT TO。

DATA <CRLF>。将之後的資料作為資料發送,以<CRLF>.<CRLF>标志資料的結尾。

REST <CRLF>。重置會話,目前傳輸被取消。

NOOP <CRLF>。要求server傳回OK應答,一般用作測試。

QUIT <CRLF>。結束會話。

VRFY <string> <CRLF>。驗證指定的郵箱是否存在,因為安全方面的原因,server大多禁止此指令。

EXPN <string> <CRLF>。驗證給定的郵箱清單是否存在,因為安全方面的原因,server大多禁止此指令。

HELP <CRLF>。查詢server支援什麼指令。

2.2.4.  經常使用響應

經常使用的響應例如以下所看到的,數字後的說明是從英文譯過來的。更具體的說明請參考RFC821。

501參數格式錯誤

502指令不可實作

503錯誤的指令序列

504指令參數不可實作

211系統狀态或系統幫助響應

214幫助資訊

220<domain>服務就緒

221<domain>服務關閉

421<domain>服務未就緒,關閉傳輸信道

250要求的郵件操作完畢

251使用者非本地,将轉發向<forward-path>

450要求的郵件操作未完畢,郵箱不可用

550要求的郵件操作未完畢,郵箱不可用

451放棄要求的操作;處理過程中出錯

551使用者非本地,請嘗試<forward-path>

452系統存儲不足,要求的操作未運作

552過量的存儲配置設定,要求的操作未運作

553郵箱名不可用,要求的操作未運作

354開始郵件輸入,以"."結束

554操作失敗

第3章.     SMTP的擴充

3.1.  SMTP的缺點

從2.2.2的樣例能夠看出,SMTP至少還有例如以下缺點。

1)        指令過于簡單,沒提供認證等功能。

2)        僅僅傳送7位的ASCII碼,不能傳送二進制檔案。

針對缺點1),标準化組織制定了擴充的SMTP(即ESMTP),相應的RFC文檔為RFC1425。針對缺點2),标準化組織在相容SMTP的前提下,提出了傳送非7位ASCII碼的方法,相應的RFC文檔有兩個:郵件首部的擴充相應于RFC1522,郵件正文的擴充相應與RFC1521(即MIME)。

3.2.  ESMTP

ESMTP最顯著的地方是加入了使用者認證功能。假設使用者想使用ESMTP提供的新指令,則在初次與server互動時,發送的指令應該是EHLO而不是HELO。先來看一個樣例。

C:EHLO smtp.126.com /* 除了HELO所具有的功能外,EHLO主要用來查詢server支援的擴充功能 */

S:250-mail

S:250-AUTH LOGIN PLAIN

S:250-AUTH=LOGIN PLAIN

S:250 8BITMIME /* 最後一個響應數字應答碼之後跟的是一個空格,而不是'-' */

C:AUTH LOGIN /* 請求認證 */

S:334 dxNlcm5hbWU6  /* server的響應——經過base64編碼了的“Username” */

C:Y29zdGFAYW1heGl0Lm5ldA==  /* 發送經過BASE64編碼了的username */

S:334 UGFzc3dvcmQ6  /* 經過BASE64編碼了的"Password:" */

C:MTk4MjIxNA==  /* client發送的經過BASE64編碼了的password */

S:235 auth successfully /* 認證成功 */

對于這個樣例有例如以下幾點說明。

1)        僅僅是一個示意性的過程,再輸入username、password時需採用base64編碼,這須要專門的計算,是以在telnet終端上模拟比較麻煩。

2)        認證過程有非常多種,有基于明文的認證,也有基于MD5加密的認證,這裡給出的僅僅是一個示意性的過程。

3)        EHLO對于詳細server,響應會不同,keyword“8BITMIME”用來說明server是否支援正文中傳送8位ASCII碼,而以“X”開頭的keyword都是指server自己定義的擴充(還沒納入RFC标準)

更具體的說明,請參看RFC1425。

3.3.  郵件首部的擴充

首部通過兩種編碼方式來支援傳送非7位ASCII碼。它首先通過一個例如以下格式的編碼字來表明所用的編碼方式。

=?charset?encoding?encoded-text?text

charset是字元集規範。有效值是兩個字元串us-ascii和iso-8859-x,當中x 是一個單個數字,比如iso-8859-1中的數字為“ 1”。

encoding是一個單個字元用來指定編碼方法,支援兩個值。

Q代表quoted-printable(可列印)編碼。不論什麼要發送的字元若其第8比特置1則被作為3個字元發送:第1個是字元是“=”,後面的兩個字元相應于字元的十六進制表示。比如對于二進制碼11111111,其相應的十六進制表示為“FF”,是以相應的編碼位“=FF”。為了可以傳輸“=”,“=”的編碼方式與第8比特置1的字元同樣,由于其二進制代碼為00111101,是以相應的編碼為“=3D”。可以看出這樣的編碼方式的開銷達200%,是以僅僅适合傳送僅僅含有少量非7位ASCII碼的文本。

B代表base64編碼。它的編碼方法是先将二進制代碼劃分為一個24bit長的單元,然後将這24 bit單元劃分為4個6 bit組。每一個組按圖 2所看到的的方法轉換成ASCII碼。

圖 2 base64映射表

能夠看出這種映射方法是這種:0-25依次映射成A-Z,26-51依次映射成a-z,52-61依次映射成數字0-9,然後62映射成+,63映射成/。

對于二進制代碼01001001 00110001 01111001,先将其劃分成4個6 bit組,即010010 0100011 000101 111001。接着按圖 2所看到的的映射表,可得到base64編碼為:STF5。能夠看出,這樣的編碼方式的開銷是25%,相對quoted-printable編碼來說,它更适合用來傳送含大量非7位ASCII碼的二進制檔案。

3.4.  正文的擴充

正文的擴充主要是使正文不僅能夠傳輸NVT ASCII字元,并且能夠傳輸随意字元,相應的文檔為RFC1511(即MIME)。

MIME全稱為“Multiple Internet Mail Extensions”, 比較确切的中文名稱為“多用途網際網路郵件擴充”。它通過新增一些郵件首部字段、郵件内容格式和傳送編碼,使得其成為一種應用非常廣泛的能夠傳輸多媒體的電子郵件規範。

更具體的說明請參看還有一篇文章《MIME協定分析》和RFC1511。

第4章.     常見的疑問

4.1.  為什麼須要SMTPserver

一般的PC資源不夠,處理能力不夠,不可能全天候地連接配接在網際網路上來收發郵件。是以使用SMTPserver,能夠讓多個使用者共用server,有效地減少了成本。

4.2.  SMTP和郵件格式的關系

如前所述,SMTP是客戶機向server發送郵件時所使用的協定,其核心是2.2中所述的指令和響應,至于它指令和響應中所帶的參數採用什麼格式,則是依賴于其它标準的。比如DATA後所帶的參數,則應遵循郵件格式标準RFC822.

SMTP和郵件格式的關系可用這麼一個樣例來說明。甲與乙書信往來,甲通過郵局向乙發信,郵局間轉交郵件可看成使用了SMTP協定,至于書信的格式則會由于地區習慣等的不同而不同(中國人的書信格式和美國人的書信格式不同),這個書信格式則可看成是郵件格式标準。

應當認識到不能孤立地看待協定,各個協定之間往往存在着耦合關系,但為了分析友善,我們在詳細叙述某個協定時,僅僅能抓住主要沖突——主要闡述單個協定。

4.3.  浏覽器發送郵件用的什麼協定

浏覽器如IE、Maxthon可通過登陸使用者郵箱,來收發郵件,這是如何實作的?比如[email protected]可通過登陸www.126.com來收發郵件。

這個過程是這種:[email protected]在www.126.com提供的郵件頁面上填寫的對應資訊(如發信人郵箱、收信人郵箱等),通過http協定被送出給126server;126server依據這些資訊組裝一封符合郵件規範的郵件(就像使用者代理一樣);然後smtp.126.com通過SMTP協定将這封郵件發送到接收端郵件server。

能夠看出,浏覽器發送郵件僅僅是使用者代理的功能直接放到郵件server上去做了,至于郵件server間發送郵件還是採用的SMTP協定。我們看問題,假設有必要還是要适當地透過現象看本質。

4.4.  怎樣用實驗驗證SMTP的通信過程

1)        能夠通過ethereal等協定分析軟體來抓包分析協定。

2)        能夠利用socket程式設計實作SMTP的通信過程。

3)        能夠利用使用者代理來檢視一封郵件的原始編碼。比如在Foxmail中,能夠選擇郵件清單右鍵菜單的“原始資訊”進行檢視。

第5章.     分析方案

ID Protocol Captured contents
user name password sender receiver subject contents attachments
4 smtp

表 1 協定分析要求

表 1給出了協定分析要求。easy看出,擷取各個字段是比較easy的。我們可以抓取client與server端的互動資訊,然後依據各指令字或響應字來提取出我們想要的字段。比如,要擷取user name,我們僅僅需檢測到server端要求client發送username這個時候,然後提取這之後client的發送資訊就可以。須要說明的是,盡管client與服務端互動的資訊可能經過了編碼或加密,但我們仍可以通過解碼或解密來獲得所須要的資訊。

第6章.     參考資料

[1]      RFC文檔:RFC821相應SMTP協定,RFC822相應郵件标準,RFC1425相應ESMTP,RFC1522相應郵件首部的擴充,RFC1521相應郵件正文的擴充,RFC1939相應POP3協定。

[2]      http://www.faqs.org/rfcs/,上面有全面的英文RFC文檔

[3]      http://www.cnpaf.net/,上面有不少實用的協定分析文檔,也有中文RFC文檔,但品質不是特别高

[4]      Stevens, W.R., TCP/IP Illustrated, Vol1. Addision-Wesley, 機械工業出版社,2002

繼續閱讀