Postfix簡史:與病毒、垃圾和僵尸斗爭到底
原創(chuàng)本文根據(jù)IBM研發(fā)中心研究員,Postfix的創(chuàng)始人Wietse Venema在2010年LISA大會上的課程資料總結(jié)形成。
【51CTO精選譯文】對于Postfix,想必大家都不會陌生。Postfix是歷史悠久的電子郵件系統(tǒng),目前全球很多大型郵件服務(wù)商提供的上億個電子郵箱都是運行在Postfix之上,如國外常用的Outblaze,UOL,國內(nèi)的263等。
1998年,全球大約70%的電子郵箱都運行在Sendmail之上。當時在IBM研發(fā)中心工作的Wietse Venema開發(fā)了一個叫做Secure Mailer的程序,也就是Postfix的前身。這個程序希望做到比Sendmail更加安全,更容易配置,并且有更高的性能。同樣在1998年,IBM加入了Apache開源項目,而Secure Mailer也以Postfix的名稱在IBM Public License下開源。
Postfix沒有采取BSD/Unix上的Sendmail那種一體式的設(shè)計思路,而是采取了分布式安全架構(gòu)的設(shè)計。這兩種設(shè)計的區(qū)別可以參考下面兩張圖:
在Sendmail中,所有的接收和文件處理的過程都通過sendmail和/bin/mail這兩個服務(wù)進行,而這兩個服務(wù)都是在root權(quán)限下執(zhí)行的。也就是說,遠程用戶可以輕易的以root權(quán)限執(zhí)行任意命令或讀寫任意文件,而內(nèi)部系統(tǒng)中隔離層的缺失,也意味著系統(tǒng)非常容易被入侵。
而在Postfix當中,整個系統(tǒng)分為了input,core和output三層,而在每一層中,不同的任務(wù)都通過不同的子模塊來完成,如通過SMTP協(xié)議接收一個消息,發(fā)送一個消息,本地傳遞一個消息等,共計十多個子模塊。除了最終需要執(zhí)行系統(tǒng)命令和讀寫文件的兩個模塊是在root權(quán)限下運行之外,其他的模塊都是在postfix權(quán)限下運行,這就避免了上述Sendmail的安全問題。后來的TIS防火墻、qmail、Apache和路由器都參考了這個架構(gòu)思路,而Sendmail后來也根據(jù)這個架構(gòu)進行了改良。
Postfix在性能優(yōu)化方面參考了Web服務(wù)器的思路。按照Wietse的話來說,當服務(wù)器被放置在互聯(lián)網(wǎng)上,那么原本最糟的情況會變成正常的情況,而正常的情況則會變成最遭的情況。比如說,Postfix可以被設(shè)計為盡可能快的傳遞郵件,但是在90%的郵件都是垃圾郵件的情況下,這樣的設(shè)計就變成了一場災(zāi)難。又好比Postfix可以被設(shè)計為按順序處理所有的SMTP客戶端請求,但事實上,SMTP客戶端端口可能會被無數(shù)個僵尸堵死。所以對于Postfix的優(yōu)化而言,需要針對互聯(lián)網(wǎng)上“最糟的情況”進行。
1999年,Melissa病毒席卷全球。Linux系統(tǒng)雖然不會感染病毒,但是Postfix服務(wù)器們卻成為了病毒傳播的載體。Postfix開發(fā)團隊決定尋找一個長久的解決辦法。這個方案必須基于已經(jīng)成為標準的SMTP協(xié)議,而避免使用當時如雨后春筍般冒出的CVP、Milter等特殊的協(xié)議。
最簡單的方式莫過于用兩個Postfix,中間用一個專門用于過濾的服務(wù)來進行垃圾郵件清理,過濾器前后各有一個郵件隊列(見下圖)。
這樣做的優(yōu)點是配置簡單,性能也不錯,但是問題在于過濾器之后的那臺Postfix只能通過quarantine(隔離)或discard(丟棄)來處理垃圾郵件,而無法采取reject(拒絕)的方式。這個倒也不是什么大問題,只是在一些歐洲國家會禁止郵件服務(wù)提供商在接收了郵件之后自行discard的做法。因此,Postfix的另一個過濾機制就是在郵件隊列建立之前進行過濾(如下圖):
根據(jù)2007年O'Reilly Sysadmin針對全球40萬家企業(yè)的調(diào)查報告數(shù)據(jù),共有12.3%的企業(yè)采用Sendmail,8.6%的企業(yè)采用Postfix。
從Google Trend的趨勢看來,過去幾年間,無論是Sendmail也好還是Postfix也好,人們對郵件服務(wù)器的關(guān)注度一直在降低。
事實上,隨著信息全球化的發(fā)展,更多個人和企業(yè)會選擇大型的郵件服務(wù)提供方的郵件方案,一方面省卻了自己配置的麻煩和成本,另一方面無論是跨國溝通的可靠性、安全性和反垃圾方面,大郵件服務(wù)提供方都有著天然的優(yōu)勢。
自己維護一個郵件服務(wù)器并不容易。從1999年到2009年,對互聯(lián)網(wǎng)上的郵件服務(wù)器最大的威脅一直是安全。
1999年,你會在UNIX系統(tǒng)上建立一個郵件系統(tǒng),不用煩惱服務(wù)器中病毒之類的問題,但是你那基于UNIX系統(tǒng)的郵件系統(tǒng)卻成為了Windows病毒最大的傳播源;
2009年,你在Linux系統(tǒng)上搭建了一套性能優(yōu)秀的郵件系統(tǒng),但是這個性能優(yōu)秀的系統(tǒng)在92%的時間都在發(fā)送來自僵尸網(wǎng)絡(luò)的垃圾郵件。
大量的僵尸擁擠在郵件服務(wù)器的端口處,阻塞整個交通。
在最糟的情況下,服務(wù)器會被僵尸網(wǎng)絡(luò)所淹沒。根據(jù)RFC 5321的建議,服務(wù)器端的timeout設(shè)置為5分鐘為宜,而設(shè)置成5分鐘timeout的postfix在遭遇僵尸網(wǎng)絡(luò)的情況下,可能會造成所有的SMTP服務(wù)器端口都被堵死的結(jié)果。
遇到這種情況,如果置之不理,那么很大的可能是僵尸網(wǎng)絡(luò)堵塞的情況越來越糟糕。解決方法分為兩種,臨時性的和持久性的。
臨時性解決方法,無非就是減少每個SMTP客戶端的處理時間,如減少time limits和rejected命令數(shù)量等。
#將Postfix master(8)守護進程定義為過載狀態(tài) smtpd -o stress=yes #默認參數(shù) smtpd_timeout = ${stress?10}${stress:300}s smtpd_hard_error_limit = ${stress?1}${stress:20}
這樣的處理方式可能會造成正常郵件發(fā)送的延遲,不過延遲總比完全發(fā)不出去要好多了。
持久性的解決方法有兩個,一個就是配置更多的郵件服務(wù)器進程,上更多的帶寬、內(nèi)存、硬盤、CPU等等(前提是你有錢);另一個很簡單,就是在僵尸們到達服務(wù)器之前將它們過濾掉,即所謂的before-smtpd連接過濾器:postscreen。
postscreen(8)的很多理念來自Michael Tokarev在OpenBSD spamd和MailChannels Traffic Control當中的工作。postscreen的工作流程如下圖描述:
簡單來說就是根據(jù)白名單/黑名單決定每個流程中如何處理一個連接。為了防止被列入黑名單,僵尸們一般會避免在一段時間內(nèi)重復(fù)騷擾同一個站點,所以除了本地名單之外,還會用到DNS上的黑名單/白名單。postscreen(8)能夠?qū)⒈徽J為是僵尸的連接在幾個小時內(nèi)列入黑名單,但是在此之前,它需要辨認究竟哪些是僵尸,哪些是正常的客戶端。這點要如何實現(xiàn)?
Wietse將這個過程描述為一個捉狗的游戲。假設(shè)你是一個捉狗人,來到一個大房子外面,如何才能最快的確認房子里面是否有狗?答案就是,按下門鈴,如果有狗的話就會立刻聽見狗叫聲。
postscreen(8)采用了類似的思路。SMTP連接建立的過程中,服務(wù)器端會發(fā)送歡迎信息,而客戶端則在接收歡迎信息之后返回信息。好的SMTP客戶端會等待完整的歡迎信息:
mail server: 220–server.example.com ESMTP Postfix<CR><LF> mail server: 220 server.example.com ESMTP Postfix<CR><LF> good client: HELO client.example.org<CR><LF>
而大多數(shù)僵尸則會提前說話,即pregreet:
postscreen: 220–server.example.com ESMTP Postfix<CR><LF> spambot: HELO i-am-a-bot<CR><LF>
結(jié)果證明這一個方法很有效。根據(jù)2010年9月間針對mail.python.org的一次數(shù)據(jù)收集,有超過70%的僵尸都會進行pregreet。
根據(jù)在不同郵件服務(wù)提供方的數(shù)據(jù)收集,發(fā)現(xiàn)的結(jié)論是,全球大部分垃圾郵件都來自少數(shù)幾個國家,但針對不同郵件服務(wù)商來自不同國家的垃圾郵件流量是各自不同的。
另外一個發(fā)現(xiàn)是,垃圾郵件是個24小時持續(xù)不斷的行為,但僵尸們的活動是有規(guī)律可循的。
2011年1月發(fā)布的Postfix 2.8.0中內(nèi)置了postscreen守護進程,支持DNS白名單/黑名單以及相應(yīng)的模式匹配。目前Postfix最新版本是5月7日發(fā)布的2.8.3版本。
結(jié)論
Postfix已經(jīng)是一個相當成熟的系統(tǒng),其模塊化的設(shè)計可以允許維護人員/開發(fā)者在僅僅修改或添加一個小程序的情況下添加功能。這種可擴展性避免了用戶修改Postfix本身的煩惱,并給予用戶更多的選擇。在未來很長一段時間內(nèi),僵尸網(wǎng)絡(luò)仍然難以斷絕,需要更加智能的連接過濾機制來維持郵件服務(wù)器的可運行性。Postfix和僵尸們的斗爭仍在繼續(xù)。
【編輯推薦】