Ubuntu 26.04 の Apache に WAF を入れる場合、最初から遮断モードで運用するより、まずは ModSecurity を DetectionOnly で動かし、監査ログと誤検知を確認する方が現実的です。WAF は入れれば安全になる魔法の部品ではなく、ルール、ログ、除外設定、運用確認まで含めて扱うものです。
この記事では、Apache に ModSecurity と Core Rule Set を導入し、検知モードで動かす基本手順を整理します。実環境では構成管理で /etc/modsecurity/modsecurity.conf を配布していますが、ここでは手動で行う場合の流れに落とし込みます。
libapache2-mod-security2とmodsecurity-crsを導入するsecurity2とunique_idモジュールを有効化する- まず
SecRuleEngine DetectionOnlyで動かす - 監査ログ
/var/log/apache2/modsec_audit.logを確認する - 誤検知を確認してから遮断モードへの移行を判断する
| 対象 OS | Ubuntu 26.04 |
|---|---|
| 対象サービス | apache2.service |
| 主要パッケージ | libapache2-mod-security2, modsecurity-crs |
| 設定ファイル | /etc/modsecurity/modsecurity.conf |
| 初期モード | DetectionOnly |
| 監査ログ | /var/log/apache2/modsec_audit.log |
-
1
WAF パッケージを入れるModSecurity 本体と Core Rule Set を導入します。
-
2
Apache モジュールを有効化する
security2とunique_idを有効にします。 -
3
ModSecurity 設定を配置するまず検知モードで起動し、レスポンスボディ検査や status engine を整理します。
-
4
Apache 設定を検証する
apache2ctl -tで構文確認します。 -
5
ログを見て調整する誤検知を見ながら遮断モードへの移行可否を判断します。
書籍
ModSecurity Handbook, Second Edition
ModSecurity のルール、監査ログ、誤検知調整を深く確認したい場合の参考書籍です。価格や在庫はリンク先で確認してください。
Amazon で見るこのリンクは Amazon アソシエイトリンクです。
Apache WAF の考え方
WAF はアプリケーション手前で不審な HTTP リクエストを検知、または遮断する仕組みです。ただし、正規のリクエストでもルールに引っかかることがあります。特に WordPress、管理画面、API、ファイルアップロード、JSON リクエストでは誤検知が起きやすくなります。
- 最初は
DetectionOnlyでログを見る - 誤検知しやすい URL やパラメータを把握する
- 遮断モードへ移行する前に管理画面と API を確認する
- ルール除外は範囲を絞って行う
- WAF を入れてもアプリケーション本体の更新は必要
ModSecurity と CRS をインストールする
Ubuntu 26.04 では、Apache 用 ModSecurity と Core Rule Set をパッケージから導入できます。
sudo apt update
sudo apt install -y libapache2-mod-security2 modsecurity-crsApache モジュールを有効化する
ModSecurity の Apache モジュールと、ログの識別に使う unique_id モジュールを有効化します。
sudo a2enmod security2
sudo a2enmod unique_idmodsecurity.conf を作成する
まずは検知モードで設定します。DetectionOnly ではルールに一致しても原則として遮断せず、ログで挙動を確認できます。
sudo tee /etc/modsecurity/modsecurity.conf >/dev/null <<'EOF'
SecRuleEngine DetectionOnly
SecRequestBodyAccess On
SecRule REQUEST_HEADERS:Content-Type "^(?:application(?:/soap\+|/)|text/)xml" \
"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"
SecRule REQUEST_HEADERS:Content-Type "^application/json" \
"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
SecRequestBodyInMemoryLimit 131072
SecRequestBodyLimitAction Reject
SecRequestBodyJsonDepthLimit 512
SecRule REQBODY_ERROR "!@eq 0" \
"id:'200002',phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"
SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
"id:'200003',phase:2,t:none,log,deny,status:400,msg:'Multipart request body failed strict validation.'"
SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \
"id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"
SecPcreMatchLimit 100000
SecPcreMatchLimitRecursion 100000
SecRule TX:/^MSC_/ "!@streq 0" \
"id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"
SecResponseBodyAccess Off
SecResponseBodyMimeType text/plain text/html text/xml
SecResponseBodyLimit 524288
SecResponseBodyLimitAction ProcessPartial
SecTmpDir /var/cache/modsecurity
SecDataDir /var/cache/modsecurity
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecAuditLogParts ABDEFHIJZ
SecAuditLogType Serial
SecAuditLog /var/log/apache2/modsec_audit.log
SecArgumentSeparator &
SecCookieFormat 0
SecUnicodeMapFile unicode.mapping 20127
SecStatusEngine Off
EOFDetectionOnly は、導入直後の確認に向いたモードです。本番で遮断する場合は SecRuleEngine On にしますが、その前に誤検知を確認します。設定を検証して Apache を再起動する
Apache の構文確認を行い、問題がなければサービスを再起動します。
sudo apache2ctl -t
sudo systemctl restart apache2.service
systemctl status apache2.service --no-pager基本動作を確認する
Web サイトへ通常のリクエストを投げ、Apache が正常に応答することを確認します。WAF 導入直後は、正常アクセスが壊れていないことの確認が重要です。
curl -I http://www.example.com/
curl -I https://www.example.com/監査ログを確認する
ModSecurity の検知結果は監査ログに出ます。まず通常アクセス時に余計な検知が大量に出ていないか確認します。
sudo test -f /var/log/apache2/modsec_audit.log
sudo tail -n 200 /var/log/apache2/modsec_audit.logApache のログも合わせて確認する
journalctl -u apache2.service --no-pager -n 100
sudo tail -n 100 /var/log/apache2/error.log
sudo tail -n 100 /var/log/apache2/access.log遮断モードにする場合
検知ログを確認し、正規のアクセスに問題がないと判断できたら、遮断モードを検討します。変更点は SecRuleEngine です。
sudo sed -i 's/^SecRuleEngine .*/SecRuleEngine On/' /etc/modsecurity/modsecurity.conf
sudo apache2ctl -t
sudo systemctl restart apache2.service誤検知が出た場合の考え方
誤検知が出た場合、ルール全体を無効化するのではなく、対象 URL、対象パラメータ、対象ルール ID を確認し、範囲を絞って除外します。
- どの URL で発生しているか
- どのパラメータが検知されているか
- どのルール ID が反応しているか
- ログインや管理画面だけの問題か
- API や JSON リクエスト特有の問題か
WordPress のような CMS では、投稿保存やアップデート処理が WAF に引っかかることがあります。WAF の保護と運用性のバランスを取りながら、ルール除外を小さく設計します。
まとめ
Ubuntu 26.04 の Apache WAF 設定では、libapache2-mod-security2 と modsecurity-crs を導入し、まず DetectionOnly で検知ログを見る構成が扱いやすいです。
WAF は遮断できることよりも、何を検知し、何を誤検知し、どこまで除外するかを継続して見られることが重要です。Apache の基本設定、TLS、リバースプロキシと組み合わせる場合も、まずはログで挙動を確認してから遮断モードへ進めるのが安全です。



