chrootで学ぶ環境構築時のポイント

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

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

目次


Part2 chroot環境構築の基礎知識

Part1で触れたようにchrootを利用することで、不要な情報流出の可能性を格段
に下げることができる。多くのネットワークデーモンプログラムでは、プログラ
ム自身でchrootシステムコールを発行して不要なファイルへのアクセスを防ぐよ
うになっている。

chrootは歴史のあるきわめて基本的な機能でありながら、稼動中のシステム全体
のファイルシステムを保護する働きには絶大なものがある。また、Part3で紹介
する FreeBSD の jail(8) のベースとなる技術となっているので、ここで特定の
サービスデーモンを起動するためのchroot環境の構築に必要な知識を整理してお
こう。

「本来のファイルシステムを見せない」という意味だけであれば、ホストOSの最
小インストールセットと同じものを特定のディレクトリ以下に全てコピーしてし
まえば良い。たとえば、/opt/chroot ディレクトリをchroot用ディレクトリにし
たい場合、このディレクトリにOSの基本配布ファイルすべてを展開することにな
る。FreeBSD 5.1R の場合であれば

# cd somewhere/5.1-RELEASE/base
# sh -c 'DESTDIR=/opt/chroot . install.sh'

などとすれば、あらゆるユーザランドプログラムに必要なファイル群が揃ったディ
レクトリツリーができる。しかし、完全なベースシステムをインストールすると
ネットワーク設定コマンドなど、システム管理ツールも揃うことになる。それゆ
え仮想環境とはいえ万一環境を乗っ取られた場合、ホスト環境全体を乗っ取られ
たのとあまり差がなくなってしまう。したがって、chrootをベースとする仮想環
境でデーモンプログラムを動かす場合は、それに必要な最低限のファイル群のみ
を環境内にインストールするようにしなければ、敢えてchrootを利用する意味が
乏しくなってしまう。そのために、特定のプログラムがどんなファイルやディレ
クトリを要求するかを見極める技術が必要となる。まずは、それらを調べるため
の基本知識を押さえておこう。


■
■最小chroot環境構築の流れ
■

chroot環境を作る手順は、

	1 起点となるディレクトリを決定する
	2 必要となるファイルのコピー
	3 実際にchrootして動作確認

となる。作業時には2と3を繰り返すことになるだろう。ここでは、トライアンド
エラーで実際に構築作業を行なうことを想定して順次解説して行こう。

■
■最小chroot環境の構築
■

まずは理解の助けとするために、非常に簡単なchroot環境を作ってみよう。
目標として cvs コマンドを起動するのに必要なものを揃えることを考えよう。

[ステップ 1]

まず最初に、どこでも良いが、chroot仮想環境に見せるトップディレクトリ(仮
想環境にとってのルートディレクトリ)を決定する。以下の例では /opt/chroot 
をトップディレクトリとする。この配下に、必要最低限と思われるコマンドをコ
ピーしていく。一般的には、動かす目標とするコマンド(cvs)の他に、シェル、
ls コマンドなど頻繁に使うコマンドをまず用意する。単純な例としてここで 
chroot 環境にコピーするコマンドは

	/bin/sh
	/bin/ls
	/usr/bin/cvs

だけとする。

	(ディレクトリを作成)
	# mkdir -p /opt/chroot
	# mkdir /opt/chroot/bin
	# mkdir /opt/chroot/root
	# mkdir -p /opt/chroot/usr/bin
	(コマンドとファイルのコピー)
	# cp /bin/sh /bin/ls /opt/chroot/bin
	# cp /usr/bin/cvs /opt/chroot/usr/bin

実際に chroot して sh, ls, cvs コマンドが正常に機能するか試してみよう。

	# chroot /opt/chroot /bin/sh

chroot コマンドは第1引数に新たなルートとなるディレクトリ、第2引数以降に
chroot後に実行するコマンドラインを指定する。上記のコマンドラインを実行す
ると、新しく sh が起動し、プロンプトがあらわれる。

	(chroot)#

