Logo address

コンセプト

目次

2002/11/29 更新

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

通常の web のサーバ

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

通常の web サーバではサーバルートはアクセス制限に対して何の意味も持っていません。この事は CGI を使用した場合に直ちに問題になります。即ち web のサーバは一見するとクライアントからのアクセス可能なファイルを制限しているように見えても、CGI プログラムからはシステムの全てのファイルが見えてしまいます。この事は重大なセキュリティ上の問題をもたらしかねません。そのためにエンドユーザによる CGI の使用は禁止されるかあるいは厳重な統制下に置かれるのが普通です。

図1: 伝統的な web サーバの名前空間
real space = service space

図1 に通常の web サーバにおける名前空間の様子を概念的に示します。
外枠の矩形領域が実空間( real space )を表しています。そして外枠と一致するうすい灰色で示した矩形領域がサービス空間(service space)です。実空間とはコンソールから見えるファイルの集合であり、(Plan9 以外の OS では)システムのファイルの全体を表しています。サービス空間とは web のサーバがサービスを行っているファイルの集合です。これはまた CGI プログラムから見えるファイルの集合でもあります。通常の web のサーバでは実空間とサービス空間が正確に一致しています。

ドキュメント空間( document space )は web ページを構成するファイルの集合です。alice のドキュメント空間はブラウザからは /~alice でアクセスされるファイルの集合です。サーバ上には様々な人々が作成するドキュメントがありますが、これらはサービス空間の中にあるので CGI からは隠されていません。

Plan9 の標準 web サーバによる進展

サーバルートの概念に本質的な意味を最初に与えたのは Plan9 第2版の標準 web サーバです。Plan9 がプロセス毎に名前空間を編成できる事を利用して、このサーバでは web サーバのサービス空間を(従って CGI プログラムから見える空間も)、サーバルートの下に綴じ込めることができました(図2)。

図2: Plan9 の標準 web サーバで実現された名前空間
real space > service space

従ってこのサーバの下では CGI プログラムから見えるファイルは、指定されたサーバルートの下にあるファイルだけです。つまり CGI プログラムはサーバルートによって指定された名前空間の中に完全に綴じ込められるのです。図2はこの様子を示しています。濃い灰色で示された部分がサービス空間の外にあるファイルの集まりです。この部分は CGI プログラムから本質的に隠されています。

Pegasus によって実現された web サーバの名前空間

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

一般に1つのサーバ(some.dom.com)には様々な人々が作成する web のドキュメントが存在し、それらはサーバにおけるそれらの人々の位置付けに従って次のようにいろいろな方法でクライアントからアクセスされます。

	http://some.dom.com/pathname	# 実ホストのドキュメント
	http://some.dom.com/~alice/pathname	# ユーザドキュメント
	http://other.dome.com/pathname	# 仮想ホスト(IP が異なる)のドキュメント
	http://virtual.dom.com/pathname # 仮想ホスト(IP が同じ)のドキュメント
ここに pathname はドキュメントルートからみたドキュメントへのパスです。
これまでの web サーバの大きな問題点は、サービス空間がこれらの間で共有される事にあります(図1, 図2)。この事は、ある人が作成した CGI プログラムを通じて、他の人のファイルにアクセスできる可能性がある事を意味しています。従ってドキュメントを作成し公開する人々の間の相互干渉の可能性をもたらします。
注釈: コンピュータの仕組みに例えると、全てのプロセスがアドレス空間を共有している初期のパソコンとよく似ている。プロセスごとの論理アドレスに相当する機能を提供していないのである。UNIX が PC に移植できたのは i386 が MMU との組み合わせで論理アドレスをプロセスに提供できるようになっからである。

この問題は図3a、図3b に示すように、サービスを行う web のサーバが、ドキュメントごとの名前空間の中でサービスを行うことによって解決されます。そしてこれは Pegasus によって初めて解決されました。

図3a 図3b

ドキュメントの管理者ごとに独立した名前空間が与えられる必要がある
図3a は {alice} のドキュメントをサービスしているときの Pegasus のサービス空間
図3b は {bob} のドキュメントをサービスしているときの Pegasus のサービス空間である

Pegasus における名前空間の再編成

話をもう少し具体的にし、次のように3人の役割を仮定しましょう。
この場合には /sys/lib/http.rewrite
http://car	*/usr/carol/www
/		*/usr/bob/www
と設定します。alice のような一般ユーザは設定なしにホームページが持てます。すなわち、
/~alice		*/usr/alice/web
が暗黙のうちに仮定されます。

そしてシステムの管理者(たぶん bob でしょう)は /lib/namespace.httpd で web サーバのサービス空間を定義します。するとクライアントからアクセスがあるたびに、このサービス空間の中に、要求があったドキュメントの管理者のファイルだけが、マージされます。その結果クライアントから alice のドキュメントに要求があった場合には図4に示されるサービス空間とドキュメント空間が実現されます。(但し、この図では /lib/namespace.httpd による編成部分は省略されています。この部分は薄い灰色の領域に含まれます。)

図4. Pegasus で実現された web サーバの名前空間
ドキュメントの管理者ごとに独立した名前空間が与えられる

それ以外は見えないわけですから、お店の経営に例えると、alicebobcarol との寄り合い所帯のお店ではなく、独立したお店を与えられた事になります。この事が、CGI におけるトラブルを避ける基礎になります。

