2026年6月5日
2026年6月5日
ModSecurity と fail2ban の違いと使い分け|WordPressサーバーでの役割分担と併用の手順
ModSecurity と fail2ban は、どちらも「不正なアクセスを止める」ための道具ですが、止め方が根本的に違います。ModSecurity はWebサーバーの中でリクエスト1件ごとの中身を検査して遮断するWAF(Webアプリケーションファイアウォール)で、fail2ban はログを後から読み、失敗を繰り返したIPアドレスをファイアウォールで一定時間締め出すツールです。そのため「どちらが優れているか」ではなく、防ぎたい攻撃に応じて役割を分け、多くの場合は併用するのが現実的です。この記事では、両者の仕組みの違い、WordPressサーバーでの使い分け、併用するときの設定の考え方を説明します。
仕組みの違い
ModSecurity:リクエストの中身を見て1件ずつ止める
ModSecurity はWebサーバーに組み込んで動くWAFエンジンです。Apache用のモジュールとして広く使われてきたバージョン2系と、Webサーバーから独立したライブラリ(libmodsecurity)とnginx用のコネクターで構成されるバージョン3系があります。
ModSecurity 自体は検査の仕組みで、何を攻撃とみなすかはルールで決まります。一般的には OWASP の Core Rule Set(CRS)を使います。CRS はSQLインジェクションやクロスサイトスクリプティング、ディレクトリトラバーサルなどのパターンを検出し、各ルールの点数を合計する「異常スコア」方式で、しきい値を超えたリクエストを遮断します。検出の厳しさは「パラノイアレベル」で調整します。
なお、ModSecurity は長く Trustwave 社が開発を主導していましたが、2024年にOWASPのプロジェクトへ移管されました。OWASP Coraza のような互換性を持つ別実装もあります。導入する場合は、使っているディストリビューションのパッケージやプロジェクトの現在の提供状況を確認してください(2026年10月現在)。
fail2ban:ログを読んで繰り返す相手を締め出す
fail2ban はログファイルを監視し、正規表現(フィルター)に一致する行が、一定時間内(findtime)に一定回数(maxretry)を超えたIPアドレスを、一定時間(bantime)ファイアウォールで遮断します。監視対象と条件の組み合わせを「jail」と呼び、SSH、メールサーバー、Webサーバーなど、ログを出すサービスなら幅広く対象にできます。
遮断はiptables・nftables・firewalldなどのファイアウォールで行うため、締め出されたIPアドレスからの通信はWebサーバーに届く前に止まります。
比較
| 観点 | ModSecurity | fail2ban |
|---|---|---|
| 判断の材料 | リクエストの中身(URL・ヘッダー・本文) | ログに残った結果 |
| 止めるタイミング | そのリクエストを処理する前 | 一定回数を超えた後 |
| 止める単位 | リクエスト1件 | IPアドレス(一定時間) |
| 得意な攻撃 | SQLインジェクション、XSSなどの攻撃パターン | ブルートフォース、繰り返しのスキャン |
| 主な負担 | 誤検知の調整、処理負荷 | フィルターの作成、正しい接続元IPの取得 |
どちらで何を防ぐか
ModSecurity が向いている場面
1回のリクエストで成立する攻撃は、fail2banでは防げません。ログに残った時点で、そのリクエストはすでに処理されているためです。プラグインの脆弱性を狙ったSQLインジェクションや、ファイルの読み取りを狙うパス操作などは、ModSecurity のように処理前に中身を見る仕組みが必要です。
ただし、WAFは脆弱性そのものを直すものではありません。WordPress本体・プラグイン・テーマの更新を優先し、WAFはその間の被害を減らす層として考えます。
fail2ban が向いている場面
wp-login.php へのパスワード総当たりや、xmlrpc.php への大量のリクエストは、1件ずつ見ると正常な形をしているため、WAFのルールでは止めにくい攻撃です。「同じ相手が短時間に何度も失敗している」という振る舞いで判断する fail2ban の方が向いています。SSHへの総当たりも同様です。
WordPress で fail2ban を使うときの注意
WordPress のログイン失敗は、HTTPステータスとしては通常の200で返ることが多く、Webサーバーのアクセスログだけでは失敗を判別しにくい点に注意が必要です。対策としては次の方法があります。
- ログイン失敗をログに書き出すプラグインを使う: 「WP fail2ban」のように、ログインの失敗などをsyslogに記録するプラグインがあります。fail2ban側はそのログを監視します。機能の詳細はバージョンで変わるため、プラグインの説明を確認してください。
- **アクセスログで
wp-login.phpへのPOSTの回数を数える**: 失敗かどうかは区別できないため、しきい値はある程度ゆるめに設定し、正規の利用者を締め出さないようにします。
自分で wp_login_failed アクションを使ってログを書き出す方法もありますが、その場合はユーザー名やパスワードをそのまま記録しないようにします。
もう一つの落とし穴が、接続元IPアドレスです。CDNやリバースプロキシの背後にあるサーバーでは、ログに残る接続元がCDNのアドレスになり、そのままではCDNごと遮断してしまいます。Webサーバー側で本来の接続元を取り出す設定(nginxの real_ip モジュールやApacheの mod_remoteip)を行い、信頼するプロキシのアドレスを限定します。さらに、CDNを経由する通信はサーバーのファイアウォールで止めても効果がないため、CDN側のAPIで遮断するアクションを使う構成も検討します。
併用する場合の設定の流れ
両者を組み合わせると、ModSecurity が攻撃のリクエストを遮断し、その記録を fail2ban が読んで繰り返す相手を締め出す、という分担ができます。作業は本番の前にステージング環境で行い、設定ファイルのバックアップを取ってから進めます。
- ModSecurity を検出のみのモードで動かす:
SecRuleEngine DetectionOnlyにして、しばらくログだけを取ります。WordPress の管理画面やブロックエディターの保存、REST API の利用など、普段の操作で誤検知が出ないかを確認します。 - 誤検知を除外ルールで調整する: 検出されたルールを無効にするのではなく、対象のURLやパラメーターに限って除外します。CRS には WordPress 向けの除外設定を有効にする仕組みがあるため、使っているCRSのバージョンの説明を確認します。
- 遮断モードに切り替える:
SecRuleEngine Onに変え、異常スコアのしきい値で遮断を始めます。 - fail2ban のjailを用意する: ログイン失敗用のjailと、ModSecurity の遮断記録を読むjailを作ります。fail2ban には ModSecurity のログ向けのフィルターが同梱されていることがあります。
fail2ban のjailの例です(ファイル名やログのパスは環境に合わせて変えてください)。
# /etc/fail2ban/jail.d/wordpress.local
[wordpress-login]
enabled = true
port = http,https
filter = wordpress-login
logpath = /var/log/nginx/access.log
# 10分間に10回を超えたら1時間遮断
findtime = 10m
maxretry = 10
bantime = 1h
# 管理者の固定IPなど、遮断しないアドレス
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
# /etc/fail2ban/filter.d/wordpress-login.conf
[Definition]
failregex = ^<HOST> .* "POST /wp-login\.php
ignoreregex =
設定後は、フィルターがログに一致するかを確かめてから有効にします。
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/wordpress-login.conf
sudo systemctl reload fail2ban
sudo fail2ban-client status wordpress-login
自分のIPアドレスを ignoreip に入れておくと、テスト中に締め出される事故を防げます。締め出された場合は sudo fail2ban-client set wordpress-login unbanip <IPアドレス> で解除できます。
レンタルサーバーの場合
共用のレンタルサーバーでは、ModSecurity や fail2ban を自分で入れられないことがほとんどです。多くの事業者はサーバー側でWAF機能を提供しているため、管理画面で有効にできるかを確認します。ログイン試行の制限は、WordPress のセキュリティプラグインで行うのが現実的です。
まとめ
- ModSecurity はリクエストの中身を処理前に検査するWAF、fail2ban はログを後から読んでIPアドレスを一定時間遮断するツール
- 1回で成立する攻撃(SQLインジェクションなど)は ModSecurity、繰り返しの攻撃(ログイン総当たりなど)は fail2ban が向いている
- ModSecurity は検出のみのモードで誤検知を調整してから遮断に切り替える
- fail2ban は WordPress のログイン失敗を判別できるログと、CDN背後での正しい接続元IPが前提になる
- どちらも脆弱性の修正の代わりにはならないため、本体とプラグインの更新を優先する