- 论坛徽章:
- 1
|
原帖由 爱之旅 于 2006-2-11 12:00 发表
能具体说一下吗?
看得懂就看,看不懂就算了,
- # 這個檔案需要存在 $HOME/.procmailrc , 做為 sendmail 的Mlocal 中的 procmail 取用,屬於
- # User 的個人設定,不同於 /etc/procmailrc 之內容
- PATH=$PATH
- SHELL=/bin/sh
- MAILDIR=/var/spool/mail
- VERBOSE=yes
- LOGABSTRACT=all
- SENDMAIL=/usr/sbin/sendmail
- # LOG FILE , 可以不設,或設了後使用 logrotate resize
- # 需建立 $HOME/procmail 目錄,以存放 log 檔以利除錯及統計
- LOGFILE=$HOME/procmail/procmail.log
- # 暫存檔名,需建 $HOME/procmail/mail_folder 目錄,並為該 user 權限
- FILE=`echo $HOME`/procmail/mail_folder/mail-`date +%Y%m%d%H%I%S`-`echo $$`.eml
- # 存檔並改變檔案屬性
- tmp=`formail > $FILE; chmod 644 $FILE`
- # 取得郵件中的標題
- tmp=`formail -zxSubject:`
- #還原標題中的 MIME/QP 編碼(無編碼不處理),去除標題的一些特殊符號,以免 shell 出錯
- SUBJ=`/etc/parser_subj "$tmp"| sed -e "s/[\$,\(,\),\',\\]//g"`
- # 取得寄件人 From
- FROM=`formail -zxFrom:| sed -e 's/.*<\(.*\)>.*/\1/g'`
- # 取得收件人
- TO=`formail -zxTo:|tr ',' '\n'| sed 's/\(.*\) \(.*\)/\2/'`
- # 從何而以的 IP ,不使用 head -1 時可得所有經過的 IP
- IP=`formail -zxReceived:|grep ^from|sed -e 's/.*\[\(.*\)\.\(.*\)\.\(.*\)\.\(.*\)\].*/\1.\2.\3.\4/g'|head -1`
- # 轉成反解格式,以利 RBL使用
- PTR=`formail -zxReceived:|grep ^from|sed -e 's/.*\[\(.*\)\.\(.*\)\.\(.*\)\.\(.*\)\].*/\4.\3.\2.\1/g'|head -1`
- # 計算 Mail Size , 做為統計用 (尚無作用)
- MAIL_SIZE=`formail | wc -c | awk '{print $1}'`
- # 資料庫連線參數
- MYSQL="mysql -h procmail.mydomain.net.tw -u abel -pPASSWORD procmail"
- # 這個 Rule 是取回信時所使用,可見 www/back_to_me.cgi, 並注意自身的 CGI 執行權限
- :0 H
- * ^X-resend:
- /var/spool/mail/$LOGNAME
- # 白名單,符合即可進入 MailBox,免檢查,此名單由 User 從 Web 介面去設定,
- # 詳可見 www/SPAM/show_white_list.php 及 TABLE 中的 WHITE_LIST
- #下列的$($..)用法在做檢查,為 Header 中只有有 match 即可通過到 $ORGMAIL(Mailbox)
- WHITE_LIST=`echo "SELECT WHITE_NAME FROM WHITE_LIST WHERE USERNAME='$LOGNAME' AND instr('$FROM', WHITE_NAME ) or instr('$SUBJ', WHITE_NAME )"| $MYSQL | tr '\n' '|' ; echo "aaaaaaaazzzzzzzzzggggggggg"`
- :0 H
- * $($WHITE_LIST)
- $ORGMAIL
- # 黑名單,符合即可進入 SPAM List,此名單由 User 從 Web 介面去設定,
- #下列的$($..)用法在做檢查,為 Header 中只有有 match 即歸類到 SPAM 中
- WHITE_LIST=`echo "SELECT BLACK_NAME FROM BLACK_LIST WHERE USERNAME='$LOGNAME' AND instr('$FROM', BLACK_NAME ) or instr('$SUBJ', BLACK_NAME )"| $MYSQL | tr '\n' '|' ; echo "aaaaaaaazzzzzzzzzggggggggg"`
- :0 H
- * $($WHITE_LIST)
- {
- :0 fw
- | echo "insert into SPAM(MAIL_FROM,RCPT_TO,SUBJ,FILE_NAME,MAIL_TYPE,USERNAME,REASON,PATTEN,IP ) values('$FROM ','$TO ','$SUBJ ','$FILE',1,'$LOGNAME','發信軟體','mailserver 信商發出','$IP')" | $MYSQL
- :0
- /dev/null
- }
- # 巳被標為 SPAM,因為不是我們判斷的,所以另外做一個,若不 Care 亦可直接設於 Patten
- # 檢查中,請注意,信一進來時,巳經另存新檔了,所以此處的 mysql 在做 Record 的記錄
- # /dev/null 則是不希望它進入信箱中
- :0 HD
- * ^Subject: .*SPAM.*
- {
- :0 fw
- | echo "insert into SPAM(MAIL_FROM,RCPT_TO,SUBJ,FILE_NAME,MAIL_TYPE,USERNAME,REASON,PATTEN,IP ) values('$FROM ','$TO ','$SUBJ ','$FILE',1,'$LOGNAME','SPAM','標題 SPAM','$IP')" | $MYSQL
- :0
- /dev/null
- }
- # 不為 自己的 user 所寄,且 IP 不為 mydomain user 使用的網段,但 Message-ID 帶
- # mydomain 的名稱,判為 SPAM,因為這種情況是發信軟體所產生,一般不為該 Domain
- # User 一定會先經過別的 Mail Server Relay 過來,一過 Server 即會標示
- # Message-ID
- :0 H
- * !^From: .*@mydomain.net.tw.*
- * !^Received: .*(111\.172\.21[0-1]\.|127.0.0.1|local).*
- * ^Message-Id: .*@mydomain.net.*
- {
- :0 fw
- | ( echo "insert into SPAM(MAIL_FROM,RCPT_TO,SUBJ,FILE_NAME,MAIL_TYPE,USERNAME,REASON,PATTEN,IP ) values('$FROM ','$TO ','$SUBJ ','$FILE',1,'$LOGNAME','發信軟體','Message-ID 為 mydomain','$IP')" | $MYSQL )
- :0
- /dev/null
- }
- # 檢舉廣告信後的 SpamCop 回函,此回函為 text ,帶有一個 link, 主要在取出此
- # Link 中的 id 值,做為批次 Submit 依據,詳可見 TABLE SPAMCOP_ID , 及
- # www/SPAM/show_result.php 中的大量檢舉,及 www/SPAM/submit_to_SPAMCop.cgi
- # www/SPAM/spamcop.sh (cronjob)
- # 其中 submit 該程式為套用 Spamcop 的 From 的自動 submit, 以 Perl 寫成,需
- # 裝有該 Perl module 方能作用,若不做檢舉功能,則可拿掉這些相關程式及 rule
- :0 H
- * ^Subject: .*SpamCop has accepted.*
- {
- SPAMID=`formail -I ""|grep '/sc?id=' | sed -e 's/.*id=\(.*\)/\1/g'`
- :0 fw
- | ( echo "insert into SPAMCOP_ID(SPAM_ID) values('$SPAMID')" | $MYSQL)
- :0
- /dev/null
- }
- # 數字型收件者,例如 123.txt 等明顯的 SPAM
- :0 HD
- * ^To: .*[0-9][0-9][0-9].*
- {
- :0 fw
- | echo "insert into SPAM(MAIL_FROM,RCPT_TO,SUBJ,FILE_NAME,MAIL_TYPE,USERNAME,REASON,PATTEN ,IP) values('$FROM ','$TO ','$SUBJ ','$FILE',1,'$LOGNAME','發信軟體','數字型收件者','$IP')" | $MYSQL
- :0
- /dev/null
- }
- # From 為 mydomain 但 IP 不屬 mydomain, 檢查使用者是否存在,這個檢查以 /home 下的
- # 目錄為主,不同可自行修改
- :0 HD
- * ^From: .*@mydomain.net.tw.*
- * !^Received: .*111\.172\.21[0-1]\..*
- {
- :0 fw
- | (username=${FROM%%@*};if [ -d /home/$username ] ; then formail -A "Bogus: No"; else formail -A "Bogus: Yes"; echo "insert into SPAM(MAIL_FROM,RCPT_TO,SUBJ,FILE_NAME,MAIL_TYPE,USERNAME,REASON,PATTEN ,IP) values('$FROM ','$TO ','$SUBJ ','$FILE',1,'$LOGNAME','寄件人不存在','$FROM ','$IP')" | $MYSQL ;fi );
- :0
- * ^Bogus: Yes
- /dev/null
- }
- # 簡體信件,不為 cnnic 來源者皆檔,放行 chinaunix
- :0 H
- * ([Gg][Bb][Kk]|[Gg][Bb]2312)
- * !^From: .*(mydomain|cnnic|chinaunix).*
- {
- :0 fw
- | (echo "insert into SPAM(MAIL_FROM,RCPT_TO,SUBJ,FILE_NAME,MAIL_TYPE,USERNAME,REASON,PATTEN,IP ) values('$FROM ','$TO ','$SUBJ ','$FILE',1,'$LOGNAME','簡體信件','GBK/GB2312 編碼','$IP')" | $MYSQL)
- :0
- /dev/null
- }
- # 主旨過濾,這個過濾較費資源,所以排到後面才做
- # 直接以 mysql INSTR 函數做字串比對,比對結果不為 NULL 表示為 SPAM
- # patten2 主要在處理呈現的結果
- # CNT 的加一主要在讓 user 了解什麼主旨的過濾狀況
- :0 HD
- * ! ^From: .*@mydomain.net.tw.*
- {
- patten=`echo "select concat(\"'\",PATTEN,\"'\") from SPAM_PATTEN where USERNAME='$LOGNAME' and instr('$SUBJ',PATTEN)"|$MYSQL | grep -v 'PATTEN'| tr '\n' ','`
- patten2=`echo $patten | sed -e "s/'//g"`
- :0 fw
- * ? test -n "$patten"
- | ( formail -A "Spam: $patten" ; \
- echo "insert into SPAM(MAIL_FROM,RCPT_TO,SUBJ,FILE_NAME,MAIL_TYPE,USERNAME,REASON,PATTEN ,IP) values('$FROM ','$TO ','$SUBJ ','$FILE',1,'$LOGNAME','符合特定字串','$patten2','$IP'); update SPAM_PATTEN set CNT=CNT+1 where USERNAME='$LOGNAME' and PATTEN in ($patten ''); " | $MYSQL ;\
- )
- :0
- * ^Spam: .*
- /dev/null
- }
- # RBL的檢查,雖然可直接於 sendmail 中直接使用 FEATURE(`DNSBL...'),但其退信
- # 不好補救,所以仍採用類似作法,但留存記錄供 user 查看
- # rbl 的 domain 設在 mysql 中,從 mysql 中取出所設的 rbl domain
- # (Ex:bl.spamcop.net), 再加以 dig $PTR.$DOMAIN, 來查詢其黑名單結果
- # 本處所有之三個 RBL, 為經過一個月的實際 100 個以上的 RBL Domain, 在準確度
- # 及誤判率下之最好之結果
- :0
- * ! ^From: .*@(mydomain.net.tw|mydomain.net).*
- * ! ^Received: .*159\.226\.*
- {
- rbl=`for spam in $(echo "select RBL_DOMAIN from SPAM_SOURCE order by SN"| $MYSQL | grep -v 'RBL_DOMAIN'); do rbl=$(host $PTR.$spam| grep 'has address'); test -n "$rbl" && echo $PTR.$spam && break; done`
- :0 fw
- |( test -n "$rbl" && (echo "insert into SPAM(MAIL_FROM,RCPT_TO,SUBJ,FILE_NAME,MAIL_TYPE,USERNAME,REASON,PATTEN,IP ) values('$FROM ','$TO ','$SUBJ ','$FILE',1,'$LOGNAME','來自 RBL IP','$rbl.$spam','$IP')" | $MYSQL) && formail -A "Spam: From_RBL $rbl.$spam" )
- :0
- * ^Spam: .*
- /dev/null
- }
- # 通過以上檢查,則信件進入使用者信箱
- # 但請注意,沒有 100% 的 anti SPAM 效果,也沒有 0% 的失誤率
- # 但據個人使用,結果是令人滿意的
- # 如果要加載 SA 可於後面補上
- #:0fw
- #* < 256000
- #| /usr/local/bin/spamc
- # SA header 動作
- # ...
复制代码
以上還是存在許多可以優化的地方,不過這對我們來說並不重要
結果頁面
一週走勢 uptime 從未過 3 !
[ 本帖最后由 abel 于 2006-2-14 14:59 编辑 ] |
|