プロクシとは

広告

広告

プロクシ

思いつくままに脈絡もなく信憑性も無いセキュリティ総論。第3回目としまして、プロクシについて考えてみましょう。「串」「proxy」「プロキシ」「2694」「264」など記述の仕方は様々ですが、一度くらいはこれらの単語を耳(目?)にしたことがあるのではないでしょうか。プロクシサーバーの本来の役割は、プロクシサーバーのキャッシュ機能(アクセス先のデータをプロクシサーバー内に蓄積し、蓄積済みの同じデータを要求された時にはプロクシサーバからそのデータが返される)により、ネットワークトラフィックを軽減することと、回線が込み合っているWEBページなどを表示する際に、プロクシを経由して遠回りし、空いている回線を使用することによって通信速度を向上することです。ただ、プロクシがここまで有名になったのは、本来の機能を使用する上で起こる、TCP/IP上のある仕組みによるところが大きいのです。そのある仕組みとは・・・

自分の本来のIPアドレスを偽り、他の端末に接続できる

という仕組みです。

細かい説明は抜きにして、ここでは簡単に説明します。

インターネットであるページを見るとしましょう。通常のデータのやり取りを簡単に書くと以下のようになります。

クライアント →プロバイダ → WEBサーバ

クライアント ←プロバイダ ← WEBサーバ

実際にはもっと複雑なのですが、上記のような流れを繰り返すことによりWEBページがブラウザに表示されます。

では、プロクシを使用した場合はどうでしょう。データの流れは以下のようになります。

クライアント →プロバイダ → プロクシサーバ → WEBサーバ

クライアント ←プロバイダ ← プロクシサーバ ← WEBサーバ

つまり、自分のプロバイダからWEBサーバーに直接アクセスするのではなく、プロクシサーバーを介してデータの送受信をします。この結果として、WEBページがあるサーバーのログにはプロクシサーバーのIPアドレスとリモートホスト、そして自分のパソコンの環境変数などなどが残ることになるのです。

そしてこれはWEBページを見ることに限った話ではありません。プロクシサーバ(FTP プロクシ、SMTP プロクシなどです)を中継した場合、どのようなサーバであろうが、ログとして残るのはプロクシサーバのIPアドレスとリモートホストなのです(唯一中継したプロクシサーバだけ、本当の接続元IPなどがログとして残ります)。IP アドレスはTCP/IPネットワーク上で個人を確定するための最有力手段です(詳しくはIP アドレスの話を参照下さい)ので、このIP アドレスを「偽る」という行為により、インターネット上での匿名性をある程度確保することができるのです。

とまぁ、プロクシの概略などはどうでも良いわけで、大事なのは「本来の身元を偽って悪さをする輩がいる」ってことです。ただでさえ匿名性の高いインターネットの世界で、更に身元を偽られるともうこれはどうしようもありません。「匿名性をある程度確保できる」とは既述ですが、本当は完全に匿名なのです。考えても見てください。個人で運営している掲示板を、プロクシ経由で荒らされたとしましょう。当然気持ちのよいものではないので、なんとかして正義の鉄槌をくらわせてやりたいと大抵の管理人は思うでしょう。で、掲示板のログから荒らした本人のIP アドレスを抜き取って、鉄槌をくらわすまでの手順ですが、

  1. IP アドレスから「ドメインサーチ」などを使い、相手のプロバイダを確かめる。
  2. どうも相手はプロクシ経由らしい。(ここで諦める人:約50%)
  3. プロクシのIPアドレスから「whois」などでプロクシサーバの管理人への連絡先をつきとめる
  4. どうも管理人殿は外国の方らしい(ここで諦める/諦めざるを得ない人:約50%)
  5. なんとかつたない英語を駆使して管理人殿へログの開示を求める(返事が来ない確率:約50%)
  6. ログを参照してみると・・・またプロクシのIPだった(ここで諦める人:約80%)
  7. 紆余曲折あったが、なんとか生IPを調べ上げた(ここまでたどり着く確率:約5%)
  8. 生IPの管理先に連絡をとったところ・・・ネットカフェだった。(絶望度:70%/疲労度:120%)

とまぁ、こんな感じで鉄槌どころでは無いのが現状です(各項目につけている確率は適当なもので、統計情報等に基づいたものではありません)。プロクシ経由の接続が完全な匿名ではないということは間違いの無い事実です。しかし、それは何らかの犯罪につながり、国家権力が動かざるを得ない状態になった場合にのみ匿名性が保障されないだけであり、個人の掲示板を荒らす場合などはほぼ間違いなく匿名なのです。

なんだか荒らしを擁護するような文面になってきていますが、ここでのコンセプトは「いかに自分の身は自分で守るか」です。これ以降の文書は、プロクシ経由での掲示板荒らし対策スクリプトに的をしぼって話をします。

