CGI 環境の構築
目次- 1.0.0
/usr/webの構成 - 2.0.0
/lib/namespace.httpd - 3.0.0
$webの構成 - 4.0.0
$web/etc/handler - 5.0.0
$web/etc/namespace_80 - 6.0.0 CGI とセキュリティ
2003/01/03
Pegasus で CGI 環境を構築する場合に考えるべきことは、CGI プログラムを実行するのに必要な環境です。UNIX あるいは他の OS の web サーバと異なり、Plan9 の Pegasus は選択的に環境を構築でき、その場合、明示的に必要な環境を構築する必要があるからです。
CGI を実行するには結構多くのものが必要です。例えば CGI プログラムが、来るはずのないデータを待って、いつまでも終らないかも知れません。Pegasus は(特に指定がない限り) 5 秒待っても CGI プログラムが終了しない場合には強制的に終了させます。そのためには /proc が準備されていなければなりません。
/usr/web の構成
配布ファイルの example/usr/web に次のディレクトリとファイルが含まれています。d-rwxrwxr-x M 8 arisawa arisawa bin/386 d-rwxrwxr-x M 8 arisawa arisawa bin/rc d-rwxrwxr-x M 8 arisawa arisawa dev d-rwxrwxr-x M 8 arisawa arisawa doc d-rwxrwxr-x M 8 arisawa arisawa env d-rwxrwxr-x M 8 arisawa arisawa etc d-rwxrwxr-x M 8 arisawa arisawa lib d-rwxrwxr-x M 8 arisawa arisawa mnt d-rwxrwxr-x M 8 arisawa arisawa proc d-rwxrwxr-x M 8 arisawa arisawa rc/lib d-rwxrwxr-x M 8 arisawa arisawa sys/log d-rwxrwxr-x M 8 arisawa arisawa sys/lib d-rwxrwxr-x M 8 arisawa arisawa sys/man d-rwxrwxr-x M 8 arisawa arisawa tmp --r-------- M 8 arisawa arisawa unreadableこれらのディレクトリやファイルには、ユーザ
none や ユーザ web による書き込み権を与えてはいけません。最後の unreadable はサーバが allow モードで動作しているか否かの判定に使用されています。(allow モードで動作しているときには Pegasus は CGI の実行サービスを停止します。)これらのディレクトリは
bin/386 と bin/rc を除けば空です。筆者は bin/386 と bin/rc に CGI のサービスに固有のプログラムを置いています。次に紹介する /lib/namespace.httpd の内容は、その事を前提にしています。CGI プログラムにとってこれらの全てが必要ではありませんが、ゆとりをもってとった方が良いでしょう。
読者は配布ファイルの
example/usr/web以下のディレクトリをそのまま
/usr/web にコピーするのが無難です。筆者の cpdir を使うと簡単にコピーできます。cpdir -mv example/usr/web /usr/web
/lib/namespace.httpd
Pegasus のサービス空間は /usr/web を基に構成されます。それに内容を与えるために/lib/namespace.httpdで実体を
bind しなければなりません。配布ファイルのexample/lib/namespace.httpdにその例が載っています。それによると、そのファイルの内容は(コメントを省くと)
bind -a /usr/web/bin/$cputype /bin bind -a /usr/web/bin/rc /bin bind /sys/log/http /usr/web/sys/log/http bind /sys/lib /usr/web/sys/lib bind /sys/man /usr/web/sys/man bind /lib /usr/web/lib bind /bin /usr/web/bin bind /rc/lib /usr/web/rc/lib bind -c #e /usr/web/env bind #c /usr/web/dev bind /proc /usr/web/procここに載せた全てが必要な訳ではありません。また
bind /sys/lib /usr/web/sys/libでは、
/sys/lib 以下の全てがサービス空間の中に入り、CGI からアクセス可能になります。必要なファイル(あるいはディレクトリ)だけを選択的に bind した方が良いかも知れません。(/sys/lib/ssh や /sys/lib/tls に秘密にすべき情報をオープンにしたまま入れているかも知れませんよ)
/lib/namespace.httpd で設定した CGI 環境は
/usr/web/doc /usr/web/etcを除けば全て、仮想ホストや一般のユーザに引き継がれます。従ってセキュリティには充分に注意を払う必要があります。
$web の構成
以下の説明では web ルートを $web で表します。例えば、ユーザ
alice の場合には $web は(特に指定しない限り)/usr/alice/webです。実ホストと仮想ホストの
$web の値は /sys/lib/httpd.rewrite によって決定されます。例えば /sys/lib/httpd.rewrite で/ */usr/bob/wwwとした場合には実ホストの
$web は/usr/bob/wwwとなります。
各ドキュメント管理者は
$web の下に以下のディレクトリを持ちます。doc etc bin/386 bin/rc
docは web ドキュメントを置くディレクトリで、通常は web ページの案内であるindex.htmlがそこに置かれるでしょう。
etcは、アクセス制御に関するファイルや次に紹介する実行ハンドラなど web ページの管理に関するファイルが置かれます。
bin/386とbin/rcには実行ファイルを置きます。ここに置かれたファイルは Pegasus が自動的に/binに追加モードで bind します。
$web/etc/handler
実行ハンドラ定義ファイル $web/etc/handler はホームページの運営者が自分で管理します。自分で管理しやすいように運営者のホームディレクトリの下に置かれています。これらはサービス空間の/etc/handlerとなります。このファイルの役割は、クライアントからのリクエストの処理を、指定されたプログラムに渡すことです。
典型的な実行ハンドラは
# suffix mimetype unused execpath arg ... /netlib/*/index.html text/html 0 /bin/ftp2html *.http - 0 $target *.html text/html 1 $target *.dx_html text/html 0 /bin/dx $targetのようなものです。(これは筆者が
plan9.aichi-u.ac.jp で現在使用しているものです。) 最初の行はコメントです。従って2番目以降の行だけが意味を持っています。(第3フィールドは今回の版では使用されていません。)*.html を含む行によって、いわゆる CGI ファイルが定義されています。この行の言っている事は、.html の場合、第4フィールドのファイルが実行ファイル(others に対して実行フラグが立っている)であれば、それを実行しなさい。そのときの引数は(もしも存在すれば)第5フィールド以下で与えられています。$target と言うのはリクエストされたファイルです。出力のMIME 形式は text/html ですよ。
つまり、CGI ファイルの拡張子は Pegasus が決めてるのではなく、ユーザ定義であることを理解してください。(ついでに、CGI は拡張子によって定められているのではなく、リクエストのパスパターンであることも理解してください。)
$web/etc/handler のテーブルは、リクエストに対するアクションを定めているので、リクエストされたファイルが実際に存在する必要もありません。もっと詳しい解説については、実行ハンドラを見て下さい。
$web/etc/namespace_80
ホームページの運営者は自分の名前空間を再編成できます。(しかしそのような必要は殆どないでしょう。)$web/etc/namespace_80 はポート 80 に対する名前空間の編成ファイルです。このファイルの名前から分かるように、使用されるポートごとに名前空間の編成ファイルを作成します。(名前空間を再編成する必要が無い場合にはファイルは必要ありません)
$web/etc/namespace_80 が実行される段階で Pegasus は既にサービス空間にいます。従ってこのファイルの中で指定されるパスは $web をルートとしたパスです。
セキュリティの関係で、全ての再編成が許されているわけではありません。(httpd で -m オプションが指定されていない限り)このファイルの中では bind だけが許されます。すなわち本来見えているディレクトリを隠したり、配置を変更したりするだけです。さらに、システムのファイルをドキュメント空間の中に bind する行為も許されていません。
隠すためには何か空のディレクトリを作成し(例えば /doc/nil) それを bind してください。)
bind /doc/nil /doc/privatePegasus 2.0 では
$web/etc/bin/386 $web/etc/bin/rcに置かれたプログラムは自動的に
/bin に(追加モードで) bind されます。
CGI とセキュリティ
Pegasus は他の web サーバと異なり、CGI はシステム管理者だけの特権ではないと考えています。/lib/namesspace.httpd の編成の結果は全てのドキュメント管理者が利用できます。/lib/namesspace.httpd の編成はそのことを念頭に置く必要があります。Pegasus は、悪質なユーザが CGI を使って企みそうな事をいろいろ考えた上で設計されていますが、実際に悪質なユーザがいる環境での運用実験はされていません。
listen の管理下で httpd を実行すると、ユーザ none のプロセスとして振る舞います。ホームページへの書き込みを目的として CGI を実行する場合には、ファイルのアクセスモードについて充分に考慮する必要があります。無難なのは
alrw-rw-rw- # 読み取りが必要な場合あるいは
alrw--w--w- # 他人に見られたくない場合にすることでしょう。大切なデータを消されない、或いは不正に変更されないと言う事が何よりも大切です。
httpd だけに読み取りを許可して、システムの他のユーザからの読み取りは阻止したい場合にはサーバモードで httpd を実行して下さい。