郵件系統的組成

MUTT的官網上有些材料對郵件系統裏各個部分的作用做了詳盡解釋。很早以前我就看過這些東西了,但最終還是沒能搞清楚誰是誰。


MUA直接根用戶打交道,MUTT即是如此。它遵循“一個程序只做一件事”的原則,既不能收郵件,也不能發郵件。這是我見過對“一個程序只做一件事”最蛋疼的信奉。MUTT在整理郵件方面確實好用,至少潛力非凡,工作方式合程序員口味。但如果要使用它還得裝一個fetchmail,裝一個sendmail,然後配置好這三個東西才能正常工作,這不是蛋疼是什麼?


如果不瞭解郵件系統中各個部分的作用,確實不好理解爲什麼MUTT不能XXX,以及fetchmail或者sendmail是做什麼的。最簡單的郵件系統組成,只需要MUA和MTA。用戶與MUA打交道,編輯郵件,告訴MUA把郵件發出去。MUA把郵件傳給MTA,MTA再經過網絡上一些MTA最終到達另一臺主機,另一臺主機的MUA就可以讀取文件了。


一個問題是:第一MTA在本地還是外部?Thuderbird之類的郵件客戶端看起把MUA和MTA集合在一起了,上述流程第一次數據傳輸在這種情況下是虛擬的(程序內部的)。用戶寫郵件時Thuderbird是MUA,用戶發送郵件時Thuderbird是MTA。它用SMTP協議將郵件發轉至你的郵箱提供商服務器(比如Gmail),後者再將郵件發至最終目的地。


Gmail服務器顯然也是一個MTA,它與最終接收郵件的主機間也是用SMTP協議通信。在那臺主機上,也有一個MTA,它接收Gmail傳來的郵件。這是到此爲此的描述中,MTA第一次不是用來發郵件,而是用來接郵件。


等一下,既然Thuderbird知道SMTP協議,爲什麼不直接把郵件發到最終目的地而要通過Gmail間接傳輸郵件?可能的解釋是,SMTP協議需要確認,發完郵件之後,MTA要等到最終MTA的迴應,不然就報告失敗。如果Thuderbird要跟最終主機通信,那麼它同時也得做爲一個server,等待着目的MTA的消息。


發往Gmail是什麼情況?只需等待Gmail的迴應,即Gmail報告已成功從Thuderbird接到郵件。Gmail服務器上的MTA是真正的MTA,可以接受Thuderbird的消息,將郵件往其它MTA傳(發);也可以接收其它MTA的消息,將郵件保存在服務器上(收)。Thuderbird只是將郵件交給Gmali轉發,大概就是所謂的relay。從這個角度上來說,Thuderbird只能算半個MTA,msmtp可以實現這個半個MTA的功能,其官網上的描述爲SMTP Client。


如果Gmail向最終主機投遞失敗要怎麼通知Thuderbird呢?不需要通知,只要新生成一封報告錯誤的郵件就行了,Thunderbird下次同步郵箱時,用戶就可以看到這封報告郵件投遞失敗的郵件。


MUTT是什麼情況?且認爲MUTT真的只是個MUA,即麼起初MUA到MTA的通信就確實存在了。這個MTA是個本機程序,MUA用管道或者其它IPC方式與之通信。如果sendmail是MTA,信件最終 就是通過sendmail發送出去的。sendmail真的是個MTA,不像Thunderbird只有一半的MTA功能。所以,用sendmail可以直接把郵件投向最終目的地,不需要將郵件relay到全功能的MTA。當然通過設定應該也可以讓sendmail只將郵件中轉到指定MTA而非直接投向最終目的地。網絡上搜到的一些用sendmail將郵件中轉到Gmail的博客看起來蠻複雜的。不知道是Gmail的原因還是sendmail的原因。


這樣一來,MUTT爲什麼要配sendmail就很清楚了。顯然,一般人根本不用着sendmail:誰會把自己的電腦配成一個郵件服務器?而且,據說,如果對方服務器不能反向通過IP查到域名,很可能就將這封郵件當成垃圾郵件了。絕大部分的MUTT用戶都會想使用網絡上郵件提供商的服務,如Gmail。所以,MUTT需要的不是一個完整的MTA,而是像Thuderbird那樣半調子的MTA:能將郵件relay到一個全功能的MTA即可。前文提到的msmtp就很好,MUTT需要的是STMP Client功能,真正做事的MTA在郵件提供商的服務器上。


