2026年7月7日

2026年7月7日

iptablesでWordPressサーバーへの接続数を制限する方法|connlimit・hashlimitの設定と注意点

同じ IP アドレスから大量の接続が来ると、Web サーバーや PHP の処理が埋まり、ほかの訪問者のページ表示が遅くなります。iptables の拡張モジュールを使うと、1つの IP アドレスからの接続数をサーバーの入口で制限できます。

この記事では、WordPress を動かしている Linux サーバー(Ubuntu・Debian)で、iptables の connlimit と hashlimit を使って接続を制限する手順を説明します。

iptablesでできること・できないこと

iptables が見ているのは、IP アドレスとポート番号などの通信の外側の情報です。

できること できないこと
1つの IP からの同時接続数を制限する wp-login.php など、特定の URL だけを制限する(HTTPS の中身は見えない)
1つの IP からの新しい接続の速さを制限する 1つの接続の中で送られるリクエストの数を数える
制限に当たった接続をログに残す 回線を埋めるほどの大規模な DDoS 攻撃を防ぐ

ログインの試行回数を制限したい場合は、Nginx の limit_req(WordPressのNginxでlimit_reqを設定してリクエストを制限する方法)や fail2ban(WordPressのFail2Banでブルートフォースを防ぐ方法)を使います。iptables の制限は、それらの手前で、明らかに多すぎる接続を落とす役割です。

ポート 80・443 への新しい接続を「10分間に3回まで」のように少なく制限すると、普通の訪問者も拒否されます。ブラウザーは1回のページ表示で複数の接続を使い、ページを移動するたびに接続し直すこともあるためです。制限の値は、普通の使い方では届かない大きさにします。

始める前に確かめること

CDN・リバースプロキシを使っていないか:Cloudflare などの CDN を経由している場合、サーバーに接続してくるのは CDN の IP アドレスです。IP ごとの制限をかけると、多くの訪問者の通信をまとめて落とすことになります。この場合、iptables での接続数の制限は使わず、CDN 側のレート制限の機能を使ってください。

ufw や firewalld で管理していないか:ufw や firewalld でファイアウォールを管理しているサーバーで iptables コマンドを直接使うと、どのルールが効いているかが分かりにくくなります。そのツールの方法で設定するか、iptables での管理に一本化してください。

今のルールを保存しておく:

sudo iptables-save > ~/iptables-before.rules
sudo ip6tables-save > ~/ip6tables-before.rules

Ubuntu 24.04・Debian 12 以降の iptables コマンドは、内部で nftables を使う版(iptables -V で nf_tables と表示される)です。コマンドの書き方は従来と同じです。

手順1:制限用のチェーンを作る

ルールをまとめておくため、専用のチェーン(ルールの集まり)を作ります。

sudo iptables -N WP-HTTP-LIMIT

手順2:同時接続数を制限する(connlimit)

1つの IP アドレスからの同時接続が 50 を超えたら、新しい接続を拒否します。

# 制限に当たった接続を記録する(記録は1分に5件まで)
sudo iptables -A WP-HTTP-LIMIT -p tcp -m connlimit --connlimit-above 50 --connlimit-mask 32 \
  -m limit --limit 5/min -j LOG --log-prefix "wp-connlimit: "

# 拒否する(相手にはすぐ接続の失敗が伝わる)
sudo iptables -A WP-HTTP-LIMIT -p tcp -m connlimit --connlimit-above 50 --connlimit-mask 32 \
  -j REJECT --reject-with tcp-reset
  • --connlimit-above 50:同時接続が 50 を超えたら当てはまります
  • --connlimit-mask 32:IP アドレス1つごとに数えます(24 にすると /24 のまとまりごと)
  • -p tcp:REJECT --reject-with tcp-reset を使うルールには、チェーンの中でも -p tcp が必要です(ないとルールの追加に失敗します)

手順3:新しい接続の速さを制限する(hashlimit)

1つの IP アドレスからの新しい接続が、1秒あたり 20 を超える状態が続いたら落とします。最初の 100 接続までは、まとめて来ても許容します(--hashlimit-burst)。

sudo iptables -A WP-HTTP-LIMIT -p tcp -m hashlimit --hashlimit-name wp-http \
  --hashlimit-mode srcip --hashlimit-above 20/second --hashlimit-burst 100 \
  -m limit --limit 5/min -j LOG --log-prefix "wp-hashlimit: "

sudo iptables -A WP-HTTP-LIMIT -p tcp -m hashlimit --hashlimit-name wp-http \
  --hashlimit-mode srcip --hashlimit-above 20/second --hashlimit-burst 100 \
  -j DROP
  • --hashlimit-mode srcip:接続元の IP アドレスごとに数えます
  • --hashlimit-name:この制限の名前です。同じ名前のルールは同じ数え方を共有します

手順4:80・443番の新しい接続をチェーンに通す

sudo iptables -I INPUT -p tcp -m multiport --dports 80,443 \
  -m conntrack --ctstate NEW -j WP-HTTP-LIMIT

-m conntrack --ctstate NEW で、新しく始まる接続だけをチェーンに通します(古い記事にある -m state --state NEW は、同じ働きの古い書き方です)。チェーンの最後まで当てはまらなかった接続は INPUT に戻り、その後ろのルールで扱われます。