プロクシ経由で掲示板に入室されると、とっても丁寧なお断りメッセージを表示したり、虫かご(プロクシ経由でこられた方専用掲示板)に放り込んだりと対策方法は千差万別ですが、まずは「今来た人が、プロクシ経由かどうか」を判別しなければ話にもなりません。簡単なPerlの知識が無いと、理解に苦しむ個所があるかもしれませんが、自分で自分のサイトを守るためにもがんばって読み進めて下さい。

では、実際にどうやってプロクシ経由か否かを調べるのでしょうか。インターネット上でWEBページを見る際に、あなたのコンピュータは「HTTPリクエスト」というものをWEBサーバに送信します。リクエストに対してレスポンスが返ってくることによって、WEBページを「見る」ことができるのですが、HTTPリクエストを送信する際に、WEBブラウザの内部データの一部も一緒に送信しているのです。この内部データは「環境変数」と呼ばれ、ブラウザの種類やリンク元のWEBページなど、様々な情報が含まれています。この環境変数を調べることにより、プロクシからのリクエストか否かを調べることができるのです(あなたのコンピュータが送信している環境変数は「ENVチェッカー」で確かめて下さい)。

ここで、Perlの場合環境変数は、連想配列「%ENV」に代入されます。Perlの世界で環境変数を調べたい場合は、「%ENV{'環境変数名'}」という形式で個々のデータを取り出します。実際に今回の話に関係のありそうな環境変数を下に列記します。参考にして下さい。

#アクセス元の IPアドレスが格納されます。
#この IPアドレスは、IPパケットのIPヘッダから読み出されたものです。
$remote_addr = $ENV{'REMOTE_ADDR'};
#IPアドレスのドメインネームが格納されます。
$remote_host = $ENV{'REMOTE_HOST'};
#使用ブラウザ名。
#プロクシ経由の場合、経由したサーバ情報や接続元情報を含むことがあります。
$http_user_agent = $ENV{'HTTP_USER_AGENT'};
#電子メールアドレス等ユーザ固有情報
$http_from = $ENV{'HTTP_FROM'};
#経由したプロクシの情報。
#経由したサーバ情報や接続元情報を含むことがあります。
$http_forwarded = $ENV{'HTTP_FORWARDED'};
$http_via = $ENV{'HTTP_VIA'};
#接続元のIPアドレス。
#HTTP_FORWARDEDからHTTP_VIAへのヘッダ移行に伴ない、接続元クライアントの
#IPアドレスの情報が省かれることが多くなったため追加するプロクシがあります。
$http_x_forwarded_for = $ENV{'HTTP_X_FORWARDED_FOR'};
#経由できるプロクシの最大数。
#プロクシ経由の場合このヘッダを含むことがあります。
$http_max_forwards = $ENV{'HTTP_MAX_FORWARDS'};
#キャッシュ情報。
#プロクシ経由の場合、経由したプロキシサーバ情報を含むことがあります。
$http_cache_info = $ENV{'HTTP_CACHE_INFO'};
#プロクシとWEBサーバ間のCONNECTION指定をするためのヘッダ。
#プロクシ経由の場合、このヘッダを含むことがあります。
$http_proxy_connection = $ENV{'HTTP_PROXY_CONNECTION'};
$http_xroxy_connection = $ENV{'HTTP_XROXY_CONNECTION'};
#プロクシ等がサポートするTransfer-Encoding
$http_x_te = $ENV{'HTTP_TE'};
#プロクシに認証が必要な場合の認証情報。
#Hop-by-Hopにはなっているが目的サーバまで洩れている場合があります。
$http_proxy_authorization = $ENV{'HTTP_PROXY_AUTHORIZATION'};
#Norton Internet Security、Norton Personal Firewall等で
#HTTP_REFERERを遮断/隠蔽に設定すると追加されるヘッダ。
$http_wefere = $ENV{'HTTP_WEFERER'};
$http_wser_agent = $ENV{'HTTP_WSER_AGENT'};
#接続元のIPアドレス。
#プロクシ経由の場合、接続元情報を含むことがあります。
#IPアドレスが逆順や16進変換されていることもあります。
$http_client_ip = $ENV{'HTTP_CLIENT_IP'};
#接続元のIPアドレス。
#プロクシ経由の場合、接続元情報を含むことがあります。
$http_sp_host = $ENV{'HTTP_SP_HOST'};
$http_x_cisco_bbsm_clientip = $ENV{'HTTP_X_CISCO_BBSM_CLIENTIP'};
#経由したプロクシの情報。
#プロクシ経由の場合、このヘッダを含むことがあります。
$http_x_htx_agent = $ENV{'HTTP_X_HTX_AGENT'};
#プロクシ経由の場合、このヘッダを含むことがあります。
$http_extension = $ENV{'HTTP_EXTENSION'};
$http_xonnection = $ENV{'HTTP_XONNECTION'};
$http_x_locking = $ENV{'HTTP_X_LOCKING'};