想來,git send-email也是一個STMP Client。這個MUTT情何以堪吶,人家git一個插件都可以relay郵件,雖然人家的功能是用Perl實現的。其實較新的MUTT有內含SMTP Clinet功能的版本,看編譯時怎麼配置的。我在Ubuntu倉庫中裝的MUTT是有這個功能的。如果配置文件中設定了smtp的地址,MUTT會忽略$sendmail這個變量,郵件便會通過SMTP relay到某個服務器,而不是通過管道傳給$sendmail所指定的程序(sendmail或msmtp)。


接收端又是如何?回到Thunderbird的例子,用戶查看郵件時,Thunderbird會先通過IMAP或者POP3協議將郵件下載到本地。這時,它扮演了MRA的角色。但這個角色只在這種情形下才有意義。想象一下,如果你能ssh到Gmail的郵件服務器,在上面開個MUTT直接讀郵件,那還要個毛的MRA。據說,國外的ISP都會提供郵件服務器,你直接登上去看郵件就行了。我這個年代的人,恐怕已經將用MRA把郵件下載下來看視爲理所當然了。


如果MUTT僅僅是一個MUA,那麼我們需要一個下載郵件的軟件。而且,這時的情況跟發送時有些不一樣。發送時,MUA要找到MTA(配置裏指定),要通過某種方式與MTA交流。而接收時,MRA和MUA沒有類似的關係,甚至MUA都不管你用的啥MRA:我只要在本地文件系統看到郵件就行了。它們間用文件系統交流,這個關係比上一個關係弱得多。fetchmail就是一個MRA。令人吃驚的,每一封郵件在本地文件系統中竟然不是一個文件:一個本地郵箱居然是一個文件,所有屬於這個郵件的郵件都寫在這個文件裏。當這個文件更新以後,你就可以用MUTT打開它,查看郵件了。


和發送的情況一樣,較新的MUTT也是內置MRA功能的版本。打開郵箱時不指定本地郵箱路徑,而用imap://之類的路徑,即可打開遠程郵件。這就跟Thunderbird差不多了。轉了半天,原來MUTT就可以和Thuderbird一樣用,不需要其它軟件配合。這已經足夠大多數人用了。


但我需要fetchmail。爲什麼?因爲用MUTT當MRA時,郵件不經過MDA。MDA的作用是根據規則及郵件的內容將郵件存放在文件系統中不同的地方。fetchmail將郵件全部下載到默認本地郵箱,可以對它進行配置,把郵件傳給MDA,由MDA來確定郵件在文件系統上的歸宿。這是個將郵件分類的好時機。每天的郵件量有幾百封時,如果能根據細緻的定義規則將郵件分類,那該有多爽。比如,我訂閱了linux-kernel,kvm,linux-fsdevel三個郵件列表,linux-kernel簡單是洪水猛獸,kvm和linux-fsdevl郵件量是有可能每天看完的。如果將來自三個不同郵件列表的郵件分類,另外將發送或抄送給我(雖然近期內還不會有這種情況。。。)的郵件單獨列出來,如果將來自自己比較關注的幾個開發者的郵件單獨分類來自,每天按優先級看一看,那就多好。Lotus Notes就有類似功能,可以說,它內部集成了一個MDA。


MUTT雖有MRA,卻無法通過配置將郵件交給MDA,這對我來說是極不方便的。還是用fetchmail將郵件下載到本地,再用procmail把郵件分類吧。這個過程不需要對MUTT做什麼額外的配置,MUTT只要能在本地文件系統上看到郵件就行。


還有一個MSA的概念,大意是,攔在MTA前面,進行一些安全認證。其它MTA完全可以(而且有理由)集成這樣一個功能。可以說,SMTP Client其實是與郵件服務器的MSA交流,這個過程有各種安全驗證,一切順利的話,MSA纔會接收郵件,最後再把郵件交給MTA。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章