Apache設定ファイルのSetEnv/SetEnvIf適用順番
2020年1月30日現在、ココVALUE-SERVERで使用されているapache2.2(古い)で.htaccessを使っていろいろな設定が出来る。出来るけど、その設定には適用順番があるって話(2.4でも同様)。
事の発端
SetEnv HOGE "deny"
Order Deny,Allow
Deny from env=HOGE
この.htaccessが置かれたディレクトリが見えてしまう。論より証拠がこちら(VALUE SERVER上なのでConoHaに移行した現在はない)。
参考リンクに置いたapacheのドキュメントに従って解説を入れると、
- SetEnvは環境変数HOGEに値denyを設定している
- Orderはまず全てをAllowとした上で、Deny処理を適用後に、Allow処理を入れるという宣言
- Denyは環境変数HOGEが設定されていたら、全部Denyとするという意味
つまり、「書かれた順番どおりに処理されたなら、この.htaccessが置かれたディレクトリでは全て403 Forbiddenになるはず」ということ。しかし200 OKで見えてしまっているわけです。
いろいろ疑い調べましたが、日本語の2.2のマニュアルには記載がありませんが、英語の2.2以降のマニュアルと、日本語の2.4以降のマニュアルに、
https://httpd.apache.org/docs/2.4/ja/env.html#setting
SetEnv
はリクエスト処理の 段階の中でも遅くに実行されます。つまりSetEnvIf
やRewriteCond
などからは、変数がそこで設定されていることがわかりません。
という、よ~く読み漁らないと見つからない記述を見つけました。2.2の日本語版ではどれだけ読み漁っても見つかりませんけど…。
で、「それ本当なの?」「本当ならどう書けばいいの?」というのを読み解くのが今回のミッションです。
実験
そもそもSetEnv出来てるの?
SetEnvの成功例が必要です。確認できたのが、こちらの.htaccessになります。
SetEnv HOGE "deny"
Header set X-Frame-Options %{HOGE}e env=HOGE
解説
- 環境変数HOGEに値denyを設定する
- 環境変数HOGEが設定されていたら、HTTPレスポンスヘッダのX-Frame-Optionsに環境変数HOGEの内容を設定する
結果
こちらのリンク先(VALUE SERVER上なのでConoHaに移行した現在はない)のディレクトリに当該.htaccessを置いています。Chromeなどの開発者ツールでNetworkモニタリングしつつ、リンク先を読み込めば、HTTPプロトコルのレスポンスヘッダを見ることで分かります。
HTTP/1.1 200 OK
...
X-Frame-Options: deny
...
SetEnv自体は出来てますね。成功です。つまり処理順序の問題であるという可能性が高まりました。
じゃあDeny fromは出来てるの?
次はDeny fromの成功例が必要です。環境変数パターンは試せてませんが、.htaccessでAllow/Deny設定を上書き可能かどうかはApacheの設定次第なので、確認が必要ということです。確認用の.htaccessが以下です。
Order Deny,Allow
Deny from All
解説
- Orderはまず全てをAllowとした上で、Deny処理を適用後に、Allow処理を入れるという宣言
- 全てをDenyする
つまり、「この.htaccessを含むディレクトリ以下は全て403 Forbiddenになる」という設定です。
結果
こちらのリンク先(VALUE SERVER上なのでConoHaに移行した現在はない)のディレクトリに当該.htaccessを置いています。 辿れば分かりますが、403になります。置かれてるファイルはいつものsample.htmlです。
SetEnvIfとSetEnvの処理順序確認
記述内容の確認になります。SetEnvIfからSetEnvの結果を参照して本当にうまく動作しないかどうかを見ます。確認用.htaccessが以下になります。
SetEnv HOGE "deny"
SetEnvIf HOGE "deny" HOGECHILD=deny
Header set X-Frame-Options %{HOGECHILD}e env=HOGECHILD
解説
- 環境変数HOGEに値denyを設定する
- 環境変数HOGEの値がdenyだったら、環境変数HOGECHILDに値denyを設定する
- 環境変数HOGECHILDが設定されていたら、HTTPレスポンスヘッダX-Frame-Optionsに環境変数HOGECHILDの値を設定する
結果
こちらのリンク先(VALUE SERVER上なのでConoHaに移行した現在はない)のディレクトリに当該.htaccessを置いています。Chromeなどの開発者ツールでNetworkモニタリングしつつ、リンク先を読み込めば、HTTPプロトコルのレスポンスヘッダを見ることで分かります。
HTTP/1.1 200 OK
Date: Wed, 29 Jan 2020 23:38:37 GMT
Server: Apache
Last-Modified: Wed, 29 Jan 2020 21:28:41 GMT
ETag: "1581901-31-59d4e063ccc5b"
Accept-Ranges: bytes
Vary: Accept-Encoding,User-Agent
Content-Encoding: gzip
Content-Length: 61
Connection: close
Content-Type: text/html
X-Frame-Optionsヘッダの出力がありません。確かにうまく動作しておらず、SetEnvIfがSetEnvより処理が早い可能性が高まります。
SetEnvIfは単体なら動くの?
単体で機能するなら、処理順序で確定します。確認用.htaccessが以下になります。
SetEnvIf Remote_Addr ".*" HOGE=deny
Header set X-Frame-Options %{HOGE}e env=HOGE
解説
- クライアントIPアドレスRemote_Addrの値が正規表現で".*"にマッチしたら、環境変数HOGEに値denyを設定する(何でもマッチするので、必ず設定される)
- 環境変数HOGEが設定されていたら、HTTPレスポンスヘッダX-Frame-Optionsに環境変数HOGEの値を設定する
結果
こちらのリンク先(VALUE SERVER上なのでConoHaに移行した現在はない)のディレクトリに当該.htaccessを置いています。Chromeなどの開発者ツールでNetworkモニタリングしつつ、リンク先を読み込めば、HTTPプロトコルのレスポンスヘッダを見ることで分かります。
HTTP/1.1 200 OK
...
X-Frame-Options: deny
...
X-Frame-Optionsヘッダの出力されています。単体なら確かにうまく動作しており、SetEnvIfがSetEnvより処理が早いことが確定しました。
SetEnvの代わりにSetEnvIfにしてみる
最後にどうすればいいの?の回答です。.htaccessが以下になります。
SetEnvIf Remote_Addr .* HOGE=deny
Order Deny,Allow
Deny from env=HOGE
新しい要素がないので解説は省略
結果
こちらのリンク先(VALUE SERVER上なのでConoHaに移行した現在はない)のディレクトリに当該.htaccessを置いています。 辿れば分かりますが、403になります。置かれてるファイルはいつものsample.htmlです。
ディスカッション
コメント一覧
まだ、コメントがありません