Logo address

CGI 環境の構築

目次

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 で解決したかったのですが、そのままになっています。