これらの情報を使用し、プロクシ判定をするわけです。

実際に例を見てみましょう。

ENV Checker 2.0 by Key

プロクシ経由でも実験してみて下さい。当サイトのENVチェッカーでかけているプロクシ判定部分は下記の通りとなっています。

sub chkProxy{
    my($proxy) = 0;
    my($rtn, $strH);

    if($ENV{'HTTP_USER_AGENT'} =~ /via|squid|delegate|httpd|proxy|cache|gateway|www|ANONYM|keeper/i){$rtn = 1;}
    elsif($ENV{'REMOTE_HOST'} =~ /^dns|^gw|^fw|^ns|^news|^web|^secure|cgi|ftp|pop|cache|dummy|
firewall|gate|www|keep|mail|proxy|prox|smtp|squid|w3/i){$rtn=1;}
    elsif($ENV{'HTTP_FORWARDED'}){$rtn=1;}
    elsif($ENV{'HTTP_VIA'}){$rtn=1;}
    elsif($ENV{'HTTP_X_FORWARDED_FOR'}){$rtn=1;}
    elsif($ENV{'HTTP_MAX_FORWARDS'}){$rtn=1;}
    elsif($ENV{'HTTP_SP_HOST'}){$rtn=1;}
    elsif($ENV{'HTTP_CLIENT_IP'}){$rtn=1;}
    elsif($ENV{'HTTP_CACHE_INFO'}){$rtn=1;}
    elsif($ENV{'HTTP_PROXY_CONNECTION'}){$rtn=1;}
    elsif($ENV{'HTTP_XROXY_CONNECTION'}){$rtn=1;}
    elsif($ENV{'HTTP_TE'}){$rtn=1;}
    elsif($ENV{'HTTP_PROXY_AUTHORIZATION'}){$rtn=1;}
    elsif($ENV{'HTTP_X_CISCO_BBSM_CLIENTIP'}){$rtn=1;}
    elsif($ENV{'HTTP_X_HTX_AGENT'}){$rtn=1;}
    elsif($ENV{'HTTP_EXTENSION'}){$rtn=1;}
    elsif($ENV{'HTTP_XONNECTION'}){$rtn=1;}
    elsif($ENV{'HTTP_X_LOCKING'}){$rtn=1;}

    if($ENV{'HTTP_WEFERER'}){$rtn+=2;}
    elsif($ENV{'HTTP_WSER_AGENT'}){$rtn+=2;}

    $strH = $ENV{'HTTP_SP_HOST'} if($ENV{'HTTP_SP_HOST'} ne '');
    $strH = $ENV{'HTTP_VIA'} if($ENV{'HTTP_VIA'} =~ s/.*\s(\d+)\.(\d+)\.(\d+)\.(\d+)/$1.$2.$3.$4/);
    $strH = $ENV{'HTTP_CLIENT_IP'} if($ENV{'HTTP_CLIENT_IP'} =~ s/^(\d+)\.(\d+)\.(\d+)\.(\d+)(\D*).*/$1.$2.$3.$4/);
    $strH = $ENV{'HTTP_X_FORWARDED_FOR'} if($ENV{'HTTP_X_FORWARDED_FOR'} =~ s/^(\d+)\.(\d+)\.(\d+)\.(\d+)(\D*).*/$1.$2.$3.$4/);
    $strH = $ENV{'HTTP_FORWARDED'} if($ENV{'HTTP_FORWARDED'} =~ s/.*\s(\d+)\.(\d+)\.(\d+)\.(\d+)/$1.$2.$3.$4/);
    $strH = $ENV{'HTTP_FROM'} if($ENV{'HTTP_FROM'} ne '');
    if($rtn == 0){$strH = $ENV{'REMOTE_ADDR'};}

    return $rtn, $strH;
} # end of chkProxy

上記サブルーチンは、どこで使おうが、改造しようが、配布しようが、自分で考えたふりをしようが、罵倒しようが文句は言いません。許可もいりませんので気に入られた方はお好きにご使用下さい(伝言板にでも一言何か書いていただければ、管理人が喜びます)。

ただし、上記のサブルーチンも絶対ではありません。プロクシサーバの中には、HTTPリクエストのヘッダに、プロクシ特有の環境変数を付加しないものもあります(匿名プロクシとかAnonymousプロクシとか呼ばれます)。匿名プロクシを判断する方法も無いわけではないのですが(REMOTE_ADDRの80や8080番ポートが開いていればプロクシサーバと決め付ける)、圧倒的に誤認が増えます。今の管理人の知識ではこれくらいが限界です。どなたかいい情報お持ちの方は是非ご教授下さい。

広告

Copyright (C) 2004-2005 七鍵 key@do.ai 初版:2004年5月15日 最終更新:2005年01月13日