Postfix スパム対策総合

Back

DNSでチェック
 
あやしーDNSの場合にねこそぎリジェクトする。

main.cfで

smtpd_recipient_restrictions =
        check_sender_ns_access hash:/etc/postfix/reject_ns

/etc/postfix/reject_nsでは

ns1.toptjechnology.com REJECT match NS blacklist
ns2.toptjechnology.com REJECT match NS blacklist

# melsoho
ns1.busiassist.net REJECT match NS blacklist melsoho
ns2.busiassist.net REJECT match NS blacklist melsoho
ns1.busiassists.com REJECT match NS blacklist melsoho
ns2.busiassists.com REJECT match NS blacklist melsoho
ns1.dmfactory.net REJECT match NS blacklist melsoho
ns2.dmfactory.net REJECT match NS blacklist melsoho
ns1.dmfactorys.com REJECT match NS blacklist melsoho
ns2.dmfactorys.com REJECT match NS blacklist melsoho
ns1.dmfactorys.net REJECT match NS blacklist melsoho
ns2.dmfactorys.net REJECT match NS blacklist melsoho
ns1.magmagss.com REJECT match NS blacklist melsoho
ns2.magmagss.com REJECT match NS blacklist melsoho
ns1.smagmag.net REJECT match NS blacklist melsoho
ns2.smagmag.net REJECT match NS blacklist melsoho
ns1.sogobusi.com REJECT match NS blacklist melsoho


 などなどして、

# sudo postmap /etc/postfix/reject_ns

 する。



ディレイ
 あやしー接続元の場合にディレイをかけると接続をあきらめる場合が多いので効果あり。hotmailのサーバなどは我慢強くないみたいなので、受け付け たい場合は正規表現にかからないように。

main.cfで

smtpd_recipient_restrictions =
        check_client_access regexp:/etc/postfix/check_client_fqdn

/etc/postfix/check_client_fqdnに正規表現であやしー系を入れる

/^unknown$/ sleep 90
/^[^\.]*[0-9]{5}/ sleep 90
/^([^\.]+\.)?[0-9][^\.]*\.[^\.]+\..+\.[a-z]/ sleep 90

 などなど。




フィルタ(やり方がまずいのか超重くなるので非推奨)

 内蔵のheader_checks body_checksで大量の正規表現ルールを書くのはご法度らしいので、本家ドキュメントにある 「キューに入ったあとの簡易コンテンツフィルタ」というのを入れてみる。


 概要はこ ちらのとおりで、必要なファイルはPostfixに参照させるスクリプトと、そこから呼び出す手製スクリプトのふたつ。


  Postfixに参照させるスクリプトはドキュメントにある雛型そのままでフィルタへのパスを変えるだけ。フィルタスクリプトは正常終了さ せるか異常終了させるかだけで、正常終了すればメールは配送され、異常終了すればRejectされてbounceされる、という仕組み。

 で、フィルタスクリプトは単純に言えば以下の感じになる、と。

#!/usr/bin/perl
while (<>) {
    if ($_ =~ /spam\ word/ ) { print "detected spam word"; exit 1;}
}
exit 0;

 フィルタスクリプトが組めたら、ドキュメントにあるPostfix参照用スクリプト内のフィルタへのパス を変えて設置して、

# /path/to/script -f sender recipient... <message-file

 で実験。問題ないようならフィルタ用ユーザ(便宜上 'filter')と、そのユーザだけが読み書きできる/var/spool/filterディ レクトリを作って、master.cfに

filter unix - n n - 10 pipe
   flags=Rq user=filter argv=/path/to/script -f ${sender} -- ${recipient}

 を追加。同じくmaster.cfのsmtpの項目にオプションを足す。

smtp inet ...other stuff here, do not change... smtpd
   -o content_filter=filter:dummy


 あとはpostfix reloadすれば稼働開始。結局は受け取ってしまってからのフィルタリングなので少々釈然としないが、まあ自作スクリプトで好きにできるのでよしとす る。



【スパム選定後のメールの取扱い】

1)なかったことにする
2)即bounceされる
3)softbounceして、その間にキューを削除するか、期限切れでbounceされる


と3通りあるが、1)はPostfixが参照するスクリプトのエラー処理部分を
-   echo Message content rejected; exit $EX_UNAVAILABLE; }
+ echo Message content rejected; exit $?; }
 と通常終了させるとそのメールはなかったことになる。が、問答無用で消滅するわけで危険。確実に誤動作しないフィルタ条件であれば、これ。

2)は詐称fromにそのままbounceされる恐れがあるのでダメ。
3)はsoftbounce期間を長め(7日とか)にとっておき、「適当な時間(5日とか)がたったキューされているspam認定メールを自動削除する手 製スクリプト」を cronかdailyスクリプト等で定期的にまわし、期限切れでbounceされる前に削除する。救済期間があるので安全ではある。


【softbounceしている場合のキューの取扱い】

% mailq


 で、たまっているキューを見たり、

% sudo postsuper -d ALL

 で、キューを削除してみたりして気を和ませる。

% sudo postqueue -f

 で、たまっているキューを強制再送。

%  mailq | grep -vE "^[\(\ -]" | gawk '{print $1,$4,$5,$7}'


 などすると、キューされているメールのfromのメールアドレス一覧がチェック可能。などなど。
.
.
.

 以下、ベタに作ったフィルタスクリプト。仕様は以下のとお り。フィルタリング管理が複雑冗長になる上に意味がないと思われるのでホワイトリスト機能はな し。

・/etc/spam.listから語句を読み出して正規表現にかける
・テキスト添付の BASE64もデコードしてフィルタ
・マルチバイト対策はしておらず
・$maxLine行以上のメールは処理中断
・非日本語、かつmultipart/alternativeかつ画像添付なメールは問答無用でスパムとして遮断

spam_filter (2007/01/24)


/etc/spam.listは以下の感じの正規表現。主に誘導URLのフィルタ。またはヘッダのホスト名。行先頭に#でコメント化(無効化)。

spam.list (2007/05/22)



削除すべきキュー選分けPerlスクリプト

queuedel.pl (2007/01/24)


上記スクリプトを回すシェルスクリプト

queuedel (2007/01/24)


# cp queuedel queuedel.pl /usr/local/bin
# ln -s /usr/local/bin/queuedel.pl /usr/local/bin/queueshow.pl


 で設置。


# /usr/local/bin/queuedel -l
D1AEC43170C Wed kfg64ryhds@lycos.com
*D266942E3F8 Mon tinat_myc_com_2006@mail.goo.ne.jp *remove*
DC09642B7F6 Sun annahaas.com@worldwideflavors.com
DDEE342EC2F Tue FallintoFashions@kinderlinggroup.com


 で、キューの状態閲覧。


# /usr/local/bin/queuedel -d
D266942E3F8


 で、削除すべきキューID表示。なので、


# /usr/local/bin/queuedel -d | postsuper -d -

 で、実際に削除。上記を/etc/dailyなどに入れておく。キューに入った後、おおよそ四日後に削除される仕様。



updated on 2008 6