スパム対策(自動学習)

auto-sa-learn修正

http://d.hatena.ne.jp/kazkun/20071109/1194641443 の続き。
半自動であれ、(内容は変化しないけど)メールをいろいろ処理するので、処理した事を示すヘッダがないと自分的に面倒になるので、auto-sa-learnを修正。

#!/bin/sh

MAILDIR_BASE=~hogeuser/Maildir
MAILDIR_SPAM=.INBOX.SPAM
MAILDIR_FALSENEGATIVE=.INBOX.SPAM\&MGuP\,VKg-
MAILDIR_FALSEPOSITIVE=.INBOX.SPAM\&MFgwgzBqMEQ-

cd $MAILDIR_BASE/$MAILDIR_FALSENEGATIVE/
for path in cur/* ; do
	[ ! -f $path ] && continue
	fname=`basename $path`
	mv cur/${fname} tmp/${fname}_sa-learn
	/usr/bin/sa-learn --spam tmp/${fname}_sa-learn
	# Add header but keep i-node, owner, permission
	cp -p tmp/${fname}_sa-learn tmp/${fname}_tmp
	echo "X-Spam-FalseLearn: FalseNegative learned at `date -R`" > tmp/${fname}_sa-learn
	cat tmp/${fname}_tmp >> tmp/${fname}_sa-learn
	rm tmp/${fname}_tmp
	mv tmp/${fname}_sa-learn $MAILDIR_BASE/$MAILDIR_SPAM/cur/${fname}
done

cd $MAILDIR_BASE/$MAILDIR_FALSEPOSITIVE/
for path in cur/* ; do
	[ ! -f $path ] && continue
	fname=`basename $path`
	mv cur/${fname} tmp/${fname}_sa-learn
	/usr/bin/sa-learn --ham tmp/${fname}_sa-learn
	# Add header but keep i-node, owner, permission
	cp -p tmp/${fname}_sa-learn tmp/${fname}_tmp
	echo "X-Spam-FalseLearn: FalsePositive learned at `date -R`" > tmp/${fname}_sa-learn
	cat tmp/${fname}_tmp >> tmp/${fname}_sa-learn
	rm tmp/${fname}_tmp
	mv tmp/${fname}_sa-learn $MAILDIR_BASE/cur/${fname}
done

Maildirに突っ込まれたメールは、i-node番号をファイル名の一部に使っていたりするので、(本当は意味ないんだろうけど気持ち的に)i-nodeとかを変えずに処理させる。(cpしてechoしてcatしてrmしてるところ)
まぁこれでファイルのOwnerとかパーミッションとかを気にしなくても元のファイルのものが保持されるようなので、自分的に良しとする。
こうすることで「X-Spam-FalseLearn」ヘッダが追加され、IMAPでFalse-PositiveやらFalse-Negativeやらを振り分けた作業を元にBeckyとかで自動振り分けすることができる。(今までは二度手間だった)

procmailレシピ作成

とりあえず、ということで、SquirrelMailでメールフィルタを書いて、SPAMを振り分けてからBeckyで処理していたが、当然に面倒、そして人間、忘れてしまい、「SPAMが取りこぼされてる〜」と本当はSPAM認定されているメールをFalse-Negative登録してしまう事になる(実話)。
ということで、そのうちやろうと思っていたprocmailのレシピ作成。
実のところ、このサーバでprocmailをはじめて使う。まぁサーバを新規復旧して一ヶ月もたっていないので当然なのだが、その昔qmailマンセーだった自分にとっては.forwardとか馴染みが薄くて、ちょっと焦る。
で、.procmail

SHELL=/bin/sh
PATH=/usr/local/bin:/usr/bin:/bin
MAILDIR=$HOME/Maildir
DEFAULT=$MAILDIR/
LOGFILE=$MAILDIR/procmail.log
SPAMDIR=.INBOX.SPAM

:0H:
* ! ^X-Spam-FalseLearn:
* ^X-Spam-Flag: YES
$SPAMDIR/

で、.forward

"|IFS=' ' && exec /usr/bin/procmail -f- || exit 75"

.forwardは安直にviとかするんじゃなくて、dotforwardとかでまず作成して、chmod/chown(必要なら)してからmvしましょうね。メールを失いかねません。
あと、なぜか

"|IFS=' ' && exec /usr/bin/procmail -f- || exit 75 #hogeuser"

とするように書いてあるサイトが多いのだが、なぜ?(もしかして何か忘れてる?)*1

はじめ、.procmailにDEFAULTがなくて、/var/mail/hogeuserとかにメールを書きに行ってしまってびっくり。Maildirがらみのノウハウがあまりネット上にも蓄積されてない気がする。

あとはSPAMフォルダのメール自動削除かなぁ。cronでfindとかすれば簡単だよな〜。

*1:2007/12/22注記:.forwardの実行がログに出るんでどのユーザの処理かというのが判って便利、という事っぽい