あまりのスパムメールの多さに業を煮やして、最近話題のSpamAssassin(スパムアサシン)を導入するなり。
SpamAssassinはprocmailから呼び出す例が多いが、使ってみたところprocmailはqmailの仮想メールボックスへの配送ができなさそうだったので、qmailから直にSpamAssassinを使用する事に。2003/12/27
まずはperlのCPANモジュールをinstallする。
[yano@portage software]# perl -MCPAN -e shell
cpan> o conf prerequisites_policy ask
cpan> install LWP MD5
cpan> install HTML::Parser DB_File Net::DNS BerkeleyDB Net::SMTP Mail::SPF::Query IP::Country::Fast Digest::SHA1
http://spamassassin.apache.org/から3.0.1をダウンロードしてinstallする。
[yano@portage software]$ wget http://www.meisei-u.ac.jp/mirror/apache/dist/spamassassin/Mail-SpamAssassin-current.tar.bz2取り敢えず単体でテスト。ゴミ箱からスパムメールを取出して喰わせてみる。
[yano@portage software]$ mv Mail-SpamAssassin-current.tar.bz2 Mail-SpamAssassin-3.0.1.tar.bz2
[yano@portage software]$ bunzip2 -dc Mail-SpamAssassin-3.0.1.tar.bz2 | tar xvf -
[yano@portage software]$ cd Mail-SpamAssassin-3.0.1/
[yano@portage Mail-SpamAssassin-3.0.1]$ perl Makefile.PL PREFIX=/usr/local
What email address or URL should be used in the suspected-spam report
text for users who want more information on your filter installation?
(In particular, ISPs should change this to a local Postmaster contact)
default text: [the administrator of that system] [Enter]
Check network rules during 'make test' (test scripts may fail due to network problems)? (y/n) [n] [Enter]
Checking if your kit is complete...
Looks good
Writing Makefile for Mail::SpamAssassin
Makefile written by ExtUtils::MakeMaker 5.45
[yano@portage Mail-SpamAssassin-3.0.1]$ make
[yano@portage Mail-SpamAssassin-3.0.1]$ sudo make install
$ /usr/local/bin/spamassassin -t < spamtest.txtと、このメールではスパムらしさ10.2ポイントと判定された模様。デフォルトで5.0ポイント以上をスパムと判定するようになっているそうだ。
Spam detection software, running on the system "portage", has
identified this incoming email as possible spam. The original message
has been attached to this so you can view it (if it isn't spam) or block
similar future email. If you have any questions, see
the administrator of that system for details.
Content preview: extlucbvdaztq kuvpqebtvuk mxeuokdavdjbgc tacmetbgjm…
Content analysis details: (10.2 points, 5.0 required)
pts rule name description
---- ---------------------- --------------------------------------------------
1.0 SUBJ_HAS_SPACES Subject contains lots of white space
0.6 PENIS_ENLARGE2 BODY: Information on getting larger penis/breasts
4.3 MONEY_BACK BODY: Money back guarantee
0.1 HTML_70_80 BODY: Message is 70% to 80% HTML
0.1 HTML_FONTCOLOR_RED BODY: HTML font color is red
0.4 HTML_FONT_INVISIBLE BODY: HTML font color is same as background
0.1 HTML_FONTCOLOR_UNKNOWN BODY: HTML font color is unknown to us
0.0 HTML_MESSAGE BODY: HTML included in message
0.1 HTML_FONT_BIG BODY: HTML has a big font
0.3 HTML_TAG_BALANCE_BODY BODY: HTML has unbalanced "body" tags
0.1 HTML_FONTCOLOR_UNSAFE BODY: HTML font color not in safe 6x6x6 palette
3.1 USERPASS URI: URL contains username and (optional) password
0.0 CLICK_BELOW Asks you to click below
このままでは日本語のスパムメールには対応していないので、TLECから日本語スパム対応版の設定ファイルを頂戴し、サイト全般に対応させるべく /etc/mail/spamassassin/local.cf と置き換える。 ついでに題名の"drug"、本文の"アフィリエイト"、"報酬"も条件に追加。HTMLメールとSPAM_COP登録済みのポイントも増やす。全体的に厳しくした分、判定閾値も10.0ポイントに上げておく。2004/01/09
$ cd /etc/mail/spamassassinちなみに日本語の条件を追加する場合、"od -a"の出力から編集する
/etc/mail/spamassassin
$ mv local.cf local.cf.org; chmod -w local.cf.org
$ snarf http://tlec.linux.or.jp/docs/user_prefs local.cf
$ cp local.cf local.tlec; chmod -w local.tlec
$ vi local.cf # ここで編集
$ od -a実際の設定ファイル > http://www.bravotouring.com/~yano/computer/linux/spamassassin.local.cf.txt
報酬
0000000 J s = 7 nl
0000005
$ less /etc/mail/spamassassin/local.cf
# "報酬" -> JIS文字調査方法:od -a
body BODY_HOUSHU /Js=7/
describe BODY_HOUSHU HOUSHU include
score BODY_HOUSHU 3.0
~/.qmail から呼び出すフィルタを作成する。スパムと判定した場合は99を返してqmail-localで配送されないようにする。
#!/bin/sh続いて ~/.qmail を変更。/var/qmail/bin/qmail-spamassassin を呼ぶようにする。
PATH=/usr/bin:/usr/local/bin:/bin
export PATH
bname=`basename $0`
tmpfile=`mktemp /var/tmp/$bname.XXXXXX` || exit 111
trap 'rm -f $tmpfile' 0 1 2 3 5 9 15
/usr/local/bin/spamassassin -e > $tmpfile
case $? in
0)
# not spam. normal operation
exit 0;
;;
*)
case $# in
0)
;;
*)
# forward spammed mail for 1st argument
/var/qmail/bin/qmail-inject $1 < $tmpfile
esac
exit 99; # no more deliver in .qmail
esac
# SPAMは問答無用で捨て(転送する時はアドレスを指定)これでスパムメールを自分宛に送ってみて、spam@bravotouring.comに転送される事を確認。しばらくは受信しといてまとめて捨てる事にしよう。
# /var/qmail/bin/qmail-spamassassin メアド
| /var/qmail/bin/qmail-spamassassin spam@bravotouring.com
# Mailディレクトリの設定
./Maildir/
参照 | |
---|---|
SpamAssassin | http://spamassassin.apache.org/ |
Bug 2855:Simple patch to make spamc return is_spam result http://bugzilla.spamassassin.org/show_bug.cgi?id=2855 | |
TLEC | http://tlec.linux.or.jp/ |
ITmedia エンタープライズ:Linux Tips | http://www.itmedia.co.jp/help/tips/linux/l0679.html |
人生ままならず | http://ssss.jp/~trombik/email/spamassassin.html |
みもりのさんぽう | http://www.mimori.org/~h/diary/d200305b.html |
procmail | http://www.procmail.org/ |
と言ってもバイナリはできているので daemontools 用の起動環境を作るだけ。念の為、実行アカウント:グループもspamd:spamdで新規作成。
## アカウント:グループ作成
# /usr/sbin/groupadd spamd
# /usr/sbin/useradd -c "SpamAssassin Account" -d /dev/null -g spamd -s /bin/false spamd
#
## 起動環境作成
# mkdir /etc/spamassassin
# mkdir /etc/spamassassin/log
#
## それぞれrunファイルを作成する
#
## ログファイル環境作成
# mkdir /var/log/spamassassin
# chown -R spamd:spamd /var/log/spamassassin
#
## superviser管理下に配置(自動起動)
# sudo ln -s /etc/spamassassin /service
spamd のポート番号のデフォルトは 783 だが、敢えて 5783 に変更。
#!/bin/sh
exec env PATH=/usr/local/bin:/usr/bin:/bin \
setuidgid spamd \
spamd -i localhost \
-p 5783 \
--syslog=stderr \
2>&1
#!/bin/sh
exec /usr/local/bin/setuidgid spamd /usr/local/bin/multilog t /var/log/spamassassin
「あとはspamcを呼び出すように/var/qmail/bin/qmail-spamassassinを書換えればお終い」と思いきや、実はspamcは SPAM の検出を終了コードで返さないという事がわかり愕然。しかしさすがは困った時のGoogle先生。ソースをちょこっと読んで変数名を指定して検索するとお見事、先週リリースされたばかりBugzilla Bug 2855を教えてくれたので、早速パッチを適用。(2003/12/27)
これは2.61導入時の話で、最新版の3.0.0ではこの修正が盛り込まれた為パッチ不要。(2004/10/20)
$ cd Mail-SpamAssassin-2.61/spamd
$ snarf "http://bugzilla.spamassassin.org/attachment.cgi?id=1624&action=view" \ ## 続く
SPAMC_RETURN_RESULT.diff
http://bugzilla.spamassassin.org/attachment.cgi?id=1624&action=view (unknown size)
SPAMC_RETURN_RESULT.diff [\] 2K
2546 bytes transferred in 0.01 sec (351.48k/sec)
$ patch < SPAMC_RETURN_RESULT.diff
patching file libspamc.h
patching file spamc.c
$ cd ..
$ make
$ sudo make install
spamassassin を spamc に変更。ホスト名、ポート番号、-E オプションも抜かり無く。 また誤判定の救出を速やかに行う為、スパムとして排除したメール(日本語タイトルのもののみ)の題名と送信者を ~/.spamassassin/spam.log に記録し、~/.bashrcで表示するようにする。
#!/bin/sh
PATH=/usr/bin:/usr/local/bin:/bin
export PATH
logfile=~/.spamassassin/spam.log
# 日本語の題名だけログに記録
function logging {
awk -v result=$1 '
BEGIN { title = sprintf("%s,%s", strftime("%Y/%m/%d %X"), result) }
/^Subject:/ { subject=$0; if(/?iso-2022-jp?/) jp=1;}
/^From:/ { from=$0; }
END { if(jp) printf("%s,%s,%s\n", title, subject, from);}
' $tmpfile \
| nkf -m # MIME decode
}
bname=`basename $0`
tmpfile=`mktemp /var/tmp/$bname.XXXXXX` || exit 111
trap 'rm -f $tmpfile' 0 1 2 3 5 9 15
/usr/local/bin/spamc -d localhost -p 5783 -E > $tmpfile
#/usr/local/bin/spamassassin -e > $tmpfile # コメントアウト
case $? in
0)
# not spam. normal operation
exit 0;
;;
*)
case $# in
0)
;;
*)
# forward spammed mail for 1st argument
/var/qmail/bin/qmail-inject $1 < $tmpfile
esac
if [ $logfile ]; then
logging spam >> $logfile
fi
exit 99; # no more deliver in .qmail
esac
最後にspamd用のポートはlocalhost以外の接続を拒否する設定を 追加。
…
# spamd
-A input -s 127.0.0.1/24 -d 127.0.0.1/24 5783 -p tcp -j ACCEPT
-A input -s 0/0 -d 0/0 5783 -p tcp -j REJECT -l
…
blogwatcher、cron、tcpanalogなど実在しないメールアカウントを宛先にして送られてくるメールも多数ある。しかもほとんどが架空の発信者を偽装しているので、エラーメールもまた "failure notice" としてpostmasterに返って来てしまう。そんな悪循環を断つために前記アドレスをおとりアドレスとして受信してしまい、洗いざらいスパムとして登録する事にした。
収集用のメールボックス spam-learn を新たに作成し、おとりアドレスで受信したメッセージを全て集約する。
$ su pop # DOMAINOWNERアカウントで操作する
$ cd
/home/pop/
$
$ # spam-learnを作成する
$ vida-passwd -a -u spam-learn -p ********
$ vida-assign -a -u spam-learn
$ vida-maildirmake spam-learn Maildir
$ echo ./Maildir/ > ~/spam-learn/.qmail
$
$ cd /var/qmail/alias/
/var/qmail/alias/
$
$ # おとりアドレスをspam-learn(spam-decoy)に関連付ける
$ sudo echo "&spam-learn" > .qmail-spam-decoy
$ sudo ln -s .qmail-spam-decoy .qmail-default # 宛先不明はdefaultで処理される
囮で収集したスパムメールは学習させたあとspam@bravotouring.comに転送する。またSpamAssassinのログをデイリーに分割する時に、囮で収集したスパムの件数を"collected by decoy"としてロギングする。
#!/bin/sh
#
# awkのパス
AWK=/bin/awk
# qmail-injectのパス
QMAIL=/var/qmail/bin/qmail-inject
#
LANG=us;
# イベント抽出対象:昨日
#
TARGET='yesterday'
TARGET_DATE=`date -d "$TARGET" | awk '{printf("%s %2d",$2,$3)}'`;
TARGET_YMD=`date -d "$TARGET" +"%Y-%m-%d"`;
logfolder=~yano/.spamassassin/
dailylog=$logfolder/$TARGET_YMD.log
#======================================================
# 前日分の処理
#======================================================
/usr/local/bin/svc -a /service/spamassassin/log # currentログのローテート
# 前日分のログをデイリーに書き出し
#-----------------------------------------------------
sed -e 's/^@[0-9a-f]* //' /var/log/spamassassin/@* \
| grep ^$TARGET_YMD | sort > $dailylog
chown yano:members $dailylog
# おとりアドレスで収集したSPAMを学習させ、spamへ転送
#-----------------------------------------------------
# ドメインオーナーのアカウント(pop)
DomPopOwner=pop
export HOME=/home/$DomPopOwner
MAILFOLDER=$HOME/spam-learn/Maildir/new
# 転送先
FWD_ADDRESS=spam
# SPAMの学習
setuidgid $DomPopOwner sa-learn --no-rebuild --spam --dir $MAILFOLDER >/dev/null 2>&1
setuidgid $DomPopOwner sa-learn --rebuild >/dev/null 2>&1
# スパム件数として計上されるようログに残す
ls $MAILFOLDER/* | wc | $AWK '{print "'$TARGET_YMD' collected by decoy " $1}' >> $dailylog
# メールを個々にspam@…へ転送
for mailmsg in $MAILFOLDER/* ;
do
# awkでヘッダーの最後に"X-Spam-Flag: YES"を追加して、転送
$AWK '/^$/{if(!ignore)print "X-Spam-Flag: YES";ignore=1;}{print}' $mailmsg \
| $QMAIL -a $FWD_ADDRESS
# 処理したら削除
/bin/rm -f $mailmsg
done
月初からのスパムメール処理件数を日毎に纏めてレポートする。
#!/bin/sh
#
# awkのパス
AWK=/bin/awk
# qmail-injectのパス
QMAIL=/var/qmail/bin/qmail-inject
MAILTO=logwatcher@bravotouring.com
MAILFROM=spamassassin@bravotouring.com
MAILSUBJECT="SpamAssassin report"
# メール送信用出力ファイル
#
outfile=/tmp/$$mail.$RANDOM
#
LANG=us;
# イベント抽出対象:昨日
#
TARGET='yesterday'
TARGET_DATE=`date -d "$TARGET" | awk '{printf("%s %2d",$2,$3)}'`;
TARGET_YMD=`date -d "$TARGET" +"%Y-%m-%d"`;
TARGET_YM=`date -d "$TARGET" +"%Y-%m-"`;
date | awk '{print "'$0' working at " $0}' >> $outfile
#
# SpamAssassinのサマリー抽出 2003/12/29
#
# format:
# 2003-12-29 14:14:18.544718500 connection from portage [127.0.0.1] at port 1902
# 2003-12-29 14:14:19.614265500 processing message <WKWGIVK-0009981715518@croft> for pop:503.
# 2003-12-29 14:14:30.997354500 identified spam (8.6/7.0) for pop:503 in 12.0 seconds, 1978 bytes.
#
logfolder=~yano/.spamassassin/
dailylog=$logfolder/$TARGET_YMD.log
#======================================================
# 前日までのSPAM件数レポートを作成
#======================================================
echo -e "\n# SpamAssassin report at $TARGET_DATE" >> $outfile
echo -e "#---------------------------------------" >> $outfile
echo -e "\n date, total,clean, spam, perscent" >> $outfile
for logfile in $logfolder/$TARGET_YM*.log;
do
$AWK '
BEGIN { total=0; spam=0; clean=0; checking=0; }
/processing message/ { total++; checking=0; }
/checking message/ { checking=1; } # test結果は除外
/clean message/ { if(!checking) clean++; checking=0; }
/identified spam/ { if(!checking) spam++; checking=0; }
/collected by decoy/ { total+=$5; spam+=$5; } # 囮による収集数
{ date = $1 }
END {
printf("%s, ", date);
if (0 < total) printf("%5d,%5d,%5d,%5d%%", total, clean, spam, (spam * 100)/total);
else printf("no mail");
printf("\n");
} ' $logfile >> $outfile
done
#
# メール送信
#
(echo "To: $MAILTO"
echo "From: $MAILFROM"
echo "Subject: $MAILSUBJECT in $TARGET_DATE"
echo ""
cat $outfile )| $QMAIL -f $MAILTO
rm -f $outfile