灰名單教學文檔

1. Introduction

註:寫這份指南的原意是要補充基本的 postfix 指南postfix 規限指南,但其後已演變至適用於其它 MTA 。

postgrey 是個政策伺服器,透過實施灰名單在 Postfix 郵件伺服器上過濾垃圾郵件。灰名單的原理建基於多數垃圾郵件都寄件者都是垃圾郵件程式或其它不乎合 RFC 的 MTA。postgrey 會在預設時限內臨時以「稍後重試」450 號錯誤拒絕新郵件,並在它的資料庫內記錄客端 IP/寄件者/收件者這三組資料。假若寄件的伺服器乎合 RFC,它應該重寄該郵件,到時 postgrey 便會在資料庫內找尋配對並接納該郵件。這個拖延時限是可自訂的,而且 postgrey 維護一個資料庫儲存已知的組合,因此來自同一位寄件者郵件只會在首封經歷延誤。

相反地,典型的垃圾郵件程式一般都會接收大量的回郵或被拒郵件,因此垃圾郵件寄件者多數在臨時被拒的情況下不會重寄郵件。故此任何來自該類來源地的郵件將會被棄置。這樣額外帶來的好處就是減省郵件伺服器花在過濾及處理郵件上的時間,因為大部份的郵件在進入 MTA 之先便會被棄置,所以不必過濾或處理。

postgrey-en.png

2. 設定

灰名單可以因應不同的 MTS 而被設定。請根據你所採用的 MTA 來參考下列相關部份。

2.1. Postfix

Postgrey 在 CentOS 5.1 上是通過 RPMForge 安裝最新版本的,雖然這裡的指示也適用於其它版本。要啟用 RPMForge 軟件庫,請參閱 RPMForge 內的指引。首先,請安裝 postgrey:

# yum install postgrey

Postgrey 是用 Perl 寫成的,因此 Perl 及某些 Perl 模塊必須被安裝。Yum 應該會自動判斷你所仍未安裝的依賴性套件,而你亦可以在 Postgrey 的網站查閱它的要求。

我們首要是設定 Postfix 應用 Postgrey。編輯 /etc/postfix/main.cfg 仿照下面在 smtpd_recipient_restrictions 這個部份加入 check_policy_service 這一行(假如你沒有 smtpd_recipient_restrictions 這部份,那麼下面是個不錯的列子):

smtpd_recipient_restrictions =
   permit_mynetworks,
   reject_unauth_destination,
   check_policy_service unix:postgrey/socket,
   permit

按預設值,Postgrey 拒絕新郵件的時間是 5 分鐘,但我們可以利用 --delay 這個選項來更改它。這裡要權衡的,就是時間越長拒絕垃圾郵件的機會越大,但合法郵件初次被延誤的時間也會越久。你也許值得在開始時把這個值設為 1 分鐘(60 秒),然後當 Postgrey 已經為你的郵件伺服器建立了一個常見郵件聯絡人的資料庫時,才把數值增大。我們不建議你把延誤時間設至多於 300 秒(5 分鐘)。要以手動的方式設定延誤時間(以秒計算),我們必須在 /etc/sysconfig/postgrey 建立 Postgrey 的設定檔,然後如下所示加入 --delay 這個選項(選項清單請參閱 man postgrey):

OPTIONS="--unix=/var/spool/postfix/postgrey/socket --delay=60"

最後,我們須要啟動 Postgrey 這個服務及重新載入 Postfix 的設定:

# /sbin/service postgrey start
# /sbin/service postfix reload

請確保 postgrey 在機器開機時會被自動啟動:

# /sbin/chkconfig --levels 345 postgrey on 

現在我們可以檢查郵件日誌並看到 postgrey 大展所長。以下內容來自我的 /var/log/maillog:

#
# postgrey loads:
#
Dec 17 21:44:58 jessie postgrey[6844]: Process Backgrounded
Dec 17 21:44:58 jessie postgrey[6844]: 2007/12/17-21:44:58 postgrey (type Net::Server::Multiplex) starting! pid(6844)
Dec 17 21:44:58 jessie postgrey[6844]: Binding to UNIX socket file /var/spool/postfix/postgrey/socket using SOCK_STREAM
Dec 17 21:44:58 jessie postgrey[6844]: Setting gid to "101 101"
Dec 17 21:44:58 jessie postgrey[6844]: Setting uid to "100"
#
# postgrey greylisting a message:
#
Dec 17 21:23:49 jessie postfix/smtpd[6714]: connect from mk-outboundfilter-4-a-1.mail.uk.tiscali.com[212.74.114.8]
Dec 17 21:23:49 jessie postfix/smtpd[6714]: NOQUEUE: reject: RCPT from mk-outboundfilter-4-a-1.mail.uk.tiscali.com[212.74.114.8]:
        450 4.2.0 <ned@example.com>: Recipient address rejected: Greylisted, see http://postgrey.schweikert.ch/help/example.com.html;
        from=<bob@example.com> to=<ned@example.com> proto=ESMTP helo=<mk-outboundfilter-4-a-1.mail.uk.tiscali.com>
Dec 17 21:23:54 jessie postfix/smtpd[6714]: disconnect from mk-outboundfilter-4-a-1.mail.uk.tiscali.com[212.74.114.8]
#
# postgrey accepting a message:
#
Dec 17 22:23:45 jessie postgrey[2218]: action=pass, reason=triplet found, client_name=mk-outboundfilter-3-a-1.mail.uk.tiscali.com,
        client_address=212.74.114.7, sender=bob@example.com, recipient=ned@example.com

如果你看到這樣一則信息:

Nov 18 09:39:03 jessie postfix/smtpd[26006]: warning: connect to postgrey/socket: Permission denied

