2009/09/17

bsfilter を仕込む

メールサーバが稼働したのですが、家族にも使わせるので、スパムフィルタを仕込もうと思ったのです。

スパムフィルタには様々ありますね。

POPFile
SpamAssassin
bogofilter

あたりがメジャーどころでしょうか。
# ベイジアンフィルタしかないやんけ、とか言わないように

色々調べてみた結果、bsfilter を使うことに決めました。

本当は、SpamAssassin を使おうかと思っていたのですけれど。
bogofilter も、C で書かれていて軽い、と言う点で魅力的だったのですけれど。
bsfilter は、独自に日本語に対応している、と言う点で日本人が使うならこれが良さそうだ、と判断しました。
ryby スクリプトなので、重さが気になるんですけどね。
# それを言ったら SpamAssassin は Perl じゃないか、とか言われそう


bsfilter 単体では、うまく日本語の文章から単語を切り出すことが出来ません。
なので、外部の形態素解析器を使います。
形態素解析器というのは、日本語の文章の中から、単語分けして切り出してくれるものだと思っといて下さい。
というか、bsfilter は、そう言う目的でしか使ってません。

使用できる形態素解析器は3つ。
和布蕪 (めかぶ)
茶筅 (ちゃせん)
案山子 (かかし)

今回は、和布蕪を使うことにしました。
本当は茶筅を使おうとしたのですけれど、調べたら和布蕪の方が良さそうだったので。
和布蕪は、茶筅がベースで、精度はほぼ同等、速度は倍以上、と言うことだそうです。

と言うわけで、追加インストールするのは、
mail/bsfilter: bsfilter 本体
japanese/ja-mecab: 和布蕪本体
japanese/ja-ruby-mecab: 和布蕪の Ruby バインディング
japanese/ja-mecab-ipadic: 和布蕪の辞書
となります。

bsfilter を ports からインストールすると、オプション選択で和布蕪と茶筅と案山子とを選ぶことが出来ます。
ここで和布蕪にチェックを入れておけば、和布蕪と Ruby バインディングは、依存で入ります。
ただし。
和布蕪の辞書は入れてくれないので、これだけは自分で入れる必要があります。
入れ忘れると、bsfilter 実行時に、「辞書がない!」 って怒られちゃいます。

さて。

bsfilter は、データディレクトリとして、$HOME/.bsfilter を使います。
設定も、ここに用意してやります。
内容はこんな感じ。

$HOME/.bsfilter/bsfilter.conf
jtokenizer mecab
insert-flag
insert-probability
auto-update

これで、
形態素解析器として和布蕪を指定
X-Spam-Flag: ヘッダを追加
X-Spam-Probability: ヘッダを追加
自動データベース更新
を指定したことになります。

あとは、データベースの用意です。
手元に、今まで受信した 7,000 通あまりの spam と、1,000 通あまりのメールがあるので、これを使います。

通常は、

bsfilter -c ~/Maildir/cur/*
bsfilter -s ~/Maildir/spam/cur/*

ってやって下さい、って言うところなんですが。。。
spam が 7,000 通あまりもあると、Argument too long! って言われちゃいまして (^”^;;;
仕方がないので、bsfilter に IMAP で読みに行ってもらいました。

bsfilter --imap --imap-server サーバ名 --imap-user ユーザ名 --imap-password パスワード -s inbox.spam

すんごく時間掛かりました。
どこにもログ更新などはされないので、思わず

tcpdump -i lo0 port imap

して見ちゃいました (笑)

クリーンメールもデータベースに突っ込んで。
で、データベース更新。

bsfilter -u

しばらく待っていれば、データベースができあがります。
あとは使うように設定するだけ。

一応、システム全体でこれを有効にするのは怖いので、各ユーザごとに使うようにしました。
ので、.forward で指定するわけだ。
んが、フィルタしてヘッダ付けて貰うだけ、って言うのをシンプルにやる方法が思いつかなかったので。
将来的に、自動振り分けも視野に入れて、procmail 使いました。

そんなわけで、.forward は、こんな感じ。

~/.forward
"| IFS=' ' && pmprog=/usr/local/bin/procmail && test -f $pmprog && exec $pmprog -Yf- .procmailrc.tamon || exit 75 #ユーザ名



レシピは、こんな感じ。

~/.procmailrc

PATH=$HOME/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
MAILDIR=$HOME/Maildir
DEFAULT=$MAILDIR/
LOGFILE=$HOME/log/procmail.log
LOCKFILE=$HOME/.lockmail

:0 fw
| bsfilter --pipe

まさに、フィルタ処理してるだけ (笑)
procmail にしてみれば、役不足でしょう。
フォルダ自動振り分けレシピを書く気力がないので、この辺 SeaMonkey に任せっぱなしです。


今のところ、全ユーザで有効にするので、全ユーザでこの処理をやります。
設定ファイルなんかはコピーですが、データベースだけは怖いので、正規の手順通りに。

 bsfilter --export-clean > clean.list.txt
 bsfilter --export-spam > spam.list.txt

して、各ユーザごとに

 bsfilter --import-clean > clean.list.txt
 bsfilter --import-spam > spam.list.txt
 bsfilter -u

を実行。

今のところ、すり抜けはあっても誤認はないので、他のユーザの奴は、spam 判定されたら spam フォルダへ振り分けました。
レシピは、こんな感じ。

 ~/.procmailrc
  PATH=$HOME/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
  MAILDIR=$HOME/Maildir
  DEFAULT=$MAILDIR/
  LOGFILE=$HOME/log/procmail.log
  LOCKFILE=$HOME/.lockmail
  
  :0 fw
  | bsfilter --pipe
  
  :0 H
  * ^X-Spam-Flag: Yes
  $MAILDIR/.spam/


さて。

誤認されたら、再学習させなきゃいけません。
で、使用説明書には、

 bsfilter -S -c -u clean_mail
 bsfilter -C -s -u spam_mail

しなさい、とか書いてあるわけだ。
しょうがないので、メールの中身だけ転送すればいいように、拡張アドレスでちょこっとやりました。
# spam のヘッダなんか、偽装されてるかなんかで、まともな情報ないだろ、って言ういい加減な考え

 ~/.procmailrc.toclean
  :0 fw
  | bsfilter -S -c -u --pipe
  
  :0
  /dev/null

 ~/.procmailrc.tospam
  :0 fw
  | bsfilter -C -s -u --pipe
  
  :0
  /dev/null

何やってんだおまえ、って言われそうです (^”^;;;
まぁ、これで乗り切っていくことにしてみますよ。


次は、AntiVirus スキャナか・・・

0 件のコメント:

コメントを投稿