自分の IP アドレスや、監視サービスの IP アドレスを制限から外す場合は、チェーンの先頭に入れます。203.0.113.10 は除外したい IP に置き換えます。

sudo iptables -I WP-HTTP-LIMIT 1 -s 203.0.113.10 -j RETURN

設定を確かめます。

sudo iptables -S WP-HTTP-LIMIT
sudo iptables -L WP-HTTP-LIMIT -n -v --line-numbers

-L ... -v の pkts の列に、それぞれのルールに当てはまった数が表示されます。

この記事のルールは、Ubuntu 24.04(iptables 1.8.10、nf_tables 版)で、追加・保存・削除ができることを確認しています。

手順5:IPv6にも同じ制限をかける

サーバーが IPv6 でも公開されている場合(DNS に AAAA レコードがある場合)は、ip6tables で同じ制限をかけます。IPv6 では、1つの契約者に /64 以上のまとまりが割り当てられることが多いため、/64 ごとに数えます。

sudo ip6tables -N WP-HTTP-LIMIT
sudo ip6tables -A WP-HTTP-LIMIT -p tcp -m connlimit --connlimit-above 50 --connlimit-mask 64 \
  -j REJECT --reject-with tcp-reset
sudo ip6tables -A WP-HTTP-LIMIT -p tcp -m hashlimit --hashlimit-name wp-http6 \
  --hashlimit-mode srcip --hashlimit-srcmask 64 --hashlimit-above 20/second --hashlimit-burst 100 \
  -j DROP
sudo ip6tables -I INPUT -p tcp -m multiport --dports 80,443 \
  -m conntrack --ctstate NEW -j WP-HTTP-LIMIT

手順6:ログを確かめて値を調整する

LOG で記録した内容は、カーネルのログに出ます。

sudo journalctl -k | grep -E "wp-connlimit|wp-hashlimit" | tail -20

# rsyslog が動いている Ubuntu・Debian では次のファイルにも出ます
sudo grep -E "wp-connlimit|wp-hashlimit" /var/log/kern.log | tail -20

SRC= が制限に当たった IP アドレスです。数日分のログを見て、次のように調整します。

  • 検索エンジンのクローラーや、自分が使っている監視サービスが当たっている → 値を上げるか、手順4の方法で除外する
  • 携帯電話の回線や会社のネットワークなど、多くの人が同じ IP を共有している接続元が当たっている → 値を上げる
  • ほとんど当たっていない → 値はそのままで、効いているかは攻撃を受けたときのログで確かめる

調整するときは、ルールを削除して追加し直します(手順8の削除方法を参照)。

手順7:再起動後も残るように保存する

iptables のルールは、そのままではサーバーを再起動すると消えます。Ubuntu・Debian では iptables-persistent を使って保存します。

sudo apt install iptables-persistent

# 今のルールを保存する(/etc/iptables/rules.v4 と rules.v6 に書かれる)
sudo netfilter-persistent save

インストールの途中で「今のルールを保存するか」を聞かれます。後から netfilter-persistent save を実行すれば、どちらを選んでも構いません。保存したルールは、起動時に読み込まれます。

手順8:制限を取り消す

チェーンへの入口を削除してから、チェーンを空にして削除します。

sudo iptables -D INPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW -j WP-HTTP-LIMIT
sudo iptables -F WP-HTTP-LIMIT
sudo iptables -X WP-HTTP-LIMIT

# IPv6 も設定した場合
sudo ip6tables -D INPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW -j WP-HTTP-LIMIT
sudo ip6tables -F WP-HTTP-LIMIT
sudo ip6tables -X WP-HTTP-LIMIT

# 保存しているなら、保存し直す
sudo netfilter-persistent save

運用での注意

  • 値はサイトに合わせる:この記事の 50 接続・毎秒 20 接続は出発点の例です。画像やスクリプトを多く読み込むページ、HTTP/2 を使っていない環境では、普通の閲覧でも接続数が増えます
  • 大規模な攻撃には別の対策が必要:サーバーの回線そのものが埋まる攻撃は、サーバーの中の iptables では防げません。CDN や回線事業者の対策を使います(DDoS攻撃の対策と緩和方法)
  • SSH を締め出さない:この記事のルールは 80・443 番だけに効くため、SSH には影響しません。ほかのルールと一緒に変更するときは、コンソールで操作できる状態にしてから作業します

iptables の基本的なルールの組み方は iptablesの基本設定|WordPressサーバーのファイアウォールを締め出されずに構築する手順 を参照してください。

まとめ

  • iptables で制限できるのは IP ごとの接続数と接続の速さで、URL ごとの制限やログイン試行の制限は Nginx や fail2ban で行う
  • connlimit で同時接続数、hashlimit で新しい接続の速さを制限し、値は普通の閲覧では届かない大きさにする
  • CDN を経由しているサーバーでは IP ごとの制限を使わない
  • ログで当たった IP を確かめて調整し、netfilter-persistent save で保存する

関連記事:

お気軽にご相談ください

お見積りへ お問い合わせへ
▲