本稿ではホスト環境のシェルと区別しやすくするため、chroot内のシェルプロン
プトを (chroot)# で表すことにする。ls コマンドを試してみよう。

	(chroot)# ls
		  ~~
	bin	usr

	(chroot)# ls -lF
		  ~~~~~~
	total 4
	drwxr-xr-x  2 0  0  512 Jul 28 19:47 bin/
	drwxr-xr-x  3 0  0  512 Jul 29 00:12 usr/

結果は得られたのでlsコマンド自体の起動はうまく行っている。ただし、ls -l
の出力で、ユーザ名とグループ名の出るべきところが UID/GID の 0 0 と出てい
る。これは、パスワードファイルをchroot空間内にコピーすれば解決する。ただ
し、情報の隠蔽という観点からは、そのままホスト環境のパスワードファイルを
chroot環境内にコピーしたのでは意味がない。これに関しては後述する。

続いてcvsコマンドが起動できるか確かめよう。

	(chroot)# cvs
		  ~~~
	ELF interpreter /usr/libexec/ld-elf.so.1 not found
	Abort trap

エラーが出る。これは、shやlsと違ってcvsコマンドが dynamic executable
(動的ライブラリをリンクする必要のある実行ファイル)であるため、実行時に動
的ライブラリをロードするプログラムを必要とするからである。これに関して管
理上必要な基礎知識をまとめよう。

[基礎知識 1 動的ライブラリ]

多くのプログラムで共通している処理手順をまとめて、ひとつのプログラムファ
イルの中に詰め込んでおき、実際のプログラミングのときにそれを利用すること
でプログラミングの労力と、ディスクスペースを節約することができる。共通処
理をまとめたプログラムファイルのことを「ライブラリ」といい、たいていのシ
ステムでは /usr/lib ディレクトリに数多く格納されている。たとえば、どんな
プログラムでも端末やファイルとの入出力を行なう。そのように最も基本的な機
能を集約したライブラリが libc で、これは /usr/lib/libc.* ファイルである。

ライブラリには「静的ライブラリ」と「動的ライブラリ」【註: 動的ライブラリ
は共有オブジェクト(shared object)ともいう】があり、前者はプログラムのコ
ンパイル時に必要なライブラリ(中の関数)が実行プログラムに静的に組み込まれ
る。後者はコンパイル時にライブラリを組み込むのではなく、必要とするライブ
ラリファイルの名前だけを埋め込んでおく。プログラムを実行するときにライブ
ラリをロードする。ライブラリのファイル名は、

	静的ライブラリ		lib<名前>.a
	動的ライブラリ		lib<名前>.so

となっている。動的ライブラリの場合はファイル名にバージョン番号が付く場合
がある。

動的ライブラリを要求する実行プログラムを起動したときに実際にライブラリ
(shared object)をロードするのが

 	/usr/libexec/ld-elf.so.1	FreeBSD(ELF)の場合
	/lib/ld-linux.so.2		Linuxの場合

となっている。

