【無料ツール】画像をPDFに変換するPhotoPDF Appを公開しました!

【Nginx応用講座 第2回】WAF(Web Application Firewall)の構築。ModSecurityとOWASP CRSで鉄壁の要塞を作る

記事内に広告が含まれています。
[PR]

ファイアウォールをすり抜ける「アプリケーションへの攻撃」を防げ。

こんにちは!「LINUX工房」管理人の「リナックス先生」です。
前回は、大規模なトラフィックをさばくためのロードバランシングとキャッシュ戦略について学びました。
サーバーが落ちなくなった今、次に心配すべきは「中身(データ)の安全」です。

一般的なファイアウォール(L4)は、ポート(80/443)を開けるか閉じるかしか制御できません。
しかし、ハッカーは開いているポートを通って、堂々と「SQLインジェクション」「クロスサイトスクリプティング(XSS)」といった攻撃コードを送り込んできます。
これらはアプリケーションの仕様やバグを突くため、通常のネットワーク防御では防げません。

コウ君

先生、また怖い話ですか…。
一応、アプリ側(PHPやNode.js)でも入力チェックはしてるつもりなんですけど、それだけじゃダメなんですか?
WAFって導入が難しそうで、専用のアプライアンス製品を買わないといけないイメージがあります。
僕の小規模なサーバーにも導入できるんでしょうか?

リナックス先生

アプリ側の対策はもちろん必須よ。それがセキュリティの基本。
でも、人間が書くコードにバグは付きもの。WordPressのプラグインに脆弱性が見つかることだって日常茶飯事よ。
だからこそ、アプリに届く前のNginxの段階で「怪しいリクエスト」を検知して遮断するWAF(Web Application Firewall)が必要なの。
今回は、オープンソース最強のWAF「ModSecurity」をNginxに組み込んで、最強の盾を手に入れるわよ!

本記事では、NginxにModSecurity v3を導入し、世界標準のルールセットであるOWASP CRSを適用して、Webアプリケーションをサイバー攻撃から守る方法をステップバイステップで解説します。

🚀 Nginx応用講座(全8回)カリキュラム

現在地:【第2回】WAF(Web Application Firewall)の構築。ModSecurityと最新のNginxセキュリティ

  • 【第1回】大規模負荷分散とキャッシュ戦略。数万リクエストをさばく「Proxy Cache」と「Upstream」の極意
  • 【第2回】WAF(Web Application Firewall)の構築。ModSecurityと最新のNginxセキュリティ
  • 【第3回】マイクロサービス時代のルーティング。gRPC、WebSocket、認証プロキシ(auth_request)の統合
  • 【第4回】Nginxをプログラマブルに。Lua言語(OpenResty)による動的処理と機能拡張
  • 【第5回】絶対停止させない高可用性(HA)。KeepalivedによるVIP管理とフェイルオーバー
  • 【第6回】可観測性(Observability)の確保。Prometheus/Grafana連携とカスタムメトリクス
  • 【第7回】動的モジュールとカスタムビルド。必要な機能だけを組み込む軽量化テクニック
  • 【第8回】Kubernetes Ingress Controller入門。クラウドネイティブ時代のNginx運用

※基本講座の復習はこちら:Nginx基本講座(全8回)アーカイブ


第1章:ModSecurityとOWASP CRSの基礎知識

構築を始める前に、今回使う2つの重要なコンポーネントについて理解しておきましょう。
単にインストールするだけでなく、「何がどう動いて守ってくれるのか」を知ることが重要です。

ModSecurity(モド・セキュリティ)とは?

元々はApache用に開発された、世界で最も普及しているオープンソースのWAFエンジンです。
バージョン3(ModSecurity v3 / libmodsecurity)からはアーキテクチャが刷新され、Webサーバーに依存しない独立したライブラリとなりました。
これにより、Nginxでもパフォーマンスを落とさずに利用可能になっています。

注意点: ModSecurityはあくまで「エンジン」です。これ単体では動きません。Nginxと連携する「コネクタ」と、攻撃を判定する「ルール」が必要です。

