REMOTE_HOST

メタ変数 REMOTE_HOST (CGI)

[8] CGIメタ変数 REMOTE_HOST は、要求しているクライアント完全修飾ドメイン名 (FQDN) を値として持ちます。

代替

[33] 昔はこのメタ変数が常に提供されるのが普通でした。

[34] しかし CGIスクリプトがこのメタ変数を利用するか否かに関わらず、 常にHTTPサーバーHTTPクライアントIPアドレス逆引きする必要があり、 これはそれなりの時間がかかる演算なので、好ましくないと考えられるようになりました。 CGIスクリプトは、必要ならいつでも REMOTE_ADDR を自力で逆引きできます。

[35] 現在の多くの HTTPサーバーCGI や、 PSGI などの CGI の系譜にあるインターフェイスの実装では、 REMOTE_HOST を提供しないか、提供しないのが標準設定となっています。

[36] CGIスクリプトPHP、その他のWebアプリケーションは、 相互運用性 (可搬性) のため、 REMOTE_HOST を使うべきではありません。

仕様書

構文

[10] RFC 3875 によれば、 REMOTE_HOST の値は次の構文によります。

[18] 鯖はこの変数を設定するべきです RFC 3875 4.1.9。 FQDN が利用できない場合には、 NULL(空文字列または null 値) を設定します (>>12)。あるいは、 REMOTE_ADDR と同じ値にしても構いません (>>19)。

[25] >>18 の規定 (前半) は無視され、設定によって無効になっているとき値を設定しないのが普通であるように思えます。

[20] REMOTE_HOST の値が IP 番地かホスト名かは、 REMOTE_ADDR の値と比較すればわかります。 (IP 番地が設定される REMOTE_ADDR は鯖が必ず設定しなければなりませんから、必ず比較ができます。) 両者が等しければ REMOTE_HOST は IP 番地です。 (厳密には、大文字・小文字を区別しないで比較しなければなりません。)

[24] REMOTE_HOSTREMOTE_ADDR とは別の IPアドレスになることは無いはずです。

[31] この値はを挟む場合などに最終的な受信者と異なることがあります。 >>30

[32] HTTP::Request::AsCGI は常に localhost とします。

ドメイン名

[26] ドメイン名LDHラベルで無いものが含まれている場合、例えば _ が含まれる場合も存在し得ると考えられ、その場合前述の構文には適合しませんが、 があえてそれをチェックしているとは思えませんから、おそらくそのまま CGIスクリプトに渡ることになるでしょう。

[27] CGI の仕様はIDN以前のものであり、また構文的にもIDN未対応ドメイン名スロットであると考えられます。 つまり Punycode はそのまま返され、 IDN が返されることは無いはずです。

[28] IDNA 以外の方法、例えば生の UTF-8ラベルが登録されている場合はこの限りではありません。 システム定義charsetによって符号化された非ASCII文字を含む値が返されることになるかもしれません。

歴史

NCSA CGI/1.1

[2]

The hostname making the request. If the server does not have this information, it should set REMOTE_ADDR and leave this unset.

要求を作成したホスト名。鯖がこの情報を持ち合わせていなければ変数 REMOTE_ADDR を設定し、こちらは設定しないでおくべきです。

CGI/1.1 I-D 03 版

[3]

The fully qualified domain name of the client sending the request to the server, if available, otherwise NULL. (See section 6.1.9.) Fully qualified domain names take the form as described in section 3.5 of RFC 1034 [10] and section 2.1 of RFC 1123 [5]. Domain names are not case sensitive.

Servers SHOULD provide this information to scripts.

要求を鯖に送信したクライアントの完全修飾ドメイン名か、 それが利用できなければ NULL です。 完全修飾ドメイン名は RFC 1034 の3.5節と RFC 1123 の2.1節で説明されている形式を取ります。 ドメイン名は大文字・小文字を区別しません。

鯖はこの情報をスクリプトに提供するべきです

RFC 3875 (CGI/1.1)

RFC 3875 4.1.9

メモ

[21] REMOTE_HOSTCGI/1.0 の最初の原案 CGP#515 で既に CGI の環境変数として用意されていました。 CGI/1.0 の正式版仕様書は現時点で未発見ですが、 おそらくそのまま残ったのでしょう。

その後、 CGI/1.1 NCSA にも REMOTE_HOST は引き継がれました。

[4] 当初の仕様書 NCSA は値が FQDN であることは要求せず、 単にホスト名としか述べていませんでした。新しい仕様書 RFC 3875 は明確に FQDN であることを要求していますが、 現在に至るまで、実装が必ずしも FQDN を返すわけではありません。 (何も考えずに実装すると gethostbyaddr を使って IP番地から変換することになるのでしょうから、 FQDN であることは保証されません。)

[1] また、古い仕様書 NCSA ではホスト名情報が利用できない時にこの変数を設定するべきではないと述べているのに対し、 現在の仕様書 RFC 3875NULL 値を設定するべきであるとしています。 加えて、新しい仕様書 RFC 3875IP番地を値として設定することも認めています。

後者については、新しい仕様書 RFC 3875 が出版されるかなり以前から IPv4番地を値として設定するがあることが知られています。

[7] >>1 ところが IPv4 番地を REMOTE_HOST に設定するのは実は NCSA の鯖だったりします。 手元の雑誌 (1997) の画面写真によれば、 NCSA/1.5.2 です。

[5] 以前はほとんどの鯖で REMOTE_HOST に適当なホスト名が入れられていたようですが、 1990年代の後半にこの状況は激変しました。 IP 番地からホスト名を引くのにはそれなりの時間がかかるので、 Apache の設定の既定値がこの機能をとするようになったためです。 これにより REMOTE_HOST が存在することを当てにしていた少なからぬ CGIスクリプトが影響を受けました。

実装

[6] Apache では、 HostnameLookups 指令の値によりこのメタ変数が設定されるかが決まります。

メモ

[22] REMOTE_HOST の値としてホスト名が得られない場合は、 REMOTE_ADDR の値を使って変換するのがよいでしょう (というか普通はそれしか方法がないでしょう)TCP/IP が使える環境なら、ほぼ間違いなく gethostbyaddr が存在するはずです。 (CPerlPHP などではこの名前の関数があります。)

注意: 古い環境では gethostbyaddrIPv6 番地に対応していないかもしれません。新しい環境であっても IPv6 が有効でなければ意味がありません。もっとも、 そのような場合に鯖から IPv6 番地が渡されることはありえないはずです。