コンピュータネットワークが一般の人々に急速に浸透した結果として、 ネットワークの匿名性を利用した犯罪や無責任な投稿が社会問題と なっています。この問題に対する唯一の対策は、アクセス主を特定できる IDを逆探知で割り出すことで、アクセス主に責任を持たせることです。
この章ではCGIへのアクセスを逆探知してアクセス主を特定する 手順の概略を紹介して、私が作成したCGI専用逆探知ライブラリ 「CGITrace」が提供する関数を使っての逆探知の方法を紹介します。
Httpdは次の手順でCGI所有者が逆探知を行えるようにするための 情報を入手してCGIに渡してくれます。また、管理者による設定によって httpd自体にすべての逆探知を行わせることもできます。
管理者が httpd.conf ファイル中で「IdentityCheck on」とすれば、 httpdはすべてのアクセスに対して(4)の作業をhttpd内部で行い、 その結果のuser名を環境変数 REMOTE_IDENT に設定します。
この手順から逆探知が成功するためには次の3つの条件が必要で あることがわかります。
(1)の条件を満たすコンピュータは現在はまだ多くはありませんが、今後、
これを備えることを義務とする法律が整備されると思われます。
ident daemonの役割を担うソフトには pident, authd など幾つかあり、
無償で配布されています。このソフトを起動するにはroot権限が必要です。
Web server管理者に導入を依頼して下さい。
Web server管理者は利用者に不正アクセスを
させないためにもident daemonを早急に導入するべきです。
(2)の条件は比較的新しいapacheならこの条件を満たしています。
(3)の条件が厄介で、アクセス主のsecurity保護のため最近流行っている firewallなのですが、逆探知も遮断してしまいます。
私が作成した CGITrace をC/C++言語で作成されるUNIX上のCGIに 組み込むことで、そのCGIへのアクセス主のユーザー名を逆探知することが できます。
ただし、逆探知を行うなら プライバシを
十分に尊重して下さい。 また、逆探知を
行っていることをなるべくHomepage上に明記してください。
GetUser(), GetFinger() の実行はネットワークに対して重い負担となり
ますので、頻繁にこれらの関数を連発しないようにCGIを工夫して下さい。
このライブラリを利用するには、CGIプログラムで cgitrace.h を
includeした上で、cgitrace.cc と一緒にコンパイルしてください。
もしくはobject fileを生成しておいてからリンクしてください。
ライブラリ自体はC++言語で作成されていますが、C言語のCGIでも利用
できます。
CGITraceライブラリのsource file (cgitrace.cc, cgitrace.h) と document (cgitrace.html) の3つのfileをLZH形式で圧縮したものを 用意しましたのでdownloadして下さい。
cgitrace.hこのライブラリが提供する関数は以下の通りです。
[使用例]
char host[HOST_SIZE]; if( GetHost( host ) == -1 ){ terror("GetHost"); }else{ printf("Remote host = %s<BR>\n", host ); }[出力例]
Remote host = somemachine.somewhere.co.jp.(1024)<BR>
()の中の数字がアクセス主が接続に使用したport番号です。
[使用例]
char user[USER_SIZE]; if( GetUser( user ) == -1 ){ terror("GetUser"); }else{ printf("Uesr name = %s<BR>\n", user ); }[出力例]
User name = naoki<BR>
[使用例]
char addr[ADDR_SIZE]; if( GetAddr( addr ) == -1 ){ terror("GetAddr"); }else{ printf("Remote address = %s<BR>\n", addr ); }[出力例]
Remote address = 123.45.67.8.(1024)<BR>
()の中の数字がアクセス主が接続に使用したport番号です。
[使用例]
char referer[REFERER_SIZE]; if( GetReferer( referer ) == -1 ){ terror("GetReferer"); }else{ printf("Referer URL = %s<BR>\n", referer ); }[出力例]
Referer URL = http://www.mymachine.mydomain/index.html<BR>
[使用例]
char agent[AGENT_SIZE]; if( GetAgent( agent ) == -1 ){ terror("GetAgent"); }else{ printf("Agent = %s<BR>\n", agent ); }[出力例]
Agent = Mozilla/3.01 (X11; I; FreeBSD 2.1.0-RELEASE i386)<BR>
[使用例]
char handle[HANDLE_SIZE]; if( GetHandle( handle ) == -1 ){ terror("GetHandle"); }else{ printf("Handle name = %s<BR>\n", handle ); }[出力例]
Handle name = naoki<BR>
[使用例]
int i, num; char finger[FINGER_LINES][FINGER_SIZE]; if( (num=GetFinger( finger )) == -1 ){ terror("GetFinger"); }else{ puts("<PRE>"); for( i=0 ; i<num ; i++ ){ fputs( finger[i], stdout ); } puts("</PRE>"); }[出力例]
Login Name TTY Idle Login Time Where naoki Naoki Watanabe p0 Sat 19:29 :0.0
[使用例]
char time[TIME_SIZE]; GetTime( time ); printf("Current time = %s<BR>\n", time );[出力例]
Current time = 26/Dec/1998:21:56:41<BR>
逆探知の作業はネットワークに少なからぬ負担を掛けますので 逆探知の実行が必要最小限になるようにCGIを工夫して作って下さい。
Chatのように頻繁に投稿があるCGIでは、逆探知回数を減らすために ホスト、ハンドル名が同じなら逆探知を繰り返さないようにすると 良いでしょう。
Browserの機能である cookie を利用すれば、一度逆探知に成功した人の アクセスでは、逆探知しなくても同一人物であることがわかるので これを利用すると良いでしょう。
アクセス元にident daemonが走っていなくても finger daemonが走って いるなら GetFinger() 関数でアクセス主を特定できる可能性があります。
Firewallやproxy経由のアクセスでも、深刻な不正アクセスの主を特定する 捜査が必要である場合には、そのプロバイダ管理者にそのアクセスの [GetHost()の値]、[時刻]、[URL]の情報を添えて捜査を依頼して下さい。 そのマシンの記録と照合して犯人を特定できるかもしれません。