OWASP Core Rule Set (CRS) とは?

ModSecurityを動かすための「ルールの詰め合わせセット」です。
セキュリティの世界的権威であるOWASPプロジェクトがメンテナンスしており、以下の「OWASP Top 10」を含む主要な攻撃を防ぐルールが含まれています。

  • SQLインジェクション (SQLi): データベースを不正操作する攻撃
  • クロスサイトスクリプティング (XSS): 悪意あるスクリプトを埋め込む攻撃
  • ローカルファイルインクルード (LFI): サーバー内のファイルを不正に読み出す攻撃
  • シェルショック等の既知の脆弱性攻撃: 古いミドルウェアの穴を突く攻撃
  • 悪質なボットやクローラー: サイトを重くしたり情報を盗むボット

「ModSecurity + OWASP CRS」の組み合わせは、OSSでWAFを構築する場合のデファクトスタンダードであり、多くの商用WAFサービスのベースにもなっています。


第2章:ModSecurity v3の導入(ビルドとインストール)

NginxでModSecurityを使うには、少し高度ですが「動的モジュール」としてコンパイルして組み込むのが一般的です。
パッケージ管理ツール(dnf/apt)だけでは最新版の連携が難しいため、ソースコードからのビルドを行います。
※OS: AlmaLinux 9 / Nginx: Mainline版 を前提とします。

ステップ1:必要な依存パッケージのインストール

ビルドに必要なコンパイラやライブラリ群をインストールします。

sudo dnf groupinstall "Development Tools"
sudo dnf install git wget pcre-devel zlib-devel openssl-devel libxml2-devel libcurl-devel geoip-devel yajl-devel doxygen

ステップ2:ModSecurity本体(libmodsecurity)のビルド

GitHubからソースコードを取得し、コンパイルします。
libmodsecurity はNginxとは独立したライブラリとしてシステムにインストールされます。

cd /usr/local/src
sudo git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity
cd ModSecurity
sudo git submodule init
sudo git submodule update
sudo ./build.sh
sudo ./configure
sudo make
sudo make install

これで /usr/local/modsecurity 配下にライブラリがインストールされます。
※コンパイルには数分〜十数分かかる場合があります。

ステップ3:Nginxコネクタのビルド

次に、NginxとModSecurityを繋ぐためのモジュール(ModSecurity-nginx)を作成します。
【最重要】 ここでは、現在インストールされているNginxと「全く同じバージョン」のソースコードが必要です。

# バージョン確認
nginx -v
# 例: nginx version: nginx/1.27.0 と表示された場合

# 同じバージョンのソースをダウンロード
cd /usr/local/src
sudo wget http://nginx.org/download/nginx-1.27.0.tar.gz
sudo tar -zxvf nginx-1.27.0.tar.gz

# コネクタのソースを取得
sudo git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git

# モジュールのコンパイル
# --with-compat オプションをつけることで、既存のNginxバイナリと互換性を持たせます
cd nginx-1.27.0
sudo ./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
sudo make modules

成功すると objs/ngx_http_modsecurity_module.so というファイルが生成されます。
これをNginxのモジュールディレクトリにコピーします。

sudo cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/

ステップ4:モジュールの読み込み設定

nginx.conf の先頭(eventsブロックより前)に、作成したモジュールを読み込む設定を追記します。

sudo vi /etc/nginx/nginx.conf

load_module modules/ngx_http_modsecurity_module.so;

events {
    ...
}

第3章:OWASP Core Rule Set (CRS) のセットアップ

エンジンが入ったので、次は頭脳となる「ルール(CRS)」を配置します。

1. CRSのダウンロード

設定ファイルを置くディレクトリを作成し、GitHubからCRSをクローンします。

sudo mkdir /etc/nginx/modsec
cd /etc/nginx/modsec

# ModSecurityの推奨設定ファイルをソースからコピー
sudo cp /usr/local/src/ModSecurity/modsecurity.conf-recommended ./modsecurity.conf
sudo cp /usr/local/src/ModSecurity/unicode.mapping .

