市場とショップは本質的にどこが違うのだろう?
ここではセキュリティ面から考察してみる。
もちろん Web サーバーに望まれる特性を論じるためである。
Web サーバの動作の基本はクライアントからのファイル要求に対して、クライアントにそのファイルを渡すことにある。
Web サーバーは、httpd
とも呼ばれる。
「Web サーバー」はハードウェアをさす事が多いが、「httpd
」はソフトウェアをさす。
Web サーバーはクライアントからのファイル要求以外にも、様々な要求に答えている。
例えば、
サーバー側は個別のニーズに応じてプログラムを書き、それを CGI(Common Gateway Interface) を通じて呼び出す。
CGI プログラムを書くのは、サーバーを運営している SE 達であるが、必ずしも十分な経験を積んでいるとは言いがたい。CGI プログラムは攻撃のターゲットとなっているのであり、攻撃の手法を知った上で正しく書く必要がある。その意味で CGI プログラミングは実は難しい。
広い共有スペースに多くの小さな店舗が並んでいる。
お互いが丸見えで、店舗間に明確な仕切がない。
市場というのは信頼で結ばれている空間である。商売仲間、そして売り手と客の間の。
しかし、
あそこのバアさん、いい人なんだがね... 人が良すぎて、この前なんか、誰かが「あんたのとこの息子が大怪我で病院へ運ばれたよ... 店番してやるから...」と言ったんだ。するとバアさん、真っ青になって飛んで行ったんだ。その後が大変でね... 荒らされたのはバアさんのトコだけではないんだ。みんなやられたよ...
伝統的な Web サーバーは市場に似ている。
サーバーソフト(httpd
)自体はアクセス可能な範囲を定めているが、CGI のプログラムからはシステムの中が丸見えで、どのファイルへもアクセス可能である。(もっとも OS のアクセス制御が設定できるので、必ずしもファイルの読み書きができるわけではない。)
アクセス制限はもっぱら CGI プログラムに任せられる。
しかし、プログラムの書き方がマズかったりすると騙される。その場合管理ミスは致命的である。
ひとつのサーバーに多数の仮想店舗が存在すると、人の良すぎる店主(CGI プログラムの作成者)も居るだろう。また最近では悪意のある店主も紛れ込んでいるかも知れない。
さてここで、現実の Web の仮想店舗の形態を整理しておこう。
大きく2つに分類できる。
種類 | URL | IPアドレス |
---|---|---|
実ホスト | http://ar.aichi-u.ac.jp |
202.250.160.40 |
仮想ホスト1 | http://plan9.aichi-u.ac.jp |
202.250.160.122 |
仮想ホスト2 | http://cpa.aichi-u.ac.jp |
202.250.160.40 |
ユーザ | http://ar.aichi-u.ac.jp/~arisawa |
202.250.160.40 |
「ユーザ」はサーバーのユーザなので、実ホストの名前の後にユーザ名を、/~
の後に続ける。(レンタルサーバでは /~
は嫌がられるらしく、これが表に出ないように工夫をしているものがある)
仮想ホストには2つのタイプがある: 実ホストとIPアドレスを共有するもの(名前ベースの仮想ホスト)、異なるIPアドレスを割り当てるもの(IPアドレスベースの仮想ホスト)。
現在ではIPアドレスが枯渇しているので、名前ベースの仮想ホストの方がコストがかからない。レンタルサーバーの場合には全て名前ベースだと考えてよい。DNS に登録すればよいだけなので余計なコストがかからないのである。
nslookup コマンドを使えばホストのIPアドレスがわかる。
http://202.250.160.40
でアクセスすれば http://ar.aichi-u.ac.jp
のページが表示されるだろう。このことから http://cpa.aichi-u.ac.jp
は名前ベースの仮想ホストであることがわかる。
なお、Apache の場合は、実ホストと仮想ホストは両立しない。(「実ホスト」は「仮想ホスト」の一つとして運用される) 仮想ホストで運用されている場合は、さらに「ユーザ」をサポートしようとすると、そのユーザがどのホストに属するか曖昧な形で運用されるので注意が必要である。(対処法があるのかも知れないが...)
year | name | author | 方式 | OS |
---|---|---|---|---|
1996-1998 | cgiwrap | Neulinger | wrapper | Unix/Linux |
1998 | suEXEC | The Apache Group | wrapper | Unix/Linux |
1998 | SBOX | Stein | wrapper | Unix/LInux |
Web のサーバーには、一般に複数のドキュメントの管理者が存在し、彼らの作成した CGI が他に干渉するのを防ぐための代表的な工夫が1996年から1998年にかけて発表された。Neilinger の cgiwrap
、Apache グループによる suEXEC
、それから Stein による SBOX
である。
インターネットが民間に解放されたのは 1993年であり、Windows95 が販売された1995年頃には Web のサーバーは爆発的に広がったと考えられる。それとともに Web サーバーの CGI には問題があることが認識されたのであろう。
いずれも Unix/Linux 上のサーバーで対策が採られ、wrapper 方式を採用している。
管理者は絶大な権限を保有している。管理者の仕事には、システムのファイルの整理や、場合によってはファイルシステムの初期化まで広い範囲のものを含んでいる。それらをこなすために必要な権限を含んでいるのである。
Unix/Linux の管理者 ID は root
である。root
のプロセスは、所有者属性を任意に変更できる。
httpd
は管理者 root
によって実行されるが、クライアントからのリクエストを受け取る前に弱い権限のプロセス(noboy
や http
)に変更される。root
のままでリクエストを受け取るのは危険すぎるからである。
wrapper方式が現れる以前の Web サーバーの問題点をまず解説する。
クライアントからのリクエストはまず httpd
に伝えられる。CGI が絡む場合にはリクエストの内容には
httpd
は通常は仮想ユーザー noboy
として動いており。この場合には、どの CGI も nobody
として動作する。alice
が管理するファイルも、bob
が管理するファイルも、nobody
に対してはアクセスを許さなくてはならない。この事は、alice
が作成した CGI が bob
のファイルにアクセスできる事を意味する。
CGI wrapper は Unix/Linux の特殊なファイル属性 SUID を利用する。
所有者が root
の実行ファイルに SUID 属性が設定されていると、それが実行された時に特権モードとなる。(root 特権)
この特権は、CGI プログラムの実行主体を変更するのに使われる。alice
の CGI であれば alice
として実行される。bob
は自分の領域に、bob
自身と httpd
以外は入り込めないように設定しておけば、alice
の CGI からの干渉を防ぐ事ができる。
bob
のファイルに SUID 属性が設定されている場合、alice
がそれを実行すると、あたかも bob
が実行したかのように振る舞うのである。bob
が他人によるファイルの書き換えを排除するように設定していたとしても、SUID を設定された bob
のファイルを通じて、他人が bob
のファイルを変更したり、削除したりするリスクが発生する。root
所有のファイルは危険きわまりない。システム全体が誰かによって破壊されるリスクを負うことになる。
CGI wrapper は SUID 属性が設定された root
所有のプログラムである。リスクを軽減するために、このプログラムの中でいくつかのチェクが行われる。その中で最も重要なのは、これを実行したユーザのチェックである。Unix/Linux のプログラムは、誰が実行したかを知る仕組みを備えている。CGI wrapper は httpd
によって実行されるものであるから、httpd
以外による実行は拒否されるであろう。CGI wrapper の設定には、このチェックを可能にする項目が含まれているはずである。
適切に使用すると、この機能によりユーザが個別の CGI や SSI プログラムを開発し実行することで生じるセキュリティ上の危険を、 かなり減らすことができます。しかし、suEXEC の設定が不適切だと、 多くの問題が生じ、あなたのコンピュータに新しいセキュリティホールを 作ってしまう可能性があります。
suEXEC を Apache のデフォルトインストールには含めないことが Apache グループで決定されています。