jailによるセキュアサーバー環境

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

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

目次


Part3 jailを利用したセキュアサーバーの構築法

FreeBSD ではchrootをさらに強化した仮想環境実現機構として、jail(8)が利用
できる。jailにはIPアドレスを一個割り当ててネットワーク的に独立した一台の
ホストとして振る舞わせることができるので、物理的には一台のマシンでありな
がら複数のサーバとしての役割を持たせることができる。これを上手に活用する
と、単一ホスト本来の環境の安全性を高いレベルで確保しつつ、「ホスティング
サービス」のような運用も可能である。

Part3ではjailの機能を活用して、Webサーバのマルチホスティングを行なう設定
を紹介しよう。代表的なWebサーバプログラム Apache では複数のドメインをひ
とつのサーバないに持てる「バーチャルホスト」機能があるが、これはひとつの
設定ファイルで複数のドメインを管理するので、管理者が設定をいじるときには
全てのドメインに影響をおよぼすことになる。これとは違い、ドメイン名の保持
者がWebサーバひとつを占有し、他者のドメインのWebサーバには影響を及ぼした
くないという場合、本来であれば複数のマシンを用意する必要がある。jailを用
いて別のIPアドレスを持つ仮想環境を作成すると、独立したWebサーバとして管
理することができる【図 い】。

---[図 い]------------------------------------------------------------
Apacheのバーチャルホスト機能を用いた場合

                      +---///---→ the Internet...
		     /
	            /
  +------- ひとつの/ホスト(ひとつのIPアドレス)---------------------+
  |               /
  |     +---- httpd.conf -----+
  |     |  .....              |
  |     |  ............       | ←管理するのは1グループ
  |     |  .....              |
  |     +---------------------+
  |     /           \         \--
  |  +-- www1 --+  +-- www2 --+   \
  |  | Virtual  |  | Virtual  |   +-- www3 --+
  |  |  Host 1  |  |  Host 2  |   | Virtual  |
  |  +----------+  +----------+   |   Host 3 |  . . . . . .
  |  			          +----------+
  |
  +----------------------------------------------------------------+



Jailによる仮想環境でマルチホスティングを行なう場合


                +------------------+---------------+--///→ the Internet...
	       /                  /               /
	      /                  /               /
  +------- ひ/とつの/ホスト(複数/のIPアドレス)--/------------------+
  |         /                  /               /
  |  +--- jail  1 --+  +--- jail  2 --+  +--- jail  3 --+  
  |  | [httpd.conf] |  | [httpd.conf] |  | [httpd.conf] |
  |  |		    |  |	      |	 |		|
  |  +--------------+  +--------------+  +--------------+
  |     ↑それぞれjailの数だけ独立した管理グループが
  |
  |
  +----------------------------------------------------------------

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

■
■jailの機能
■

Part2で解説したchroot(8)で得られるディレクトリ空間の一部のみを見せる機能
に加えjailでは、ホスト環境からの独立性を高める以下の機能が追加されている。

●jail空間へのIPアドレスの付与

jailでは、仮想環境ひとつに対してひとつのIPアドレスとホスト名を割り当てる
ことができる。このため、ひとつのネットワークサービスを別々の仮想環境で独
立して持たせることができる。

●プロセス空間の分離

chrootでは、アクセスできるファイルシステム空間は一部のみに限定できるがプ
ロセス情報は本体の環境のもの全てを得ることが可能となっている。たとえば、
chrootされたプロセスから、chroot外部のプロセスをkillすることも可能である。

jailでは、jail環境内で動くプロセスからはそれ以外のプロセスは全くアクセス
できなくなっている【実行例 ろ】。

---[実行例 ろ]--------------------------------------------------------

