jail環境によるWebサーバーの構築

以下のテキストは、執筆時当時の情報を元に書いたものであり、 現在の情勢にそぐわないことを含む場合があるので注意されたい。 また、テキストは最終提出原稿で校正を経る前のものなので、実際にUNIXUSER 本誌に記載されたものとは異なる。誤字脱字等そのままである。

致命的な誤り以外は加筆修正等は行なわないので情報の鮮度に気をつけつつ 利用して欲しい。

目次

註: 本記事は当初Part3として執筆したが前後の記事のバランスを 考えてPart2として掲載された。


PartIII Jail環境で堅牢なサーバを作る


■Jail環境の特徴

jail(8)は FreeBSD 4.0-RELEASE で登場した、プロセス(群)をある制限された環
境に閉じ込めてしまう機構である。古くから存在する同種の機構にchroot(8)が
あるが、jailはそれを機能強化して、本体OSとの隔離度をより一層高めたものと
することができるものである。ここでは、閉じた環境を作ることの意味の解説か
ら入り、新しいFreeBSDが獲得したjail環境をセキュアサーバシステムの構築に
利用するための方法について解説してゆく。

 ●閉じた環境の意義

	PC-UNIXによってUNIX系OSに出会った人々には目新しく感じるかもしれ
	ないが、システムの一部だけしかアクセスできないようにすることは初
	期の段階から利用されていた。不特定多数の人にファイルを供給する手
	段として利用されている anonymous ftp サーバには、誰でも自由にロ
	グインして所望のファイルを持って行くことができる。誰にでもログイ
	ンを許可するので、サーバ上にローカルアカウントを持っているユーザ
	と同じ環境でファイルにアクセスできてしまってはセキュリティの確保
	は困難である。たとえば、パスワードファイル(/etc/passwd)やグルー
	プ定義ファイル(/etc/group)などは、テキスト形式で書いてあり一瞥す
	るだけでシステムの管理者が誰であるのかが分かってしまう。重大な意
	味を持つファイルもシンプルな形式で設計されているのはUNIX系システ
	ムの美徳ではあるが、それは正規に管理・利用するときに有効なこと。
	その読みやすさは侵入を企てている者にとっても有利に働いてしまうこ
	とに注意しなければならない。

	そこで anonymous ftp では、システムの持つファイルシステムの限ら
	れた部分だけがアクセスできるようにchrootを利用している。chrootは
	Change root directory の略で、ある特定のディレクトリをルートディ
	レクトリと見立ててひとつのプロセスを起動する機構である。図(い)の
	ようなファイルシステム空間があったとしよう。その一部、
	/usr/chrootdir/ 以下にファイルシステム全体のサブセットのようなディ
	レクトリツリーを用意しておいて、

		+-------------------------------------------
		| # chroot /usr/chrootdir /bin/sh
		+-------------------------------------------

	と、chrootコマンドを起動する。すると /usr/chrootdir ディレクトリ
	を新たなルートディレクトリとみなした状態で /bin/sh が起動する。
	ここで起動された /bin/sh は(本来のファイルシステムの)
	/usr/chrootdir/ よりも上位のディレクトリは全く見えなくなる。つま
	り、chrootdir/ を起点に構成された箱の中に「閉じ込められて」しま
	うわけだ。一般に、ftp サービスデーモンでは、ユーザ名として ftp
	または anonymous でログインした場合、あらかじめ指定したディレク
	トリにchrootしてからファイルの授受を行うようになる。こうすること
	で、システムにとって重要な意味を持つファイルの漏洩を防げる。

