Tommy 碎碎念

Tommy Wu's blog

« 上一篇 | 下一篇 »

MySPAM, 我的廣告信管理程式
post by tommy @ 17 四月, 2006 19:30
幾年前開始用 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 程式存到資料庫中, 而不會送給使用者了.

接著修改你的 spamassassin 設定, 不要加上 ***SPAM*** 在信件標題上頭. 如果你用的是 amavisd-new 的話, 就改這個參數:

$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, 最好能看懂程式在做些什麼, 然後再來討論吧.

Del.icio.us Furl HEMiDEMi Technorati MyShare
commons icon [1] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

請教Tommy先生:

我之前成功將MySpam應用在自己的Linux伺服器上,但是,由於一些狀況,這台Linux要變成一台只作過濾的機器,而存放MAILBOX 的要換成別的協同作業系統(如EXchange, Domino...)。

有辦法在maildrop的部份,設定將正常的信件送到Postfix 10026 port(another listen port),而在master.cf關於10026的設定中拿掉mydestination,讓它利用transport的方式往下一台傳遞。

有辦法在maildrop時做到嗎?

commons icon [2] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

不能. maildrop/procmail 一定是最後要把信寫入到信件檔前才會執行.
要另外寫程式模擬成 MTA, 把信收下來處理, 如果沒有問題再轉發.

commons icon [3] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

Tommy先生您好,

我偶而發現你寫的這支好用的程式,並且想把它應用在我們公司的mail server(FreeBSD)上,但目前我遇到2個問題,煩請給我解惑:

1. 我一樣使用amavisd搭配maildrop來使用,但我們公司目前是使用雙domain放在同一台機器上,故不同的user收發mail使用的帳號皆為:[email protected],而不是william這樣的格式,故當你的notify.sh這支程式要發信時,收件人便會改為
,而因此會造成退信,請問你我應該如何修改才可以讓它正常使用。

2. 因為是使用amavisd,故目前不管是廣告信還是病毒,都會直接存放在/var/amavis/quarantine/這個目錄底下,而不會存放到我在config.php給它設定的目錄,例如$notspam_path = '/var/spool/myspam/notspam/';,這樣即使成功收到通知信,裡面也不會有東西,請問是否amavisd.conf裡還有地方需要修改來配和才能正常運作?謝謝!

by william

commons icon [4] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

1. 在 notify.php 中檢查 $user 有包含 @ 時, 就不要再加上 domain. 如果沒改過, 應該是在 85 行那兒, 把
$to = "$user@$mydomain";
改成
if (strstr($user, '@'))
$to = $user;
else
$to = "$user@$mydomain";
就應該可以了.

2. notspam 那一段與 amavisd 沒什麼關係, 也與 quarantine 沒關係. 那只是把信存到該目錄下,再利用 sa-learn 去讓 spamassassin 學習.

commons icon [5] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

請教Tommy先生:

小弟將你程式的最後一個版本抓下後,發現解壓縮後只有一個檔案,不知道是否是檔案有問題,還是我個人的問題。

麻煩請Tommy先生將Source Code及sql.txt的檔案,重新打包一次寄給我.......謝謝

commons icon [6] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

你要的東西都在那個 .tgz 檔案內, 等你學會怎麼解開 .tgz 的檔案後就可以看到了.
要我再打包一次, 也還是同樣的檔案. 你如果不會解 .tgz, 結果還是會一樣的.

commons icon [7] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

Tommy先生:

原來你的檔案是.tgz的附檔丫,但是我下載後它自已會存成.gz的檔案,難怪解出來的檔案會怪怪的。

謝謝你的答覆,我已經解開了,應該是我的IE怪怪的...

commons icon [8] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

請問已經被標示為 SPAM 並放入資料庫的信件, 能否在頁面標示為非廣告信後取回

commons icon [9] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

不會. 標示為非廣告信只是把信件寫到特定的目錄讓 spamassassin 去學習而已.

commons icon [10] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

謝謝

選擇非廣告信後, 該信件並不會自SPAM列表清除, 這樣會讓使用者 Confuse, 請問有何方法可以移開, 或者做個 Mark, 或者顏色區隔都可以.

commons icon [11] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

[1] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]
請教Tommy先生:

我之前成功將MySpam應用在自己的Linux伺服器上,但是,由於一些狀況,這台Linux要變成一台只作過濾的機器,而存放MAILBOX 的要換成別的協同作業系統(如EXchange, Domino...)。

有辦法在maildrop的部份,設定將正常的信件送到Postfix 10026 port(another listen port),而在master.cf關於10026的設定中拿掉mydestination,讓它利用transport的方式往下一台傳遞。

有辦法在maildrop時做到嗎?

作者 Polo | 24/04/2007, 11:33
[2] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]
不能. maildrop/procmail 一定是最後要把信寫入到信件檔前才會執行.
要另外寫程式模擬成 MTA, 把信收下來處理, 如果沒有問題再轉發

請問一下那有其他方法嗎?

commons icon [12] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

就自己寫個小程式, 在 maildrop/procmail 最後把正常的信轉到這個程式去, 然後這程式把信寄到你指定的機器.

找不到程式就自己改寫個來用吧, 基本上就是 myspam 裡頭那 save.php 那個程式, 把 CheckFilter() 那個地方改成永遠成立就是了.

commons icon [13] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

@ 這個小程式要自己寫還真不會寫~不知大大有時間的話,能否幫個忙~ 真的會五體投地感激不盡啊~(只差這個了‥ /_\ )

commons icon [14] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

自己學著寫或花錢請人寫(不要找我寫, 我的價碼很高的)吧.

commons icon [15] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

@了解,我慢慢翻書來弄好了~謝謝您寫出這麼棒的程式~

commons icon [16] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

@ Tommy大,有個問題想請教~
以下這個錯誤是要怎麼解決呢?

procmail: Skipped "|/usr/bin/php -Cq /var/www/html/myspam/web/index.php save_spam"
procmail: Closing brace unexpected

煩請指點一下~感恩~

commons icon [17] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

procmail 的設定檔寫錯了, 裡頭的語法不對吧.

commons icon [18] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

@ Tommy大,我是之前那個要把MySPAM架在Gatewya主機上的,目前困難就是,已經有將save.php改成re_send.php,以利轉給第二台收信主機,但‥目前MAIL會在Gateway那台無限迴圈,所以我只好引入phpmailer來幫忙看能不能用第二台的SMTP來寄信,看會不會就可以將信寄走不會鬼打牆~

但‥phpmailer的程式碼是要加在哪裏才會生效~請給一盞明燈吧~謝謝~

commons icon [19] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

Tommy大大:要如何check or 判斷myspam安裝後是沒問題?

commons icon [20] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

Hi Tommy哥,請問我在重送非廣告信件的時候,彈出視窗顯示「總共選送出0封信(已選擇1封)」,是我哪個地方沒設定好?

commons icon [21] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

最後有收到信嗎?
我記得這個在舊版會這樣, 最後那個版本應該是正常的.

commons icon [22] Re:MySPAM, 我的廣告信管理程式 [ 回覆 ]

最後沒有收到信…,如果是版本問題,那小弟再換版本試試好了,感謝Tommy哥。

迴響
暱稱:
標題:
個人網頁:
電子郵件:
authimage

迴響

  

Bad Behavior 已經阻擋了 45 個過去 7 天試圖闖關的垃圾迴響與引用。
Power by LifeType. Template design by JamesHuang. Valid XHTML and CSS