up_l dmy up_r
dmy home dmy dmy dmy

●postfixのスパムメール対策●
(2007/2/3更新)

昨年の4月から「阻止率99%のスパム対策方式の研究報告」(以下S25R方式)さんを参考にしたものと、
Postfixが持つ制限機能を組み合わせたスパムメール対策を行っておりましたが、非スパムなメールがREJECTされてしまうことあったり、
これでもすり抜けてくるスパムメールがあったりと、なにかと落ち着かない日々が続いておりました。(;´Д`)

» 非スパムメールのREJECTを限りなく0にする
» 配送されたスパムメールは隔離する
» 隔離されたスパムメールの中に非スパムメールが混在していないか確認できるようにする
» 隔離されたスパムメールを容易に削除できるようにする

これらの条件を満たすべく、いろいろ調べてたどり着いたスパムメール対策が下記の方法です。

» Postfixが持つ制限機能の利用(但しあまり厳しくしない)
» 「S25R方式」を参考にした制限
» ベイジアンスパムフィルタ「bsfilter」の導入
» Postfixの「reject_rbl_client」「reject_rhsbl_sender」を使用しない(procmailから使用)DNSBL、URLBLの導入

※「reject_rbl_client」「reject_rhsbl_sender」を使用すると、DNSBL、URLBLに該当した場合にREJECTされてしまい、
非スパムなメールの救済が難しくなる為、今回は使用しないことにしました。

■Postfixが持つ制限機能、「S25R方式」を参考にした制限の利用

●Postfixが持つ制限機能の利用
ルール1:SMTPセッションの最初にHELO(EHLO)コマンドを送信してこない場合は要求を拒否する。
ルール2:HELO(EHLO)パラメータ内のホスト名の文法が間違っている場合は要求を拒否する。
ルール3:MAIL FROMパラメータ内のメールアドレスのホスト名がDNS AまたはMXレコードを持っていない場合は要求を拒否する。
ルール4:MAIL FROMパラメータ内のメールアドレスのホスト名がFQDN形式ではない場合は要求を拒否する。
ルール5:MAIL FROMパラメータ内のメールアドレスがバウンスしたり配送先に到達できない場合は要求を拒否する。

「S25R方式」を参考にした制限
ルール6:逆引きFQDNの最下位のホスト名にハイフン(-)で2つ以上に区切られた1〜3桁の数字が含まれる場合は要求を拒否する。
ルール7:逆引きFQDNの最下位のホスト名にドット(.)で2つ以上に区切られた1〜3桁の数字が含まれる場合は要求を拒否する。
ルール8:逆引きFQDNの最下位のホスト名に連続した4つ以上の数字が含まれる場合は要求を拒否する。
ルール9:逆引きFQDNの最下位のホスト名に「dhcp、dial、ppp、dsl、flets、ftth、cable」が含まれる場合は要求を拒否する。

●/etc/postfix/client_restrictionsの作成
> vi /etc/postfix/client_restrictions

------------------------------------------------------------------------------
# *** WHITE LIST ***
/^192\.168\.1\.2$/                                              OK

# *** BLACK LIST ***
#
/^219\.117\.232\.107$/                                          REJECT
/^59\.106\.20\.223$/                                            REJECT
/^124\.37\.15\.8$/                                              REJECT
/^ns1\.mdhfc\.com$/                                             REJECT

# *** GENERIC PROTECTION ***
# [rule 1]
/^[^.]*.*[0-9]{1,3}-[0-9]{1,3}.*\..+\.[a-z]/                   450 may not be mail exchanger
# [rule 2]
/^[^.]*.*[0-9]{1,3}\.[0-9]{1,3}.*\..+\.[a-z]/                  450 may not be mail exchanger
# [rule 3]
/^[^.]*.*[0-9]{4}.*\..+\.[a-z]/                                450 may not be mail exchanger
# [rule 4]
/^[^.]*.*(dhcp|dial|ppp|dsl|flets|ftth|cable).*\..+\.[a-z]/    450 may not be mail exchanger
------------------------------------------------------------------------------

●/etc/postfix/main.cfの編集

> vi /etc/postfix/main.cf
------------------------------------------------------------------------------
smtpd_client_restrictions =                                          #SMTPコネクション時の制限
        permit_mynetworks                                            #自ネットワークは無条件で許可
        check_client_access btree:/etc/mail/dracd                    #POP3認証を通ったIPは許可
        check_client_access regexp:/etc/postfix/client_restrictions  #ルール6〜9に該当するものは拒否
        reject_unlisted_recipient                                    #宛先不明なアドレスへの配送要求は拒否
        reject_unauth_destination                                    #自ネットワーク以外への配送要求は拒否

smtpd_helo_required = yes                                            #ルール1に該当するものは拒否(HELOコマンドを必須に)

smtpd_helo_restrictions =                                            #HELOコマンド時の制限
        permit_mynetworks                                            #自ネットワークは無条件で許可
        reject_invalid_hostname                                      #ルール2に該当するものは拒否
        permit                                                       #上記に該当しないものは許可

smtpd_sender_restrictions =                                          #MAIL FROMコマンド時の制限
        reject_unknown_sender_domain                                 #ルール3に該当するものは拒否
        reject_non_fqdn_sender                                       #ルール4に該当するものは拒否
        reject_unverified_sender                                     #ルール5に該当するものは拒否
------------------------------------------------------------------------------
※編集が終わったらpostfix reloadを実行します。
※参考までに当方の現在のmain.cfです。

■ベイジアンスパムフィルタ「bsfilter」の導入

bsfilterのインストール
> apt-get install bsfilter

●作業ディレクトリの作成
> mkdir /var/lib/bsfilter
> chmod 755 /var/lib/bsfilter

●bsfilter.confの作成
> vi /etc/bsfilter.conf

------------------------------------------------------------------------------
homedir /var/lib/bsfilter         #作業ディレクトリ
insert-revision                   #メールのヘッダに「X-Spam-Revision」を追加
insert-flag                       #メールのヘッダに「X-Spam-Flag」を追加
insert-probability                #メールのヘッダに「X-Spam-Probability」を追加
auto-update                       #cleanかspamか判定した後、その結果をtokenデータベースに追加し確率データベースも更新
pipe                              #標準出力する(procmail用)
------------------------------------------------------------------------------

http://www.db.is.kyushu-u.ac.jp/computer/solarisserver/bs.spamからスパムメールを頂いてくる
> wget http://www.db.is.kyushu-u.ac.jp/computer/solarisserver/bs.spam

●頂いてきたスパムメールを学習させる
> bsfilter --config-file /etc/bsfilter.conf --import-spam ./bs.spam

●クリーンなメールを学習させる
> bsfilter --config-file /etc/bsfilter.conf --mbox --add-clean ./***.mbx
※普段使っているメーラーがmbox形式だったのでそれを全部入れてみました。

●sdbmを更新
> bsfilter --update --config-file /etc/bsfilter.conf

●オーナーの関係でデータベースが読み込みできなかったのでパーミッションを変更
> chmod 666 /var/lib/bsfilter/*

●スパムと認識されたクリーンなメールを学習させるスクリプトを作成
> vi /usr/local/bin/bsfilter-clean.sh

------------------------------------------------------------------------------
#!/bin/sh

FILE=$1

if [ -n "$1" ]; then
    bsfilter --homedir /var/lib/bsfilter --sub-spam --add-clean --update ${FILE}
    chmod 666 /var/lib/bsfilter/*
fi
------------------------------------------------------------------------------
> chmod 700 /usr/local/bin/bsfilter-clean.sh

※使い方:/usr/local/bin/bsfilter-clean.sh クリーンなメール

●クリーンと認識されたスパムなメールを学習させるスクリプトを作成 > vi /usr/local/bin/bsfilter-spam.sh

------------------------------------------------------------------------------
#!/bin/sh

FILE=$1

if [ -n "$1" ]; then
    bsfilter --homedir /var/lib/bsfilter --sub-clean --add-spam --update ${FILE}
    chmod 666 /var/lib/bsfilter/*
fi
------------------------------------------------------------------------------
> chmod 700 /usr/local/bin/bsfilter-spam.sh

※使い方:/usr/local/bin/bsfilter-clean.sh スパムなメール

■procmailから使用するDNSBL、URLBLチェックスクリプトの導入
※今回は自分でprocdnsblというスクリプトを作成しました。
procdnsblはDNSBL、URLBLに該当した場合にメールヘッダーにX-DnsBL、X-UrlBLを付与します。

> wget http://cmf.ohtanz.com/download/procdnsbl.txt
> mv procdnsbl.txt /usr/local/bin/procdnsbl
> chmod 755 /usr/local/bin/procdnsbl
※利用するDNSBL、URLBLを変更したい場合はprocdnsbl内の13行目の@DNS_BL、19行目の@URL_BLを変更して下さい。

■procmailの準備

●procmail用ログファイルの作成
> touch /var/log/procmail
> chmod 666 /var/log/procmail

●procmail用ログファイルをlogrotateに追加 > vi /etc/logrotate.d/procmail

------------------------------------------------------------------------------
/var/log/procmail {
    create 666 root root
}
------------------------------------------------------------------------------

●スパムと判定されたメールを格納するspamディレクトリの作成
> mkdir ~hoge/Maildir/spam
> chown hoge:hoge ~hoge/Maildir/spam
> chmod 700 ~hoge/Maildir/spam

●spamディレクトリに入ったメールを1つのメールにまとめるスクリプトの作成
※~hoge/Maildir/newに擬似的なメールを生成します。
> vi /usr/local/bin/spamsend.sh

------------------------------------------------------------------------------
#!/bin/sh

export LANG=en
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
CONF=/usr/local/etc/spamsend.txt
HOST=`hostname`
MAILDATE=`date "+%a, %d %b %Y %H:%M:%S +0900"`

LIST=`cat $CONF`

for u in $LIST
do
    COUNT=`ls /home/$u/Maildir/spam/ | wc -l`

    if [ $COUNT -ne 0 ]; then
        FILEDATE=`date '+%s'`
        MAIL=/home/$u/Maildir/new/$FILEDATE.$$.$HOST

        echo "Date: $MAILDATE" >> $MAIL
        echo "From: postmaster@example.com" >> $MAIL
        echo "To: $u@example.com" >> $MAIL
        echo "Subject: SPAM MAIL LIST" >> $MAIL
        echo "MIME-Version: 1.0" >> $MAIL
        echo "Content-Type: text/plain; charset=iso-2022-jp" >> $MAIL
        echo "Content-Transfer-Encoding: 7bit" >> $MAIL
        echo "" >> $MAIL
        echo "[[[[[SPAM MAIL LIST]]]]]" >> $MAIL
        echo "" >> $MAIL

        nkf -mj /home/$u/Maildir/spam/* >> $MAIL
        chown $u:$u $MAIL
        chmod 600 $MAIL
        rm -f /home/$u/Maildir/spam/*
    fi
done
------------------------------------------------------------------------------
> chmod 700 /usr/local/bin/spamsend.sh

●spamsend.sh対象のアカウントを管理するファイルの作成
> vi /usr/local/etc/spamsend.txt

------------------------------------------------------------------------------
hoge
hogehoge
------------------------------------------------------------------------------

●spamsend.shをcronに追加
> vi crontab -e

------------------------------------------------------------------------------
0 0-23/4 * * * /usr/local/bin/spamsend.sh
------------------------------------------------------------------------------
※4時間おきに実行

●~hoge/.forwardの作成
> vi ~hoge/.forward

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

●~hoge/.procmailrcの作成
> vi ~hoge/.procmailrc

------------------------------------------------------------------------------
PATH=/bin:/usr/bin:/usr/local/bin
LOGFILE=/var/log/procmail
MAILDIR=${HOME}/Maildir
DEFAULT=${MAILDIR}

:0 fw
| /usr/local/bin/procdnsbl

:0
* ^X-(Dns|Url)BL: *
${MAILDIR}/spam/.

:0 fw
| /usr/bin/bsfilter --config-file /etc/bsfilter.conf

:0
* ^X-Spam-Probability: *(1|0\.[89])
${MAILDIR}/spam/.

:0
${MAILDIR}/
------------------------------------------------------------------------------

■あとがき

上記のフィルタリングをまとめますと。
» Postfixの制限機能でチェック(REJECT)
» 「S25R方式」を参考にした制限でチェック(REJECT)
» procdnsblでチェック(スパム判定)
» bsfilterでチェック(スパム判定)
という流れになります。

また当方は以前からメールチェッカー「Liam」を使用しているので、
Liamでspamsend.shでまとめられたスパムメール中に非スパムメールが混在していないかをチェックし、
もし混在してた場合はそのまま非スパムメールをコピペして救済するといった方法をとっています。
※導入して1週間ほど経過しましたが現在のところ誤判定は起きていません。

本音を言うとスパム自体を受取りたくはないですが、非スパムを救済することが1番と考え今回こういった形にしてみました。

これだけのフィルタリングを行うとサーバーへの負荷が気になるところですが、
昨年末に自宅サーバーを余っていたCPU:Pen4 3.06Ghz、Memory:512Mx2、MB:P4P800-E Deluxeに
Vine4.0を入れて運用してますが、load averageが1.00に達することはありません。

結論として1つのフィルタリングのみに頼らず複数のフィルタリングを組み合わせることが1番効果的ではないかと思いました。

Postfix2.3からアクセステーブルでsleepが使用できる(2.2でもコンパイル時にオプションを付ければ可)そうなので、
「S25R方式」で該当した場合にsleepで遅延を起こすことで、向こうが諦めてコネクションを切ってくる
(正常なMTAであれば5分まで平気なはず?)なんてこともできるみたいです。VineでPostfix2.3のrpm早くリリースされないかな〜・・・

▲TOP

dmy
low_l dmy low_r