postfixで送信元毎の同時送信数を制限する方法
名探偵コナンじゃないですが、
『犯人はこの中にいる!』
みたいな事件が社内で起こってしまいました。
今回の犯人はT.M.君。
犯した罪はメールボムを使用したサーバー攻撃です。
どうもプログラムのデバッグでメールを送信するようにしていたようですが、そのプログラムを走らせたまま帰ってしまいました。
おかげでメールのキューが溜まってしまった結果、業務のメールが送信できなくなり他部署から思いっきり怒られてしまう始末。トホホです。
一度間違いを犯した人は間違いを犯さなくなると思いますが、他の人がやってしまう可能性もあるわけで、善良な社員をゲリラ的テロリストにさせない為にも、きちんと制限を行っておいた方が良いでしょう。
という訳でpostfixで送信元毎の同時送信数を制限する方法について調べて設定してみました。
postfixで使用できるパラメータ
postfixのパフォーマンスチューニングに関するマニュアルは下記のページに書かれています。
Postfixパフォーマンスチューニング
今回のケースでは過剰に接続するクライアントに対する測定に書かれた設定が参考になりそうです。
パラメータ名 | デフォルト値 | 説明 |
---|---|---|
smtpd_client_connection_count_limit | 50 | 1つのSMTPクライアントからの同時最大接続数 |
smtpd_client_message_rate_limit | 制限なし | 1つのSMTPクライアントからの単位時間あたりのメッセージ配送要求数 |
smtpd_client_recipient_rate_limit | 制限なし | 1つのSMTPクライアントからの単位時間あたりの送信先アドレス数 |
smtpd_client_connection_rate_limit | 制限なし | 1つのSMTPクライアントからの単位時間あたりの同時最大接続数 |
anvil_rate_time_unit | 60s | 上記制限を行う単位時間 |
smtpd_client_event_limit_exceptions | $mynetworks | 上記制限を掛けないSMTPクライアント |
『1つのSMTPクライアントからの』と書かれていますが、IPで制限されますので、『1サーバー』とか『1拠点』と考えた方が良いでしょう。
上記の設定をmain.cfとmaster.cfの適切な箇所に記載します。
/etc/postfix/main.cf
main.cfで設定を行うと全体的な設定になります。
今回は下記の通り設定しました。
anvil_rate_time_unit=60s smtpd_client_message_rate_limit=120 smtpd_client_event_limit_exceptions=127.0.0.0/8
- anvil_rate_time_unitはデフォルトと同じ60sです。今回の場合、ここは特に変更しなくて良いでしょう。
- smtpd_client_message_rate_limitを120に制限します。
- smtpd_client_event_limit_exceptionsを127.0.0.0/8に変更します。こちらを指定しないと$mynetworksの値が使用されますが、mynetworksにはローカルネットワークのサーバーも含んでおり、今回のトラブルはローカルネットワークのサーバーからのメール送信で発生したためローカルホストのみに制限します。
/etc/postfix/master.cf
master.cfで設定を行うと個別のサービスに対しての設定になります。
今回は下記の通り設定しました。
# ========================================================================== # service type private unpriv chroot wakeup maxproc command + args # (yes) (yes) (yes) (never) (100) # ========================================================================== smtp inet n - n - 50 smtpd -o smtpd_client_connection_count_limit=10 -o smtpd_client_connection_rate_limit=30 submission inet n - n - - smtpd -o smtpd_client_connection_count_limit=50 -o smtpd_client_connection_rate_limit=200 -o smtpd_etrn_restrictions=reject -o smtpd_client_restrictions=permit_sasl_authenticated,reject
smtpは社外もしくは内部のサーバーからの送信制限です。
- maxproc(最大プロセス数)を50
- smtpd_client_connection_count_limit(1 IPからの同時接続数)を10
- smtpd_client_connection_rate_limit(単位時間(anvil_rate_time_unit=60s)辺りの接続数)を30
に設定しています。
submissionはSubmission Port(587)を通して送られる社内からのユーザーからのメールで制限を掛けるとお叱りを受けるので軽めにしておきました。
設定が終わったらpostfix reloadで設定を反映します。
テスト
実際に送信して試してみます。
メールサーバーとは別のサーバーからメールを送信して試します。
アドレスは実際に使用できるアドレスに変更してください。
<?php $senders[] = 'foo@example.com'; $senders[] = 'bar@example.com'; $recipients[] = 'foo@example.com'; $recipients[] = 'bar@example.com'; for($i = 0; $i < 10000; $i++) { foreach($senders as $s) { foreach($recipients as $r) { mail($r, 'Test', 'Test', NULL, "-f$s"); } } }
上記スクリプトをtest_mail.phpという名前で保存したとして、
php test_mail.php
で実行します。
受信側サーバーのメールキューをmailqコマンドで確認し、キュー内のメールが一定まで増えた後、減っていく状況が確認できるかと思います。
又、送信側サーバーのメールキューもmailqコマンドで確認し、溜まっている状況が確認できればOKです。
キューに溜まったメールは『postfixでキューに溜まった特定の送信元、送信先のメールを一括削除する方法』に記載した方法で一括削除できます。