図 (い)
+------------------ chroot -----------------------------------------------
|  +--------------------- ファイルシステム -----------------------------+
|  |                    (/)                                             |
|  |                     |                                              |
|  |         v----v---...+-------v------v---------v---.....             |
|  |       bin/ boot/ ...       etc/ kernel      usr/  ....             |
|  |        |     |              |                |                     |
|  | v--v---+-.. v+----v-...  v--+---- ..    v----+--------v---...      |
|  | [  cat ..  boot0 boot1. XF86Config .. X11R6/ bin/     |            |
|  |                                        +---------chrootdir/ ---+   |
|  |                                        |           (/)         |   |
|  |                                        |            |          |   |
|  |                                        |  v----v----+---v---.. |   |
|  |                                        | bin/ etc/     usr/    |   |
|  |                                        |       〜 〜 〜 〜     |   |
|  |                                        +-----------------------+   |
|  +--------------------------------------------------------------------+
+--------------------------------------------------------------------------

 ●chrootの弱点

	chrootの効用によってシステム管理に重要な意味を持つファイルへのア
	クセスを阻止できる点は理解できた。しかし、それはchrootされたプロ
	セスが直接ファイルをアクセスする場合にのみ有効である。もし、
	chroot環境内からネットワーク経由で自ホスト、あるいは自ネットワー
	クの資源にアクセスするためのプロセスを起動できたとしたら、多くの
	場合chrootしていない環境で実行したのと同じ結果が得られてしまう。
	これは、特にネットワーク経由のリクエストを受け取るデーモンが内部
	的に別のプロセスを起動してその結果を送り返すような形態で問題とな
	る。典型的な例で言い換えると、WebサーバでCGIプログラムを動かす場
	合がこれにあたる。

	まず、本来のファイルシステム全てが見える状態、つまり普通にhttpd 
	を起動した環境でCGIプログラムが動く場合を考えてみよう。この場合
	CGIプログラムも本来のファイルシステムが全て見える状態で起動する。
	数年前、Apache の標準インストールで自動的にインストールされるCGI 
	スクリプト "phf" を利用するとサーバ上の任意のコマンドを実行でき
	てしまうという単純なセキュリティホールを突いて悪戯をするという問
	題が流行した。このような単純な穴が現在も残っている可能性は小さい
	が、同種のものが今後発見されないという保証はない。また、標準的シ
	ステムが内包するセキュリティホールのみならず、該当サーバの利用者
	が不注意によって(場合によっては故意に)何でも起動できてしまうCGI
	を置いてしまった場合はもはやそのホストにあるファイルは丸裸状態と
	なってしまう。

	では、httpdをchroot環境下で起動した場合はどうだろう。たとえ任意
	のファイルを取得できたとしてもそれは閉じた環境内でのこと。システ
	ムの設定にかかわるという意味での重要なファイルにはアクセスできな
	い。しかし、ファイルシステムを直接アクセスするのではなく、ネット
	ワーク経由でアクセスするような事が行われたとしたら、問題はchroot 
	環境の外に出てしまうことになる。たとえば、ypcatコマンドなど、シ
	ステムにとって重要な意味を持つ情報をネットワーク経由で取得するた
	めのコマンドを起動された場合はたとえchroot環境でもそれを防ぐ手立
	てはない(※[ろ])。

--- 註[ろ] ---------------------------------------------------------------

	このように書くとchrootが弱いもののように感じられるかもしれないが、
	それはjailと比較しての話であって、chroot無し環境と比べればはるか
	に守りは固い。現実的にはchroot環境内に外部からネットワークアクセ
	スするコマンドを送り込まれることがあったとしたら、その時点でシス
	テムのセキュリティがかなりのレベルまで崩壊していると考えて良く、
	そこまで最悪の状況を憂いてchrootが有効でないと判断するのはナンセ
	ンスである。逆に、正規ログインアカウントをもつ利用者がchroot環境
	内に危険性を持つコマンドを持ち込んだとしたら……、これは既にシス
	テムのセキュリティチューン以前の問題で、与えるべきサービスがユー
	ザ層の平均的モラルに見合ったものかどうかなどを考え直す必要がある。

--------------------------------------------------------------------------

 ●jail環境

	ここまで説明したchroot環境の弱点を潰す形で設計されたものがjailで
	あると考えて良いだろう。jailは内部的にchrootを利用しているので、
	特定のディレクトリ以下しかjail環境に見えない点は同様である。jail
	ではそれに加えていくつかの制約が加えられている。

  ・プロセス空間の分離

	jail環境内からはjail環境内のプロセスしか参照できない。chroot環境
	では環境内部のプロセスは、ルートディレクトリが違うというだけの制
	約しかなく、もしchroot環境内でプロセステーブルを参照できるような
	設定にしてあるのなら、システム全体の持っているプロセス全てが参照
	でき、また環境外のプロセスにシグナルを送ることも可能である。いっ
	ぽうjail環境からは環境外のプロセスには一切アクセスすることができ
	ない。もちろん仮に環境外の特定のプロセスのPIDが分かったとしても、
	シグナルを送ることはできない。したがって、jail環境内でroot権限を
	獲得したとしても(※は)、そこから動作システム本来の環境で動いてい
	るプロセスに影響を与えることはできない。

--- 註[は] ---------------------------------------------------------------
	むしろjailを設計した思想としては、積極的にjail環境内利用者にroot
	権限を与えて、各種ネットワークサービスを供給する Virtual Server
	として運用してもらうという方向性の方が強いように思われる。
--------------------------------------------------------------------------

  ・ネットワークアドレスの独立

	chroot環境では、本来のホストのネットワークインタフェースに付いた
	IPアドレスをそのまま引き継ぐので、本体OSと独立したメイルサーバを
	起動する、などのことは不可能である。jailの場合、ネットワークイン
	タフェースに付けたひとつの alias アドレスを代表する形で動作する
	ので、本体とは独立したIPアドレスを持って動くことになる。jail動作
	環境セットの作成は以下のような流れで行う。

	+------------------------------------------------------------------
	| # ifconfig ed0 alias 192.168.0.2
	| # jail /subfilesystem/for/jail NewHostname 192.168.0.2 /bin/sh
	+------------------------------------------------------------------

	ここで /subfilesystem/for/jail はjail環境が動作できるだけのディ
	レクトリ構造の最上位ディレクトリ、NewHostname はjail環境に与える
	ホスト名、192.168.0.2 はそのホストに対応したIPアドレスである。こ
	のようにjail環境を開始するとあたかも新しいホスト NewHostname
	(192.168.0.2) が生まれたかのように振舞う。ネットワーク的にも本体
	システムとは違う個体として動くようになる。

	もう一点、jail用ディレクトリ構造の作成と、jail環境に付けられたIP
	アドレスに向かうリクエストをjail環境だけが処理するように仕向ける
	工夫などがあるがそれらについては後述する。

  ・制限されたroot権限

	jail環境内でもスーパーユーザは特権的に多くの状態変更操作などを行
	うことができるが、通常環境で許されている操作全てが許されているわ
	けではない。本体の環境に影響を与える可能性のある操作は禁止されて
	いる。jail環境内のスーパーユーザに与えられている特権にはおもに以
	下のものがある。

	* ユーザ/グループ ID操作 (set*id系, setlogin等)
	* リソース操作 (strlimit)
	* kern.hostnameを始めとするいくつかの sysctl
	* chroot
	* ファイルのフラグやパーミッション、タイムスタンプなどの変更
	* 特権ポート(1024番未満のポート)へのサービス割り当て

	逆に、jail外の環境に影響を与える操作や、ネットワークを流れる raw
	packet を見ることは許されていない。したがって、jail環境内でのスー
	パーユーザが tcpdump などを利用してパケットを覗き見ることは不可
	能である。もっとも、現状ではこれらの制約によりjail内では、pingを
	利用することもできない。また、どのような操作が禁じられているかは
	カーネルソースにハードコードされており、どのような操作を許すかを
	管理者が調整することができない。以後のリリースでは設定ファイル等
	により禁止する権限をカスタマイズできるように改善されるのではない
	かと期待する。

■jail環境の構築

	FreeBSDがもたらした新しい封印環境 jail を早速体験してみよう。ま
	ずは、manpageを参照してもらいたい。

		% man jail

	jail(8) manpage には大きく分けて4つのステップが記載されている。

	* jail用のディレクトリツリーの作成
	* jail用のネットワーク関連設定
	* jailコマンドによるjail環境の開始
	* jail環境の操作

	このステップで分かるように、jail環境の管理はjail環境にどれだけの
	ディレクトリツリー内容を与えるかと、どのようなネットワークサービ
	スを持たせるかが鍵を握っている。manpageの解説は以下のようになっ
	ている。

	+----------------------------------------------------------
	| D=/here/is/the/jail
	| cd /usr/src
	| make hierarchy DESTDIR=$D
	| make obj
	| make depend
	| make all
	| make install DESTDIR=$D
	| cd etc
	| make distribution DESTDIR=$D NO_MAKEDEV=yes
	| cd $D/dev
	| sh MAKEDEV jail
	| cd $D
	| ln -sf dev/null kernel
	+----------------------------------------------------------

	これは特定のディレクトリ以下に、FreeBSD標準インストール状態と同
	じ構造を作ってそこをjail用ルートディレクトリにするというものであ
	る。FreeBSD標準ファイル構成が全てjail環境内に供給されることにな
	るので、完全にひとつのサービス用ホストを立ててしまうのに近い意味
	合いになる。逆に、jail内には一部のファイルのみを置くようにすると
	いう事ももちろん可能で、どちらを選ぶかはポリシーに依存する。それ
	ぞれの方策を取る場合の特徴を簡単にまとめると次のようになるだろう。

	【jail内に全てのファイルをインストールする】
	  * jail内で全てのコマンド群を利用できる
	    (jailで禁止されている一部の特権操作を行うものを除く)
	  * 必要なものを厳選したりしないのであまり考えずに済む
	  * ディスク容量をそれなりに消費する
	  * jail環境なら壊されてもいいという前提で構築するもののそれなり
	    に大きな環境となるので壊された場合のショックが大きい

	【jail内に一部のファイルだけをインストールする】
	  * 利用させたくないコマンドを置かないで済む
	  * 不要なファイル必須のファイルを選定する作業を伴う
	  * フルインストールに比べディスクを節約できる
	  * (運用にもよるが)環境内が壊されても比較的ショックは小さい

	どちらも一長一短があるわけだが、もう一度jailの特徴に立ち戻って考
	えてみると、仮にroot権限を与えても大丈夫という思想のもとで設計さ
	れているだけに、できれば前者の構成を取って利用者に最大限の権利を
	与えたい。しかしその一方で、jail内環境を壊されてしまうことも(本
	体のシステムに影響が出ないとはいえ)大きな不利益である。したがっ
	て、本稿では「最大限の環境を与え」て、「その環境を壊せない」よう
	にする工夫を加えて環境を構築する方法を考えてみることにする。

 ●jail用ディレクトリツリーの作成

	jail(8)のmanpageにあるように、ほぼフルセットのFreeBSDディレクト
	リツリーをjail環境に与えてしまっても本体システムに影響を与える程
	の問題は起きないように思えるが、ここではさらに一歩進めて、jail環
	境内部の改ざんもできるだけ防げるようにするため Union File System
	(unionfs) を利用してディレクトリツリーを作成することを試みる。簡
	単のため /usr 以下を unionfs でリードオンリマウント、/etc や
	/dev, /var など封印環境毎に独立して必要なディレクトリはコピーを
	作って用意することにする。

	ちなみに従来 unionfs を利用するためには kernel config ファイルに

		options		UNION

	を追加し、UNIONオプションを有効にしたカーネルで起動する必要があっ
	たが、4.x-RELEASE では unionfs マウントを要求したときに自動的に
	必要なカーネルモジュールが組み込まれるようになっている。マウント
	操作をしたのちに kldstat コマンドを利用して union.ko が組み込ま
	れていることを確認しよう。

	+------------------------------------------------------------
	| # mount -t union /usr /mnt
	|   ~~~~~~~~~~~~~~~~~~~~~~~~
	| # kldstat
	|   ~~~~~~~
	| Id Refs Address    Size     Name
	| 1    3 0xc0100000 314050   kernel
	| 2    1 0xc0d31000 11000    linux.ko
	| 3    1 0xc0e69000 9000     union.ko  ←
	+------------------------------------------------------------


 +---[コラム]--------------------------------------------------------------
  = Union File System =

  Union File System はその名が示す通り、二つのディレクトリの結合を作るファ
  イルシステムである。たとえば、
      /---- /dir-A ----\     /---- /dir-B ----\
      |  file-1        |     |   file-2       |
      |  file-2        |     |   file-3       |
      |                |     |                |
      \----------------/     \----------------/
  のような二つのディレクトリがあった場合を想定しよう。Union File System
  では片方のディレクトリをもう片方のディレクトリに重ね合わせることができ
  る。ここで、

	# mount -t union /dir-B /dir-A

  とすると、/dir-B のツリーが /dir-A に重ね合わせられ、結果として /dir-A
  の内容は以下のように見える。
      /---- /dir-A ----\
      |  file-1        |
      |  file-2        |
      |  file-3        |
      \----------------/
  この状態は /dir-A という箱の上に /dir-B という透明な箱を重ねて、その中
  身を上から見ているようなものととらえるとわかりやすい。file-2はもともと
  /dir-A, /dir-B 両方に存在するファイルであるが、/dir-B のほうを上に重ね
  ているので実際に見えるのは本来の /dir-B/file-2 のほうである。またここ
  で /dir-A の中に新たにファイルを作成すると実際にはそれは上に重ねた箱で
  ある /dir-B のほうに作成されるが、/dir-A にも存在するように見える。

  また、mount_union(8) のオプションを利用することでディレクトリの重ね方
  を逆にすることもできる。

	# mount -t union -o -b /dir-B /dir-A

  とすると、/dir-B が /dir-A に結合されるが、/dir-B を /dir-A の下にもぐ
  り込ませるような関係でマウントするので、/dir-A に新しく書き込む操作は
  そのまま本来の /dir-A に対して行われることになる。

  Union File System の典型的な用途としては CD-ROM などの読み取り専用メディ
  アの上にプログラムのソースが展開された状態で入っているようなときに、そ
  の上に書き込み可能なファイルシステムにあるディレクトリを重ねて、あたか
  もCDROMのあるディレクトリに書き込みできるかのようにしてからコンパイル
  作業をするというものがある。

  なお、FreeBSD 4.1-RELEASE の段階では、kernelの config file に以下のコ
  メントがある。

    NB: The NULL, PORTAL, UMAP and UNION filesystems are known to be
    buggy, and WILL panic your system if you attempt to do anything with
    them.  They are included here as an incentive for some enterprising
    soul to sit down and fix them.

  ずいぶん以前のバージョンから null, portal, umap, union の各ファイルシ
  ステムは「バギー」であるとの警告があったが、unionfs に関してはバージョ
  ン4系に移った辺りから落ち着いてきたように感ずる。筆者が試した限りでは
  unionfs 上のディレクトリに連続的なファイルの読み書き負荷を与えてもとく
  にトラブルは発生しなかったので今回 Union File System を利用しての解説
  に踏み切った。読者の環境では不安定動作をする可能性も否定できないのでそ
  のような場合は素直にディレクトリツリーをjail用ツリーにコピーする方法を
  取って欲しい。もちろん、config file にあるコメントのように腰を据えて各
  ファイルシステムの問題点の修正を試みるのも歓迎されるであろう。ちなみに、
  jail環境用のディレクトリツリーをリードオンリでマウントするだけの目的で
  あれば mount_null(8) で十分である。がしかし、筆者の環境では安定動
  作が見られなかったので今回は利用を見送った。
 +---[コラム終わり]--------------------------------------------------------

	まず、jail環境のルートとなるディレクトリを作成し、ルートパーティ
	ション固有のディレクトリをコピーする。

	+------------------------------------------------------------
	| # cd /
	| # mkdir /jail
	| # mkdir -m 1777 /jail/tmp
	| # tar cf - bin etc root sbin var | tar xvpfC - /jail
	+------------------------------------------------------------

	jail環境に必要なデバイスファイルを作成する

	+------------------------------------------------------------
	| # mkdir /jail/dev
	| # cp /dev/MAKEDEV /jail/dev
	| # cd /jail/dev
	| # sh MAKEDEV jail
	+------------------------------------------------------------

	jail環境で利用できる procfs をマウントする。

	+------------------------------------------------------------
	| # mkdir /jail/proc
	| # mount -t procfs proc /jail/proc
	+------------------------------------------------------------

	/usr ディレクトリ以下を読み取り専用で unionfs マウントする。

	+------------------------------------------------------------
	| # mount -t union -o ro /usr /jail/usr
	+------------------------------------------------------------

	以上で jail 用のディレクトリツリーの準備はほぼ完了である。

 ●jail環境のネットワーク関係の設定

	先に説明したようにjail環境は固有のIPアドレスを一つ保持して動作す
	る。jail用のIPアドレスは IP alias で設定する。ここでは、プライベー
	トアドレスである 192.168.0.2 をjail環境用に設定しよう。

	+------------------------------------------------------------
	| # ifconfig fxp0 alias 192.168.0.2 netmask 255.255.255.0
	+------------------------------------------------------------

	また、jail環境内でネットワークサービスデーモンを起動する場合、本
	体システムのデーモンプログラムがその邪魔をしないように、必要に応
	じて以下の定義を本体の /etc/rc.conf に書くと良い。

	/--[ /etc/rc.conf の一部 ]-----------------------------------
	|  sendmail_enable="NO"
        |  inetd_flags="-wW -a 192.168.11.23"
        |  portmap_enable="NO"
        |  syslogd_flags="-ss"
	\------------------------------------------------------------

	この例は本体システムのIPアドレスが 192.168.11.23 の場合の設定で
	ある。

 	inetdに-aオプションで特定のIPアドレスを与えると、inetd経由で起動
 	されるデーモンがそのIPアドレスだけを使うようになる。syslogdの-ss
 	オプションによってログ保存要求をネットワーク経由では受け取らなく
 	なる。また、sendmailとportmapperは、jailに持たせたIPアドレスと干
 	渉しないようにするには本体システムでは止めてしまうのが手っ取り早
 	い。

 ●jail環境の開始

	ここまでの準備が完了すればjail環境を立ち上げることが可能である。
	立ち上げはjailコマンドで単純に行える。

	+------------------------------------------------------------
	| # jail /jail 192.168.0.2 prison.mydomain /bin/zsh
	| prison# 
	+------------------------------------------------------------

	ここで、prison.mydomain は 192.168.0.2 に対応するjail環境につけ
	るホスト名である。第4引数にはjail環境下で最初に起動するコマンド
	で、この例は /bin/zsh を起動するものである。なお、以後の説明では
	本体システムのroot権限でのコマンド入力を # のみのプロンプト、
	jail環境内でのroot権限でのコマンド入力を prison# というプロンプ
	トで表現することにする。

	上記のコマンドにより /jail ディレクトリをルートディレクトリとす
	る新しい jail 環境が起動する。コマンドラインから起動した場合には
	現在利用中の端末にjail環境の親となるプロセス(この場合は/bin/zsh) 
	が上がってくる。このシェルで、この環境が本体システムとは隔離され
	たものであることを確認しよう。

	+------------------------------------------------------------
	| prison# ls -F /
	|         ~~~~~~~
	| bin/    dev/    etc/    proc/   root/
	| sbin/   tmp/    usr/    var/
	| prison# ifconfig fxp0 | grep inet
	|         ~~~~~~~~~~~~~~~~~~~~~~~~~
        | inet 192.168.0.2 netmask 0xffffff00 broadcast 192.168.0.255
        | inet6 fe80::200:eff:fec3:c144%fxp0 prefixlen 64 scopeid 0x1 
	| prison# hostname
	|         ~~~~~~~~
	| prison.mydomain
	| prison# ps ax
	|         ~~~~~
	|   PID  TT  STAT      TIME COMMAND
	| 12443  p0  SJ     0:00.24 /bin/zsh
	| 12464  p0  R+J    0:00.01 ps a
	+------------------------------------------------------------

	jail環境が、本体システムの /jail にchrootされ、なおかつ起動時に
	与えられたIPアドレスとホスト名を持ち、jail内部からはjail内で起動
	されたプロセスしか参照できないことが分かる。

	さてここで、jail環境内でネットワークサービスデーモンを起こしてみ
	よう。試しに inetd を起動してtelnetが反応するか確認しよう。もち
	ろんinetd起動前にjail環境内の /etc/inetd.conf に telnetd のエン
	トリがあるか確認するのを忘れずに。

	+------------------------------------------------------------
	| (jail環境で)
	| prison# grep telnet /etc/inetd
	|         ~~~~~~~~~~~~~~~~~~~~~~
	| telnet stream tcp  nowait root /usr/libexec/telnetd telnetd
	| telnet stream tcp6 nowait root /usr/libexec/telnetd telnetd
	|        (telnetが有効になっている)
	| prison# inetd
	|         ~~~~~
	| (別のホストから)
	| % telnet 192.168.0.2
	|   ~~~~~~~~~~~~~~~~~~
	| Trying 192.168.0.2...
	| Connected to prison.mydomain.
	| Escape character is '^]'.
	|
	| FreeBSD/i386 (prison.mydomain) (ttyp1)
	| login: 
	+------------------------------------------------------------

	外部ホストからjail環境に向かってtelnetをかけてみて、loginプロン
	プトが出て来たら設定は成功である。ところでjail環境からjail環境自
	身に向かってtelnetをかけることはできない。言い替えると、jail環境
	が動いているホストからそのjail環境に対してのネットワークアクセス
	はできない。したがって本体システムからjail環境内に直接リモートロ
	グインすることや、jail環境で動いているWWWサーバにアクセスするこ
	とができないので注意が必要である。ただし、この制約に関しての説明
	がマニュアルページに見当たらないのでこの仕様が今後も有効なものな
	のかを判別できなかった。


 ●jail環境の停止

	jail環境を停止するときには環境内の全てのプロセスを停止することに
	注意する。jail環境開始時に起動したシェルから、もしくは外部から
	jail環境内にログインしてrootになり、環境内の全プロセスにシグナル
	を送る。

	+------------------------------------------------------------
	| prison# kill -TERM -1
	|   (または)
	| prison# kill -KILL -1
	+------------------------------------------------------------

	もしjail環境内にログインできない状態であれば、環境の外、つまり本
	体システムでjail環境プロセスを全て捜し出して終了させる必要がある。
	jail環境に閉じ込められているプロセスはpsコマンドの出力のステータ
	ス欄に付けられたJというタグで知ることができる。

	+------------------------------------------------------------
	| # ps ax
	|   PID  TT  STAT      TIME COMMAND
	|     0  ??  DLs    0:00.01  (swapper)
	|     1  ??  SLs    0:00.12 /sbin/init --
	|     2  ??  DL     0:00.02  (pagedaemon)
	|     3  ??  DL     0:00.00  (vmdaemon)
	|     4  ??  DL     0:00.00  (bufdaemon)
	|     5  ??  DL     0:00.10  (syncer)
	|    26  ??  Is     0:00.01 adjkerntz -i
	|    86  ??  Is     0:00.13 syslogd -ss
	|    89  ??  Is     0:00.01 /usr/sbin/portmap
	|    95  ??  I      0:00.00 nfsiod -n 2
	|    96  ??  I      0:00.00 nfsiod -n 2
	|   117  ??  Is     0:00.04 inetd -wW -a 192.168.11.23
	|   119  ??  Is     0:00.05 cron
	|   150  ??  Is     0:00.28 /usr/local/openssh/sbin/sshd
	|   160  ??  S      0:00.85 sshd: yuuji@ttyp0 (sshd)
	|   229  ??  IsJ    0:00.06 inetd
	|   231  ??  SsJ    0:00.02 syslogd
	|   161  p0  Is     0:00.52 -zsh (zsh)
	|   181  p0  S      0:00.60 /bin/zsh
	|   207  p0  TJ     0:00.52 /bin/zsh
	|   233  p0  SJ     0:00.02 /usr/local/Canna/bin/cannaserver
	|   234  p0  R+     0:00.02 ps ax
	|   154  v0  Is+    0:00.05 /usr/libexec/getty Pc ttyv0
	|   155  v1  Is+    0:00.03 /usr/libexec/getty Pc ttyv1
	|	 :
	|	略
	+------------------------------------------------------------

	この例ではJタグの付いている inetd, syslogd, zsh, cannaserver の
	各プロセスがjail環境内で動作していることが分かる。あるホストで
	jail環境を複数個起動している場合は、どのjail環境で動いているプロ
	セスなのかを知る必要がある。この場合は procfs に頼ればどのjailで
	動いているかが分かる。psコマンドの出力が上記のものであった場合、
	たとえば、プロセスID229番のinetdに対応するプロセス状態ファイルは
	以下のようになっている。

	+------------------------------------------------------------
	| # cat /proc/229/status
	| inetd 229 1 229 229 -1,-1 sldr 970203331,440531 0,23785 [行折返!]
	| 0,35677 select 0 0 0,0,2020,0 prison.mydomain
	+------------------------------------------------------------

	statsファイルの最後の項目はjail内プロセスの場合そのjailに割り当
	てられているホスト名が入る。よって、ある特定のjail環境を終了させ
	たいときは /proc/*/status ファイルのうちそのjail環境のホスト名が
	含まれているプロセスIDを選んでkillしてゆけば良い。

	しかしながら、デフォルトではjail環境内でホスト名を変えることが可
	能になっていることから、途中でホスト名を変えられてしまうとあとで
	該当プロセスを探すことが困難になってしまうので注意が必要である。
	jail環境内でのホスト名変更を禁止することができるので適宜そのよう
	に設定する。本体システムの /etc/sysctl.conf に以下の行を追加すれ
	ば良い。

	/------------------------------------------------------------
	| jail.set_hostname_allowed=0
	\------------------------------------------------------------


■セキュアサーバのベースとしてのjail環境の整備

	jail環境の立ち上げ方が分かったところで今度は各種ネットワークサー
	ビスを安全に供給するサーバマシンとして利用するための管理環境を整
	えよう。jail(8)のmanpageでは最終的に jail環境の開始時に /etc/rc
	を呼び出して、本体システムとほとんど同じ初期設定を行わせているが、
	WWWサーバやメイルサーバを受け持つことだけが目的であれば、多くの
	サービスプログラムはjail環境内には不要である。ここでは、必要最低
	限の設定をjail環境内に施す方針で解説する。

  ●/etc の整理

	本稿で解説したjail環境の/etcは本体システムからコピーしたものなの
	で、その多くは不要なものとなる。

    ・アカウントの整理

	本体システムとは独立したものにする。すくなくともルートのパスワー
	ドは本体システムのものとは全く違うものにする。また、/etc/group
	なども必要の無いエントリは削ってしまおう。そして、まずは自分のア
	カウントを作成しておこう。

    ・不要なネットワークサービス起動の抑止

	jail環境に限ったことでないが、不要なネットワークサービスデーモン
	が起動しないようにする。jail環境内では基本的にinetdは起動しない
	こととし、もしinetd経由でサービスデーモンを起動する場合はそのサー
	ビスだけが含まれたinetd.confを作成するようにし、デフォルトで付い
	て来るinetd.confを残したりしないように注意する。

    ・その他のファイル

	他に、リゾルバの設定(resolv.conf)、タイムゾーンファイル
	(localtime)の確認、ログインして使う場合にはマニュアルページの位
	置の設定ファイル(manpath.config)、ログインシェルの一覧(shells)な
	ども確認しておく。

  ●作業環境の整備

	のちのちjail環境内にログインして各種設定をすることを考えて、管理
	作業に必要なツールを用意しておこう。

    ・SSHデーモンの起動

	FreeBSD 4.1.1-RELEASE ではついにフルスペックの OpenSSH がシステ
	ム標準コマンドとして組み込まれた。もちろん libwrap(※に) にも対
	応しているので、これによりセキュアなログインサーバとしてセットアッ
	プすることがきわめて容易になった。本体システムのインストール時、
	もしくは /stand/sysinstall の Configure → Networking メニューで
	"Sshd" の起動をYESにした場合は、初回起動時に sshd が必要とする、
	ホスト固有の鍵ファイルを自動生成してくれるようになっている。この
	鍵ファイルはデフォルトでは /etc/ssh ディレクトリに置かれる。jail 
	環境にも鍵ファイルを用意しておこう。jail環境内でssh-keygenコマン
	ドを起動する。

	+------------------------------------------------------------
	| prison# ssh-keygen -N '' -f /etc/ssh/ssh_host_key
	|         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	| prison# ssh-keygen -N '' -d -f /etc/ssh/ssh_host_dsa_key
	|         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	+------------------------------------------------------------

	これでjail環境ホストでのSSHデーモン起動準備は完了である。実際に
	sshdを起動して外部からsshでログインをしてみよう。

+------------------------------------------------------------
| anotherhost% ssh prison.mydomain
|              ~~~~~~~~~~~~~~~~~~~
| The authenticity of host 'prison.mydomain' can't be established.
| RSA key fingerprint is 1c:89:b8:06:d9:24:c7:52:6d:62:7c:3d:18:99:3d:bc.
| Are you sure you want to continue connecting (yes/no)? yes
|                                                        ~~~
+------------------------------------------------------------

	本体システムではなく、/jail にchrootされたjail環境にログインでき
	れば成功である。

--- 註[に] ---------------------------------------------------------------
	TCP wrappers の中核をなすライブラリで、接続要求ホストによりアク
	セス許可・不許可を /etc/hosts.allow ファイルに従い決定する機能を
	持つ。詳しくは1999年12月号参照。
--------------------------------------------------------------------------

    ・syslogの起動

	jail環境でメイルサーバなどの起動を予定しているのであればsyslogも
	起動しておこう。

	+------------------------------------------------------------
	| prison# /usr/sbin/syslogd
	|         ~~~~~~~~~~~~~~~~~
	| prison# logger hello
	|         ~~~~~~~~~~~~
	| prison# tail -1 /var/log/messages
	| Sep 30 19:34:43 prison yuuji: hello
	+------------------------------------------------------------

	loggerコマンドでメッセージがログファイル(/var/log/messages) に書
	き足されていれば正常動作している。

  ●設定のまとめ

	ここまでjail用の設定を逐一確かめながら行なって来た。一度正常動作
	することが確認できたら、次は再起動したあとに自動的にjail環境が上
	がるように設定をまとめておこう。

    ・ディレクトリの用意

	既に /jail に etc/ や dev/ などがコピーされた状態で、あとは /usr
	を unionfs マウントすれば良いだけまでの準備が整っていると仮定す
	る。この場合本体システムの /etc/fstab の末尾に以下のエントリを追
	加する。

	/-----[ /etc/fstab ]----------------------------------------------
	| proc	/jail/proc	procfs	rw	0	0
	| /usr	/jail/usr	union	ro	0	0
	\-----------------------------------------------------------------

    ・ネットワーク設定

	jail用のIPアドレス(alias)を起動時に設定するには本体システムの
	/etc/rc.conf に以下の行を追加する。

	/-----[ /etc/rc.conf ]--------------------------------------------
	| ifconfig_fxp0_alias0="inet 192.168.0.2 netmask 255.255.255.0"
	\-----------------------------------------------------------------

	この例はネットワークインタフェースがfxp0の場合のものである。fxp0
	の部分は自身の環境に合わせて適切なインタフェース名に変更する。

	また、本体システムのinetdは止めてしまうか、jail環境で起動するネッ
	トワークサービスと干渉しないようにする。

	/-----[ /etc/rc.conf ]--------------------------------------------
	| inetd_enable="NO"		# inetdを止める場合
	\-----------------------------------------------------------------
	/-----[ /etc/rc.conf ]--------------------------------------------
	| inetd_enable="YES"		# inetdを使う場合
	| inetd_flags="-wW -a 192.168.11.23"
	\-----------------------------------------------------------------

	syslogdも同様。

	/-----[ /etc/rc.conf ]--------------------------------------------
	| syslogd_flags="-ss"
	\-----------------------------------------------------------------

    ・jail環境開始スクリプト

	jail環境内であらかじめ立ち上げておくサービスを初期化スクリプトに
	書いておくと良い。ファイル名は何でも良いが、ここでは 
	/etc/rc.jail(本体システムから見た /jail/etc/rc.jail) としておこう。

	/----[ /etc/rc.jail ] --------------------------------------------
	| syslogd
	| /usr/sbin/sshd
	\----[ /etc/rc.jail ] --------------------------------------------

	これをjail環境起動スクリプトとして与えれば良い。

	+-----------------------------------------------------------------
	| # jail /jail 192.168.0.2 prison.mydomain /bin/sh /etc/rc.jail
	+-----------------------------------------------------------------

■Jail環境へのネットワークサービスデーモンの組み込み

	jail環境での管理ツールまで揃ったところで、その上にネットワークサー
	ビスデーモンを組み込むことを試みよう。WWWサーバを例に、jail環境
	を安全なサーバ環境として利用する手順を紹介する。堅牢なjail環境を
	セットアップしたのであれば、自分が管理しているいくつかのWWWサー
	バをその環境内で賄いたいと思うのは自然な発想であろうと考え、ここ
	では複数のドメインのサービスを一つのjail環境(もちろん非jail環境
	でも利用できる)で供給する方法、つまり virtual domain 運用に主眼
	を置いて解説を試みる。

  ●WWWサーバの導入

	WWWサーバの導入に必要な手順を大まかにまとめると、

	  * サーバ名のDNS登録
	  * WWWサーバプログラム(apache)のインストール
	  * apacheの起動
	  * その他設定

	となる。順を追って解説しよう。

    ・WWWサーバ名のDNS登録

	まず最初にWWWサーバ名となるホスト名をDNS登録しなければならない。
	ネームサーバとしてBINDを利用していることを想定し、例として 
	hoge.co.jp というドメインのWWWサーバを www.hoge.co.jp で公開した
	い場合を考えよう。hoge.co.jp のゾーン設定ファイルとしてもともと、
	リスト1:hoge.zone を持っていたとする。

	/--- リスト1 [hoge.zone] -------------------------------------------
	|$TTL	86400
	|@	IN	SOA	ns.hoge.co.jp. postmaster.hoge.co.jp. (
	|			2000101000	; Serial No
	|			10800		; Refresh = 3 hours
	|			3600		; Retry   = 1 hour
	|			3600000		; Expire  = 1000 hours
	|			86400		; Minimum = 1 day
	|			)
	|	IN	NS	ns.hoge.co.jp.
	|	IN	NS	ns2.hoge.co.jp.
	|	IN	MX	0  mail.hoge.co.jp.
	|	IN	MX	10 mail2.hoge.co.jp.
	|;一般ホスト
	|venus	IN	A	192.168.0.2
	|	IN	MX	0 mail.hoge.co.jp.
	|	IN	MX	10 mail2.hoge.co.jp.
	\-------------------------------------------------------------------

 +---[コラム]--------------------------------------------------------------
  = DNS ゾーンファイル =
  
  既にDNSサーバ自体が上がっていることを前提に、ゾーンファイルに書くべき
  エントリについて簡単に紹介しておこう。

  ゾーンファイルはリスト1から分かるように

	エントリ名	IN	種別	値

  という記述になっている。エントリ名を省略すると直前のエントリに対する追
  加レコードの指定となる。リスト中に現れる各種別名とその値として指定すべ
  きものは以下の通りである。

  - SOA
  プライマリサーバがそのゾーンの情報を供給するにあたっての情報を指定する。
	ゾーン名  IN  SOA  自ホスト名 管理者メイルアドレス (
			   シリアル番号
			   更新頻度(秒)
			   更新のリトライ間隔(秒)
			   非更新データのエクスパイア時間(秒)
			   各エントリの最小有効時間
		  )

  ゾーン名の部分に @ を書くと自分自身のゾーン名(例の場合 hoge.co.jp.)に
  なる。メイルアドレスの部分は通常の@マークの変わりにピリオドを指定する。
  シリアル番号はゾーンファイルに修正を加えたら必ず数字を上げる必要がある。
  シリアル番号は一般的には、西暦・年・月・日 を利用して

	YYYYMMDDxx

  のようにし、同じ日に複数回の修正があったときにxxの部分を1ずつ増やして
  いくようにする。

  - NS
  そのゾーンのネームサーバを指定するレコード
	ゾーン名  IN  NS  ネームサーバ名
  複数指定できる。

  - A
  IPアドレスを表す
	エントリ  IN  A   IPアドレス

  - MX
  メイルドメイン名の配送ホスト(Mail eXchanger)の指定
	メイルドメイン名  IN  MX 優先度  メイルを受け取れるホストの名前
  優先度は整数で指定し、小さいほうが優先度が高くなる。
 +-------------------------------------------------------------------------

	ゾーンファイル中 192.168.0.2 をAレコードに持つvenusというエント
	リはこれからWWWサーバを置こうというホストである。このホストを
	www.hoge.co.jp で参照できるようにCNAME(別名)を登録する。
	hoge.zone ファイルにリスト2の定義を追加する。

	/--- リスト2 [hoge.zone 追加分] ------------------------------------
	|www	IN	CNAME	venus
	\-------------------------------------------------------------------

	ゾーンファイルにエントリを追加したら、SOAフィールドのシリアル番
	号も増やしておくことを忘れないようにする(リスト3)。

	/--- リスト3 [hoge.zone シリアル番号] ------------------------------
	|$TTL	86400
	|@	IN	SOA	ns.hoge.co.jp. postmaster.hoge.co.jp. (
	|			2000101001	; Serial No
	|                       ~~~~~~~~~~
	|			 :
	|			 : 略
	|			)
	\-------------------------------------------------------------------

	ゾーンファイルの更新が完了したら、ネームサーバにゾーンファイルの
	再読み込みを指示する。

	+-------------------------------------------------------------------
	| # /usr/sbin/ndc reload
	+-------------------------------------------------------------------

	実際にCNAMEが登録されているか確認する。

	+-------------------------------------------------------------------
	| # /usr/sbin/nslookup www.hoge.co.jp
	|   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	| Server:  localhost
	| Address:  127.0.0.1
	|
	| Name:    venus.hoge.co.jp
	| Address:  192.168.0.2
	| Aliases:  www.hoge.co.jp
	+-------------------------------------------------------------------

	hoge.co.jp のDNSプライマリサーバを直接参照しているホストからは、
	この更新がすぐに反映されるように見える。それ以外の場所にこの
	CNAME設定が伝わるには多少の時間を要することもある。

    ・apacheの導入と起動

	一般的な設定でapacheを入れるだけならば簡単なので、ここではソース
	パッケージからインストールする方法で説明する。まず、ソースアーカ
	イブを持って来よう。本誌付録CD-ROMに apache_1.3.12.tar.gz を収録
	しているのでそれを利用して欲しい。ここでは、apacheをインストール
	するディレクトリを /www/apache、ドキュメントを置くディレクトリを
	/www/htdocs にするという仮定で例を記述する。apacheの新しいバージョ
	ンが出ると同時にアップグレードをする予定であれば、apache本体のディ
	レクトリとドキュメントディレクトリを分けておいた方が都合が良い。

	+-------------------------------------------------------------------
	| prison# tar zxpf apache_1.3.12.tar.gz
	|         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	| prison# cd apache_1.3.12
	|         ~~~~~~~~~~~~~~~~
	| prison# ./configure --prefix=/www/apache --htdocsdir=/www/htdocs
	|         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	|  〜〜 略 〜〜
	| prison# make && make install
	|         ~~~~~~~~~~~~~~~~~~~~
	|  〜〜 略 〜〜
	+-------------------------------------------------------------------

	この作業によりapacheのインストールは完了する。今回の例では、jail
	環境内にあるコンパイラ環境でmakeを行なったが、もしjail環境にコン
	パイラ環境を置かない場合は本体システム環境でコンパイルする必要が
	ある。そのような場合は、本体システムから、インストール対象となる
	jail環境内のディレクトリに対してシンボリックリンクを張って作業す
	ると簡単である。例えば、jail環境の /www ディレクトリ以下にインス
	トールする場合は、

	+-------------------------------------------------------------------
	| # mkdir /jail/www
	| # ln -sf /jail/www /www
	+-------------------------------------------------------------------

	という状態にしてからmake installすると作業量が軽減できる。

	さて、make install 終了後、とりあえず正常に起動できるかどうかを
	確認してみよう。

	+-------------------------------------------------------------------
	| prison# /www/apache/bin/apachectl start
	+-------------------------------------------------------------------

	実際に外部からアクセスできるか確かめよう。jail環境、本体システム、
	どちらでもない全く別のホストから http://prison.mydomain/ にアク
	セスし 図 (apacheinst.png) のようなデフォルトコンテンツが読める
	か確認する(図はテキストブラウザw3mで確認)。

	----------------------------------------------------------------------
	図 (apacheinst.png) Apache デフォルトインストール完了で現れるコ
	ンテンツ
	----------------------------------------------------------------------

	もしapacheの起動に失敗した場合はいちどjail環境外で正常に起動でき
	るか確認すると良い。jail環境外で正常動作するようであれば、jail環
	境にプログラム実行に必要なファイルが足りないということなので、エ
	ラーメッセージや、ログファイルを見てjail環境を修正する。

    ・apache動作の調整

	動作が確認できたら、次は細かい動作を調整する段階に入る。apacheは
	非常に細かい設定ができるが、日常的に必要となる設定に関する情報は
	本誌9月号の特集記事を参照してもらいたい。ここでは、jail環境を利
	用するという利点を活かすための設定に絞って簡単に説明しよう。
	apacheを上記のパス名でインストールした場合設定ファイルは
	/www/apache/conf/httpd.conf となる。デフォルト状態で多くのコメン
	トが記されているのでそれも参考にしながら書き換えてみよう。

	* VirtualHost の設定

	  apacheでは、どれも自分自身を指す複数のホスト名にたいしてのHTTP 
	  アクセスに対し、それぞれ違うコンテンツ集合を見せることができる。
	  prison.mydomain というホスト名と www.mydomain というホスト名が
	  どちらも 192.168.0.2 というIPアドレスを指していた場合、
	  http://prison.mydomain/ という資源名でアクセスしたときと
	  http://www.mydomain/ という資源名でアクセスしたときに違うコン
	  テンツを表示させることができる。閲覧者から見るとあたかも
	  www.mydomain というサーバが prison.mydomain とは別に存在するか
	  のように見えるわけである。このようにして新たにつくり出すことの
	  できるWWWホストを apache では VirtualHost と呼ぶ。

	  apacheの VirtualHost には、大別して二種類の提供方法がある。一
	  つはIPアドレスベースのVirtualHostで、これは一つのシステムに複
	  数のIPアドレスが割り当ててある場合に、それぞれのIPアドレスに対
	  して、違うコンテンツ集合を見せる方法である。今回は、jail環境を
	  利用するので割り当てるIPアドレスが1個であるから、もう一つの方
	  法である名前ベースのVirtualHostを利用する。こちらは同じIPアド
	  レスを指し示す、複数のホスト名にたいし違う空間を見せる方式であ
	  る。名前ベースのVirtualHostを定義するには httpd.conf の、
	  NameVirtualHost 指示子と  指示子を利用する。

	  まず、複数のホスト名が指し示す、共通のIPアドレスを
	  NameVirtualHost 指示子に与える。ここでは、jail環境の持つ
	  192.168.0.2 を記述する。

	  /---[ httpd.conf の一部 ]-----------------------------------------
	  | NameVirtualHost 192.168.0.2
	  \-----------------------------------------------------------------

	  続いて、各ホスト毎に、対応するコンテンツを置くディレクトリを指
	  定する。この指定は  指示子で行なう。

	  /---[ httpd.conf の一部 ]-----------------------------------------
	  | 
	  |   ServerName	prison.mydomain
	  |   DocumentRoot	/www/htdocs/contents.prison
	  |   CustomLog		logs/prison-access_log  combined
	  |   ErrorLog		logs/prison-error_log
	  | 
	  | 
	  |   ServerName	www.mydomain
	  |   DocumentRoot	/www/htdocs/contents.www
	  |   CustomLog		logs/www-access_log  combined
	  |   ErrorLog		logs/www-error_log
	  | 
	  \-----------------------------------------------------------------

	  この例では、http://prison.mydomain/ へのアクセスに対し
	  /www/htdocs/contents.prison/ 以下のファイルを、
	  http://www.mydomain/ へのアクセスに対し
	  /www/htdocs/contents.www/ 以下のファイルを供給するという設定を
	  行なっている。また、アクセスログ/エラーログファイルもそれぞれ
	  のホスト名固有のものとしている。

 +---[コラム]--------------------------------------------------------------
  = 各 VirtualHost のログファイルの一本化 =

  VirtualHostも数が多くなって来ると管理が大変になる。ログファイルもホス
  ト名毎に分けて出力するようにしているとかなりの数のログファイルができる
  ことになる。非常に多くのVirtualHostそれぞれにログファイルを作ると、そ
  の分だけファイルをオープンすることになるので、httpdに与えられたファイ
  ルディスクリプタの上限に近付き、場合によってはCGIプログラムに十分な数
  のディスクリプタが渡らないなどの問題が起きる可能性もある。また、それほ
  ど数が多くない場合であっても、アクセスログを解析をする場合に不便が生ず
  ることがある。というのも各ログファイルに残っている取得ファイルはそれぞ
  れ基準ディレクトリが違うので同じ "GET /index.html" であっても違うファ
  イルを指していることになる。全てのVirtualHostを通したログ解析をしたい
  ときにこれは不都合である。

  上記の問題を解決する一つのTipsとして、全てのVirtualHostのログファイル
  を一つにまとめ、取得ログ行に VirtualHost 名を埋めるという方法がある。
  デフォルトのアクセスログのフォーマットは

	LogFormat "%h %l %u %t \"%r\" %>s %b                (一行で)
        	 \"%{Referer}i\" \"%{User-Agent}i\"" combine

  となっている。\"%r\" の部分がリクエスト行、つまり "GET /index.html" な
  どに置換される部分であるから、ここにVirtualHost名を入れて、たとえば
  "GET /www.mydomain/index.html" となるようにしてしまえば後のログ解析が
  楽になる。このようにするときは %r を、リクエストメソッド(%m)とリクエス
  トURL(%U)に分解して次のように記述すれば良い。

	/------------------------------------------------------------------
	| 
	|   ServerName	 prison.mydomain
	|   DocumentRoot /www/htdocs/contents.prison
	|   LogFormat "%h %l %u %t \"%m prison.mydomain%U\" %>s %b   (一行で)
	           \"%{Referer}i\" \"%{User-Agent}i\"" log_PRISON
	|   CustomLog    logs/access_log  log_PRISON
	| 
	| 
	|   ServerName	 www.mydomain
	|   DocumentRoot /www/htdocs/contents.www
	|   LogFormat "%h %l %u %t \"%m www.mydomain%U\" %>s %b      (一行で)
	           \"%{Referer}i\" \"%{User-Agent}i\"" log_WWW
	|   CustomLog    logs/access_log  log_WWW
	| 
	\------------------------------------------------------------------

  こうすることでhttpdの消費するファイルディスクリプタ数が節約でき、なお
  かつアクセス数解析をするスクリプトの設計が簡単になる。もちろん、ログファ
  イルを分割する場合も有効な方法なので試してみると良いだろう。
 +---[コラム終わり]--------------------------------------------------------


    ・jail環境での CGI/SSI 動作の確認

	jail環境が有効に機能しているかをCGI/SSIを利用して確認してみよう。
	一般利用者にCGIとSSIを開放する設定は以下の通りである。

	* CGI開放

	    CGIを有効にしたいコンテンツディレクトリが /foo/bar/cgidir で
	    あると仮定すると、httpd.conf中で

	    /---------------------------------------------------------------
	    | 
	    |   AddHandler cgi-script .cgi
	    |   Options ExecCGI
	    | 
	    \---------------------------------------------------------------

	    のように、指定したディレクトリに対して、拡張子 .cgi を持つファ
	    イルをCGIプログラムであるとみなし、さらに ExecCGI オプション
	    を立てればそこでのCGIが利用可能になる。一般利用者にCGIを開放
	    したい場合はシステムのhttpd.confでExecCGIオプションを立てて
	    おくよりも、利用者のディレクトリでそれらのオプションを立てさ
	    せることを許可しておく方が手軽かもしれない。この場合は、
	    AllowOverride ディレクティブを利用する。

	    /---------------------------------------------------------------
	    | 
	    |   Options ExecCGI
	    |   AllowOverride Options FileInfo
	    | 
	    \---------------------------------------------------------------

	    一般利用者は、CGIを利用したいディレクトリに .htaccess ファイ
	    ルを置き、そこに httpd.conf に書くのと同様の記述をすれば良い。

	    /--[.htaccess]--------------------------------------------------
	    | AddHandler cgi-script .cgi
	    | Options ExecCGI
	    \---------------------------------------------------------------

	* SSI開放

	    SSIは、apacheに対し "server-parsed" 形式とみなすファイル名
	    (拡張子)を指定することで有効化できる。たとえば、".shtml" と
	    いう拡張子を持つファイルでSSIを有効にしたい場合は httpd.conf 
	    に以下のような記述を追加する(デフォルト状態ではコメントアウ
	    トされている)。

	    /---------------------------------------------------------------
	    | AddType text/html .shtml
	    | AddHandler server-parsed .shtml
	    \---------------------------------------------------------------

	さて、実験的にjail環境の効果を見るCGIを動かしてみよう。リスト4は
	ルートディレクトリのファイル一覧をlsで出すだけの単純なCGIスクリ
	プトである。

	/--- リスト4 [ls-root.cgi] -----------------------------------------
	| #!/bin/sh
	| echo 'Content-type: text/plain'
	| echo ''
	| /bin/ls -FC /
	\-------------------------------------------------------------------

	実行属性をつけ忘れないようにして、このスクリプトを
	/www/htdocs/ls-root.cgi というパスで置く。そして外部からこのCGI 
	にアクセスしてみよう。本体システムのルートディレクトリではなく、
	jail環境のルートディレクトリ一覧が表示されれば設定は全てうまくいっ
	ていると言える。

■jail環境のまとめ

	以前官公庁などのWWWサーバがクラック被害に遭い重大な改ざん事件が
	起きたときに、被害に遭ったのは「ファイヤーウォール」を設置してい
	なかったからで、ファイヤーウォールさえ設置していれば大丈夫、であ
	るかのような短絡的な噂が流れてしまったが、jail環境を使う場合も
	「jailを使えば安全」といった短絡的思考に陥らないように気を付けな
	ければならない。jailが確保してくれるのは、ネットワークサービスを
	行なうホストの本体システムからの隔離だけであって、外部からの侵入
	を自動的に遮断してくれるような類のものでは決してない。サーバ環境
	の構築にどんな高い技術を注いでも、パスワード管理の甘さなど利用者
	全体の心構えがシステム全体の安全性の大きな比重を持つのも事実であ
	る。技術的なアプローチとともにモラルの向上にも努める必要があるの
	を忘れてはならない。


yuuji@example.org
Fingerprint16 = FF F9 FF CC E0 FE 5C F7 19 97 28 24 EC 5D 39 BA
HIROSE Yuuji - ASTROLOGY / BIKE / EPO / GUEST BOOK / YaTeX [Tweet]