幾年前開始用
amavisd-new 這個程式搭配
spamassassin 來做病毒與廣告信件的過濾, 效果還算不錯. 不過, 由於這是一個 server 端的 daemon 程式, 並不是針對每個使用者單獨執行的, 所以, 如果把廣告信擋住不送的話, 一般的使用者在得知被擋了那些信之後, 並沒有辦法可以把這個信件送出. 必須有系統管理員來處理. 所以, 如果要讓使用者知道那些信件被認為是廣告信的話, 就只能把這些信都寄給使用者. 而在檔頭或標題加上註記, 讓使用者自己去分辨. 而且, 使用者也沒有辦法設定自己的白名單, 只能使用系統本身的白名單. 所以, 搭配 maildrop, 我用 php 寫了這個程式, 用來解決這個問題.
程式的最後一個版本, 可以由這兒抓取:
http://www.teatime.com.tw/~tommy/myspam/myspam.tgz 需求:
*
MySQL, 你必須有一個 mysql 的資料庫, 最好是支援 UTF-8 的 4.1 之後的版本. (我的環境是 5.0.18 )
* Web server (
Apache), 可以跑 PHP 就可以.
*
PHP, 應該都可以執行才對, 確定要有 iconv 與 mysql 的支援. 除了 webserver 用的 module 外, 也要有 CLI 版本, 也就是在 console 執行的版本. (我的開發環境是在 PHP 5.1.2)
*
Smarty (我的環境版本是 2.6.3)
*
maildrop, 我用的是 1.5.3 版.
* MTA, 當然了, 要用這個, 表示你應該早就有一個 mail server 了. (我用的是
postfix 2.2.10)
首先, 解開檔案後, 有個 db.sql 檔案. 裡頭有三個 table 的定義. 在 mysql 中執行這個 script, 產生那三個所需要的 table. 然後修改 web/index.php 有關資料庫的設定:
// 改成你使用的資料庫
$dbhost = 'your_db_host';
$dbuser = 'your_db_user';
$dbpass = 'your_db_password';
$dbname = 'your_db_name';
接著修改 smtp 與 pop3 的設定:
// smtp 伺服器的設定
$smtp_server = 'your_smtp_host';
$smtp_port = 25;
// pop3 伺服器的設定
$pop3_server = 'your_pop3_host';
$pop3_port = 110;
smarty 的路徑:
// 改成你的 smarty 存放的路徑
require_once('smarty/libs/Smarty.class.php');
其它的設定:
// 你的 email domain
$mydomain = 'your_domain_name';
// 你要使用的 MySPAM 的 URL
$spam_url = 'http://your_myspam_website';
// 使用者認為不是廣告信的信件, 要存放的路徑
$notspam_path = '/var/spool/myspam/notspam/';
// 每頁顯示的數量
$pagesize = 15;
// 資料保留的日數
$keep_days = 30;
// 轉碼除錯用, 如果不知道用來做什麼, 不要改成 true
$debug = false;
設定好後, 在你的 webserver 中, 設定一個 VirtualHost 或路徑, 指到 web 那個目錄 (請設定好使用 UTF-8 ), 然後打開你的 broswer, 連到你設定的 URL 上頭, 看看是否有看到登入的畫面. 然後輸入正確的使用者名稱與密碼 (程式使用 POP3 去檢查是否正確), 登入後, 應該就可以看到 MySPAM 的主畫面了. 如果看不到登入的畫面或看不到主畫面.... 我也不知道, 自己檢查看看 webserver, php, mysql 之間, 是否有問題吧.
在確定 Web 介面可以正常運作後, 就來設定 maildrop 吧. 修改 /etc/maildroprc 或者是某個使用者 HOME 下頭的 .mailfilter 檔案 (可以先用某個使用者來測試, 等運作成功後, 再改用 /etc/maildroprc, 讓全部的使用者都使用):
# Global maildrop filter file
# Uncomment this line to make maildrop default to ~/Maildir for
# delivery- this is where courier-imap (amongst others) will look.
DEFAULT="$HOME/Maildir"
if ( /^X-Spam-Flag: YES/:h )
{
if ( !( /^X-MySPAM: YES/:h ) && $SIZE < 20480000 )
{
to "| /usr/bin/php -Cq /var/spool/myspam/web/index.php save_spam"
exit
}
}
其中, 那個 DEFAULT 如果不是使用 Maildir 格式的話, 請勿設定成上頭那個樣子 (不要設定應該就可以用一般的 unix mbox 格式). 注意你的 php 所在的路徑與 myspam 的 index.php 的路徑對不對.
接著, 更改你的 mail server 設定, 把 local 存檔的動作, 改用 maildrop 來執行. 以 postfix 來說, 就是改這個設定:
mailbox_command = /usr/bin/maildrop -d ${USER}
這樣子設定之後, 只要被 spamassassin 認定是廣告信的話, 在 header 上頭, 應該 X-Spam-Flag 就會被設為 YES. 這樣子, 信就會被這個 php 程式存到資料庫中, 而不會送給使用者了.
$sa_spam_modifies_subj = 0;
如果一切正常的話, 在你的 cron 每天選一個時間, 加上一個設定, 去執行 notify.sh 那個程式 (請修改裡頭的路徑), 這樣子每天就會把收到的廣告信列表寄給每個使用者. 使用者如果需要做自己白名單的設定, 也可以經由那個 web 介面來設定. (所有的設定都不分大小寫, 除了正規表示式外)
系統會把符合使用者白名單的信件, 直接寄給使用者, 而不放到資料庫中.
如果系統執行有問題, 會傳回 EX_TEMPFAIL, 你的 mail server 應該會把信放到 queue 裡頭, 過一段時間再重送.
最後, 記得每天執行一下這個指令, 把使用者認定該信不是廣告信的信件都學習一次:
# NOTSPAM
/usr/bin/sa-learn --ham \
-p /var/lib/amavs/.spamassassin/user_prefs \
/var/spool/myspam/notspam/*
rm -f /var/spool/myspam/notspam/*
本程式授權採 GPL. 本人不保證這個程式的任何運作結果. 任何因本程式所造成的問題, 本人概不負責. 要不要採用請自行決定.
如果有任何疑問, 請先學學 PHP, 最好能看懂程式在做些什麼, 然後再來討論吧.
本文同步發表於我的 blog:
http://blog.teatime.com.tw/post/1/52