
ポート 80 に httpd を備えた Ubuntu 12.04 サーバーがあり、次のことを制限したいと考えています。
- IPアドレスあたりのhttpdへの最大接続数を10にする
- httpdへの1秒あたりの最大新規接続数を150にする
iptables でこれをどうやって実現するのでしょうか?
答え1
iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 --connlimit-mask 32 -j REJECT --reject-with tcp-reset
これにより、1 つのソース IP からの 15 を超える接続が拒否されます。
iptables -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 150/second --limit-burst 160 -j ACCEPT
この場合、1 秒あたり 150 個の新しい接続 (パケット) の制限が適用される前に、160 個の新しい接続 (実際にはパケット) が許可されます。
答え2
質問の両方の要件を満たすには、iptables で次のルールを設定する必要があります。
iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -I INPUT -p tcp --dport 80 -m state \
--state RELATED,ESTABLISHED -j ACCEPT
# Adjust "--connlimit-above NN" to limit the maximum connections per IP
# that you need.
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
--connlimit-above 10 --connlimit-mask 32 -j DROP
# Adjust "--connlimit-above NNN" to the maximum total connections you
# want your web server to support
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
--connlimit-above 150 -j DROP
-I を使用しているため (OP のリクエストに従って)、逆の順序で実行して、下から上に「読み取る」必要があります。
また、--connlimit-mask NN を 32 から 24 に変更することも検討することをお勧めします。これにより、完全なクラス C ネットワーク (同じ範囲内の最大 256 個の IP アドレス) が 10 の接続に制限されます。サービスがどのように使用されるかに応じて、22 や 30 などの他のクラスレス番号を使用することもできます。
また、クライアントにどのような行動をしてほしいかによって、かもしれない上記の 2 つのルール、または 150 接続最大ルールでのみ、「-j DROP」の代わりに「-j REJECT --reject-with tcp-reset」を使用します。
接続を拒否すると、ポート 80 を使用するブラウザまたはソフトウェアはすぐに「利用不可」ステータスを表示しますが、ドロップ オプションを選択すると、クライアントは待機して数回再試行してから、サイトが利用不可であると報告します。オフライン サーバーというよりも、接続不良のように動作するので、私はドロップを選択する傾向があります。
また、再試行中に接続制限が 150 (または 10) 未満に戻ると、最終的にサーバーに接続できるようになります。
ただし、REJECT オプションでは、再試行中に追加のパケットが送信されるため、サイトへのトラフィックがわずかに減少します。おそらく、それほど重要ではありません。
一方、ポート 80 のトラフィックがクラスターの一部である場合、REJECT はクラスター コントローラーにそのクラスターがダウンしていることを通知し、再試行タイムアウトの間はトラフィックの送信を停止します。
RELATED,ESTABLISHED ルールは、デフォルトのルールがすべてのトラフィックをブロックすること (iptables -t filter -P INPUT DROP) を前提としています。これにより、承認された接続に属する追加のパケットのみが受け入れられます。
また、--syn は TCP 接続を確立するパケットに注意を払う (またはカウントする) ように指示します。
答え3
connlimit
クライアント IP アドレス (またはアドレス ブロック) ごとにサーバーへの並列 TCP 接続の数を制限できるモジュールを使用する必要があります。
/sbin/iptables -I INPUT -p tcp --syn --dport 80 -m connlimit \
--connlimit-above 10 -j DROP