return
環境変数のお話
目次
- はじめに
- プロキシサーバーを経由しない場合
- プロキシサーバー経由の場合
- 串のお話
はじめに
クライアント(ブラウザ)がCGIを呼び出したした場合、サーバーは、各種の環境変数を設定してからこのCGIを起動します。この環境変数には、クライアントがサーバーにリクエストした際の情報に基づくものや、サーバー自身の情報などがあります。
そして、CGIがこれらの環境変数を調べることにより、訪問者に関する情報やプロキシサーバー経由かどうかなどを知ることができる可能性があります。
あなたがここのサーバーのCGIを起動した場合に設定される環境変数は、「ここ」をクリックしてご覧ください。
なお、この環境変数表示用 perl script のソースも公開しておきます。
| ファイル | 使用方法 | FTP | パーミッション |
| env.txt | env.cgi に名称変更 | ASCII転送 | 755 |
第1行目のperlのパスは、設置環境に合わせて変更してください。
このスクリプトは、PDS扱い(無断使用改造配布自由)ということで好き勝手にご利用ください。
ただし、元のものは他のCGIとの連携のための小細工とかがあるんで、公開したものは不要なコードを削除して少し変えてあります(実際の実行イメージはこちら)。また、ネットスケープ用には、環境変数表示の最後にJavaのオマケも付けておきました。
プロキシサーバーを経由しない場合
まず、ここ をクリックしてプロキシサーバーを経由しない場合の環境変数を見てください。この環境変数は、「TOOLS」のページで「getenv.html」から「getenv.cgi」を介して「env.cgi」を呼び出した場合に設定される全環境変数を表示したものです。「getenv.cgi」は、NNのリクエストヘッダを模したWebクライアントなので、あなたの環境とは多少違うでしょうが、以降も、この「getenv.cgi」を用いて予め取得した環境変数を例示しますので、比較のために見ておいてください。
「env.cgi」は、環境変数を3種類に色分けします。ここでは、REMOTE と HTTP で始まる環境変数が重要になるので、REMOTE で始まる環境変数は赤色背景■で表示し、HTTP で始まる環境変数は緑色背景■で表示しています。なお、黄色背景■で表示した環境変数は、主にサーバー自身に関する情報であり、プロキシサーバーとはほとんど関係ありません。 (悪戯防止関係では、REQUEST_METHOD にも注意する必要はありますが…)
REMOTE で始まる環境変数■は、CGI を呼び出したクライアントに関する情報であり、もっとも重要なものとなります。
- REMOTE_ADDR には、アクセス元の IPアドレスが格納されます。この IPアドレスは、IPパケットのIPヘッダから読み出されたものであるため、クライアントが勝手に操作できない貴重な、そしてたぶん唯一の情報源となるものです(もっとも、このパケット自身を書き換えられればお手上げですが…、ここではそこまでは考えないことにします(^^;)。
なお、ここで示されるIPアドレスの 133.205.9.138 ( bgsv107.tk.mesh.ad.jp ) は、プロキシサーバーを経由しないいわゆる生IPとなります。
- REMOTE_HOST には、この IPアドレスのドメインネームが格納されますが、うちのサーバーでは負荷の軽減のため IPアドレスがそのまま格納されます。このため、ページの上欄にドメインネームに変換した REMOTE_HOST を別に表示しています。
なお、IPアドレスとドメインネームの変換が必要な場合は、「nslookup.html」を利用してください。
- REMOTE_USER は、認証が行われた際に設定されるようなので、普通は関係ありません。
- REMOTE_PORT は、クライアント側のポート番号が設定される筈ですが、ここのサーバーでは設定されません!
HTTP で始まる環境変数■は、クライアントが CGI を呼び出す際のHTTPリクエスト・ヘッダの一部がそのまま設定されます。
リクエスト・ヘッダとレスポンス・ヘッダについては、「TOOLS」のページの「get.html」を参照してください。また、リクエスト・ヘッダを変えた場合に、環境変数にどのように反映されるかについては、「getenv.html」を参照してください。
- HTTP_REFERER には、CGI の参照元の URL が格納されます。掲示板などでは、CGI 自身が出力したフォームから書き込まれることが多いので、この場合には参照元がその CGI の URL であるかどうかを検査することにより外部からの投稿(「イメージ見せかけタグ」などによるいやがらせ)を禁止することができます。ただし、ブラウザによってはこの HTTP_REFERER が正しく設定されない場合もあるので、このような検査を行うときには注意が必要です。
- HTTP_USER_AGENT には、クライアント(ブラウザなど)に関する情報が格納されます。
なお、ここでの「Mozilla/4.01 [ja] (Win95; I)」は、「getenv.cgi」がWindows95 版 NN4.01 のマネをしたことによるものです。
ここで表示された他の環境変数は、ブラウザなどに応じていろいろ変化するものであり、特に重要ではありません。この例では HTTP_USER_AGENT 以外にも NN4 が送るリクエスト・ヘッダを模していますが、IE などではまた違った環境変数が設定されます(クライアントの端末の情報など)。
プロキシサーバー経由の場合には、後に説明するように、この HTTP で始まる環境変数が最も重要なものとなります。
ここで注意して頂きたいのは、HTTP で始まる環境変数はあくまでもクライアントから送られてくるリクエスト・ヘッダに基づいてサーバーがそのまま設定するものであるため、この情報を無条件に信頼することはできないということです。たとえば、「なりきりブラウザ」のように、既存のブラウザが送り出す HTTP_USER_AGENT の内容を自由に書き替えることができるようにするものもあります。また、「getenv.html」が呼び出す「getenv.cgi」も、クライアントとして任意のリクエスト・ヘッダにより「env.cgi」を呼び出すことができます。ここで、Referer: ヘッダや User-Agent: ヘッダなどの内容を書き換えて、これが HTTP_REFERER や HTTP_USER_AGENT などに反映されることを確認してみてください。つまり、自作のクライアントであれば、これらのリクエスト・ヘッダは、好きに変更することが可能になる訳です。そして、このようなクライアントは、perl などによる CGI 以外にも、Java や VB などを用いれば比較的容易に作成可能なものなのです(最近、perl や java を用いたネットワーク・プログラミングの本も多くなって来ています)。
ちなみに、「getenv.html」や「getenvp.html」が呼び出す「getenv.cgi」は、クライアントとして GET METHOD により「env.cgi」を呼び出すだけの CGI ですが、これを POST METHOD により QUERY 文字列を伴い任意の URL を呼び出すことができるようにしたものが PerlDUCK であり、掲示板アタック兵器として有名な PerlDUKE も基本的にはそのようなものであると思われます。また、ガブリエル(Gabriel)についてはよく分からないんですが、ガブリエナイ(Gabrienai)は、パソコン上などで実行する Java のアプリケーションによるクライアント(サーバー機能もあるローカル串)です。これらは、もともとは HTTP_REFERER を書き換えて、掲示板などに外部から書き込みできるようにすることを目的に作られたもののようですが、今では他のリクエスト・ヘッダも自由に書き換えて、経由するプロキシサーバーも簡単に多段にしたり切り替える機能があるようです。
プロキシサーバー経由の場合
プロキシサーバーと環境変数との関係について簡単に説明します。
プロキシサーバー経由の場合に設定される特有の環境変数の一覧です。
ただし、これらがすべて設定される訳ではなく、プロキシサーバーの種類に応じて設定されるようです(主なプロキシサーバーとしては、Squid, DeleGate, CERN-HTTPD, Netscape-Proxy などがあるようですが…)。
また、プロキシサーバーであるにもかかわらず、これらをまったく設定しない場合もあります。
- HTTP_VIA プロキシサーバーの情報が設定されます。
- HTTP_FORWARDED プロキシサーバーの情報が設定されます。
- HTTP_CACHE_INFO プロキシサーバーの情報が設定されます。
- HTTP_X_FORWARDED_FOR 経由するIPアドレスが設定されます。
- HTTP_CACHE_CONTROL プロキシサーバーへの指示情報だそうです。
- HTTP_PROXY_CONNECTION プロキシサーバーへの指示情報だそうです。
ブラウザがプロキシサーバーに接続する際にリクエストする Proxy-Connection: Keep-Alive に基づく環境変数です。ただし、プロキシサーバーは、このHTTPヘッダをそのまま通すとは限りません。
- その他
- HTTP_X_LOCKING 元のIPアドレスや参照先が設定されるようです。
- 漏れ串
Biglobe のプロキシサーバー(proxy01.biglobe.ne.jp)を経由して環境変数を表示したものです。
濃い緑色の背景■の環境変数は、ここではプロキシサーバーが設定したものであり、普通はこれらを調べることにより、プロキシサーバー経由のアクセスかどうかを判定できます(なお、「env.cgi」では、HTTP で始まる環境変数■のうち、標準的と思われるもの以外の環境変数をこの色■で表示するので、プロキシサーバーとはまったく関係ないものである場合もあります)。
このプロキシサーバーの場合、生IP の 133.205.9.138 ( bgsv107.tk.mesh.ad.jp ) は、HTTP_X_FORWARDED_FOR に漏れるので、「荒らし」のあいだでは「漏れ串」と称され、匿名ではなくなるので普通は使用されません(なお、「串」や「串鯖」は、プロキシサーバーを示す隠語です)。
ただし、このような漏れ串でも、多段串として次に説明する匿名串の後段のプロキシサーバーに用いられる場合はあります。
多段串を設定した場合、HTTP_X_FORWARDED_FOR には、左から順に生IP→1段目の串のIP→2段目の串のIP→という順序でIPアドレスが , を挟んで設定されるので、一番左側が最も根元のIPアドレスということになります。
ところで、HTTP_VIA の場合には、逆に右から順に1段目の串のIP→2段目の串のIP→という順序で設定されます。また、ここは、経由するプロキシサーバーに関する情報が設定されるので、生IPは現れません。
- 匿名串(その1)
生IP は漏れず隠蔽されるので、「匿名串」と称されます。
ただし、HTTP_VIA, HTTP_CACHE_CONTROL, HTTP_X_FORWARDED_FOR によりプロキシサーバー経由のアクセスかどうかを判定できます。
しかし、HTTP_X_FORWARDED_FOR には unknown が設定され、生IPが隠蔽されます。unknown 以外にも、ここを単に空欄にするプロキシサーバーもあります。
- 匿名串(その2)
生IP が隠蔽されます。もともとプロキシサーバーは、本来のクライアントの代理としてWebサーバーにリクエストを送るものであるため、特に悪意はなくても生IPは普通隠蔽されるものです。むしろ漏れ串というものは、このような匿名性を悪用されるのを防止するために、後に工夫されたものではないかと考えています?
このような串も、HTTP_FORWARDED(や HTTP_VIA などの特有の環境変数) が設定されるので、これにより検出が可能です。
- 匿名串(その3)
生IP が隠蔽されます。
また、プロキシサーバー特有の環境変数も一切設定されないので、これによる串の検出もできません。
ただし、HTTP_USER_AGENT に「via proxy gateway」などの文字が追記されるので、これによりプロキシサーバー経由のアクセスかどうかを判定できます。
(CERN-HTTPD がこのような書き換えを行うようです。)
- 匿名串(その4)
生IP が隠蔽されます。
しかも、プロキシサーバー特有の環境変数も一切設定されず、HTTP_USER_AGENT も書き換えられません。
従って、このようなプロキシサーバーは、環境変数による串の検出が不可能です。プロキシ制限ライブラリlq.pl でも、このようなプロキシサーバーは、lq.dat に個々に IPアドレスを登録して排除する他ありません。
この種の串は、かなり特殊なものだとは思いますが、実際には意外と多数存在するようです。プロキシサーバー経由のアクセスを排除する場合は、このような串の IPアドレスをどれだけ多く収集しているかがポイントになりそうです。
なお、ブラウザが Proxy-Connection: Keep-Alive ヘッダを出力する場合には、HTTP_PROXY_CONNECTION を設定するプロキシサーバーもあります。また、HTTP_XONNECTION や HTTP_XROXY_CONNECTION のような訳の分からない環境変数を設定するものもあるようです。
串のお話
- 串トピックス(その1)
この串は、HTTP_X_FORWARDED_FOR を設定しないので、匿名串のように見えます。しかし、HTTP_FROM には、生IP ならぬ生のドメインネーム(bgsv107.tk.mesh.ad.jp)が漏れています。(なお、この場合は、HTTP_FORWARDED にも漏れてますが…)
HTTP_FROM は、本来はクライアントのメールアドレスを設定していたものなのですが、過去にこの情報が悪用されたために今では使われなくなりました。しかし、プロキシサーバーによってはここにアクセス元を設定する場合があるので、アクセスログを取る場合は、この環境変数も記録しておいた方がいいでしょう。
- 串トピックス(その2)
串経由ではありますが、一見 HTTP_X_FORWARDED_FOR に生IPが漏れているようにも見えます。
しかし、このIPアドレスは、ページの上欄にドメインネームに変換して示しているように、元の生IPとはまったく関係ないものです。つまり、HTTP_X_FORWARDED_FOR に IPアドレスが設定されているからといって、必ずしも善意の訪問者であるとは限らないということに注意してください(ただし、このようなプロキシサーバーは、数が限られていると思われるので、個別にIPアドレスをハネればよく、それほど神経質になる必要はないかも知れません)。
- 串トピックス(その3)
これも、一見 HTTP_X_FORWARDED_FOR に生IPが漏れているようにも見えます。
しかし、これらのIPアドレスは、ページの上欄にドメインネームに変換して示しているように、到底現実のものとは思えません。
このような環境変数は、「getenvp.html」により、1段目のプロキシサーバーに一切を秘匿する匿名串(その4のタイプ)を設定すると共に、2段目に普通の匿名串(REMOTE HOST に現れたもの)を設定して、X-Forwarded-For: ヘッダにウソのIPアドレスを列挙することにより設定可能です。つまり、HTTP_X_FORWARDED_FOR は、プロキシサーバーが勝手に設定するほか、アクセス者が偽装することも可能であるということにも注意してください。
なお、プロキシサーバーによっては、特に明示的に指定しなくても自動的に多段串を設定するものもあります(Squid のキャッシュ階層によるものでしょうか?)。
また、アクセスを匿名にするという点では、プロキシサーバー以外にも anonymizer やダイアルQ2を利用した PPP 接続などにも注意が必要です。