Logo address

コンセプト

2002/04/02 更新
2002/02/12

名前空間の綴じ込め

通常の Web のサーバにおいてはサーバルートと言う概念は本質的な意味を持っていません。
例えば Apache の httpd.conf は ServerRoot を指定しますが、単にアクセス記録などを置く場所がこれによって指定されるだけです。

通常の Web サーバではサーバルートはアクセス制限に対して何の意味も持っていません。この事は CGI を使用した場合に直ちに問題になります。即ち Web のサーバは一見するとクライアントからのアクセス可能なファイルを制限しているように見えても、CGI プログラムからはシステムの全てのファイルが見えてしまいます。この事は重大なセキュリティ上の問題をもたらしかねません。そのためにエンドユーザによる CGI の使用は禁止されるかあるいは厳重な統制下に置かれるのが普通です。
図1 に通常の Web サーバにおける名前空間の様子を概念的に示します。 太線の矩形領域がコンソール空間( console space )を表しています。コンソール空間とはコンソールから見えるファイルの集合であり、システムのファイルの全体を表しています。サービス空間( service space )とは Web のサーバがサービスを行っているファイルの集合です。これはまた CGI プログラムからアクセス可能なファイルの集合でもあります。通常の Web のサーバはコンソール空間とサービス空間が正確に一致しています。
ドキュメント空間( document space )はホームページを構成するドキュメントの集合です。alice のドキュメント空間はブラウザからは /~alice でアクセスされるドキュメントの集合です。サーバ上の全てのユーザのドキュメント空間はサービス空間の中にあるので CGI からは等しくアクセス可能です。

サーバルートの概念に本質的な意味を最初に与えたのは Plan9 第2版の標準 httpd です。 このサーバでは、Plan9 がプロセス毎に名前空間を編成できる事を利用して、 httpd のサービス空間を(従って CGI プログラムからアクセス可能な空間も)、サーバルートの下に綴じ込めることができました(図2)。従ってこのサーバの下では CGI プログラムから見える名前空間は、指定されたサーバルートがルート "/" となります。つまり CGI プログラムはサーバルートによって指定された名前空間の中に綴じ込められるのです。図2はこの様子を示しています。灰色で示した部分がサービス空間の外にあるファイルの集まりです。この部分は CGI プログラムから本質的に隠されているのです。

Plan9 第2版の標準 httpd は CGI 環境が不自由でした。CGI プログラムの配置が固定されていたのと、POST メソッドがサポートされていなかったためです。この問題は Charles Forsyth によって解決されました。(筆者はそのためにずっと彼の httpd を使用してきました。彼のは HTTP/1.0 レベルだったために不自由はしましたが…)

Pegasus はこれまでの Plan9 上のサーバのこの素晴らしいアイデアを引き継ぎ、さらに発展させる事にしました。


ドキュメントの管理主体に基づく名前空間の分離

一般に1つのサーバ(some.dome.com)には様々な人々が作成する Web のドキュメントが存在し、それらはサーバにおけるそれらの人々の位置付けに従って次のようにいろいろな方法でクライアントからアクセスされます。
http://some.dom.com/pathname	# ホストドキュメント
http://some.dom.com/~alice/pathname	# ユーザドキュメント
http://other.dome.com/pathname	# 仮想ホスト(IP が異なる)のドキュメント
http://vertual.dom.com/pathname # 仮想ホスト(IP が同じ)のドキュメント

現状の Web サーバ(Plan9のこれまでの Web サーバを含めて)の大きな問題点は、httpd のサービス空間がこれらの間で共有される事にあります(図1, 図2)。(コンピュータの仕組みに例えると、全てのプロセスがアドレス空間を共有している初期のパソコンとよく似ている。論理アドレスに相当する機能を提供していないのである。)
この事は、ある人が作成した CGI プログラムが他の人のファイルにアクセス可能である事を意味します。従ってドキュメントを作成し公開する人々の間の相互干渉の可能性をもたらします。

Pegasus はこの問題を次のように解決しました。

Pegasus ではどのドキュメントもサービス空間の中で単一のドキュメントルート(/doc) を持ちます。Web のブラウザからそのように見えているだけではなくて、サービスを実行しているサーバの名前空間のレベルで実際に単一です。即ち、実行中の Web のサーバのサービス空間には一人分のドキュメントしか存在しないのです(図3a, 図3b)。
図3a は /~alice でアクセスした場合の図ですが、 /~bob でアクセスした場合には図3b のようになります。この事はどの CGI プログラムも他人のファイルから遮蔽されている事を意味します。個々のファイルのアクセスコントロールによってアクセスできないのではなく、その存在すら分からないのです。CGI プログラムが正常に運用されている限り、CGI プログラムから他人のドキュメントやファイルにアクセスする必要はない訳ですから、これで運営上の支障は無いはずです。この特性を備えた Web サーバは現在の所 Pegasus だけです。