さて、chroot環境作成のためには各プログラム実行時にリンクされる動的ライブ
ラリを知る必要がある。そのための必要なツールをいくつか紹介しよう。

	* ldd - リンクされる動的ライブラリの表示

	実行プログラムが必要とする動的ライブラリ(shared object)の一覧を
	表示する。

	* ldconfig - 動的ライブラリのキャッシュ情報の更新

	FreeBSDでは動的ライブラリを検索するパスを
	/var/run/ld-elf.so.hints に、キャッシュしておく。これを作成/更新
	するのが ldconfig で、通常システムのスタートップ時に自動的に実行
	される【→Linuxの場合[ち]】。

	----[Linuxの場合 ち]---------------------------------------------
	Linuxでは /etc/ld.so.cache ファイルにキャッシュされる
	-----------------------------------------------------------------

	# ldconfig ディレクトリ1 ディレクトリ2 ... ディレクトリn

	のように起動することで、引数として与えたディレクトリ群を全てキャッ
	シュファイルに登録する。ライブラリを検索するディレクトリとして 
	/usr/lib 以外のものを含ませたいときは一度chroot環境内でldconfig 
	を実行する【→Linuxの場合 り】。

	実行例:
	# mkdir -p /opt/chroot/var/run
	# mkdir /opt/chroot/sbin
	# cp /sbin/ldconfig /opt/chroot/sbin
	# chroot /opt/chroot /sbin/ldconfig /usr/lib /usr/local/lib ...

	などとすれば、/opt/chroot/usr/local/lib などにインストールした動
	的ライブラリがchroot環境内で利用できるようになる。

	----[Linuxの場合 り]------------------------------------------------
	/etc/ld.so.conf ファイルに動的ライブラリを検索すべきディレクトリ
	一覧を記述しておき、ldconfig コマンドを起動すれば各ディレクトリ
	にあるライブラリを調べて /etc/ld.so.cache にキャッシュファイルを
	作成する。

	実行例:
	# mkdir -p /opt/chroot/etc /opt/chroot/sbin
	# cp /sbin/ldconfig /opt/chroot/sbin
	# cat > /opt/chroot/etc/ld.so.conf
	/usr/lib
	/usr/local/lib
	/usr/foo/lib
	^D
	# chroot /opt/chroot /sbin/ldconfig
	-------------------------------------------------------------------

	* locate - ファイルの検索

	動的ライブラリとは直接関係ないが、ファイルシステム中に含まれるファ
	イルを高速に検索するのが locate である。ファイル名の一部を指定す
	ることで、ファイル名にその文字列が含まれるものを全て表示する。特
	定のコマンドが必要とするファイルがどこにあるのか分からないときは
	locate コマンドを利用して探すのが良いだろう。

	-	-	-	-	-	-	-

以上のことをふまえて、cvsコマンドを実行するために、chroot環境に必要なファ
イルを補充しよう。

	(chroot)# cvs
		  ~~~
	ELF interpreter /usr/libexec/ld-elf.so.1 not found
	Abort trap

	(ホスト環境に抜けて ld-elf.so.1 をコピーする)【→Linuxの場合[ぬ]】
	(chroot)# exit
	# mkdir /opt/chroot/usr/libexec
	# cp /usr/libexec/ld-elf.so.1 /opt/chroot/usr/libexec

	----[Linuxの場合 ぬ]-----------------------------------------------
	(ホスト環境に抜けて /lib のファイルをコピーする)

	Linuxの場合は /lib のライブラリファイルと動的ライブラリローダ
	(ld-linux.so)chroot環境内にコピーしておくのが良いだろう。

	(chroot)# exit
	# cd /
	# tar cf - lib/l* | tar xvpfC - /opt/chroot
	-------------------------------------------------------------------

	(cvsコマンドに必要なライブラリを調べる)
	# ldd `which cvs`
	  ~~~~~~~~~~~~~~~
	/usr/bin/cvs:
        libgnuregex.so.2 => /usr/lib/libgnuregex.so.2 (0x280e9000)
        libmd.so.2 => /usr/lib/libmd.so.2 (0x280f1000)
        libcrypt.so.2 => /usr/lib/libcrypt.so.2 (0x280fb000)
        libz.so.2 => /usr/lib/libz.so.2 (0x28114000)
        libgssapi.so.6 => /usr/lib/libgssapi.so.6 (0x28122000)
        libkrb5.so.6 => /usr/lib/libkrb5.so.6 (0x2812e000)
        libasn1.so.6 => /usr/lib/libasn1.so.6 (0x2816a000)
        libcrypto.so.3 => /usr/lib/libcrypto.so.3 (0x28190000)
        libroken.so.6 => /usr/lib/libroken.so.6 (0x2829b000)
        libcom_err.so.2 => /usr/lib/libcom_err.so.2 (0x282aa000)
        libc.so.5 => /usr/lib/libc.so.5 (0x282ac000)


