2009/09/29

2009-09-29:postfix+bsfilter で spam 排除

ユーザーサイド(?)で procmail+bsfilter での spam よけを自分自身のアカウントではやっていたんだけど、最近、同じサーバの fml でやってる ML 宛に支那から spam が定期的に来てうざいので、サーバサイド(言い方ただしいんだろか)で撥ねることにした。

ロジックは
  postfix がメールを pipe で bsfilter に渡す
  → bsfilter が X-Spam-Flag: {Yes|No} をつけて postfix に投げる
  → postfix が header_checks でフラグを見て通しか廃棄かする
という形。

サーバは debian lenny つかっている。
bsfilter は自分はすでに入れていたのだけど、まだの人(と将来のサーバ再セットアップする私)向けにメモを整備。
まずは bsfilter 自体の環境作り。

% sudo groupadd -g 115 bsfilter
% sudo useradd -u 115 -g bsfilter bsfilter
% sudo mkdir /var/lib/bsfilter
% sudo chown -R bsfilter.bsfilter /var/lib/bsfilter
% sudo vipw
% grep bsfilter /etc/passwd
bsfilter:x:115:115::/var/lib/bsfilter:/bin/false
% sudo -u bsfilter vi /var/lib/bsfilter/bsfilter.conf
% cat /var/lib/bsfilter/bsfilter.conf
homedir /var/lib/bsfilter
jtokenizer kakasi
pipe
insert-flag
insert-probability

postfix 用のフィルタは以下。

% sudo -u bsfilter vi /var/lib/bsfilter/postfix_bsfilter.sh
% cat /var/lib/bsfilter/postfix_bsfilter.sh
#!/bin/sh
HOME="/var/lib/bsfilter"
FILTER="/usr/bin/bsfilter"
CONF="/var/lib/bsfilter/bsfilter.conf"
SENDMAIL="/usr/sbin/sendmail -i"
cat | $FILTER --config-file $CONF --auto-update | $SENDMAIL "$@"
exit $?
% sudo chmod +x /var/lib/bsfilter/postfix_bsfilter.sh

続けて、postfix が bsfilter へパイプする設定。master.cf を編集する。
変更部分だけ抜粋。

% sudo vi /etc/postfix/master.cf
% tail -n5 /etc/postfix/master.cf
smtp      inet  n       -       -       -       -       smtpd -o content_filter=filter:dummy
# anti spam filter
filter    unix  -       n       n       -       -       pipe
  flags=Rq user=bsfilter argv=/var/lib/bsfilter/postfix_bsfilter.sh -f ${sender} -- ${recipient}

最後に、ヘッダを見てメールを撥ねる postfix の header_checks の設定。

% sudo vi /etc/postfix/main.cf
% tail -n1 /etc/postfix/main.cf
header_check = regexp:/etc/postfix/header_checks

% sudo vi /etc/postfix/header_checks
% cat /etc/postfix/header_checks
/^X-Spam-Flag: Yes/ REJECT sorry

header_checks ファイルの REJECT のところ、最初は WARN にして様子を見るのが吉。WARN はログに残したうえで、撥ねずに通す設定。false-positive もあるかもしれないからね。
設定値については man 5 header_checks しましょう。

最後に postfix を再起動して、おしまい。

—-

以上で設定終了なんだけど、上記をまとめるまでにぐぐって調べていたら、罠があったので注意書き。
世のサイトには「header_checks ファイルを書いたら postmap しろ」と書かれていることがある。これ、「正規表現でのレシピを書いている場合はやらないこと」なのだ。
もし、考えずに盲目的に postmap してしまうと、

warning: /etc/postfix/header_checks, line 1: record is in “key: value” format; is this an alias file?

といったオコられ方をする。
もし、やってしまった場合は、/etc/postfix/header_checks.db ファイルを削除してから postfix を再起動すればよい。