影とのたたかい

最近spamが巧妙になってきたのか、bsfilterをくぐりぬけることが増えてきた。 まぁ、gmailのフィルタが相変わらず10割打者なので実用上問題はないが、Thunderbirdで迷惑メールマークを付ける作業が家の前に放置された他人の生ゴミを捨てさせられているような不快感があるので、フィルタの精度を上げてみることにした。

まず、Thunderbirdのメールを保存しているフォルダから、手動でマークした迷惑メールを探す。 メールフォルダ/etc/Junkのようなファイルになっているが、これはmbox形式なのでそのままbsfilterに食わせることができる。このファイルをサーバに転送して、

bsfilter -v -s --mbox Junk

で食わせてみる。 メールの数が常識的ならばこれでいいんだが、数が多いと処理にかなり時間がかかる。 あまりリッチなサーバではないので(つーかDELLの19800円のやつなので…)大きなファイルを読ませると辛い。 gmailの迷惑メールフォルダをそっくり食わせようとしたら、同じサーバで動いているrailsのインスタンスが応答しなくなった。これはマズい。 bsfilterはrubyで書かれているので、そもそもサーバ上で作業する必要はない気がするけど、Macでちょっと試したら予想外に面倒だった(MeCabが動かない…)ので負荷を下げる方向で考える。 まずは小手先の技でniceをいじってみる。

nice -n 20 bsfilter -v -s --mbox Junk

これで優先度は最低になるはず(20が最低、-20が最高)。ちなみに実行中の場合はsuspendするなりもう一枚シェルを立ち上げるなりして、

renice 20 [PID]

で変更できる。 が、最低まで下げても重い。ディスクIOか、あるいはメモリを使い切ってswapしてるのか… どっちにしろ巨大ファイルなのが良くないと思い、分割することに。 csplitを使って

csplit -s -f "Junk" -n 4 Junk '/^From .*/' '{*}'

で分割しようとしたがエラーが出る。え、FreeBSDだと{}使えないの?まじすか。 しょうがないのでgrep -c ‘From:’ Junkとかやって回数を調べ、の代わりに入れる。 が、なぜか分割されないファイルがある。文字コードの問題かなぁ… しゃーないのでmboxを分割するツールを探す。 Mail Export Toolというのが良さそうだったので、これでmboxをeml形式に分割。 さらに100通ずつくらいに結合…とか思ったけどいい加減飽きてきたのでそのままサーバに転送して、

bsfilter -v -s *.eml
bsfilter -u

で一件落着。途中から完全に手段が目的化してましたね。 さて、これで精度が上がっていればいいんだけど。 以後の運用方針は、抜けてきた迷惑メールをすぐさま捨てるのではなく、いったんフォルダに溜めてから週イチくらいでbsfilterに食わせていく予定。 と思ったんだけど、今見てみたらThunderbirdで迷惑メールマークを付けたメールって、見かけ上はそのフォルダから消えるけどmboxファイルには残ってるっぽいな。迷惑メールにするだけじゃなくて削除しないとまずいか。

参考までに、サーバではprocmailを使って

:0 fw
| /usr/local/bin/bsfilter --pipe --insert-flag --insert-probability

としてX-Spam-Flagを挿入し、Thunderbirdのフィルタで処理してます。