Apache の環境変数

### Apache HTTP Server

# Apache における環境変数

Apache HTTP サーバは環境変数と呼ばれる、名前のついた 変数に情報を記憶する仕組みを提供しています。この情報はログ収集や アクセス制御などのいろいろな操作を制御するために使うことができます。 これらの変数は CGI スクリプトなどの外部プログラムと通信するためにも 使われます。この文書はそれらの変数の操作方法と使用方法をいくつか 紹介します。

これらの変数は環境変数と呼ばれていますが、オペレーティング システムによって制御されている環境変数と同じではありません。 実際は、これらの変数は Apache の内部構造の中に記憶され、操作されています。 それらは、CGI や SSI スクリプトに渡されたときだけ、実際の オペレーティングシステムの環境変数になります。サーバ自身が 実行されているオペレーティングシステムの環境を操作したい場合は、 オペレーティングシステムのシェルが提供している標準の環境変数の 操作方法を使わなければなりません。

- 環境変数の設定
- 環境変数の使用
- 特別な目的の環境変数
- 例

## 環境変数の設定

関連モジュール mod_env mod_rewrite mod_setenvif mod_unique_id | 関連ディレクティブ BrowserMatch BrowserMatchNoCase PassEnv RewriteRule SetEnv SetEnvIf SetEnvIfNoCase UnsetEnv

### 基本的な環境の操作

Apache において環境変数を設定する一番基本的な方法は、 無条件に環境変数を設定する `SetEnv` ディレクティブを使用することです。 `PassEnv` ディレクティブにより、Apache が起動されたシェルの 環境変数を渡すこともできます。

### リクエスト毎に条件に基づいて設定する

より柔軟性を高めるために、mod_setenvif で提供されているディレクティブを使用することで、リクエストの 特性に基づいて環境変数を設定することができます。例えば、特定のブラウザ (User-Agent) のリクエストや特定の Referer [意図的な綴りです] (訳注: 正しい綴りは referrer ですが、HTTP の仕様では Referer となっています) ヘッダが見つかったときのみ変数を設定することができます。 mod_rewrite の `RewriteRule` ディレクティブにおいて 環境変数を設定する `[E=...]` オプションを使用することで、 より柔軟な設定を行なうことができます。

### 一意な識別子

mod_unique_id は、非常に限られた条件の下で 「すべて」のリクエストについて、一意であることが保証されている値を環境変数 `UNIQUE_ID` に設定します。

### 標準 CGI 変数

Apache の設定ファイルで設定された環境変数とシェルから渡される 環境変数に加えて、CGI スクリプトと SSI ページには CGI の仕様で要求されている、 リクエストのメタ情報を持った環境変数の組が提供されます。

### いくつかの注意

- 環境を操作するディレクティブを使って標準 CGI 変数を上書きしたり変更したりすることはできません。
- CGI スクリプトを起動するために suexec が使用されている場合、CGI スクリプトが起動するために、環境変数は安全な環境変数の組に整理されます。 この安全な環境変数の集合は、コンパイル時に `suexec.c` で定義されます。
- 移植性のために、環境変数の名前はアルファベット、 数字とアンダースコア (訳注: '_') だけから成ります。 さらに、最初の文字は数字であってはいけません。 この制限に合わない文字は CGI スクリプトと SSI ページに渡されるときにアンダースコアに置換されます。

## 環境変数の使用

関連モジュール mod_access mod_cgi mod_include mod_log_config mod_rewrite | 関連ディレクティブ Allow CustomLog Deny LogFormat RewriteCond RewriteRule

### CGI スクリプト

環境変数の主な利用法の一つは、CGI スクリプトに情報を伝えることです。 上で説明されているように、CGI スクリプトに渡される環境変数は Apache の設定により設定される変数に加えて、リクエストの標準のメタ情報を含んでいます。 詳細は CGI チュートリアル を参照してください。

### SSI ページ

mod_include の `server-parsed` ハンドラで処理される server-parsed (SSI) ドキュメントでは、`echo` 要素を使用すると環境変数が出力されます。 また、ページのある部分がリクエストの性質に応じて変更されるように、 環境変数をフロー制御要素で使うことができます。詳細は SSI チュートリアル を参照してください。

### アクセス制御

`allow from env=` ディレクティブと `deny from env=` ディレクティブを使用して、サーバへのアクセスを環境変数の値で制御することができます。 `SetEnvIf` ディレクティブと組み合わせることで、クライアントの特性に基づいて サーバへのアクセス制御を柔軟に行なうことができるようになります。 例えば、これらのディレクティブを使用して、特定のブラウザ (User-Agent) からのアクセスを拒否することができます。

### 条件付きログ記録