Pegasus ではドキュメントルートはサービス空間の中では "/doc" に固定されています。既に述べた様にサーバルートはサービス空間の中では "/" に固定されていますが、実際の名前空間の下ではユーザごとに異なるサーバルートが存在するのです。

例えば(特に指定しなければ)

	/usr/alice/web
はユーザ alice のサーバルートです。alice は
	/usr/alice/web/doc
の下にドキュメントを作成します。
サーバルートの位置は個別に指定する事もできます。


ファイルのアクセス保護

CGI からアクセスされるファイルの中には、他のユーザおよび他のユーザの CGI からの不正アクセスから保護される必要があるものもあるでしょう。
例えば alice が CGI で使用するあるファイル data は alice 自身と alice の作成した CGI からのみアクセスを許したい場合があります。

Pegasus ではこの問題を次の様に解決します。
1. サーバをユーザ web として実行する。
ただし web は実際のユーザではありません。(従ってファイルを所有する必要はありません。)
2. /adm/users に alice のグループメンバとして web を追加する。即ち、

	alice:alice:web
3. alice は data のアクセスモードを
	-lrw-rw---- alice web .... data
に設定する。(読み書き込みアクセスの場合)
注意: 他のファイルに対しては
	-lrw-r--r-- alice alice .... data
にします。(読み取られてもよい場合)

注: アクセス保護の問題がこんな簡単な方法で解決できるのは Pegasus のサービス空間がユーザ毎に綴じ込められているからです。
UNIX ではこの問題を CGI wrapper によって解決しています(例えば http://download.sourceforge.net/cgiwrap )
。すなわち httpd はCGI wrapper を通じてのみ CGI にアクセスし、CGI wrapper には root によるSUIDビットが立てられます。CGI wrapper が CGI にアクセスする時には CGI ファイルのオーナーに SETUID してアクセスします。CGI ファイルに直接 SUID を立てないのは、あまりにも危険だからです。(筆者は SUID は UNIX の失敗作であると思っていたが、こういう所で役に立つとは思っていませんでした。)

Windows ではアクセス保護の問題を解決するメカニズムはおそらく存在しないでしょう。(そうでもないか。Windows のサーバは特権モードで動いている!)

UNIX の CGI wrapper と Pegasus とを比較すると Pegasus の方が安全性が高いと言えます。CGI wrapper では下手な CGI を作ると、そのユーザの全てのファイルを危険にさらします。Pegasus ではユーザ web の書き込みアクセスを許しているファイルだけが危険にさらされます。(Windows ではシステムの全てを危険にさらす!)
管理面でも Pegasus の方がはるかに簡単です。管理者側から一切の管理が必要ありません。単にユーザ web として httpd を実行すればよいだけです。


■ 自由度の高い仮想ドキュメント環境

Pegasus の現在の目標は高度な安全性と高度な自由度を備えた CGI のサービスをユーザに提供することにあります。

Pegasus 1.0 の標準的な設定では以下の条件を満たすファイルを CGI として使用します。

  1. ユーザ others に対して実行フラグが立っている事。
  2. ファイルの拡張子が、http、html のいずれかである事。
  3. ドキュメント空間に置かれている事。
  4. 名前がピリオドで始まっていない事。
NCSA や Apache のサーバでは拡張子が cgi でかつ実行フラグが立っているファイルをドキュメント空間の中に置いて CGI プログラムとするオプションが許されていますが、サーバを安全に運用するためには CGI プログラムを一ケ所(/cgi-bin/)に集中し、ユーザが勝手にドキュメント空間の中に置くことを禁止します。しかしユーザの立場からすると CGI プログラムはドキュメントと一緒に置く方が遥かに使い勝手が良いのです。

Pegasus 1.0 では仮想ドキュメント環境を実行ハンドラによって実現します。 CGI は実行ハンドラの特殊な形態にすぎません。
「実行ハンドラ」と言うのは恐らく Pegasus の独自の概念でしょうから説明が必要です。
実行ハンドラとはリクエストされたファイルの処理を行うプログラムの事です。ユーザはパスパターンとそれを処理するプログラムの関係を定義します。(このファイルはサービス空間の中の /etc/handler です。) リクエストされたファイルを処理するプログラムが、リクエストされたファイル自体であれば所謂 CGI プログラムになります。
特殊な拡張子のファイルに対して特殊なプログラムで処理する事もできます。Server Side Include の機能も実行ハンドラを使用して実現できます。また、Web サーバで FTP サーバが行っていたサービスを代行する場合には Web サーバはファイルの一覧をクライアントに示す必要があるでしょう。このような場合には FTP 用のファイルが置かれているディレクトリに対して自動的にファイルの一覧を表示するプログラムを実行させるようにします。

「実行ハンドラ」の考え方は広い応用を持つ事が容易に想像できますが、強調しておきたい事は、Pegasus では実行ハンドラが完全にユーザの手中にあると言う事です。 !