%%Title: bogofilterを使ってみる

%%Created: Fri May 23 10:33:12 JST 2003
%%Updated: Fri Mar 12 11:17:43 JST 2004

spamassassinがあまりにも遅いので bogofilterを導入してみる。

  • bogofilter って何?
  • 使い方
  • bogofilter 0.11.2 と spamassassin 2.53 の処理速度の比較
  • spamassassinと組み合わせる
  • spamのチェックをスプールに落ちる前にやる
  • spamのチェックをメールボックスに落ちた後にする
  • 改定: spamのチェックをメールボックスに落ちた後にする
  • bogoupgrade が動かないような気がする…
    o bogofilter って何? C言語で書かれたspamフィルタ http://bogofilter.sourceforge.net/ Bayes' Theoremをspamフィルタに応用している。 メールに含まれているtokenに点数を付けてspamかnon-spamかを判断する。 o 使い方 インストールしただけではデータベースがないので全てのメールをnon-spamと判断してしまう。 spam/non-spamメールを bogofilterに喰わせてデータベースを作る。 % bogofilter -svI spam-mail % bogofilter -nvI non-spam-mail 沢山喰わせた方が精度が上がる。 http://www.spamarchive.org/から拾って来るのが早いかもしれない。 spamかそうでないかをチェックするには、こうする。 % bogofilter -vI mail 例えば、 % bogofilter -vI 25 X-Bogosity: Yes, tests=bogofilter, spamicity=1.000000, version=0.11.2 Yes なので、これは spamメールとして判断された。 % bogofilter -vI 608 X-Bogosity: No, tests=bogofilter, spamicity=0.536896, version=0.11.2 これは No なので non-spamメールである。 spamなのに non-spamとして判断されたら -svI で登録する。 何回も登録すると点数が上がるので次回spamとして判断される確立があがる。 spamじゃないのにspamと判断されたらこうやって点数を下げる。 % bogofilter -SnI non-spam-mail 面倒くさい人は、僕のデータベースを勝手に使って下さい。ただし何が起きても知りません。 人によってspamかnon-spamかの基準が違うのでチューニングが必要です。 20030525現在の spamlist.db 20040709現在の wordlist.db o spamassassinと組み合わせる bogofilter導入初期にデータベースを作るために spamassassinで spamと判断されたメールを bogofilterに喰わせていく方法が考えられる。 o bogofilter 0.11.2 と spamassassin 2.53 の処理速度の比較 ThinkPad X20 (P3-600MHz) 上で 1711バイトの spamメールを喰わせてみる。 % cat 306 | /usr/bin/time -p bogofilter > /dev/null real 0.01 user 0.00 sys 0.00 % cat 306 | /usr/bin/time -p spamassassin > /dev/null real 4.26 user 2.26 sys 0.15 % cat 306 | /usr/bin/time -p spamassassin -L > /dev/null real 2.33 user 2.18 sys 0.13 なんだか良く分からないので、1000通のspamメールを喰わせてみる。 bogofilter real 17.66 user 10.57 sys 6.90 spamassassin real 601.75 user 4.59 sys 5.46 ※ spamassassin は spamc/spamd の組合せで -L オプション付き。 o spamのチェックをスプールに落ちる前にやる procmail(8) + bogofilter(1)の組合せを使ってる人が多いけど、 bogofilter(1)けでやってみる。 スクリプトはここのspamcheckerですが使用は自己責任でお願いします。 仕組みは sendmail(8)がメールを受け取る。 .forwardでspamチェックをする。 spamと判断されたらspam用メールボックスに落す。 hamならmail.local(8)を使ってユーザのスプールに落す。 % cat .forward "| /home/sakane/bin/spamcheck sakane mbox.spam" なお mail.local(8)に uidビットを立てないと動きません。 # chmod u+s /usr/libexec/mail.local spam用メールボックスに落ちたメールのSubject:のリストを 1日1回ユーザにメールするために crontabを編集する。 % crontab -e 5 7 * * * /home/sakane/bin/spamreport sakane /home/sakane/mbox.spam o spamのチェックをメールボックスに落ちた後にする 特定のキーワードが含まれていたら spam/non-spam と判断させる 例えば、Subject: に「未承諾広告※」が含まれていたら spamの点数を猛烈にあげるには以下の1行だけを含むファイルを bogofilterに食わせて点数をあげればよい。 % cat hoge Subject: =?ISO-2022-JP?B?GyRCTCQ+NUJ6OS05cCIoGyhCCg==?= % bogofilter -vI hoge X-Bogosity: No, tests=bogofilter, spamicity=0.001379, version=0.13.6 % bogofilter -svI hoge # 3 words, 1 message % bogofilter -vI hoge X-Bogosity: Yes, tests=bogofilter, spamicity=0.999777, version=0.13.6 メールには他のキーワードも含まれているので実際は点数が下がってしまう。 その場合は上の操作を適当な回数繰り返す。 % bogofilter -vI 9455 X-Bogosity: No, tests=bogofilter, spamicity=0.490193, version=0.13.6 ※ 9455は Subject:に「未承諾広告※」を含む spamメール o 改定: spamのチェックをメールボックスに落ちた後にする 既出の方法では満足する効果を得られなかったので、 やっぱり bogofilterに喰わせる前に単純パターンマッチをする。 特にマルチバイト文字に効果がある。 スクリプトはここのspamcheckerに入ってるspammgr。 Usage: spammgr -c [-f folder] [-b begin,end] [-l list [-a]] [-e file] [-g] [-QD] spammgr -s -f folder [-b begin,end] [-DQ] spammgr -n -f folder [-b begin,end] [-l list] [-DQ] == commands == -c: check mails are spam or not -s: add mails to the spamlist of "bogofilter" -n: add mails to the non-spamlist of "bogofilter" == options == -f: specify a folder -b: make spamlist process mails between the numbers specified. -l: specify the file name to which spamlist outputs or remove the number of the spam mails. -a: append the number of the spam mails to the file specified by the option -o. -e: specify the file name to which spamlist outputs the number of the mail processed. -g: evaluate spam patterns by perl-grep. -Q: quiet mode. -D: debug mode. Aliasは便利なエイリアスを記述しておいた spampick Mail/Inbox にあるメールをチェックして Mail/.spam.listに spamリストと Mail/.spam.lastに最後の番号を保存する。 spammv Mail/.spam.listにリストされたメールを Mail/spam に移動する。 spamrm Mail/.spam.listにリストされたメールを Mail/Inboxから削除する spamout (number) 指定したメールを Mail/.spam.listから削除するとともに、bogofilter -nI (number) を実行する。 o bogoupgrade が動かないような気がする… 少なくとも 0.17.2 から、辞書は wordlist.dbに集約されてるので、 spamlist.dbとgoodlist.dbを使ってる人は wordlist.dbに移行しなきゃ いけない。 と言う作業を bogoupgrade(1)がやってくれるらしいのだがどうもうまく動かない。 やってる事は bogoutil(1)で単語と点数を引っ張りす。 spamとham用に整形する。 wordlist.dbに突っ込む。 コードをじっくり眺める時間がなかったので書く。 $home = "$ENV{'HOME'}/.bogofilter"; sub cvt2to1_get($$) { my ($filename, $format) = @_; my @tmp; open(IN, "/usr/local/bin/bogoutil -d $filename |"); while () { chomp; @a = split; push @tmp, sprintf($format, $a[0], $a[1], $a[2]); } close(IN); return @tmp; } push @list, cvt2to1_get("$home/spamlist.db", "%s %d 0 %d\n"); push @list, cvt2to1_get("$home/goodlist.db", "%s 0 %d %d\n"); open(OUT, "| /usr/local/bin/bogoutil -l $home/wordlist.db"); foreach (@list) { print OUT $_; } close(OUT);