昔の日記で書いた気がしたけど、こちらの日記ではまだ書いてなかったので書く。
日々到着するspamメールが厄介なので、何かしらの対策をしたいと思った結果、調べた当時にちょうど出来てきたbsfilterが良さそうだったので、インストールして以来、ずっと使っている。
うちのメール環境はIMAP4で、メールサーバーでもシェルが使えるという便利な環境(自宅サーバーなんだからそうだ)なので、これに沿った話になる。
基本方針。
- sendmail.cfとかprocmailをいじる設定は行わない。昔は行ってたけど、メールが来る度にbsfilterが立ち上がるのが重い上に、多重起動への対応ができないので、以下のポリシーに変更した。
- 10分に1回、INBOXのメールでまだチェックしていないメールをチェックし、spamメールだったら専用のフォルダに移動する。
- どうしても誤認識は出る(特にspamメールをhamと誤認識するのはしょうがない。逆を出さないためにも)。ので、INBOXのメールでspamメールだったものは手動で別のフォルダに移動する。
- 1日1回、3.で移動したメールを、bsfilterに「このメールはspamメールですよ」と再学習させる。
それでは設定を開始しよう。
まずIMAPサーバの設定から。INBOXの下に「0spam」「1clean_to_bsfilter」「1spam_to_bsfilter」というフォルダを作る。
次にbsfilterの設定。ホームディレクトリに.bsfilterというディレクトリを作り、その中で作業する。
bsfilter.conf
imap-server localhost
imap-port 143
imap-user imap-user-name
imap-password imap-user-password
imap-folder-clean INBOX
imap-folder-spam INBOX.0spam
jtokenizer bigram
spam-cutoff 0.2
imap-user-name と imap-user-password はそれぞれ置き換えること。言うまでもないことだが、bsfilter.confにはパスワードが平文で含まれているので、パーミッションは600で。
さて、bsfilterを運用するためには、まずspamメールとhamメールのデータベースが必要になる。何通かspamメールとhamメールを保存しておき、以下のコマンドを実行する。
% bsfilter --add-clean ~/Mail/inbox/*
% bsfilter --add-spam ~/Mail/spam/*
% bsfilter --update
そして、以下のシェルスクリプトを作成する。
#!/bin/sh
BSFILTERHOME=/home/togawa/.bsfilter ; export BSFILTERHOME
SCRIPT_PID="${BSFILTERHOME}/run_script.pid"
if [ -f $SCRIPT_PID ]; then
PID=`cat $SCRIPT_PID `
if (ps -e | awk '{print $1}' | grep $PID >/dev/null); then
exit
fi
fi
echo $$ > $SCRIPT_PID
/usr/local/bin/ruby ${BSFILTERHOME}/bsfilter --imap --imap-fetch-unflagged \
--insert-flag --insert-probability --imap-reset-seen-flag --refer-all-header \
-a inbox
rm $SCRIPT_PID
ざっと説明すると、
- IMAPを使い (–imap)
- 「X-Spam-Flag」ヘッダがないメールを対象に (–imap-fetch-unflagged)
- 見たメールには「X-Spam-Flag」ヘッダをつけ (–insert-flag)
- 見たメールには「X-Spam-Probability」ヘッダをつけ (–insert-probability)
- IMAPの既読フラグをリセットし (–imap-reset-seen-flag)
- 全てのヘッダを判断の対象にし (–refer-all-header)
- データベースを自動で更新する (-a)
- 処理するのはINBOX
の意味。他に必要な設定はさきに書いたbsfilter.confにある。
実行してみて何もエラーが出ないことを確認すること。
このスクリプトを10分に1回呼ぶように、crontabを編集する。
*/10 * * * * /home/togawa/.bsfilter/bsfilter_imap.sh
最後に、1日1回呼び出される「spam/hamの誤認識再学習」用のスクリプトを書く。
BSFILTERHOME=/home/togawa/.bsfilter ; export BSFILTERHOME
/usr/local/bin/ruby ${BSFILTERHOME}/bsfilter -v --imap -s -C -u --refer-all-header INBOX.1spam_to_bsfilter
/usr/local/bin/ruby ${BSFILTERHOME}/bsfilter -v --imap -c -S -u --refer-all-header INBOX.1clean_to_bsfilter
ざっと説明すると
- INBOX.1spam_to_bsfilterのメールはspamだよ。再学習してね。
- INBOX.1clean_to_bsfilterのメールはhamだよ。再学習してね。
これを1日1回呼ぶように、crontabを編集する。
0 4 * * * /home/togawa/.bsfilter/bsfilter_restudy.sh
最後に。何せメールが絡むことなので、運用に入る前には入念なエラーチェックを忘れずに。
(追記)
IMAPサーバ上でシェルやcronが使えなくても、他にシェルやcronが使えるマシンがあれば、そこでbsfilterを動作させればよい。