質問: ### 前提・実現したいこと 最終的にやりたいことは「特定のIPからのアクセスだけ403にせずリライトする」ですが、事象解説のため簡略例で説明させていただきます。 httpd.conf に対して、後述の Deny(for Apa2.2) または Require(for Apa2.4)設定を記載して、上位ディレクトリレベルで全てのアクセスをACLで拒否しています。 この状態でRewriteRule設定を入れた場合でも、ACLが有効化されたままで403エラーとなることを実現したいと考えています。 ### 発生している問題・エラーメッセージ <結果> ブラウザからアクセスした結果、 ・Apache2.2では403エラー(正常にACLが効いている) ・Apache2.4では302でリダイレクトでgoogleに飛ばされる(ACLが効いていない) となりました。 <問題点> ・Apache2.4では、本来deniedとなるはずのアクセスが許可されてしまい、 リライトが機能してgoogleへ302リダイレクトされてしまいます。 ・つまり2.2とは逆で、ACL設定よりもRewriteRuleの設定が優先されているように見えます。 ・ApacheのDirectory仕様ではディレクトリの階層が上のほうから処理されるため、本来であればACL設定が効いて403エラーとなるはずです。 ### 該当のソースコード ``` <設定内容> ▼Apache2.4 Require all denied RewriteEngine On RewriteRule ^(.*)$ http://www.google.com [R=302,L] ▼Apache2.2 Deny from all RewriteEngine On RewriteRule ^(.*)$ http://www.google.com [R=302,L] ``` ### 試したこと ・2.2と2.4でConf設定の差異などを調べたのですが、関連するようなものはありませんでした。 ・Apache2.4からアクセス制御の認証仕様が変更されたため、 Orderを書くのではなくRequireになりましたが、その関係では? と疑っていますが Web上にも同様の知見がなく、1日中Confをいろいろ変更して試してみたのですが解決していない状況です。 ・ Require all denied でも結果は同じでした(2.2は403で、2.4は302)。 ・RHバンドル版ではなくソースコンパイル版のApacheですので、RH社への問い合わせができず、自己解決するしかない状況です。 お力添えいただけますと幸甚です。 ### 補足情報(言語/FW/ツール等のバージョンなど) OS:Linux version 2.6.32-220.4.2.el6.x86_64 (mockbuild@x86-003.build.bos.redhat.com) (gcc version 4.4.6 20110731 (Red Hat 4.4.6-3) (GCC) ) #1 SMP Mon Feb 6 16:39:28 EST 2012 Apache:2.4.10、2.2.16
回答: TaichiYanagiya様、moonphase様 ご協力ありがとうございました。 本件、お陰様で解決しました。 2.2と2.4のエラードキュメント表示の仕様差異が原因でした。 *403時に ErrorDocument 403 を読み込むのか、読み込まないのかの違いでした。 該当するケースは「エラードキュメント含めて全部HitさせるようなRewriteRuleを書いている & ACLをかけたい」といった場合になると思います。 1.発生条件と結果 ▼条件(And条件) 1.Apache2.4を利用している 2.ACLをかけている 3.ErrorDocument 403を定義している 4.エラードキュメント含めて全コンテンツをHitさせるRewriteRuleを書いている 問題のあるConf定義 ``` (前略) ErrorDocument 403 /error/403.html (中略) Require all denied ※すべてを拒否 RewriteEngine On RewriteRule ^(.*)$ http://www.google.com [R=302,L] ※すべてをGoogleにリダイレクトさせる ``` ▼結果 Apache2.4では403エラーにはならずRewriteRuleが動作し、Googleへ302リダイレクトされる (Apache2.2でDeny from allしていた時は403になっていた) 2.原因 Apache2.4より、403エラー時の動作ロジックが以下のように変更されたことが原因と推測される Apache2.2の場合 Deny from all が機能 → ErrorDocument 403 が定義されていても【エラードキュメントを読み込まない】 →結果:ステータスコード403のみをブラウザへ返して終了 Apache2.4の場合 Require all denied が機能 → ErrorDocument 403 が定義されていると【エラードキュメントを読み込む】 →結果:通常のコンテンツと同じように403ドキュメントを表示する ※エラードキュメントも対象になるようなRewriteRuleを定義していると、403にならずにリライトが実行されてしまう 補足: v2.2で403の場合は403カスタムエラードキュメントを表示せず403となる(ErrorDocument未定義時と同じ挙動) v2.4で403の場合は403カスタムエラードキュメントを表示する(但し、ErrorDocument未定義時はカスタムエラードキュメントを表示せず403となる) 3.解決策 エラードキュメントのみをリライトで回避するルールを記載する 正しい記載例 ``` (前略) ErrorDocument 403 /error/403.html (中略) RewriteEngine On RewriteCond %{REQUEST_URI} !^/error/.*$ ★追記★ RewriteRule ^(.*)$ http://www.google.com [R=302,L] ``` 解決しましたので、本件はクローズとさせていただきます。 ありがとうございました。