s25rtarpitgreylist for postfixの最新版
- [新機能]公開バージョンリリース
- [修正]ホワイトリスト/ブラックリストを許可リスト/拒否リストに変更
- [新機能]初版リリース
このプログラムはpostfix用のホスト選択式スパム対策ソフトウェアです。 postfixのアクセスポリシーサーバとしてspawnから実行し、スパム送信元らしいホストの接続を拒否(再送要求)します。
このプログラムは拒否するホストの判定にgreylistingというメール再送を要求するアルゴリズムを使用しています。(スパマーは早く大量にメールを送信したいので再送信を嫌がり、再送信しません。)
しかし、このgreylistというアルゴリズムだけでは副作用が大きすぎますので、 S25R(選択的SMTP拒否)というアルゴリズムを使用して、スパマーがよく利用する 動的IPアドレスらしいホストのみをgreylistingの対象とするようにしています。
また、tarpit(SMTP接続時に意図的に応答を遅らせる)を実施することにより、 スパム送信元ホストの接続を拒否します。(スパマーは早く大量にメールを送信したいので、 応答遅延を嫌がり自ら切断します)
このプログラムはpythonスクリプトで実装されています。既存のソフトウェアにパッチを適用する方式ではありませんので簡単に導入できます。
このプログラムはqmail用に作成した「s25rtarpitgreylist」をpostfixにて動作するようにpython3で実装しなおしています。
実装にあたり機能を削減しております。
勉強目的で実装していますので若干作りが甘いです。
クラウド全盛の中、またAIによるスパムメール判断が優秀になってきた中(2020年現在)、今さら感がありますが、多重対策の一つとして意味があるかもしれません。
機能ごとに、その機能を有効にするか無効にするかを切り替えるスイッチがついています。
ここに定義したホストは、このプログラムでは拒否(再送要求)しません。 IPアドレスベースのものとホスト名ベースのものがあります。対象の指定には正規表現を使用することができます。
プロバイダから割り当てられたホスト名を使用する正規のメールサーバーや S25Rの条件に該当してしまう正規のメールサーバーをこの許可リストに登録することにより greylistの罠に嵌るのを防ぎます。
許可リストのメンテナンスについてはこちらをご参照ください。
「s25rtarpitgreylist の許可リスト・拒否リストのメンテナンスについて」
ここに定義したホストは無条件で拒否され、接続を切断されます。正規のメールサーバーのような振舞いをするスパム送信元ホスト等を定義します。 IPアドレスベースのものとホスト名ベースのものがあります。対象の指定には正規表現を使用することができます。
スパム送信元ホストを拒否リストに登録することにより、初回接続から2分から1日の間隔(greylistのデフォルト設定)で再送信してくるホストのメール送信を除外できます。(手動登録)
送信元ホストからのRCPTコマンドの応答を遅らせます。スパムを送信するホストはメールを大量送信するため応答の遅延を嫌がり切断します。 デフォルト動作では、S25Rリストにマッチした送信元ホストの初回接続時に実施します。
スパムを送信するホストは動的IPアドレスという前提で 動的IPアドレスらしいホスト名を持つホストと持たないホストを振り分けます。 動的IPアドレスらしいホスト名を持たないホストは、このプログラムでは拒否されません。 動的IPアドレスらしいホスト名を持つホスト(逆引きできないホストも含む)は 後の処理(ここではgreylisting・tarpit)に任されます。
副作用の大きいgreylist処理の対象を減らします。
greylistingによる検査対象にしたい正規表現パターンがあれば、S25Rで定義されている正規表現パターン以外でも追加することが可能です。
greylistに登録されていない送信元ホスト名および受信者アドレスの組み合わせ(つまり初回接続時)は再送要求されます。 この時点でgreylistに接続情報(送信元IPアドレス、送信者メールアドレス、受信者メールアドレス、初回接続日時)が登録されます。 その後の再送時の再送間隔を検査します。 再送間隔が短いホストは再度再送要求します(つまり接続情報が削除されるまで永遠にメール送信できません)。 再送間隔が長いホストはこのプログラムでは拒否しません。 greylistは送信元IPアドレス、送信者メールアドレス、受信者メールアドレス、初回接続日時を管理しています。
greylistの詳細についてはこちら。
このプラグラムの実装では、以下の点でオリジナルのgreylistと異なる挙動をします。
スパマーは他のホストにメールを送信することを優先するので再送しないことが多いです。よって、これでスパムを防ぐことができるかもしれません。
順 | 機能 | 処理内容 | その他 |
---|---|---|---|
1 | 送信メールアドレスが送信メールアドレス許可リストに登録されている→許可 | ||
2 | 受信メールアドレスが受信メールアドレス許可リストに登録されている→許可 | ||
3 | 接続ホストがホスト名ベース許可リストに登録されている→許可 | ||
4 | 接続ホストがIPアドレスベース許可リストに登録されている→許可 | ||
5 | 接続ホストがホスト名ベース拒否リストに登録されている→再送要求(拒否) | ||
6 | 接続ホストがIPアドレスベース拒否リストに登録されている→再送要求(拒否) | ||
7 | S25R | 接続ホストのホスト名がS25Rの条件に該当しない→許可 | |
8 | greylist | greylistからしばらくアクセスがないホストの記録を削除 | |
9 | greylist | 接続ホストがgreylistに登録されていない→8-1へ 登録されている→9へ | |
10-1 | tarpitting | tarpitting(指定秒数待つ) (オプションで待てたら→許可 も可) (待てない→接続ホストが自ら切断) | |
10-2 | greylist | 接続ホストをgreylistに登録 | |
10-3 | greylist | →再送要求(拒否) | |
11 | greylist | 接続ホストが指定した回数以上、「初回接続から近すぎる」(手順11)になっている →再送要求(拒否) | |
12 | greylist | 接続ホストの接続が初回接続から近すぎる →再送要求(拒否) | |
13 | greylist | 接続ホストのgreylistのアクセス時間を更新 | ここまでたどり着くとお行儀の良いホスト |
14 | greylist | →許可 |
このプログラムはpythonスクリプトですので、簡単にインストールできます。
以下にインストール手順を示します。
# groupadd greylist
# useradd -g greylist -d /usr/local/s25rtarpitgreylist greylist
# mkdir /usr/local/s25rtarpitgreylist/var
# mkdir /var/log/s25rtarpitgreylist
# chown greylist /var/log/s25rtarpitgreylist
# ln -s /var/log/s25rtarpitgreylist /usr/local/s25rtarpitgreylist/var/log
# mkdir /var/db/s25rtarpitgreylist
# chown greylist:greylist /var/db/s25rtarpitgreylist
# ln -s /var/db/s25rtarpitgreylist /usr/local/s25rtarpitgreylist/var/db
# cd /tmp
# tar zxf s25rtarpitgreylist_for_postfix_1.1.0.tgz
# cd s25rtarpitgreylist_for_postfix_1.1.0
# cp -pR bin etc /usr/local/s25rtarpitgreylist
# chown -R greylist:greylist /usr/local/s25rtarpitgreylist
# chmod 700 /usr/local/s25rtarpitgreylist/bin/s25rtarpitgreylist.py
# vi /usr/local/s25rtarpitgreylist/bin/s25rtarpitgreylist_config.py
# su - greylist
$ cd bin
$ ./s25rtarpitgreylist.py createdb
$ ./s25rtarpitgreylist.py checkconfig
Exec_User :greylist [OK]
Path_Exchange_Log:/var/log/s25rtarpitgreylist/s25rtarpitgreylist.log [OK]
Path_Allowlist_Sender:/usr/local/s25rtarpitgreylist/etc/allowlist_sender [OK]
Path_Allowlist_Rcpt:/usr/local/s25rtarpitgreylist/etc/allowlist_rcpt [OK]
Path_Allowlist :/usr/local/s25rtarpitgreylist/etc/allowlist [OK]
Path_Allowlist_Ipaddr:/usr/local/s25rtarpitgreylist/etc/allowlist_ipaddr [OK]
Path_Allowlist_Hostname:/usr/local/s25rtarpitgreylist/etc/allowlist_hostname [OK]
Path_Denylist :/usr/local/s25rtarpitgreylist/etc/denylist [OK]
Path_Denylist_Ipaddr:/usr/local/s25rtarpitgreylist/etc/denylist_ipaddr [OK]
Path_Denylist_Hostname:/usr/local/s25rtarpitgreylist/etc/denylist_hostname [OK]
Path_S25rlist_Hostname:/usr/local/s25rtarpitgreylist/etc/s25rlist_hostname [OK]
Path_Database :/var/db/s25rtarpitgreylist/greylist.db [OK]
Check regexp list - Path_Allowlist_Ipaddr :/usr/local/s25rtarpitgreylist/etc/allowlist_ipaddr
Check regexp list - Path_Allowlist_Hostname :/usr/local/s25rtarpitgreylist/etc/allowlist_hostname
Check regexp list - Path_Denylist_Ipaddr :/usr/local/s25rtarpitgreylist/etc/denylist_ipaddr
Check regexp list - Path_Denylist_Hostname :/usr/local/s25rtarpitgreylist/etc/denylist_hostname
Check regexp list - Path_S25rlist_Hostname :/usr/local/s25rtarpitgreylist/etc/s25rlist_hostname
$ exit
# vi /etc/postfix/main.cf
:(中略)
smtpd_recipient_restrictions =
permit_mynetworks,
reject_unauth_destination,
check_policy_service unix:private/policy
:(中略)
# vi /etc/postfix/master.cf
:(中略)
policy unix - n n - 0 spawn user=greylist argv=/usr/local/s25rtarpitgreylist/bin/s25rtarpitgreylist.py
# systemctl restart postfix
# cat << EOS > /etc/logrotate.d/s25rtarpitgreylist
/var/log/s25rtarpitgreylist/s25rtarpitgreylist.log {
missingok
notifempty
compress
delaycompress
daily
rotate 31
create 0644 greylist greylist
}
EOS
# vi /usr/local/s25rtarpitgreylist/bin/s25rtarpitgreylist_report.sh
mailto='admin@hoge.com'
# cat << EOS > /etc/cron.d/s25rtarpitgreylist_report
1 0 * * * root /usr/local/s25rtarpitgreylist/bin/s25rtarpitgreylist_report.sh
EOS
もしこのプログラムに更新版がリリースされた場合は、スクリプトファイルの置き換えでアップデートします。
以下にインストール手順を示します。
# cd /tmp
# tar zxf s25rtarpitgreylist_for_postfix_1.1.0.tar.gz
# cd s25rtarpitgreylist_for_postfix_1.1.0
# cp bin/s25rtarpitgreylist.py /usr/local/s25rtarpitgreylist/bin/s25rtarpitgreylist.py
ファイルが多くなってきましたので、ディレクトリツリーでファイルの説明です。
bin/s25rtarpitgreylist_config.pyについては以下を参照。
設定項目がたくさんありますが、上記手順のままインストールしている場合は、これらの設定項目の値を初期値から変更しなくても動作します。
設定はbin/s25rtarpitgreylist_config.pyにて行ってください。(s25rtarpitgreylist.pyにも設定可能な箇所がありますが、設定項目はs25rtarpitgreylist_config.pyの値で上書きされます)
このスクリプトを実行するユーザを設定します。postfix spawnの仕様により、rootユーザでは動作出来ません。rootユーザで誤ってデータベースファイルを作成することを防止するために、この設定があります。
postfix spawnプログラムとの標準入出力のやり取りをログとして出力することを設定します。
postfix spawnプログラムとの標準入出力のやり取りを記録するログファイルのパスを設定します。
送信メールアドレスベースの許可リストファイルのパスを指定します。
ファイルの内容は、許可したい送信メールアドレスを指定したリスト(改行区切り)です。
受信メールアドレスベースの許可リストファイルのパスを指定します。
ファイルの内容は、許可したい受信メールアドレスを指定したリスト(改行区切り)です。
IPアドレスベースの許可リストファイルのパスを指定します。
ファイルの内容は、許可したいホストのIPアドレスを指定したリスト(改行区切り)です。
IPアドレスベースの許可リストファイルのパスを指定します。
ファイルの内容は、許可したいホストのIPアドレスを指定したリスト(改行区切り)です。IPアドレスの指定にperlの正規表現が使用できます。
ホスト名ベースの許可リストファイルのパスを指定します。
ファイルの内容は許可したいホストのホスト名のリスト(改行区切り)です。ホスト名の指定にperlの正規表現が使用できます。書式は異なりますがこちらの許可リストもそのまま使用できます(このプログラムにて余計な情報は読み取らないようにしています)
拒否リストの機能の有効/無効、および動作方法を設定します。
0から2までの数値を指定します。
IPアドレスベースの拒否リストファイルのパスを指定します。
ファイルの内容は、接続を拒否したいホストのIPアドレスを指定したリスト(改行区切り)です。
IPアドレスベースの拒否リストファイルのパスを指定します。
ファイルの内容は接続を拒否したいホストのIPアドレスを指定したリスト(改行区切り)です。IPアドレスの指定にperlの正規表現が使用できます。
ホスト名ベースの拒否リストファイルのパスを指定します。
ファイルの内容は接続を拒否したいホストのホスト名のリスト(改行区切り)です。ホスト名の指定にperlの正規表現が使用できます。
S25Rによる動的IPアドレスらしいホストの選別をする機能を有効にするか無効にするかを設定します。
0,1の値を指定します。
S25Rリストのファイルのパスを指定します。
ファイルの内容は動的IPアドレスらしいホスト名のリスト(改行区切り)です。ホスト名の指定にperlの正規表現を使用することができます。 Mode_Denylistの値を「1」にしている場合は、拒否リストの内容も追加で定義してください。 書式は異なりますがこちらの「/etc/postfix/rejectionsファイルの中身」で紹介されているリストも使用することができます。(このプログラムにて余計な部分を読みこまないようにしています)
ヒント:正規表現で自由に定義可能ですので、最初から定義してある動的IPアドレスらしいホスト名だけでなく、クラウドやVPSらしいホスト名も追加定義することもできます。
tarpit(応答遅延)の機能の有効/無効、および動作方法を設定します。
0から2までの数値を指定します。
有効(デフォルト)。greylistに登録されていないホストに対してtarpitを実施します。
tarpitするとプロセスが増加する副作用を減らすため、デフォルト値はこちらにしています。(同一ホストは同じ挙動をする前提で、初回のみtarpit検査)
tarpit(応答遅延)する秒数を指定します。
ここで指定した秒数だけRCPTコマンド後の応答を遅らせます。デフォルトでは65秒ですが125秒ぐらいでも実用範囲だと思います(副作用には注意してください)。
tarpit(応答遅延)を待つことができたホストを許可するかどうかを設定します。
0から1までの数値を指定します。
同一接続内にて、2回目以降のRCPTコマンド実行後にtarpitを実施するかを設定します。(送信元にてメール送信時に複数のメールアドレスを指定している場合、同一接続にて複数回のRCPTコマンドが実行されます)
1回目のtarpitにて待つことができる接続元ホストであることが判明しているので、同一接続における2回目以降のtariptは無駄な遅延を発生させるだけで無意味かもしれない。
greylisting機能の有効/無効を設定します。
0,1の値を指定します。
再送要求後の、メールの受信を許可する、初回接続からの秒数を指定します。
Sec_Response_Limit_From_First_Connect=120 のとき、
2008-03-20 22:00:00に初めて接続したホストを再送要求したとします。
このとき、再送にあたる2回目の接続が
2008-03-20 22:01:30であれば、初回接続より120秒経過していないので再び拒否し再送要求します。
2008-03-20 22:02:10であれば、初回接続より120秒経過しているのでそのホストの接続を許可します。
greylistデータベースファイルのパスを指定します。sqlite3形式のファイルで、接続元IPアドレス、送信元メールアドレス、宛先メールアドレス、初回接続タイムスタンプ、直近許容タイムスタンプ、接近試行回数を保持しています。
このデータベースファイルは、このプログラムによって自動的に更新されます。
greylistに登録されているホストのうち、接続が許可されているホスト(初回接続日時!=アクセス日時)の情報の有効期限(秒数)を指定します。
有効期限が切れたホストの情報はgreylistから削除されます。
greylistに登録されているホストのうち、接続が許可されていないホスト(初回接続日時=アクセス日時、再送待ち状態)の情報の有効期限(秒数)を指定します。
有効期限が切れたホストの情報はgreylistから削除されます。この値をSec_Response_Limit_From_First_Connectより小さくしないでください。
この設定を有効することによって、greylistingの接続情報のマッチングに、IPアドレスに加えて、送信元メールアドレス、宛先メールアドレスを追加します。
接続を拒否する初回接続に近すぎて拒否した数の閾値を指定します。
???初回接続に近すぎて拒否した数がこの値を超えると、初回接続より指定の時間を経過しても接続を拒否します。短い間隔で何度も再送してきて最終的にSec_Response_Limit_From_First_Connectの設定秒数を超えてしまう場合に有効です。
許可リストのメンテナンスについてはこちらをご参照ください。
「s25rtarpitgreylist の許可リスト・拒否リストのメンテナンスについて」
# su - greylist
$ cd bin
$ ./s25rtarpitgreylist.py showgreylist
IP ADDR DOMAIN SENDER RCPT CREATE TIME ACCESS TIME COUNT
173.82.173.211 Rakuten@hotgmaill.xyz xxx@chidipy.jpn.com 2020-09-23 01:07:45 2020-09-23 01:27:46 0
# su - greylist
$ cd bin
$ ./s25rtarpitgreylist.py cleardb
# su - greylist
$ sqlite3 /usr/local/s25rtarpitgreylist/var/db/greylist.db "DELETE FROM greylist WHERE ipaddr = '123.123.123.123'"