----------------------------------------
★ホスト環境で実行
# ps axl
  UID   PID  PPID CPU PRI NI   VSZ  RSS MWCHAN STAT  TT       TIME COMMAND
    0     0     0   0 -16  0     0    4 sched  DLs   ??    0:03.50  (swapper)
    0     1     0   0   8  0   740  376 wait   ILs   ??    0:00.65 /sbin/init -
    0     2     0   0  -8  0     0   12 g_even DL    ??    5:24.70  (g_event)
    0     3     0   0  -8  0     0   12 g_up   DL    ??    5:21.52  (g_up)
    0     4     0   0  -8  0     0   12 g_down DL    ??    5:46.93  (g_down)
    0     5     0   0 -16  0     0   12 psleep DL    ??    0:06.82  (pagedaemon
    0     6     0   8  20  0     0   12 psleep DL    ??    0:00.00  (vmdaemon)
    0     7     0   0 171  0     0   12 pgzero DL    ??    0:14.61  (pagezero)
    0     8     0   0 -16  0     0   12 psleep DL    ??    0:33.46  (bufdaemon)
       :
       :〜中略〜
       :
    0   431     1   3   8  0  1612 1304 wait   Is    v0    0:01.66 login [pam]
 2020   597   431   0  20  0  2472 2180 pause  I     v0    0:04.15 -zsh (zsh)
 2020   927   597   0   5  0   224  120 ttyin  I+    v0    0:00.03 cat
    0   432     1 134   5  0  1236  908 ttyin  Is+   v1    0:00.15 /usr/libexec


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

★chrootプロセス内で実行
# 
  UID   PID  PPID CPU PRI NI   VSZ  RSS MWCHAN STAT  TT       TIME COMMAND
    0     0     0   0 -16  0     0    4 sched  DLs   ??    0:03.51  (swapper)
    0     1     0   0   8  0   740  376 wait   ILs   ??    0:00.65 /sbin/init -
    0     2     0   0  -8  0     0   12 g_even DL    ??    5:24.88  (g_event)
    0     3     0   0  -8  0     0   12 g_up   DL    ??    5:21.66  (g_up)
    0     4     0   0  -8  0     0   12 g_down DL    ??    5:47.13  (g_down)
    0     5     0   0 -16  0     0   12 psleep DL    ??    0:06.83  (pagedaemon
    0     6     0   8  20  0     0   12 psleep DL    ??    0:00.00  (vmdaemon)
    0     7     0   0 171  0     0   12 pgzero DL    ??    0:14.61  (pagezero)
    0     8     0   0 -16  0     0   12 psleep DL    ??    0:33.48  (bufdaemon)
       :
       :〜中略〜
       :
    0   431     1   3   8  0  1612 1304 wait   Is    v0    0:01.66 login [pam]
 2020   597   431   0  20  0  2472 2180 pause  I     v0    0:04.15 -zsh (zsh)
 2020   927   597   0   5  0   224  120 ttyin  I+    v0    0:00.03 cat
    0   432     1 134   5  0  1236  908 ttyin  Is+   v1    0:00.15 /usr/libexec

全てのプロセスが表示される。

----------------------------------------
★jailプロセス内で実行

# ps axl
  UID   PID  PPID CPU PRI NI   VSZ  RSS MWCHAN STAT  TT       TIME COMMAND
    0   986   632   0   8  0   896  588 wait   SJ    p0    0:00.18 /bin/sh
    0   990   986   2  96  0   656  432 -      R+J   p0    0:00.02 ps axl


jail内のプロセスのみ表示される。

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

もちろん、jailプロセスからホスト環境のプロセスIDにシグナルを送ろうとして
も不可能である。


●rootユーザの特権的操作の制限

jail内のプロセスからは、たとえスーパーユーザ(UID=0)の権限を持ってしても
ホスト環境の設定を変える可能性のある一部の操作は禁止されている。例を挙げ
ると、次のようになる。

	* カーネルモジュールのロードなど、動作中のカーネルに対する操作
	* ネットワークインタフェースのIPアドレス変更、ルーティングテーブ
	  ル操作などのネットワーク状態変更操作
	* ファイルシステムの mount/umount
	* デバイスノードの作成
	* raw, divert, ルーティングソケットへのアクセス
	* sysctlによるカーネル変数の変更操作
	* セキュアレベルの操作
	* jail環境に割り当てられたのとは無関係なネットワーク資源へのアクセス

逆に、特権的操作としては以下のものが許可されている。

	* jail内のプロセスに対するシグナル送信
	* jail内のファイルの所有者と属性の変更およびファイル消去
	  (ファイルフラグで許可されている場合のみ)
	* jailに割り当てられたIPアドレスに対するTCP/UDP予約ポートへの
	  バインド
	* uid/gid空間に対する操作


以上の制約により、jail内でroot権限を持っている場合、jail内でネットワーク
サービスデーモンを動かすためには十分な設定が行なえる一方、ホスト環境に影
響を及ぼす操作はできないことになる。このため、root権限を与えて全ての設定
を任せるようなホスティングサービスの実現に適しているといえよう。


■
■jailの導入
■

jailを動作させるための環境の構築は jail(8) のマニュアルページで解説され
ているので、そちらも参照しつつ作業を進めて欲しい。以下の例では、FreeBSD
5.1-RELEASE(以下5.1R)での設定を前提に進めるが、FreeBSD 4.x 系列でもほぼ
同様に設定できるので参考にして欲しい。5.1Rでは、4.xでのjail機能に加え、
現在稼動中のjailの一覧を表示する jls コマンド、指定したjailの識別子を指
定してそのjailにプロセスを送り込む jexec コマンドが利用できるようになっ
ているが、それら以外はほぼ同じ操作が行なえると思って良い。

●jail用ネットワークアドレスの設定

jailではひとつのIPv4アドレスを利用する。具体的にはホスト環境のネットワー
クインタフェースに複数のIPv4 アドレスを割り当てておき、そのうちのひとつ
をjailに割り当てる。ホスト環境で複数のアドレスを持たせるのは IP alias を
利用する【図 は】。

---[図 は]------------------------------------------------------------

    +------------------- jail用host ---------------------+
    |							 |
    |			  +------------+ +------------+	 |
    |	ホスト環境で利用  |jail 1で利用| |jail 2で利用|	 |
    |		/	  +---+--------+ +---+--------+	 |
    |	  _____/_____________/______________/___	 |
    |    /    /    Network  / Interface    /    \	 |
    +---|  10.1.2.100   10.1.2.101   10.1.2.102  |-------+
           アドレス1	アドレス2    アドレス3
			(alias)	     (alias)
----------------------------------------------------------------------


具体的なネットワークアドレスの設定は、/etc/rc.conf で行なう。システムで
利用するネットワークインタフェースが fxp0 だと仮定すると、【図 は】の
通りのアドレスを設定するには以下の記述を rc.conf に追加する。

	ifconfig_fxp0='inet 10.1.2.100 netmask 255.255.255.0'
	ifconfig_fxp0_alias0='inet 10.1.2.101 netmask 255.255.255.255'
	ifconfig_fxp0_alias1='inet 10.1.2.102 netmask 255.255.255.255'

ここで注意すべきことがある。それは、

	ホスト環境で起動するネットワークデーモンが
	aliasアドレスでLISTENしないようにする

という点である。たとえば、「ホスト環境」、「jail環境その1」、「jail環境
その2」の各々に対して外部からログインするために sshd を起動するのであれ
ば、ホスト環境の sshd ではaliasアドレスをLISTENしないようにする。sshdの
定義ファイル /etc/ssh/sshd_config はデフォルトで

	ListenAddress 0.0.0.0

として全てのアドレスでLISTENするようになっているので、デフォルト状態で起
動すると、10.1.2.101,  10.1.2.102 でも接続を受け付ける。このため、jail環
境でsshdを起動していない場合でもssh接続を受けることになり混乱をきたす。
多くの場合、これは好ましくないので、ホスト環境の sshd_config では、

	ListenAddress 10.1.2.100
	ListenAddress 127.0.0.1

のように、ホスト環境へのssh接続としてLISTENすべきIPv4アドレスのみを列挙
する。また、ホスト環境で、jail環境とは独立したapacheを起動する場合も同様
で、この場合 httpd.conf の Listen 指示子を

	Listen 0.0.0.0:80
から
	Listen 10.1.2.100:80
	Listen 127.0.0.1:80

のように適宜変更しておく。



●jail用ディレクトリツリーの構築

マニュアルページのEXAMPLE、"Setting up a Jail Directory Tree" の項には、
ディレクトリツリーの構築法として、FreeBSD のソースから配布ファイルフルセッ
トを特定のディレクトリにインストールする例が記述してある。

     D=/here/is/the/jail
     cd /usr/src
     mkdir -p $D
     make world DESTDIR=$D
     cd etc
     make distribution DESTDIR=$D
     mount_devfs devfs $D/dev
     cd $D
     ln -sf dev/null kernel

実際のところ、フルセットをインストールしてしまう方が試行錯誤をしなくて済
む分平易であり、jailの挙動を学習するときにはこの方が良いだろう。ただし、
マニュアルの後続する節に

     In many cases this example would put far more stuff in the jail than is
     needed.  In the other extreme case a jail might contain only one single
     file: the executable to be run in the jail.

と書いてあるように、安全性を考慮した場合、jail環境内には必要最低限のファ
イルのみを持ち込むのが望ましい。jailのセットアップ手順を理解したのち、本
運用環境を構築する場合には Part2 のchroot環境の構築方法を参考にしつつ、
「必要最低限」のものだけが含まれるディレクトリツリーを作成するのが良いだ
ろう。本稿では、Part2の知識を前提として "put far more stuff" ではないス
リムな環境を構築することを目指す。具体的手順の解説はPart2を参照して欲し
い。

以下の作業例では、【図 は】の「アドレス2」となる alias アドレス
を利用し、

	IPアドレス		10.1.2.101
	ホスト名		prison.example.net 
	jailトップディレクトリ	/opt/jail/prison
	内部で動かすコマンド	httpdとCGIから呼ばれる各種コマンド

という構成でjail環境を構築するものとする。


●httpd用のjailスリム環境

jail環境内で、どのようなことまでをしたいかによってjail環境にコピーすべき
ファイル群は変わってくる。ntpやDNSのようなデータそのものだけをやりとりす
るものであれば、jail環境内にはサービスに必要なデータファイル以外は何も置
かない、つまりほとんどからっぽの状態が良い。逆に、jail環境内にログインさ
せて通常の作業を許可する場合はOSの配布ファイルフルセットに近いものをコピー
しておいた方が良いだろう。

ここでは、jail内で apache(httpd) を動かす場合の環境構築を考える。このWeb
サーバではCGIプログラムなどにより、外部プロセスを起動する可能性があるも
のとする。

まず、主要なコマンドを起動できる環境を整えるために、【リスト に】のよう
なファイル群をコピーした。コピー方法と、それらを選択する基準となる考え方
についてはPart2参照のこと。また、CGIプログラムなどで利用するコマンドによっ
ては不要だったり、足りなかったりするものもあるので適宜判断して欲しい。

---[リスト に]------------------------------------------------------

chroot環境の /bin (ls の出力形式)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[              dd             link           pwd            sleep
cat            echo           ln             realpath       stty
chflags        ed             ls             red            sync
chmod          expr           mkdir          rm             tcsh
cp             getfacl        mv             rmdir          test
csh            hostname       pax            setfacl        unlink
date           kill           ps             sh             zsh

chroot環境の /etc (ls の出力形式)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
devfs.conf      localtime       pwd.db          spwd.db
hosts           master.passwd   resolv.conf


chroot環境の /sbin (ls の出力形式)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ifconfig        ldconfig        md5

chroot環境の /usr/libexec (ls の出力形式)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ld-elf.so.1     tcpd

chroot環境の /usr/sbin (ls の出力形式)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
chown           jls             sshd            tcpdmatch
chroot          pstat           syslogd         vipw
inetd           pw              tcpdchk

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

【リスト に】以外のファイルとディレクトリに関しては以下のように注意して
構築する。

・tmpディレクトリ

  プログラムによっては作業ディレクトリを必要とするものもあるので、作成する。

	# cd /opt/jail/prison
	# mkdir -p -m 1777 tmp var/tmp

・一般的コマンド群とライブラリ

  /usr/bin や /usr/local/bin にある一般的なコマンド群は、CGIプログラムな
  どから利用されることを想定し、全てjail空間に用意しても良いだろう。この
  ため、
	* /usr/bin
	* /usr/libexec
	* /usr/local

  以下のファイルを全てjail空間にコピーしても良い。ただし、これらのディレ
  クトリは多くの場合ホスト環境とつねに同一に保つことが期待されるのでファ
  イルシステム的にマウントするという手法が管理効率上良い選択肢となる。

	# mount -t nullfs -r /usr/lib /opt/jail/prison/usr/lib
	# mount -t nullfs -r /usr/bin /opt/jail/prison/usr/bin
	# mount -t nullfs -r /usr/local /opt/jail/prison/usr/local

---[註 ほ]------------------------------------------------------------
FreeBSD 4までの場合ファイルシステムタイプは nullfs ではなく、null とする。
ただし、2001年6月以前のカーネルによる nullfs は極端に不安定なことが知ら
れている。4.8R と 5.1R それぞれについて筆者が実験環境で nullfs について
確認した範囲では特に問題なく使用できたが、実運用に供する場合はより入念な
確認を行って頂きたい。また同様に不安定と言われていた unionfs も、4.7R時
代に筆者自身実運用で用いていてとくに問題がなかったことを付け加えておく。
----------------------------------------------------------------------

  -r オプションで read-only マウントして、jail環境内からの改ざんを防ぐ。

・デバイスファイル(/dev)

  Part2 で触れたように、FreeBSD 5.1R ではデフォルトで devfs を利用する設
  定になっている。jail環境内からアクセスできるデバイスファイルを必要最低
  限のものにしたい場合は devfs のルールセットを利用する。

  devfs(8)コマンドを使用してルールセットを作成しよう。devfsでは、複数の
  ルールセットを持つことができ、いくつかのマウントポイントに任意のルール
  セットを適用することができる。ルールセットの作成は、そのセットの識別子
  となる整数を与えて以下のように行なう。

	# devfs rule -s ルールセット番号 delset           . . . . (1)
	# devfs rule -s ルールセット番号 アクション	  . . . . (2)

  1行目でルールセットの消去(もしあれば)を行い、2行目で指定したルールセッ
  トに対する実際のルール関連アクションを行う。具体例で見てみよう。

  ここではjail環境内に「見せる」デバイスファイルとして

	null, zero, random, urandom

  の4つのみとするルールセットを作成してみよう。ルールセットに付ける識別
  番号は未使用のものであればなんでも良いので、10番で作成する。このとき
  delset にてルールセットを初期化するとよい。

	# devfs rule -s 10 delset

  最初のルールとして全てのデバイスファイルを隠す(hide)。

	# devfs rule -s 10 add hide

  続いて、上記4つのデバイスファイルだけ、隠さないようにする(unhide)。

	# devfs rule -s 10 add path null unhide
	# devfs rule -s 10 add path zero unhide
	# devfs rule -s 10 add path random unhide
	# devfs rule -s 10 add path urandom unhide

  ルールセットを確認しよう。

	# devfs rule -s 10 show
	  ~~~~~~~~~~~~~~~~~~~~~
	100 hide
	200 path null unhide
	300 path zero unhide
	400 path random unhide
	500 path urandom unhide

  行頭に付加される 100, 200, ... はひとつのルールセット内部でのルール番
  号である。作成したルールセットを用いて jail 内の /dev を設定する。
  devfsがマウントしてあることを確認する。

	# mkdir /opt/jail/prison/dev
	# mount -t devfs devfs /opt/jail/prison/dev

  このマウントポイントに対して、ルールセット10番を適用する。

	# devfs -m /opt/jail/prison/dev rule -s 10 applyset

  実際に見えるデバイスファイルを確認してみよう。

	# ls /opt/jail/prison/dev
	  ~~~~~~~~~~~~~~~~~~~~~~~
	null            random          urandom         zero

  今回利用した devfs コマンドのサブコマンドについては devfs(8) のオンラ
  インマニュアルを参照して欲しい。

  デバイスファイルのルールセット作成が完了したら、システムスタートアップ
  時に自動的にこの設定が生きるようにしておいた方が良いだろう。

  ホスト環境の /etc/fstab に以下のエントリを追加する。

	devfs  	/opt/jail/prison/dev	devfs	rw	0	0


  ルールセットの作成と、マウントポイントへのルール適用に関してはjail起動
  スクリプトで行なう(後述)。

●jail環境の起動

jail環境の起動はjail(8)コマンドで行なう。jailコマンドは

	jail [オプション] ディレクトリ ホスト名 IPアドレス コマンド

の形式で起動し、指定した「ディレクトリ」をルートディレクトリとするjailプ
ロセスが起動する。「ホスト名」と「IPアドレス」がそれぞれjailプロセスに割
り当てられる。「コマンド」がjail環境内で実行されるもので、通常はjail環境
内で必要なデーモンや管理用シェルを起動するとよい。

jail起動用のスクリプトを作成しよう。スクリプトとしては、

	a. jail環境を整えてjailコマンドを起動するスクリプト
	b. jail内部で最初に起動するスクリプト

の2種類を用意する。

・jail起動スクリプト

  devfsを設定し、jailそのものを起動するスクリプトは【リスト と】のように
  なる。

---[リスト と]--------------------------------------------------------
/opt/jail/start-prison.sh
~~~~~~~~~~~~~~~~~~~~~~~~~
	#!/bin/sh
	# devfs の設定
	devfs rule -s 10 delset
	devfs rule -s 10 add hide
	devfs rule -s 10 add path null unhide
	devfs rule -s 10 add path zero unhide
	devfs rule -s 10 add path random unhide
	devfs rule -s 10 add path urandom unhide
	devfs -m /opt/jail/prison/dev rule -s 10 applyset
	# jail起動
	/usr/sbin/jail /opt/jail/prison prison.example.net 10.1.2.101 /etc/rc
----------------------------------------------------------------------

  また、【リスト と】 で jail 内コマンドとして /etc/rc を指定している。
  これが b. に相当する。このスクリプトは「とりあえず」シェルを起動するだ
  けのものにしておこう【リスト ち】。

---[リスト ち]--------------------------------------------------------
/opt/jail/etc/rc
~~~~~~~~~~~~~~~~

	#!/bin/sh
	exec /bin/csh
----------------------------------------------------------------------

実際に、jail起動スクリプト(a.)を起動してみよう。

	# /opt/jail/start-prison.sh
	  ~~~~~~~~~~~~~~~~~~~~~~~~~
	#

シェルが起動すれば成功である。


■
■セキュアなWebサーバーの構築
■

ここまでの作業で Web サーバプログラム起動に必要な環境が揃ったので、実際
にWebサーバプログラムをインストールしよう。インストールはコンパイル環境
の揃ったホスト環境で行なう方が簡単だろう。

●Apache2のインストール

ここでは Apache 2.0.47 (アーカイブ名 httpd-2.0.47.tar.gz) をインストール
する。適当な作業ディレクトリに移動し、アーカイブを展開し、configureと
makeを行なう。インストールPREFIXは /usr/apache2 に設定するものとして例示
する。

	# tar zxpf httpd-2.0.47.tar.gz
	# ./configure --prefix=/usr/apache2 && make

さて、このままインストールした場合、ホスト環境のディレクトリに入ることに
なる。最も楽なのは一度ホスト環境にインストールしてから、jail環境に移動す
る方法だろう【註 へ】。

---[註 へ]------------------------------------------------------------
autoconf によるビルドシステムを採用した一般的なソフトウェアでは
make install のときに make DESTDIR=/opt/jail/prison install とすれば
$DESTDIRからの相対ディレクトリでインストールしてくれるものが多い。
Apache2 もこの方法が使えるのだが、同梱されている expat ライブラ
リの Makefile だけが $DESTDIR を参照しないのでこれだけつねにルートディレ
クトリを起点とした位置に入ってしまうため、この方法は残念ながら使えない。
----------------------------------------------------------------------

	# make install
	# mv /usr/apache2 /opt/jail/prison/usr

●jail内でのApacheの起動/停止/再起動

jailの起動スクリプトとして【リスト と,ち】のものを組み合わせて起動したこ
とを前提とする。jail内でApacheを起動してみよう。以下 (jail)# というプロ
ンプトはjail内で起動しているシェルを意味するものとする。

	(jail)# /usr/apache2/bin/apachectl start

別の端末、あるいは別のホストからjailホストにHTTP接続できるか確認してみよ
う。

	(別のホストから)
	% telnet 10.1.2.101 80
	  ~~~~~~~~~~~~~~~~~~~~
	Trying 10.1.2.101 80
	Connected to prison.example.net
	Escape character is '^]'.
	GET /
	~~~~
	
	
	
	  :
	  :
	  :


その他、Apacheの停止や再起動は通常のホスト環境で操作するのと同様、

	(jail)# /usr/apache2/bin/apachectl stop
や
	(jail)# /usr/apache2/bin/apachectl restart

によって行なえる。apachectlスクリプトの操作方法については、スクリプトそ
のもの、あるいはApacheのマニュアルを参照して欲しい。

また、FreeBSD 5.1R からは、jail環境外からプロセスを送り込むことができる。
このために、稼動中のjail環境の識別子(JID)を知る必要があり、これはjlsコマ
ンドにより得られる。

	# jls
	   JID  IP Address      Hostname                 Path
	     3  10.1.2.101   prison.example.net        /opt/jail/prison

上記の場合は3となる。5.1R では jexec コマンドにより、jail環境外部からプ
ロセスを送り込むことができる。たとえば、

	# jexec 3 /bin/sh

とすると、jail環境内でシェルが起動する。jexecを利用することでjail環境内
の操作をすることができる。FreeBSD 4.xではjexecがないのでjail環境起動スク
リプトから起動したシェルで操作するか、外部からSSHログインして操作するこ
とになるだろう。

実際にjail化Webサーバとして運用する場合は、apacheの起動を
/opt/jail/prison/etc/rc スクリプトに追加しておく。



●jail固有の設定

Webコンテンツとして、一般ユーザの ~/public_html も参照する場合は、各ユー
ザのホームディレクトリをjail環境内に用意する必要がある。

・ユーザアカウントがホスト環境と同じ場合

純粋にセキュリティ向上を目的として、Webサーバをjail内で起動する場合はユー
ザアカウントはホスト環境と同一のものにすることになるだろう。この場合、
Part2で述べたように、ホスト環境のパスワードファイルの一般ユーザのエント
リからパスワードフィールドを抜いたものをjail環境内にコピーするとよい。こ
の方法は XX((Part2のリスト とのあるページ)) ページの【リスト と】の
Makefileなどを利用して /opt/jail/prison/etc にパスワードファイルを作成す
る。なおかつ、jail環境のディレクトリを基準とした各ユーザのホームディレク
トリを作成する。もし、jail環境の etc/passwd ファイルのうち、UIDが1000以
上のものが一般ユーザのアカウントなのであれば、

	# cd /opt/jail/prison			(jailディレクトリに移動)
	  ~~~~~~~~~~~~~~~~~~~
	# exec sh				(/bin/shで作業する)
	# grep -v '^#' etc/passwd \
	  | awk -F: '$3 >= 1000 {print $1,$6}' \
	  | while read user dir; do
	      mkdir -p ./$dir/public_html
	      chown -R $user ./$dir
	      ls -ld ./$dir
	    done

などとすれば全一般ユーザの ~/public_html を一括して作成できる。これを各
ユーザがホスト環境のホームディレクトリにシンボリックリンクを張って利用す
るのが便利だろう。

	【taroさんの場合の例】
	taro% ln -s /opt/jail/prison/home/taro/public_html ~/


・jailごとに独立したユーザアカウントを持つ場合

マルチホスティングを目的としてjailを利用する場合は、jail環境内にユーザの
利用環境全てを用意することになる。この場合は、jail環境内にユーザアカウン
ト作成に必要なコマンド(pw, vipw等)を用意しておいて、jail内で動くシェルか
らユーザ登録作業をすると良いだろう。


この場合、外部からjail環境にログインできるようsshdを起動しておく必要があ
る。sshdの起動と外部からのログインに最低限必要な、以下のファイル群をjail 
環境に追加する。

	* /etc/sshd/ にあるSSHの設定ファイル
	* sshdユーザアカウントと /var/empty ディレクトリ
	* /etc/pam.d/sshd
	* /usr/lib のpamライブラリ
	* 仮想ターミナルデバイス(devfsで設定)
	* termcapデータベース (/usr/share/misc/termcap.db)
	* ユーザが利用するシェル等

devfsで、仮想ターミナルデバイスを追加するには【リスト と】のdevfsルール
セットに以下のルールを追加し、マウントポイントに適用する。

	(追加分のみ)
	devfs rule -s 10 add path 'tty*' unhide
	devfs -m /opt/jail/prison/dev rule -s 10 applyset

jail内で sshd を起動し、外部からログインできることを確認しよう。うまく行
かない場合は、エラーメッセージやPart2で解説したトレース結果を見て足りな
いものを補充して行けばよい。

また、ssh以外のデーモンを起動する場合にも当てはまるのだが、ホスト環境で
同種のデーモンを起動している場合は、jailの持つIPアドレスでLISTENしないよ
うに設定することをお忘れなく。

●マルチホスティング

複数のWebサーバを複数のjailで動かす場合は、ここまでの作業を純粋に繰り返
せば良い。IPアドレスとディスク容量の許す限り、何個でも「jail化サーバ」を
立ち上げることができる。

■
■ネットワークサービスのjail化
■

jail環境内でいくつかのプロセスが起動するところまでの設定が済んでしまえば
その中で色々なネットワークサービスデーモンプログラムを動かすのはたやすい。
そのようにして徐々にjail化を進めてゆくことはホスト環境の安全度を高めるこ
とに繋がる。また、一般的なネットワークサービス環境を全てjailの中に閉じ込
めておけば、サーバマシンの置き換え作業などのときに、jailディレクトリ以下
をまるごと別のマシンにコピーするだけで簡単かつ安全に完了できるというメリッ
トも得られる。

jail環境を構築する作業も、各プログラムでどのようなリソースを必要としてい
るかを知ることができるので管理スキルを上げる一助となるだろう。近年はイン
ストーラに任せるだけでWebサーバやftpサーバまで上がってしまう便利な世の中
になっているのだが、「誰が入れても同じ構成」になるシステムは、クラッカー
にとっても狙いやすいターゲットだと言える。jail化されたシステムはそれだけ
で「典型的なシステム」から外れることになるという点も大きい。ただし、守り
を固めることにこだわってできるだけ「最小のもの」を揃えようとjail環境の構
築作業に時間がかかりすぎるのも逆効果である。管理コストが高すぎると、それ
を継続しなくなりがちだからである。「守りたいもの」と「利用者の便宜」のバ
ランスを考えてリーズナブルな設定を行なって欲しい。


yuuji@gentei.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]