コンセプト
目次- 1.0.0 ドキュメントの管理主体に基づく名前空間の分離
- 1.1.0 通常の web のサーバ
- 1.2.0 Plan9 の標準 web サーバによる進展
- 1.3.0 Pegasus によって実現された web サーバの名前空間
- 2.0.0 Pegasus における名前空間の再編成
- 3.0.0 ファイルのアクセス保護
- 3.1.0 CGI wrapper
- 3.2.0 9.2.u と v9fs
- 4.0.0 自由度の高い仮想ドキュメント環境
2002/11/29 更新
ドキュメントの管理主体に基づく名前空間の分離
通常の web のサーバ
通常の web のサーバにおいてはサーバルートと言う概念は本質的な意味を持っていません。例えば Apache ではhttpd.conf
の中で ServerRoot を指定しますが、これは単にアクセス記録などを置く場所を意味しているに過ぎません。
通常の web サーバではサーバルートはアクセス制限に対して何の意味も持っていません。この事は CGI を使用した場合に直ちに問題になります。即ち web のサーバは一見するとクライアントからのアクセス可能なファイルを制限しているように見えても、CGI プログラムからはシステムの全てのファイルが見えてしまいます。この事は重大なセキュリティ上の問題をもたらしかねません。そのためにエンドユーザによる CGI の使用は禁止されるかあるいは厳重な統制下に置かれるのが普通です。
図1: 伝統的な web サーバの名前空間
real space = service space
外枠の矩形領域が実空間( 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
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 プログラムを通じて、他の人のファイルにアクセスできる可能性がある事を意味しています。従ってドキュメントを作成し公開する人々の間の相互干渉の可能性をもたらします。
この問題は図3a、図3b に示すように、サービスを行う web のサーバが、ドキュメントごとの名前空間の中でサービスを行うことによって解決されます。そしてこれは Pegasus によって初めて解決されました。
図3a | 図3b |
ドキュメントの管理者ごとに独立した名前空間が与えられる必要がある
図3a は {alice} のドキュメントをサービスしているときの Pegasus のサービス空間
図3b は {bob} のドキュメントをサービスしているときの Pegasus のサービス空間である
Pegasus における名前空間の再編成
話をもう少し具体的にし、次のように3人の役割を仮定しましょう。alice
を実ホストのユーザ
bob
を実ホストの web ドキュメントの管理者
carol
を仮想ホスト(名前をcar
としましよう)のドキュメントの管理者とします。
/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 サーバの名前空間
ドキュメントの管理者ごとに独立した名前空間が与えられる
alice
は bob
と carol
との寄り合い所帯のお店ではなく、独立したお店を与えられた事になります。この事が、CGI におけるトラブルを避ける基礎になります。
ファイルのアクセス保護
web サーバ上のファイルは、他のシステムユーザの ftp や telnet などを通じたアクセス、および他のユーザが作成した CGI を通じた不正アクセスから保護される必要があります。この問題は web サーバにとって頭の痛い問題の一つでした。例えば
alice
が CGI で使用するあるファイル data
は alice
自身と alice
の作成した CGI だけからの読みとりを許したい場合があります。UNIX では web サーバは
nobody
としてサービスを行っているので、alice
は nobody
に対して data
の読みとりを許可しなくてはなりません。すると他のユーザの CGI からも data
が読みとられることになります。Windows では web サーバは
LocalSys
としてサービスを行っています。LocalSys
は UNIX の root
と同等の特権を持っています。この場合にはどのようになるのでしょうか…Pegasus ではこの問題を次の様に解決します。
- サーバをユーザ
web
として実行する。
ただしweb
は実際のユーザではありません。(従ってファイルを所有する必要はありません。)
/adm/users
にalice
のグループメンバとしてweb
を追加する。即ち、
alice:alice:web
alice
はdata
のアクセスモードを
--rw-r----- alice web .... data
に設定する。
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 varPegasus ではドキュメントの管理者はサービス空間の中の
/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 の実行ハンドラの考え方は広い応用を持つ事が想像できますが、ドキュメント管理者にこれだけの自由が与えられるのは、ここでの設定が、他人のドキュメントに影響を与えないからです。