2003年07月02日

bogofilter(2)

これの続き

さて、実際の使い方ですが、まずbogofilterにどういうメールがspamでどういうメールは普通のメールかを教えてあげなければなりません。

で、どのメールを覚えさせるかですが自分の所に来たspamを律儀に取っている人は、それをbogofilterに食わせてあげればよいです。

具体的にはメールソフトのエクスポート機能を利用してメールを取り出してそれをFTPかなにかでbogofilterの入って居るサーバにアップロードして、それをbogofilterに覚えさせます。

たとえば、アウトルックエクスプレス系だとエクスポートは受信箱などからデスクトップなどにドラッグ&ドロップでできるので、spamメールを片っ端からエクスポートしてそれをアルファベットの名前にリネームしてから(漢字コードについてちゃんとわかっている人はそのままでも良いですが)FTPなどで送ればできます。

まとまった数がアップロードできたら、今度はtelnetなどから次のコマンドを撃てば登録できます。

cat *.eml | nkf -Zme | kakasi -w | bogofilter -s

また、spamメールなんて片っ端からゴミ箱送りにしている人は

辺りからspamを拾って登録しておきましょう。

そして必ず、普通のメールも同様の方法で登録させてください。

cat *.eml | nkf -Zme | kakasi -w | bogofilter -n

コレで、最低限運用開始はできるようになりました。
ただ、spamも普通のメールもある程度多くないといけないので注意してください。
(普通のメールはあるだけ全部。spamはその5分の1ぐらいもあれば十分だと思います)

さて、運用開始ですが、やっぱりprocmailを使うのが楽だと思います。
procmailについてはここではやりませんが、私が使っているprocmailの定義ファイルは下のような感じです。

SHELL=/bin/sh
PATH=/bin:/usr/bin:/usr/local/bin:
LOCKFILE=$HOME/.lockmail
LOGFILE=$HOME/procmail.log
DEFAULT=/var/mail/ユーザ名

:0cw
|nkf -Zme | kakasi -w | bogofilter -v | $HOME/bin/pnterr

:0 HB
* ? nkf -Zme | kakasi -w | bogofilter -u
{
:0fw
|nkf -Zme
:0
$HOME/spam/.
}

ちなみに8行目で使っているpnterrというのはbogofilterによるspam判定結果の標準出力を標準入力で取り込んでそのまま標準エラーにリダイレクトする自作のCプログラムです
↓こんな感じ

#include 
#include // calloc用
#define dfBuffLen 256 // 領域幅

/* メイン関数 */
int main(int argc, char *argv[]){
char *carr = (char *)calloc(dfBuffLen,sizeof(char));

while(fread(carr,sizeof(char),dfBuffLen,stdin) > 0){
fprintf(stderr,"%s",carr);
}

free(carr);
return(0);
}

なんでわざわざ標準エラーにしているかと言うと、procmailのlogが標準エラーしか記録してくれないからです。
(標準出力結果を記録してくれる方法があるのかもしれないけど知らないし)

あとサイトによっては

:0fw
| bogofilter -e -p

と書いてあるところがありますが、これは英語版か上で取り上げたkakasiパッチを当てたものでないと使えません。
「:0fw」の「f」はメールに対して行った処理をすべて反映して次の処理に渡す(つまり最終的にはその結果がメールとしてメールボックスに届く)ので、kakasiパッチを入れてあればメールのヘッダに

X-Bogosity: Yes, tests=bogofilter, spamicity=1.000000, version=0.13.7

といった形式でspam判定結果が記録されるのですが、kakasiをパイプ渡しで用いると、処理の段階で日本語が分かち書きになるので、最終的にぶつぶつと日本語が細切れになったメールが自分のメールボックスに届くことになります(笑)

あと7行目の「:0cw」は「c」でメールのコピーを作成して「w」でbogofilterの処理が終わるのを待ちます。
「w」をつけないとログでのbogofilterの結果がどこに入るか分からなくなるので必ず必要なんですが、もしかしたら「c」に関しては要らないかもしれません。
(念のためにつけているだけですし)

そして11行目で実際にspamかどうか判定をしつつ-uオプションで辞書に結果を登録しています。
(上のやつと一緒にできそうな気もしますが、やると-uのログも残ってしまうので分けました)

で、ここでspamと判定されたメールはログで見やすくするために14行目でタイトルのエンコードを解除したあとに16行目で$HOME/spam/の下にMH方式(1からの連番のファイル名でメールを1通ずつ)保存します。

で、これをやるとprocmailのログには次のようなログが残ります。

X-Bogosity: Yes, tests=bogofilter, spamicity=1.000000, version=0.13.7
From *************@i.ew01.com Wed Jul 2 15:51:
17 2003
Subject: Cash Out and Reduce Your Mortgage Payments
Folder: /home/ユーザ名/spam/50 4239

最初のうちは(・∀・)ニヤニヤしながらこのログをみて、誤爆がないか確認した方がいいかと思います。

ちなみに、うちでは運用2週間目ぐらいですが誤爆はまだ無し。
見逃しは日本語spamが2通となっています。

あと、無料サービスを使うと強制的に送ってくるメルマガもspamとして何通か登録しておいたらそれらもすべてspamと判定してくれて現在非常に快適に使用しています( ̄▽ ̄)ノ

Posted by Takuchan at 2003年07月02日 02:05 | トラックバック(0)

pnterrってわざわざ作るんじゃなくて、>&2で標準出力にリダイレクトするのはだめ?
条件文ですが、
* ? nkf -Zme | kakasi -w | bogofilter -v >&2
でちゃんとログ残ってます。

Posted by: R/Star at 2004年05月15日 02:47

ありゃ、その手でいけますな。
思いつきませんでした(^^;

Posted by: Takuchan at 2004年05月15日 14:13