目的
完全に自分用の備忘録です。
ローカル環境では動いていた Java Web アプリケーションが、本番の 外部リバースプロキシ+APサーバ(Apache+Tomcat)構成に導入した途端に 403 Forbidden となる事象を整理し、再発防止や他案件でも応用できるナレッジを共有する。
前提条件
アプリケーションは Tomcat 上で動作(Spring MVC / Spring Web Flow 等を利用)。
APサーバには Tomcat と内部 Apache が同居しており、内部 Apache が Tomcat へプロキシ。
さらにその前段に 外部リバースプロキシサーバ(Apache) が存在し、インターネットからの入口になっている。
URL の構成は以下の通り:
https://[APサーバホスト]/[AP]/flow/...
本番/外部リバプロ経由
https://[リバプロホスト]/[APサーバホスト]/[AP]/flow/...
※ [AP] はアプリのコンテキストルート
構成イメージ(テキスト図)
クライアント
│
▼
[外部リバースプロキシサーバ] (Apache)
│ URL: /[APサーバホスト]/[AP]/flow/...
│
▼
[APサーバ]
├─ Apache (内部プロキシ)
│ URLをTomcatへ中継
└─ Tomcat
└─ [AP] (アプリケーション)
URL: /[AP]/flow/...
症状
ローカルや直アクセスではアプリが正常に動作。
外部リバプロ経由でアクセスすると 403 Forbidden。
Apache の access_log に 403 が残るが、Tomcat のアクセスログには記録がない。
→ 原因は Apache 側でブロック。
主な原因パターン
- URLプレフィックスのずれ
外部リバプロの導入により、URLに [APサーバホスト] という余計な階層が追加されている。
Tomcat の contextPath は /[AP] を前提にしているため不一致。
- Apache の認可設定 (authz_core)
/ の Require all denied 等により、リクエストが拒否されている。
- ProxyRequests の設定ミス
誤って ProxyRequests On になっており、前方プロキシモード扱いで 403。
- mod_security / WAF のルール命中
特定のパスやパラメータがセキュリティルールに引っかかってブロック。
- VirtualHost のマッチミス
リクエストが想定していない vhost に到達し、その設定で拒否されている。
調査の手順
- アクセスログ/エラーログの確認
Tomcatに届いていないなら Apache 側で確定。
apachectl -S で vhost マッチを確認。
- ログレベルの強化
LogLevel core:info rewrite:trace6 proxy:trace2 authz_core:debug ssl:debug
rewrite や authz_core がどの条件で 403 を返したかを可視化。
mod_security がある場合は LogLevel security2:debug。
- ProxyRequests の確認
ProxyRequests Off
- 検証用の最小設定で通す
ProxyRequests Off
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
RewriteEngine On
外側URLの余分な /[APサーバホスト]/ を剥がして Tomcat へ渡す
RewriteRule ^/[^/]+/([A-Za-z0-9_-]+)/(.*)$ /$1/$2 [PT]
ProxyPass /[AP]/ http://AP_SERVER:8080/[AP]/
ProxyPassReverse /[AP]/ http://AP_SERVER:8080/[AP]/
Require all granted
- Cookie の補正
ProxyPassReverseCookiePath /[AP]/ /[APサーバホスト]/[AP]/
対応方法のまとめ
URLの余分な階層を削る:RewriteRule または ProxyPassMatch で /[APサーバホスト]/[AP]/... を /[AP]/... に変換。
認可設定を調整:対象アプリパスに対して Require all granted を設定し、全体の deny に負けないようにする。
Cookie Path/Domain を補正:外側URLと内側URLで食い違いがある場合に必要。
mod_security / WAF のルール確認:不要な場合は DetectionOnly にして原因特定。
まとめ
ローカルで動作し、本番で 403 Forbidden になる場合は Apache がブロックしている。
原因はほぼ「URLプレフィックスずれ」「認可設定」「ProxyRequests設定」「mod_security」のいずれか。
切り分けの第一歩は ログ強化で誰が 403 を返したかを特定すること。
最小構成で一度リクエストを通し、その後セキュリティ設定を追加するのが安全。