lddの出力により、必要な動的ライブラリが libgnuregex, libmd, libcrypt,
libz, libgssapi, libkrb5, libasn1, libcrypto, libroken, libcom_err, libc 
とわかるので、それらをコピーする。動的ライブラリはシンボリックリンクファ
イルを含むのでそれらをまとめて tar を使ってコピーする(以下の例はcshを想
定している)。

	# pushd /usr/lib
	# foreach f (gnuregex md crypt z gssapi krb5 asn1 crypto \
		roken com_err c)
	? tar cf - lib${f}.so* \
		| tar -xvpf - -C /opt/chroot/usr/lib --unlink
	? end

必要なライブラリが揃っているか、実際に cvs コマンドをchroot環境内で起動
して確認してみよう【→Linuxの場合[る]】。

	# chroot /opt/chroot /usr/bin/cvs
	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	Usage: cvs [cvs-options] command [command-options-and-arguments]
	  where cvs-options are -q, -n, etc.
		:
		:

	----[Linuxの場合 る]-----------------------------------------------
	# ldd /usr/bin/cvs
	  ~~~~~~~~~~~~~~~~
	libz.so.1 => /usr/lib/libz.so.1 (0x4001f000)
        libcrypt.so.1 => /lib/libcrypt.so.1 (0x4002d000)
        libc.so.6 => /lib/libc.so.6 (0x4005b000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

	必要なライブラリ /usr/lib/libz.so* をコピーする。
	# cd /usr/lib
	# tar cf - libz.so* | tar xvpfC - /opt/charoot/usr/lib

	コマンドが起動するか確認する
	# chroot /opt/chroot /usr/bin/cvs
	-------------------------------------------------------------------


chroot環境内で実際に利用するプログラム全てに対して、必要とする動的ライブ
ラリをコピーする。各プログラムが起動するまでの条件はこの作業で全て揃うこ
とになる。



[ステップ 2]

プログラムの実行には、いくつかのデータファイルも必要となる。これを確認す
るために、dateコマンドを例にとって調べてみよう。

	# cp /bin/date /opt/chroot/bin
	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	(chroot環境でdateを実行)
	# chroot /opt/chroot /bin/date
	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	Thu Jul 31 06:23:13 GMT 2003
	                    ↑↑
	(ホスト環境で実行)
	# date
	Thu Jul 31 15:23:22 JST 2003
			    ↑↑


時刻表示が全く違う。これは、chroot環境内にタイムゾーンファイルが欠落して
いるせいで、タイムゾーン未指定の場合グリニッジ標準時(GMT)で時刻が表示さ
れる。タイムゾーンファイルが /etc/localtime であるという知識があればすぐ
にそのファイルをコピーして対処できるだろう。仮にその知識がない場合はどう
したら良いかについて説明しよう。

根本的なことをいえば、「そのプログラムのソースを見る」というのが完全無欠
の正解だろうが、ソースを読んでそのプログラムの必要としている外部ファイル
を全てソースレベルで調べるなるとなかなか難しい。このような場合はカーネル
処理のトレースを行なうコマンドが役に立つ。

[基礎知識 2 カーネル処理のトレース]

ktrace/kdumpコマンドを利用するとプログラム実行時に内部で起きている処理を
調べることができる【→Linuxの場合[を]】。

	* ktrace - カーネル処理のトレースを行なう

	指定したコマンドやプロセスのカーネル処理のトレース開始を指示する。
	トレース結果は(デフォルトで) ktrace.out ファイルに保存される。

	ktrace [オプション] -p プロセスID
	または
	ktrace [オプション] コマンド

	の形式で利用する。前者は走行中のプロセスのトレースを開始し、後者
	はこれから起動するコマンドのトレースを取る。今回の目的では後者を
	利用することになる。

	* kdump - カーネルトレースの結果を表示する

	ktraceにより得られたトレース結果をユーザに分かる形に変換して表示
	する。トレース結果ファイルはデフォルトでカレントディレクトリの
	ktrace.out が用いられる。

	----[Linuxの場合 を]-----------------------------------------------
	* strace - システムコールのトレースを行なう

	strace [オプション」 コマンド

	の形式で利用し、指定したコマンドが発行するシステムコールをトレー
	スする。実行してトレースした結果がそのまま端末(標準エラー出力)に
	出されるので、トレース結果をあとから見たい場合には -o オプション
	でファイルに出力すると良い。

	strace -o trace.out date

	とすると、dateコマンド実行時のトレース結果がカレントディレクトリ
	の trace.out に出力される。
	-------------------------------------------------------------------


実際にトレースして確かめてみよう【→Linuxの場合[わ]】。

	(ktrace/kdumpをchroot環境内にコピーしておく)
	# cp /usr/bin/{ktrace,kdump} /opt/chroot/usr/bin

	(chroot環境で date コマンドをトレース)
	# chroot /opt/chroot /bin/sh
	# ktrace -i /bin/date
	Thu Jul 31 06:29:22 GMT 2003
	
	(トレース結果を確認)
	# kdump | less

---[実行例 ほ]--------------------------------------------------------
   472 ktrace   RET   ktrace 0
   472 ktrace   CALL  execve(0xbfbff3e0,0xbfbff8e0,0xbfbff8e8)
   472 ktrace   NAMI  "/sbin/date"
   472 ktrace   RET   execve -1 errno 2 No such file or directory
   472 ktrace   CALL  execve(0xbfbff3e0,0xbfbff8e0,0xbfbff8e8)
   472 ktrace   NAMI  "/bin/date"
   472 date     RET   execve 0
   472 date     CALL  gettimeofday(0xbfbff418,0)
   472 date     RET   gettimeofday 0
   472 date     CALL  access(0x80a6408,0x4)
   472 date     NAMI  "/etc/localtime"
   472 date     RET   access -1 errno 2 No such file or directory
   472 date     CALL  issetugid
   472 date     RET   issetugid 0
	:
	:
	:
----------------------------------------------------------------------

	----[Linuxの場合 わ]-----------------------------------------------
	(straceをchroot環境内にコピー)
	# cp /usr/bin/strace /opt/chroot/usr/bin
	(chroot環境内でdateコマンドをトレース)
	# chroot /opt/chroot /bin/sh
	# strace -o trace.out date
	Sat Aug  2 12:51:48 UTC 2003
	-------------------------------------------------------------------


実行例【ほ】のような結果が得られるだろう。これを見ると、/etc/localtime
の存在を確認しているのが分かる。さらにオンラインマニュアルなどを見れば、
localtimeファイルがシステムのデフォルトのタイムゾーンを持つことが分かる
だろう。したがってこのファイルもchroot環境内にコピーする。

	# mkdir /opt/chroot/etc
	# cp /etc/localtime /opt/chroot/etc

こうした処理を繰り返して行くことで、必要なファイルを揃えられる。



■
■アカウント情報の隠蔽
■

chroot環境内でWebサーバなどを起動する場合は、ユーザのホームディレクトリ
を認識する必要があるので、アカウント情報、つまりパスワードファイルを置く
必要がある。システムにより若干の差異はあるが、パスワードファイルには通常

	・ユーザ名
	・エンコードされたパスワード
	・ユーザID
	・グループID
	・名前等(gecos)
	・ホームディレクトリ
	・ログインシェル

の情報が1行1レコードで格納されている。システム本来の環境であればユーザの
持つホームディレクトリがどこであるかなどの情報はつねに色々なプログラムか
ら参照されている。しかし chroot 環境内では、それらの情報が必要かどうかは、
chroot環境内で動かすプログラムが一般ユーザのファイルに関心を持つかどうか
に依存する。たとえば、DNSやNTPを動かすのであれば、それらは一般ユーザのファ
イルアクセスを全く必要としないのでアカウント情報は全く不要である。その一
方、chroot環境内でMTAやWebサーバを動かすのであれば、一般ユーザのホームディ
レクトリ情報も必要となる。

ただし、いずれの場合もユーザのパスワード情報が必要になることはない。パス
ワード情報が必要なのは、SSHデーモンなどログインを許可するプログラムだけ
である。以上のことから、ログイン操作をさせないデーモン(つまりほとんど)の
場合、アカウント情報のうちパスワード情報を抜き取ったものをchroot環境内に
用意すれば十分で、なおかつ情報漏洩の危険性も減らせると言える。同様の考察
をすればグループファイル(/etc/group)も一般ユーザに関連するもの以外は
chroot環境内には用意しないのが望ましいと言える。

●chroot環境用パスワードファイルの作成

ここではchroot環境内のパスワードファイルには

	1. 一般ユーザのアカウントのみ
	2. パスワードフィールドを削ったもの

を用意する例を考えてみよう。通常一般ユーザはrootやbinなどの特殊ユーザよ
りも大きなUIDを持つことが多いので、ここでは単純化して1000番以上のUIDをコ
ピーすることにしよう。

  【FreeBSDの場合】

  FreeBSDでは、全てのアカウント情報が /etc/master.passwd ファイルに、そ
 のうちパスワードフィールドなどを除いたものが /etc/passwd ファイルに格納
 されている。したがってホスト環境の /etc/passwd ファイルを原本とし、それ
 に含まれるUIDが1000以上のものを選び、chroot環境内のmaster.passwd ファイ
 ルを生成するとよい。awkを利用して以下のようにする。不注意によりシステム
 本来の /etc/master.passwd ファイルを壊さないように注意しよう。

	# awk -F: '$3 >= 1000{printf "%s:*:%s:%s::0:0:%s:%s:%s\n", \
		$1,$3,$4,$5,$6,$7}' /etc/passwd \
		> /opt/chroot/etc/master.passwd

  master.passwd ファイルから spwd.db, passwd, pwd.db 各ファイルを生成す
  るために pwd_mkdb コマンドを利用する。

	# cd /opt/chroot/etc
	# pwd_mkdb -d . master.passwd
	# pwd_mkdb -d . -p master.passwd

  こちらもカレントディレクトリの移動と -d . オプションを忘れると /etc 内
  の本物のパスワードファイルを破壊するので慎重にコマンド入力する。以上の
  操作は make ユーティリティで自動化しておくことで操作ミスの危険を回避で
  きるだろう。/opt/chroot/etc ディレクトリにリスト【と】のような 
  Makefile を作成しておくと良い(BSD make用)。【→Linuxの場合[か]】

---[リスト と /opt/chroot/etc/Makefile ]------------------------------
#
# Makefile for creating password account files in chroot-environment
#
all:  spwd.db passwd

spwd.db:	master.passwd

master.passwd:	/etc/passwd
	cat $> \
	|grep -v '^#' \
	|awk -F: '$$3 >= 1000 \
	{printf "%s:*:%s:%s::0:0:%s:%s:%s\n", \
		$$1,$$3,$$4,$$5,$$6,$$7}' \
	> $@
	chmod og-r $@

spwd.db:	master.passwd
	pwd_mkdb -d . $>

passwd: master.passwd
	pwd_mkdb -d . -p $>
----------------------------------------------------------------------

----[Linuxの場合 か]-----------------------------------------------
  一般的なLinuxでも、FreeBSDと同様パスワードフィールドを含むものと、含ま
  ないものが分離されている。Linuxでは /etc/shadow ファイルにパスワード情
  報が格納されていて、ログイン操作などをしない場合は shadow ファイルはな
  くても良い。FreeBSDの例と同じように「UIDが1000以上のユーザのみ」のアカ
  ウント情報をchroot環境内にコピーするのであれば、

  # cat /etc/passwd \
	| awk -F: '$3 >= 1000 {print}' \
	> /opt/chroot/etc/passwd

  のようにすれば良い。
-------------------------------------------------------------------


■
■システムログ出力
■

デーモンプログラムでは、動作中のログを保存することが多い。デフォルトの出
力先に応じて

	* 自前のログファイルに出力するもの
	* syslog(3) 経由で出力するもの

に分類できる。前者にはWebサービスデーモンのApacheなどがあり、これらは
chroot環境内で動かしても問題なくログが保存される。

後者の場合、ログソケットをchroot環境内にも用意する必要がある。FreeBSDで
は場合デフォルトで /var/run/log をログソケットとして利用する。chroot環境
内で動くプログラムがsyslog出力を行なう場合、環境内の /var/run/log (つま
り /opt/chroot/var/run/log) を使うことになるので、syslogdがこのファイル
をソケットファイルとして利用するように指定する。これには syslogd(8) の起
動時に -l オプションを指定する【→Linuxの場合[よ]】。

       (デフォルト)
	syslogd -s
	  ↓
	(chroot環境内ソケットを追加指定)
	syslogd -s -l /opt/chroot/var/run/log

システム起動時に自動的にこのオプションが追加されるよう、/etc/rc.conf に
以下の内容を追加する。

	syslogd_flags='-s -l /opt/chroot/var/run/log'

	----[Linuxの場合 よ]-----------------------------------------------
	Linuxでは、ソケットファイルとして /dev/log を利用する。
	syslogdに追加ログソケットを使わせるためには -a オプションを指定
	する。システム起動時にchroot環境内のログソケットを指定するには
	/etc/sysconfig/syslog ファイル中にある SYSLOGD_OPTIONS 変数の値
	を変更する。

	SYSLOGD_OPTIONS="-m 0"
	↓
	SYSLOGD_OPTIONS="-m 0 -a /opt/chroot/dev/log"
	-------------------------------------------------------------------



■
■その他重要なファイル
■

Unixシステムの実行時に重要となるファイルのうち多くのものに共通すると思わ
れるものをいくつか挙げておこう。これらも仮想環境内にコピーしておく必要が
あるだろう。

●/etc ディレクトリのファイル

/etc ディレクトリにはシステム管理に大きな意味を持つファイルが数多く格納
されている。その多くはシステムの起動時に参照されるものだが、いくつかのファ
イルはプログラムの実行時にしばしば参照される。それらのうち代表的なものを
表【へ】に示した。chroot環境内にインストールするプログラムによっては必要
ない場合もある。

---[表 へ]------------------------------------------------------------

/etc/protocols		プロトコル対応表
/etc/services		ポート番号対応表
/etc/pam.conf		PAMによる認証の定義ファイル(FreeBSD4まで)
/etc/pam.d/		PAMによる認証の定義ディレクトリ(Linux, FreeBSD5から)
/etc/resolv.conf	名前解決定義ファイル(ネームサーバなどを記述)
/etc/nsswitch.conf	ネームサービスの参照順位を指定する(Linux, FreeBSD5から)
/etc/hosts		(主にローカル使用する)ホスト表
/etc/host.conf		ネームサービスの参照順位を指定する(Linux, FreeBSD4まで)
/etc/passwd		パスワードファイル
/etc/pwd.db		passwd を db(3)形式に変換したもの(FreeBSD)
/etc/master.passwd	暗号化パスワードを含むパスワードファイル(FreeBSD)
/etc/spwd.db		master.passwd を db(3)形式に変換したもの(FreeBSD)
/etc/group		グループ定義ファイル
/usr/share/misc/termcap	端末ごとの制御機能のデータベース(FreeBSD)
/usr/share/misc/termcap.db	termcapをdb形式に変換したもの(FreeBSD)
//etc/termcap		端末ごとの制御機能のデータベース(Linux)

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

●デバイスファイル

/dev 内にあるデバイスファイルも、多くのプログラムが利用する。最低限のも
のは /dev ディレクトリにある MAKEDEV スクリプトで生成できる。以下の手順
では、/dev/MAKEDEV スクリプトをchroot環境内の /dev にコピーして、必要な
デバイスファイルを作成している。

	# mkdir /opt/chroot/dev
	# cd /opt/chroot/dev
	# cp /dev/MAKE* .
	# ./MAKEDEV std

FreeBSD 5 からは、デフォルト devfs を利用するので /dev 内のデバイスファ
イルは動的に生成される。chroot環境内でデバイスファイルにアクセスするもの
を動かす場合は

	# mount_devfs devfs /opt/chroot/dev

として devfs をマウントする。ただし、マウントしただけでは全てのデバイス
ファイルにアクセスできるので devfs のルールセットを適用して必要最小限の
デバイスファイルのみを見せるようにする【→ Part3 参照】。

●tmpディレクトリ

一時ファイルディレクトリとして、デフォルトで /tmp あるいは /var/tmp ディ
レクトリを要求するプログラムがあるので、これらを作成しておく。

	# cd /opt/chroot
	# mkdir -p tmp var/tmp
	# chmod 1777 tmp var/tmp

●var
MTAなどをchroot内で起動する場合はスプールディレクトリをchroot内に用意す
る必要がある。ホスト環境の /var のディレクトリ構成にあわせてchroot内にも
作成する。


●ホスト環境からchroot環境を利用する

Webサーバなどをchroot環境内で動かすのであれば、Webサーバプログラムは
chroot環境内だけにインストールすれば良く、ホスト環境にをインストールして
おいても利用されることはない。ただし、サーバプログラムの起動・停止・再起
動などのコマンド入力を行なう場合は通常スーパーユーザのシェルから行なうの
で、ホスト環境からそれらのコマンドにアクセスしやすくしておくと効率が良い
だろう。具体的には

	ホスト環境から見たPATH = /opt/chroot/usr/local/apache
	____________________________
	/opt/chroot/usr/local/apache
                   ~~~~~~~~~~~~~~~~~
               chroot環境から見たPATH = /usr/local/apache

というPATHの関係でインストールしてあるサーバプログラムへのPATHは、ホスト
環境内でも同じPATHになるようにシンボリックリンクを張ると良いだろう。

	# ln -s /opt/chroot/usr/local/apache /usr/local

さらに、サーバプログラム起動スクリプトをつくり、その中にchrootコマンドを
書いておくとchrootし忘れがない。たとえば apacheであれば起動スクリプトと
して bin/apachectl がある。この中に

     HTTPD=/usr/local/apache/bin/httpd

という行があるが、これを

	HTTPD='chroot /opt/chroot /usr/local/apache/bin/httpd'

のようにしておくのも一案である。

以上のような工夫をしておけば、通常利用するホスト環境でchroot内のサーバプ
ログラムを制御しやすくなるだろう。

■
■環境構築後の後始末
■

chroot環境内に必要なファイルを全て揃え終わったら、調査や設定のために
chroot環境内にコピーしたファイルを消しておこう。たとえば、chroot環境内に
独自のユーザアカウント情報を作りたい場合などは、環境内に pw コマンドや
vipw コマンド(とviエディタ等)をコピーしたほうが作業しやすいだろう。また、
ライブラリパスの登録のためには ldconfig コマンドを環境内にコピーする必要
がある。このように、管理用コマンドを環境内に置いた方が作業がはかどる場合
が多いので、適宜コピーするのが良いだろう。ただし、環境構築が終わった場合
には、環境内に残す必要のない管理コマンドは消去しておくのが望ましい。


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]