◆ smtp的基本結(jié)構(gòu)
smtp (simple mail transfer protocol)協(xié)議是為了保證電子郵件的可靠和高效傳送。tcp/ip 協(xié)議的應(yīng)用層中包含有smtp協(xié)議,但事實(shí)上它與傳輸系統(tǒng)和機(jī)制無關(guān),僅要求一個(gè)可靠的數(shù)據(jù)流通道。它可以工作在tcp上,也可以工作在ncp, nits 等協(xié)議上。在tcp上,它使用端口25進(jìn)行傳輸。smtp的一個(gè)重要特點(diǎn)是可以在可交互的通信系統(tǒng)中轉(zhuǎn)發(fā)郵件。 1. smtp的模型 smtp提供了一種郵件傳輸?shù)臋C(jī)制,當(dāng)收件方和發(fā)件方都在一個(gè)網(wǎng)絡(luò)上時(shí),可以把郵件直傳給對(duì)方;當(dāng)雙方不在同一個(gè)網(wǎng)絡(luò)上時(shí),需要通過一個(gè)或幾個(gè)中間服務(wù)器轉(zhuǎn)發(fā)。smtp首先由發(fā)件方提出申請(qǐng),要求與接收方smtp建立雙向的通信渠道,收件方可以是最終收件人也可以是中間轉(zhuǎn)發(fā)的服務(wù)器。收件方服務(wù)器確認(rèn)可以建立連接后,雙發(fā)就可以開始通信。下面是smtp的模型示意圖。
發(fā)件方smtp向收件方發(fā)處mail命令,告知發(fā)件方的身份;如果收件方接受,就會(huì)回答ok。發(fā)件方再發(fā)出rcpt命令,告知收件人的身份,收件方smtp確認(rèn)是否接收或轉(zhuǎn)發(fā),如果同意就回答ok;接下來就可以進(jìn)行數(shù)據(jù)傳輸了。通信過程中,發(fā)件方smtp與收件方smtp 采用對(duì)話式的交互方式,發(fā)件方提出要求,收件方進(jìn)行確認(rèn),確認(rèn)后才進(jìn)行下一步的動(dòng)作。整個(gè)過程由發(fā)件方控制,有時(shí)需要確認(rèn)幾回才可以。
為了保證回復(fù)命令的有效,smtp要求發(fā)件方必須提供接收方的服務(wù)器及郵箱。郵件的命令和答復(fù)有嚴(yán)格的語法定義,并且回復(fù)具有相應(yīng)的數(shù)字代碼。所有的命令由ascii碼組成。命令代碼是大小寫無關(guān)的,如mail和 mail ﹑mail是等效的。 2. smtp的基本命令 smtp定義了14個(gè)命令,它們是: helo mail from: rcpt to: data rset send from: soml from: saml from: vrfy expn help [ ] noop quit turn 其中使得smtp工作的基本的命令有7個(gè),分別為:helo﹑mail﹑rcpt﹑data﹑rest﹑noop和quit.下面分別介紹如下。 helo--發(fā)件方問候收件方,后面是發(fā)件人的服務(wù)器地址或標(biāo)識(shí)。收件方回答ok時(shí)標(biāo)識(shí)自己的身份。問候和確認(rèn)過程表明兩臺(tái)機(jī)器可以進(jìn)行通信,同時(shí)狀態(tài)參量被復(fù)位,緩沖區(qū)被清空。 mail--這個(gè)命令用來開始傳送郵件,它的后面跟隨發(fā)件方郵件地址(返回郵件地址)。它也用來當(dāng)郵件無法送達(dá)時(shí),發(fā)送失敗通知。為保證郵件的成功發(fā)送,發(fā)件方的地址應(yīng)是被對(duì)方或中間轉(zhuǎn)發(fā)方同意接受的。這個(gè)命令會(huì)清空有關(guān)的緩沖區(qū),為新的郵件做準(zhǔn)備。 rcpt --這個(gè)命令告訴收件方收件人的郵箱。當(dāng)有多個(gè)收件人時(shí),需要多次使用該命令,每次只能指明一個(gè)人。如果接收方服務(wù)器不同意轉(zhuǎn)發(fā)這個(gè)地址的郵件,它必須報(bào)550錯(cuò)誤代碼通知發(fā)件方。如果服務(wù)器同意轉(zhuǎn)發(fā),它要更改郵件發(fā)送路徑,把最開始的目的地(該服務(wù)器)換成下一個(gè)服務(wù)器。 data--收件方把該命令之后的數(shù)據(jù)作為發(fā)送的數(shù)據(jù)。數(shù)據(jù)被加入數(shù)據(jù)緩沖區(qū)中,以單獨(dú)一行是"."的行結(jié)束數(shù)據(jù)。結(jié)束行對(duì)于接收方同時(shí)意味立即開始緩沖區(qū)內(nèi)的數(shù)據(jù)傳送,傳送結(jié)束后清空緩沖區(qū)。如果傳送接受,接收方回復(fù)ok。 rest--這個(gè)命令用來通知收件方復(fù)位,所有已存入緩沖區(qū)的收件人數(shù)據(jù),發(fā)件人數(shù)據(jù)和待傳送的數(shù)據(jù)都必須清除,接收放必須回答ok. noop--這個(gè)命令不影響任何參數(shù),只是要求接收放回答ok, 不會(huì)影響緩沖區(qū)的數(shù)據(jù)。 quit--smtp要求接收放必須回答ok,然后中斷傳輸;在收到這個(gè)命令并回答ok前,收件方不得中斷連接,即使傳輸出現(xiàn)錯(cuò)誤。發(fā)件方在發(fā)出這個(gè)命令并收到ok答復(fù)前,也不得中斷連接。 下面是smtp答復(fù)中用到的代碼和含義: 500 syntax error, command unrecognized [this may include errors such as command line too long] 501 syntax error in parameters or arguments 502 command not implemented 503 bad sequence of commands 504 command parameter not implemented 211 system status, or system help reply 214 help message [information on how to use the receiver or the meaning of a particular non-standard command; this reply is useful only to the human user] 220 service ready 221 service closing transmission channel 421 service not available, closing transmission channel [this may be a reply to any command if the service knows it must shut down] 250 requested mail action okay, completed 251 user not local; will forward to 450 requested mail action not taken: mailbox unavailable [e.g., mailbox busy] 550 requested action not taken: mailbox unavailable [e.g., mailbox not found, no access] 451 requested action aborted: error in processing 551 user not local; please try 452 requested action not taken: insufficient system storage 552 requested mail action aborted: exceeded storage allocation 553 requested action not taken: mailbox name not allowed [e.g., mailbox syntax incorrect] 354 start mail input; end with . 554 transaction failed 最后,讓我們看一個(gè)rfc821中給出的例子。這封信是smith在主機(jī)alpha.arpa 發(fā)給主機(jī)beta.arpa上的 jones,green和 brown.并且假定兩臺(tái)主機(jī)在同一個(gè)網(wǎng)絡(luò)上。 s: mail from: r: 250 ok s: rcpt to: r: 250 ok s: rcpt to: r: 550 no such user here s: rcpt to: r: 250 ok s: data r: 354 start mail input; end with . s: blah blah blah... s: ...etc. etc. etc. s: . r: 250 ok 郵件最后被對(duì)方接受。 ◆ 電子郵件的工作原理 電子郵件與普通郵件有類似的地方,發(fā)信者注明收件人的姓名與地址(即郵件地址),發(fā)送方服務(wù)器把郵件傳到收件方服務(wù)器,收件方服務(wù)器再把郵件發(fā)到收件人的郵箱中。如下圖所示:
更進(jìn)一步的解釋涉及到以下幾個(gè)概念: mua -- mail user agent, 郵件用戶代理,幫助用戶讀寫郵件; mta -- mail transport agent, 郵件傳輸代理,負(fù)責(zé)把郵件由一個(gè)服務(wù)器傳到另一個(gè)服務(wù) 器或郵件投遞代理; mda -- mail delivery agent, 郵件投遞代理,把郵件放到用戶的郵箱里。 整個(gè)郵件傳輸過程如下: 目前使用的smtp 協(xié)議是存儲(chǔ)轉(zhuǎn)發(fā)協(xié)議,意味著它允許郵件通過一系列的服務(wù)器發(fā)送到最終目的地。服務(wù)器在一個(gè)隊(duì)列中存儲(chǔ)到達(dá)的郵件,等待發(fā)送到下一個(gè)目的地。下一個(gè)目的地可以是本地用戶,或者是另一個(gè)郵件服務(wù)器,如下圖所示。
如果下游的服務(wù)器暫時(shí)不可用,mta 就暫時(shí)在隊(duì)列中保存信件,并在以后嘗試發(fā)送。 ◆ 電子郵件的信頭結(jié)構(gòu)及分析 1 .郵件的結(jié)構(gòu) 在最高層,郵件的結(jié)構(gòu)是非常簡(jiǎn)單的,用戶從終端機(jī)上看到的郵件格式一般為: 1. from: user1@domain1.com 2. to: user2@domain2.com 3. subject: explaination of mail format 4. date: thu, 1 apr 1999. 10:00:00 gmt 5. hi, jack 7. this mail is to explain you the mail format 8. - - - - 9. thanks 10. bob 其中, 1~~4 行稱作信件信頭(message header) 6~~10行描述信件要表達(dá)的內(nèi)容,稱為信體 (message body)。第5行是空行,根據(jù)rfc822的要求,信頭和信體之間必須加入一空行。[i]信頭通常包含字段from, to, subject 和date,有的郵件還包含cc,bcc等字段。 2. 郵件的信頭 事實(shí)上,郵件在傳輸過程中,服務(wù)器要把它打包成一個(gè)數(shù)據(jù)對(duì)象,包括上面的信件和一個(gè)信封。郵件的投遞是依靠信封上的地址或信封信頭(envelop address 或envelop header),而不是上面講的信件上的地址。 從表面上看,一封郵件是從發(fā)件人的機(jī)器直接傳送到收件人的機(jī)器,但通常這并不正確,一封郵件發(fā)送和接受過程至少要經(jīng)過四臺(tái)計(jì)算機(jī)。參考下圖所示。用戶通常在自己的電腦前編寫閱讀郵件,我們把它叫做客戶端 (client 1~~4 )。大部分組織里,都是用一臺(tái)專門的機(jī)器處理郵件,稱作郵件服務(wù)器 (smtp1, smtp2). 如果用戶是從家里撥號(hào)上網(wǎng),那末郵件服務(wù)器是isp 提供的。
當(dāng)某個(gè)用戶在自己的電腦 client1 前編寫完一個(gè)郵件,然后把它發(fā)送到他的isp 的郵件服務(wù)器smtp1。此時(shí)她的機(jī)器已經(jīng)完成了所有的工作,但郵件服務(wù)器smtp1還必須想法把郵件發(fā)送到目的地。smtp1 通過閱讀信頭或信封上的地址,找到收件認(rèn)得郵件服務(wù)器smtp2, 然后與該服務(wù)器建立連接,把郵件發(fā)到收件人的服務(wù)器上,等待收件人來取閱。 下面我們將通過一個(gè)例子說明整個(gè)郵件傳送過程及郵件的信頭變化。假設(shè)發(fā)件人的名字叫 sender, email地址是 sender@domain1.com使用的電腦名字叫 client1, ip 地址是 [111.11.1.1] (假設(shè)的地址)。 收件人的名字叫 receipt, email 地址是 receipt@domain2.com, 使用的電腦的名字叫 client2,ip 地址是 [222.22.2.2] (假設(shè)的地址)。當(dāng)郵件編輯完傳送給其郵件服務(wù)器mail.domain1.com 時(shí),郵件的信頭格式為: from: sender@domain1.com to: receipt@domain2.com date: tue, mar 18 1998 15:36:24 gmt x-mailer:sendmail 8.9.0 subject: greetings 當(dāng)郵件服務(wù)器 mail.domain1.com 把郵件傳到接收方的服務(wù)器 mail.domain2.com 時(shí),接受方服務(wù)器會(huì)在信頭上記錄下有關(guān)的計(jì)算機(jī)信息,郵件的信頭變成: received: from client1.domain1.com (client1.domain1.com [111.11.1.1]) by mail.domain1.com (8.8.5) id 004a21; tue, mar 18 1998 15:3 7:24 gmt from: sender@domain1.com to: receipt@domain2.com date: tue, mar 18 1998 15:36:24 gmt message-id: x-mailer:sendmail 8.9.0 subject: greetings 當(dāng)收件人服務(wù)器mail.domain2.com 把郵件接收并存初下來,等待收件人來閱讀時(shí),郵件的信頭將會(huì)再加入一條記錄: received: from mail.domain1.com (mail.domain1.com [111.11.1.0] ) by mail.domain2.com (8.8.5/8.7.2) with esmtp id laa20869; tue, mar 18 1998 15:39:44 gmt received: from client1.domain1.com (client1.domain1.com [111.11.1.1]) by mail.domain1.com (8.8.5) id 004a21; tue, mar 18 1998 15:37:24 gmt from: sender@domain1.com to: receipt@domain2.com date: tue, mar 18 1998 15:36:24 gmt message-id: x-mailer:sendmail 8.9.0 subject: greetings 上面整個(gè)記錄就將是收件人看到的完整的郵件信頭。讓我們逐行看一下信頭中各行的含義: received: from mail.domain1.com (mail.domain1.com [111.11.1.0] ) by mail.domain2.com (8.8.5/8.7.2) with esmtp id laa20869; tue, mar 18 1998 15:39:44 gmt 這封信是從一臺(tái)自稱為 mail.domain1.com 的機(jī)器上接收的;這臺(tái)機(jī)器的ip 地址是[111.11.1.0],真實(shí)名字就是標(biāo)稱名字 mail.domain1.com; 接收方的機(jī)器名稱是 mail.domain2.com, 運(yùn)行的郵件服務(wù)器是 sendmail, 版本(8.8.5/8.7.2) 。接收方機(jī)器給郵件的編號(hào)是esmtp id laa20869, 接收到的時(shí)間是 tue, mar 18 1998 15:39:44 gmt。 received: from client1.domain1.com (client1.domain1.com [111.11.1.1]) by mail.domain1.com (8.8.5) id 004a21; tue, mar 18 1998 15:37:24 gmt 這條記錄表明信件是由機(jī)器client1.domain1.com ( ip 地址是 [111.11.1.1]) 在tue, mar 18 1998 15:37:24 gmt交給mail.domain1.com,并賦給編號(hào)id 004a21。 from,to ,date和subject 都易于理解,分別指明發(fā)件人,收件人,信件編輯日期及信件主題。 message-id: 這是由發(fā)件方郵件服務(wù)器賦給這封郵件的編號(hào)。與其它編號(hào)不同,這個(gè)編號(hào)自始至終跟隨郵件。 ◆ open relay 的原理及測(cè)試 1.open relay 的原理 由于技術(shù)的原因,在80年代前,網(wǎng)絡(luò)還不是很健全,機(jī)器之間很少能直接對(duì)話發(fā)送郵件,人們必須得找出一條有效的連接通路來,然后信件沿著通路一步一步傳送到目的地。smtp協(xié)議中就明確指出當(dāng)郵件在不同的網(wǎng)絡(luò)間傳送時(shí),需要借助中間服務(wù)器的relay。 郵件在收件方和發(fā)件方之間會(huì)經(jīng)過毫不相干的第三方服務(wù)器,這就是郵件轉(zhuǎn)發(fā) (relay)。 如下圖所示:
圖中的 mail server 是可以對(duì)要求轉(zhuǎn)發(fā)的郵件進(jìn)行限制的,如只轉(zhuǎn)發(fā)來自某個(gè)域的郵件或來自于某些ip 得郵件。如果轉(zhuǎn)發(fā)沒有任何限制,就被稱為 open relay 或 third party relay。 從歷史上看,relay 曾經(jīng)發(fā)揮過重要作用。而且當(dāng)時(shí)這些工作主要靠手工來做,就像我們今天通過郵局發(fā)一封信一樣。假如我想從沈陽發(fā)一封信件到深圳,我再信封上寫好收信地址深圳,郵局就需要找到定義的運(yùn)送路線: 沈陽,北京,鄭州,長(zhǎng)沙,廣州,深圳。甚至還要長(zhǎng)一些。其中很重要一點(diǎn)是每一個(gè)中繼站都能很好的理解這封信將被送到哪里,下一個(gè)接收站是誰。在電子郵件里,這就相當(dāng)于每個(gè)中繼服務(wù)器清楚下一個(gè)服務(wù)起是誰,這就是郵件的轉(zhuǎn)發(fā)。 目前,正常郵件轉(zhuǎn)發(fā)已經(jīng)不再必要,相反,無限制轉(zhuǎn)發(fā)常常被發(fā)送垃圾郵件的人利用,隱藏真實(shí)的郵件來源,讓別人以為是從另外的isp 發(fā)出的信件;同時(shí),也把大量的處理工作轉(zhuǎn)移到別人機(jī)器上。 由于前面提到的歷史的原因,最初的絕大多數(shù)郵件服務(wù)器都允許open relay的。今天,大部分郵件服務(wù)器升級(jí)版本已經(jīng)在缺省設(shè)置中關(guān)閉了open relay, 如sendmail 從8.9.3版本開始,exchange server從5.5版本開始關(guān)閉了open relay。有的服務(wù)器雖然沒有相應(yīng)的升級(jí)版本,也都提供了關(guān)閉open relay 的方法,如在notes server的配置文件notes.ini 中加入一行:smtpmta_reject_relays=1。但由于很多服務(wù)器管理員的疏忽而沒能及時(shí)的修補(bǔ)這些安全漏洞,被利用來轉(zhuǎn)發(fā)垃圾郵件。 2. 如何確認(rèn)郵件服務(wù)器是否relay 假設(shè)要測(cè)試的ip是202.112.0.0. 可以使用下列命令進(jìn)行測(cè)試,文中的綠色斜題字為測(cè)試郵件服務(wù)器的反饋信息: #telnet 202.112.0.0 25 trying 202.112.0.0... connected to 202.112.0.0. escape character is ^]. 220 dns.ccert.edu.cn esmtp sendmail 8.11.1/8.11.1; sat, 30 jun 2001 21:07:10 +0800 helo mydomain 250 dns.ccert.edu.cn hello point.ccert.edu.cn [202.112.50.3], pleased to meet you mail from:nobody@yahoo.com 250 2.1.0 nobody@#yahoo.com... sender ok rcpt to:nobody@hotmail.com 550 5.7.1 nobody@hotmail.com... relaying denied 最后的relaying denied 表明該服務(wù)器已經(jīng)安全設(shè)置,不會(huì)再relay無關(guān)郵件了。如果顯示的結(jié)果是下面的樣子,這表明服務(wù)器可以轉(zhuǎn)發(fā)任何人的郵件。 rcpt to:nobody@hotmail.com 250 nobody@hotmail.com... recipient ok data 354 enter mail, end with "." on a line by itself this is a test of the relay . 250 vaa00289 message accepted for delivery 除了用上面的命令行的方法測(cè)試外,下面的鏈接提供了一個(gè)測(cè)試工具,只需輸入ip即可。 http://www./relay.html |
|