請不要灰心。這是 SELinux 的問題,而這個 wiki 頁面談論了解決方法:zh-tw/HowTos/SELinux#head-c107e0a7fef7854abd2f1e330b2bfd734b678caa

2.2. Sendmail 內的灰名單

Sendmail 採用 milter-greylist,它已收錄在 RPMForge。要啟用 RPMForge 軟件庫,請參閱 RPMForge 內的指引。首先,請安裝 milter-greylist:

# yum install milter-greylist

milter-greylist 是已 C 寫成,因此它的依賴性寥寥可數。Yum 應該會自動判斷你所仍未安裝的依賴性套件,而你亦可以在 milter-greylist 的網站查閱它的要求。

請在你的 sendmail.mc 腳本的尾部加入以下內容:

INPUT_MAIL_FILTER(`greylist',`S=local:/var/milter-greylist/milter-greylist.sock')dnl
define(`confMILTER_MACROS_CONNECT', `j, {if_addr}')dnl
define(`confMILTER_MACROS_HELO', `{verify}, {cert_subject}')dnl
define(`confMILTER_MACROS_ENVFROM', `i, {auth_authen}')dnl
define(`confMILTER_MACROS_ENVRCPT', `{greylist}')dnl

你也可以按喜好指定閒置時間,而以下的例子設定發送資訊給郵寄程式及等待回覆時等待一分鐘,因為預設的 10 秒時限或許在採用 DNSRBL 及/或 SPF 時也許會不足夠。詳情請參閱 Sendmail 的郵寄程式安裝指南

INPUT_MAIL_FILTER(`greylist',`S=local:/var/milter-greylist/milter-greylist.sock, F=, T=S:1m;R:1m')dnl

利用 m4 檔編譯 sendmail.cf 檔。很多系統都擁有一個能自動完成這個步驟的 Makefile。

/usr/bin/m4 /usr/share/sendmail/cf/m4/cf.m4 sendmail.mc > sendmail

接著重新啟動 sendmail

service sendmail restart

2.3. Exim

Exim 的設定應該放在這裡。假如你把灰名單應用在 exim(或其它 MTA)上,歡迎你自動請纓

3. 匯報

Postgrey 包含一個名叫 postgreyreport 的匯報工具。它已預設在安裝 postgrey 的套件時一併被安裝。postgreyreport 會剖析(來自 STDIN)的郵寄日誌,將它與 postgrey 的資料庫比較,然後列出所有「致命」灰名單項目的詳情。當一台主機於首次寄件往某個特定收件者的 300 秒未能重試寄件,它便被放進「致命」灰名單內。postgreyreport 將會採用客端 IP/寄件者/收件者這三組資料作識別之用。你可以利用 --delay 這個指令行選項來調整 300 秒的時限,但 300 是個不錯的基準。多數郵件伺服器都會在 300 移內重試。

基本用法:

cat /var/log/maillog | /usr/sbin/postgreyreport --delay=300

視乎你的伺服器有多繁忙,這個報告有可能會頗大。要取得首 20 個被放進灰名單內的來源地,你可以用這個方法:

cat /var/log/maillog | postgreyreport | awk '{print $1}' | sort | uniq -c | sort -nr | head -n20

要取得首 20 個灰名單來源地所寄往的電郵地址:

cat /var/log/maillog | postgreyreport | awk '{print $4}'  | sort  | uniq -c | sort -nr | head -n20

要列出 postgreyreport 支援的所有選項及它們的功用:

postgreyreport -h

4. 多重 MX 的考慮

假若你的網域擁有多於一台郵件伺服器(MX),請確保你在所有伺服器上啟用灰名單,否則垃圾郵件寄件者將會對準你的後備 MX 機器並從那裡轉寄郵件。你也值得把每台機器放在對方的白名單內。請參閱下一部份關於如何在 postgrey 內設置白單名。

要讓灰名單在後備 MX 機器上運作,灰名單的檢查必須在郵件被接納前進行!雖然這聽起來是理所當然的事,它卻是導致不少人在後備 MX 機器上設置灰名單時出現混亂的原因之一。舉個例說,如果你在 postfix 內採用 permit_mx_backup,你的備份 MX 上的 smtpd_recipient_restrictions 應該是這樣的:

smtpd_recipient_restrictions =
    reject_unauth_destination,
    check_policy_service unix:/var/spool/postfix/postgrey/socket,
    permit_mx_backup,
    permit

5. 白名單

postgrey 也可以把寄件者及收件者放在白名單內。要把一台主機加進白名單,你只需把它的完整機域名或 IP 位址加進 /etc/postfix/postgrey_whitelist_clients.local,譬如:

192.168.1.10
mydesktop.office.mydomain.com

現在所有來自 192.168.1.10 或 mydesktop.office.mydomain.com 的郵件將不會被被灰名單過濾,而會立即獲接納(只要它是合法的,並通過所有 postfix 規則)。另一方面,假若你想把一個收件者加入白名單內,你可以將電郵地址的用戶名稱部份加進 /etc/postfix/postgrey_whitelist_recipients 檔內,譬如:

postmaster@
abuse@
theboss@

現在所以寄往上述地址的電郵將不會被被灰名單過濾,而會立即獲接納。請留意 postgrey 已預設把 postmaster 及 abuse 列進白名單內。

6. 總結

灰名單能高度有效地對抗來自不乎合 RFC 的垃圾郵件程式的郵件。Postgrey 是一個易設置的灰名單政策伺服器,它僅需數分鐘便可被安裝和設置於在一台運作中的 CentOS 郵件伺服器上。

7. 連結

http://www.greylisting.org/

http://postgrey.schweikert.ch/

http://milter-greylist.wikidot.com/sendmail

Translation of revision 35

zh-tw/HowTos/postgrey (last edited 2010-10-21 01:53:23 by TimothyLee)