# OWASP CRSのダウンロード
sudo git clone https://github.com/coreruleset/coreruleset.git
sudo mv coreruleset/crs-setup.conf.example coreruleset/crs-setup.conf

2. メイン設定ファイル(main.conf)の作成

これら全てのルールファイルを読み込むための親ファイルを作成します。

sudo vi /etc/nginx/modsec/main.conf

# ModSecurity基本設定
Include /etc/nginx/modsec/modsecurity.conf

# OWASP CRS設定(バージョンによりパスが異なる場合があるため確認推奨)
Include /etc/nginx/modsec/coreruleset/crs-setup.conf

# OWASP CRSルール本体
Include /etc/nginx/modsec/coreruleset/rules/*.conf

3. Nginxでの有効化

WAFを適用したい server ブロック、または特定の location ブロックに記述します。
APIサーバーだけ守りたい場合は location /api/ の中に書くことも可能です。

server {
    listen 80;
    server_name example.com;

    # ModSecurity有効化
    modsecurity on;
    
    # 設定ファイルの指定
    modsecurity_rules_file /etc/nginx/modsec/main.conf;

    location / {
        proxy_pass http://backend;
    }
}

これで設定完了です。Nginxをリロードしましょう。
sudo systemctl reload nginx

💡 プロのノウハウ:まずは「検知モード」から
ModSecurityのデフォルト設定は “DetectionOnly”(検知のみ) です。
攻撃を見つけてもログに残すだけで、ユーザーへのレスポンスは遮断しません。
いきなり遮断モード(On)にすると、正常なアクセスまでブロックしてしまう可能性があるため、最初の1〜2週間は必ずこのモードで運用を開始してログを観察します。


第4章:WAFの動作確認と遮断テスト

実際に攻撃コードを送って、ログに残るか確認してみましょう。
※注意:以下のテストコードはご自身の管理下にあるサーバーに対してのみ実行してください。

テスト1:XSS攻撃のシミュレーション

ブラウザで以下のURLにアクセスしてみます。

http://example.com/?q=<script>alert(1)</script>

まだ遮断モードではないので、ページは普通に表示されます(アプリ側でエスケープされていれば安全ですが、WAFとしては検知すべきです)。
しかし、ログ(/var/log/modsec_audit.log)を見てみましょう。

Message: Warning. Pattern match "<script" at ARGS:q. ... [id "941100"] [msg "XSS Attack Detected via libinjection"] ...

しっかりと「XSS Attack」として検知され、ルールID 941100 が反応していることが分かります。

遮断モードへの切り替え

ログを確認して問題なさそうであれば、実際に遮断するように設定を変更します。

sudo vi /etc/nginx/modsec/modsecurity.conf

# 変更前
SecRuleEngine DetectionOnly

# 変更後
SecRuleEngine On

Nginxをリロード後、もう一度さきほどのURLにアクセスしてみてください。
今度はNginxのデフォルトエラー画面 403 Forbidden が表示されるはずです。
これで、あなたのサーバーは攻撃から守られています。


第5章:運用最大の壁「誤検知(False Positive)」との戦い

WAF運用で最も大変なのが、正常なアクセスを攻撃とみなしてしまう「誤検知(False Positive)」の対応です。
例えば、WordPressの記事投稿で「SQL文の解説」を書いたり、プログラミングブログで「<script>タグを含むコード」を投稿したりすると、WAFにブロックされることがあります。

チューニング(除外設定)の手順

誤検知が発生した場合、以下の手順で特定のルールを除外(ホワイトリスト化)します。

1. ログの確認:
403エラーが出た時の audit.log または error.log を確認し、どのルールIDが反応したかを特定します。
(例: ルールID 941160 が反応)

2. 除外ルールの作成:
/etc/nginx/modsec/coreruleset/rules/ 内のファイルを直接編集するのではなく、独自の除外ファイルを作ります。
sudo vi /etc/nginx/modsec/whitelist.conf

例1:特定のルールIDを全体で無効化する(危険なので慎重に)
そのルール自体をサーバー全体でオフにします。

SecRuleRemoveById 941160

例2:特定のURL(/wp-admin/)でのみ、特定のルールを無効化する(推奨)
管理画面でのみ、特定のチェックをスキップします。

SecRule REQUEST_URI "@beginsWith /wp-admin/" \
    "id:1001,phase:1,pass,nolog,ctl:ruleRemoveById=941160"

3. 読み込み設定:
作成したホワイトリストを main.conf最後で読み込むようにします。

Include /etc/nginx/modsec/whitelist.conf

このように、ログを見ながら「これは正常な通信だ」と判断したものを一つひとつ許可していく作業(チューニング)が、WAF運用には不可欠です。
これをサボると、ユーザビリティが著しく低下してしまいます。


第6章:パフォーマンスへの影響と対策

WAFはすべてのリクエストの中身(POSTデータ含む)を詳細に検査するため、CPU負荷が高くなります。
アクセス数が多いサイトでは、パフォーマンス低下が懸念されます。

対策1:静的ファイルを除外する

画像やCSS、動画ファイルにSQLインジェクションを仕込むことはまずありません。
静的ファイルへのリクエストではModSecurityをオフにします。

location ~* \.(jpg|jpeg|png|gif|css|js|ico|woff|svg)$ {
    modsecurity off;
    # その他の設定...
}

対策2:監査ログの出力を絞る

デフォルトでは全てのリクエストの詳細ログ(Audit Log)を保存するため、ディスクI/Oが激増します。
「遮断した時だけログに残す」設定に変更するのが一般的です。

/etc/nginx/modsec/modsecurity.conf

# RelevantOnly: 警告やエラーがあった時だけ記録
SecAuditEngine RelevantOnly

まとめ:WAFは「育てていく」セキュリティ

お疲れ様でした!
これであなたのNginxサーバーは、アプリケーションレベルの攻撃を防ぐ強力な盾を手に入れました。

今回の重要ポイント:

  • ModSecurity + OWASP CRS は最強のOSS WAF構成。
  • 最初は「DetectionOnly」でログを収集し、影響を確認する。
  • 誤検知は避けて通れない。除外ルール(ホワイトリスト)でチューニングする。
  • 静的ファイルへのWAF適用はオフにして、パフォーマンスを守る。

WAFは「入れたら終わり」ではありません。
アプリケーションの更新や新しい攻撃手法に合わせて、日々ルールを調整し、育てていくものです。
少し手間はかかりますが、その分、あなたのサイトの安全性は格段に向上します。

さて、セキュリティの次は、現代のWeb開発トレンドである「マイクロサービス」への対応です。
最近のアプリは、REST APIだけでなく、gRPCやWebSocketといった新しい通信プロトコルを使うことが増えています。
Nginxはこれらのプロトコルも完璧にハンドリングできます。

次回、第3回は「マイクロサービス時代のルーティング。gRPC、WebSocket、認証プロキシ(auth_request)の統合」です。
最新の通信プロトコルをNginxでさばく設定や、アプリの手前に認証機能を外付けする「認証プロキシ」パターンなど、モダンなアーキテクチャに必須の技術を解説します。お楽しみに!

▼ セキュリティ技術を実践で学ぶ ▼

攻撃と防御をシミュレーション
「VPS」で自分専用環境

おすすめVPSを見る

セキュリティスペシャリストへ
「ITエンジニア転職」

転職エージェントを見る

[PR]

💡 サーバー構築やコマンドの練習には、VPSが圧倒的におすすめです

手元のパソコンや大切なメイン環境で検証を行うと、設定ミスでシステムを壊してしまったり、不要なパッケージが溜まって動作が不安定になるリスクがあります。

もしあなたが実務レベルのスキルを最短で身につけたいのであれば、月額ワンコインから使えて、失敗しても数分で初期状態にリセットできるVPS(仮想専用サーバー)を利用するのが、プロも実践する最も確実で安全な学習方法です。

▼ プロも推奨するVPS環境はこちら ▼

Nignx講座
linux工房をフォローする

コメント