`LogFormat` ディレクティブのオプション `%e` を使用することで、環境変数をアクセスログに記録することができます。さらに、 `CustomLog` ディレクティブの条件分岐式を使用することで、 環境変数の値によってリクエストをログに記録するかどうかを決めることができます。 `SetEnvIf` ディレクティブと組み合わせることで、 どのリクエストをログに記録するかを柔軟に制御することが可能になります。例えば、 `gif` で終わるファイル名へのリクエストはログに記録しない、 違うサブネットのクライアントからのリクエストだけをログに記録する、という選択が可能です。

### URL の書き換え

`RewriteCond` ディレクティブで評価文字列として `%{ENV:...}` 式を指定することで、mod_rewrite の書き換えエンジンが環境変数に基いて条件分岐を行なうことができます。 mod_rewrite が使用可能な変数で `ENV:` が前についていない変数は、 実際は環境変数ではないということに注意してください。 それらは他のモジュールからは使用できない mod_rewrite 用の特別な変数です。

## 特別な目的の環境変数

互換性の問題を解決するために、特定のクライアントと通信しているときは Apache の動作を変更できる機構が導入されました。できるだけ柔軟にするために、 これらの機構は環境変数を定義することで呼び出されます。普通は、 BrowserMatch ディレクティブを使いますが、例えば SetEnv ディレクティブや PassEnv ディレクティブも使用することができます。

## downgrade-1.0

これを指定することで、リクエストが HTTP/1.0 より新しいプロトコルの場合でも、HTTP/1.0 として扱われます。

## force-no-vary

応答ヘッダがクライアントに送られる前に `Vary` フィールドを取り除きます。 クライアントの中にはこのフィールドを正しく解釈しないものがあります (クライアントの既知の問題 のページを参照してください)。この変数を設定することでその問題を回避 することができます。この変数を設定すると、force-response-1.0 が設定されたことになります。

## force-response-1.0

これが設定されていると、常に HTTP/1.0 での応答になります。この機能は、 元々は AOL のプロキシの問題のために実装されました。クライアントの中には、 HTTP/1.1 の応答を返されると正しく動作しないものがあるかもしれません。 この機能を使用することで、そのようなクライアントとの間の互換性問題を解決できます。

## nokeepalive

これが設定されている場合は、KeepAlive を使用しないようにします。

## 例

### おかしな挙動をするクライアントに対してプロトコルの動作を変更する

クライアントに関する既知の問題に対処するために、以下の行を httpd.conf に入れることを推奨しています。

    #
    # The following directives modify normal HTTP response behavior.
    # The first directive disables keepalive for Netscape 2.x and browsers that
    # spoof it. There are known problems with these browser implementations.
    # The second directive is for Microsoft Internet Explorer 4.0b2
    # which has a broken HTTP/1.1 implementation and does not properly
    # support keepalive when it is used on 301 or 302 (redirect) responses.
    #
    BrowserMatch "Mozilla/2" nokeepalive
    BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0

    #
    # The following directive disables HTTP/1.1 responses to browsers which
    # are in violation of the HTTP/1.0 spec by not being able to grok a
    # basic 1.1 response.
    #
    BrowserMatch "RealPlayer 4\.0" force-response-1.0
    BrowserMatch "Java/1\.0" force-response-1.0
    BrowserMatch "JDK/1\.0" force-response-1.0

### 画像へのリクエストをアクセスログに記録しない

この例では、画像へのリクエストがアクセスログに現れないようにします。 これを変更することで、特定のディレクトリのログ収集をやめたり、 特定のホストからのリクエストのログ収集をやめたりすることが簡単にできます。

        SetEnvIf Request_URI \.gif image-request
        SetEnvIf Request_URI \.jpg image-request
        SetEnvIf Request_URI \.png image-request
        CustomLog logs/access_log env=!image-request

### 「画像の盗用」を防ぐ

この例は、別のサーバにいる人が、あなたのサーバにある画像を inline 画像として使用することを防ぎます。 これは推奨されている設定ではありませんが、ある限定された状況では有効です。 ここでは、すべての画像は /web/images というディレクトリにあると仮定します。

        SetEnvIf Referer "^http://www.example.com/" local_referal
        # Allow browsers that do not send Referer info
        SetEnvIf Referer "^$" local_referal
        <Directory /web/images>
           Order Deny,Allow
           Deny from all
           Allow from env=local_referal
        </Directory>

注: 'referer' と 'referal' の綴りは意図的なものです (訳注: 正しい綴りは referrer と referral)。

この手法に関する詳しい情報は ApacheToday のチュートリアル "Keeping Your Images from Adorning Other Sites" を参照してください。

### Apache HTTP Server