ファイルのアクセス保護

web サーバ上のファイルは、他のシステムユーザの ftp や telnet などを通じたアクセス、および他のユーザが作成した CGI を通じた不正アクセスから保護される必要があります。この問題は web サーバにとって頭の痛い問題の一つでした。
例えば alice が CGI で使用するあるファイル dataalice 自身と alice の作成した CGI だけからの読みとりを許したい場合があります。
UNIX では web サーバは nobody としてサービスを行っているので、alicenobody に対して data の読みとりを許可しなくてはなりません。すると他のユーザの CGI からも data が読みとられることになります。
Windows では web サーバは LocalSys としてサービスを行っています。LocalSys は UNIX の root と同等の特権を持っています。この場合にはどのようになるのでしょうか…
Pegasus ではこの問題を次の様に解決します。
  1. サーバをユーザ web として実行する。
    ただし web は実際のユーザではありません。(従ってファイルを所有する必要はありません。)
  2. /adm/usersalice のグループメンバとして web を追加する。即ち、
    alice:alice:web
  3. alicedata のアクセスモードを
    --rw-r----- alice web .... data
    に設定する。
注意: アクセス保護の問題がこんな簡単な方法で解決できるのは Pegasus のサービス空間がユーザ毎に綴じ込められているからです。

UNIX における救いは、この問題の解決の必要性を認識し、解決しようと努力している人々が存在することです。2つのアプローチを紹介します。

CGI wrapper

UNIX では現在の所、この問題を CGI wrapper によって解決しようとしています(例えば http://download.sourceforge.net/cgiwrap )。すなわち web サーバはCGI wrapper を通じてのみ CGI にアクセスし、CGI wrapper には root によるSUIDビットが立てられます。CGI は指定された場所に置くことを求められます。CGI wrapper が CGI にアクセスする時には root 特権を利用して CGI ファイルのオーナーに変身してアクセスします。CGI ファイルに直接 SUID ビットを立てないのは、あまりにも危険だからです。(筆者は SUID は UNIX の失敗作であると思っていましたが、こういう所で役に立つとは考えててもみませんでした。)

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

9.2.u と v9fs

UNIX でも Plan9 の「プロセスごとに編成できる名前空間」を実現しようとするプロジェクトがあります。
第一段階として open などの標準入出力ライブラリを書き直し、新しいライブラリを使用したプログラムは Plan9 的な振る舞いをするようにします。しかしこのままでは古いライブラリを使用したプログラムに対する保護が効かないので、やがては変更はカーネルレベルにまで持っていく計画です。(完全な置き換えには10年ほどかかるでしょう。そしてその頃になったら UNIX にも Pegasus と同じコンセプトに立った web のサーバが実現するでしょう。)
カーネルレベルで名前空間を閉じこめない限り、ユーザレベルの CGI の完全な自由はありません。しかし、CGI をスクリプトに限定し、新しいライブラリを使用したスクリプト言語の使用を許すだけでも非常に大きな前進です。詳しくは次の URI を参照してください。
http://www.ddj.com/documents/s=1782/ddj0112a/0112a.htm
最近、Plan9 のファイルシステムとのインターフェースの仕組みが発表されました。(http://sourceforge.net/projects/v9fs/)

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

Pegasus の現在の目標は高度な安全性と高度な自由度を備えた仮想ドキュメント環境をユーザに提供することにあります。

Pegasus は仮想ドキュメント環境を実行ハンドラによって実現します。 CGI は実行ハンドラの特殊な設定にすぎません。実行ハンドラの内容の設定は完全にドキュメントの管理者に任せられているので、彼らは自分たちのニーズに応じた内容を盛り込むことができます。

実行ハンドラとはリクエストされたファイルのパスパターンに応じてその処理を行うプログラムの事です。実行ハンドラは Apache などでは、httpd.conf の中で可能な設定の一覧がリストアップされ、その中からコメントを外すことによってしか選択できません。Apache/1.3.27 の場合については以下の5つです。

# AddHandler cgi-script .cgi
# AddHandler server-parsed .shtml
# AddHandler send-as-is asis
# AddHandler imap-file map
# AddHandler type-map var
Pegasus ではドキュメントの管理者はサービス空間の中の /etc/handler の中で、クライアントから要求されたファイルのパスパターンとそれを処理するプログラムの関係を定義します。 プログラムはサーバーコードとは独立しており、多くの場合、簡単なスクリプトなので、短時間に開発できます。以下に筆者のサーバ(http://plan9.aichi-u.ac.jp)の実行ハンドラの設定内容を例示します。
# path           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
リクエストされたファイルを処理するプログラムが、リクエストされたファイル自体であれば所謂 CGI プログラムになります。

特殊な拡張子のファイルあるいは特殊な場所にあるファイルに対して特殊なプログラムで処理する事もできます。Server Side Include の機能も実行ハンドラを使用して実現できます。また、 FTP サーバのようなサービスをweb サーバで代行する場合にはファイルの一覧をクライアントに示す必要があるでしょう。このような場合には FTP 用のファイルが置かれているディレクトリに対して自動的にファイルの一覧を表示するプログラムを実行させるようにします。

Pegasus の実行ハンドラの考え方は広い応用を持つ事が想像できますが、ドキュメント管理者にこれだけの自由が与えられるのは、ここでの設定が、他人のドキュメントに影響を与えないからです。