CGI 環境の構築
目次- 1.0.0
/usr/web
の構成 - 2.0.0
/lib/namespace.httpd
- 3.0.0
/etc/handler
- 4.0.0
/etc/namespace.cgi
- 5.0.0 CGI とセキュリティ
- 6.0.0 おわりに
2002/08/27 更新
Pegasus で CGI 環境を構築する場合に考えるべきことは、CGI プログラムを実行するに必要な環境です。UNIX あるいは他の OS と異なり、選択的に環境を構築でき、また明示的に必要な環境を構築する必要があるからです。
CGI を実行するには結構多くのものが必要です。例えば CGI プログラムが来るはずのないデータを待って、いつまでも終らないかも知れません。Pegasus は(特に指定がない限り) 5 秒待っても CGI プログラムが終了しない場合には強制的に終了させます。そのためには /proc
が準備されていなければなりません。
/usr/web
の構成
配布ファイルの example には /usr/web に次のディレクトリを含めています。bin dev doc env etc lib mnt net proc rc sys tmpこれらは全ての CGI プログラムにとって必要ではないが、ゆとりをもってとった方が良いでしょう。(net はネットワークにアクセスする必要がない限り不要である)
読者は配布ファイルの
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 -a #I /usr/web/net mount -a #s/cs /usr/web/net mount -a #s/dns /usr/web/net bind /usr/bob/www/doc /usr/web/doc bind /usr/bob/www/etc /usr/web/etc最後の2つの bind は、実ホストのドキュメントと制御ファイルは bob が運営し、それが
/usr/bob/www/docおよび
/usr/bob/www/etcに置かれていると想定されています。
ここに載せた全てが必要な訳ではありません。特に
/usr/web/net
に関する部分は CGIを使ってネットワークにアクセスする事を想定しており、かなり特殊です。(筆者は Web メールのためにこれを行ったと思います。)
また
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を除けば全て、仮想ホストや一般のユーザに引き継がれます。従ってセキュリティには充分に注意を払う必要があります。
/etc/handler
実行ハンドラはホームページの運営者が自分で管理します。自分で管理しやすいように
$home/www/etc/handlerあるいは
$home/web/etc/handlerのように、運営者のホームディレクトリの下に置かれています。これらはサービス空間の
/etc/handlerとなります。
典型的な実行ハンドラは
# suffix mimetype ramfs 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のようなものです。(これは筆者が現在使用しているものです。) 最初の行はコメントです。従って2番目以降の行だけが意味を持っています。
*.html
を含む行によって、いわゆる CGI ファイルが定義されています。(この行の言っている事は、「拡張子が .html で、それが実行ファイル(ユーザ others に対して実行フラグが立っている)であれば、そのファイルを実行しなさい。MIME 形式は text/html
であり、ramfs が提供されているよ」)つまり、CGI ファイルの拡張子は Pegasus が決めてるのではなく、ユーザ定義なのです。
/etc/handler
のテーブルは、リクエストに対するアクションを定めているので、リクエストされたファイルが実際に存在する必要もありません。もっと詳しい解説については、実行ハンドラを見て下さい。
/etc/namespace.cgi
ホームページの運営者は自分の名前空間を再編成できます。ただし(httpd で -m オプションが指定されていない限り)本来見えているものの配置を変更するだけです。ここで特に重要なのは自分の CGI プログラムを /bin
に bind できる事です。/etc/namespace.cgi
がそれを可能にします。配布ファイルではこの内容はbind -a /etc/bin/$objtype /bin bind -a /etc/bin/rc /binとなっています。即ち bob の場合には
/usr/bob/www/etc/bin/386 /usr/bob/www/etc/bin/rcに彼の CGI に必要なツールを置く事になります。
CGI とセキュリティ
Pegasus は他の Web サーバと異なり、管理者が CGI を使えるように/lib/namesspace.httpd
を編成すると全てのユーザが CGI を使えるようになります。ユーザレベルで使える CGI と管理者レベルで使える CGI には違いはありません。CGI は管理者だけの特権ではないと考えている訳です。/lib/namesspace.httpd
の編成はそのことを念頭に置く必要があります。Pegasus は、悪質なユーザが CGI を使って企みそうな事をいろいろ考えた上で設計されていますが、実際に悪質なユーザがいる環境での運用実験はされていません。
listen の管理下で httpd を実行すると、ユーザ none のプロセスとして振る舞います。ホームページへの書き込みを目的として CGI を実行する場合には、ファイルのアクセスモードについて充分に考慮する必要があります。無難なのは
alrw-rw-rw- # 読み取りが必要な場合あるいは
alrw--w--w- # 他人に見られたくない場合することでしょう。大切なデータを消されない、或いは不正に変更されないと言う事が何よりも大切です。
httpd だけに読み取りを許可して、システムの他のユーザからの読み取りは阻止したい場合にはサーバモードで httpd を実行して下さい。
おわりに
持続型接続を CGI に対しても可能にするためには、CGI によってクライアントに渡す転送形式はチャンク形式エンコーディングにすべきですが、現在の所はそうはなっていません。そのために CGI を使用した場合には持続型接続が途絶えます。この問題は Pegasus 1.2 で解決したかったのですが、そのままになっています。