「はじめに」で述べたように、
BIND を root 権限で実行するのはあまり良い考えではありません。
従って、まず最初に BIND 専用のユーザを作りましょう。
この目的に、nobody
のような既存の一般向けユーザは、
決して使うべきではありません。
しかし、SuSE や Linux Mandrake など、
最初からこのためのユーザ (普通 named
という名前)
を用意しているディストリビューションもあるので、
その場合はお望みならこのユーザを用いても構いません。
さて、ユーザを追加するには、次のような行を
/etc/passwd
に加えます。
named:x:200:200:Nameserver:/chroot/named:/bin/false
そして次の行を /etc/group
に加えます。
named:x:200:
これで BIND 用の named
というユーザとグループができました。
UID と GID (この例では両方とも 200) が、
お使いのシステムで他と重なっていないように注意しましょう。
このユーザはログインする必要がないので、
シェルは /bin/false
にしてあります。
次に、chroot jail に使用するディレクトリ構造を作ってあげる必要があります。
ここが BIND の生活の場となるわけです。
これはファイルシステムのどこでも構いません。
非常に神経質な人は、独立したボリューム
(パーティション) に置きたいとさえ思うかもしれませんね。
ここでは /chroot/named
を使います。
まず以下のようなディレクトリ構造を作ってください。
/chroot
+-- named
+-- bin
+-- dev
+-- etc
| +-- namedb
+-- lib
+-- var
+-- run
【訳注: Debian ユーザでバイナリの再コンパイルを行いたくない人 (後述) は、
/chroot/named/etc/namedb
を
/chroot/named/etc/bind
としましょう】
既に通常のかたちで BIND がインストールできていて、
これを利用しているなら、
named.conf
ファイルとゾーンファイルがあるはずです。
これらのファイルは chroot jail の中に移動 (あるいは安全にやるならコピー)
して、BIND から見えるようにしてやる必要があります。
named.conf
は /chroot/named/etc
へ、
ゾーンファイルは /chroot/named/etc/namedb
へ移動します。
例えば:
# cp -p /etc/named.conf /chroot/named/etc/
# cp -a /var/named/* /chroot/named/etc/namedb/
【訳注: Debian の場合は named.conf の場所は /chroot/named/etc/bind
になります。
ゾーンファイルの置き場所は
named.conf
中の記述に依存するのですが、
通常は named.conf
と同じディレクトリになっています。】
BIND はおそらく namedb
ディレクトリと、
そこに置かれたファイル (の一部) に対する書きこみ権限を必要とします。
例えば、お使いの DNS があるゾーンをスレーブでサービスするなら、
BIND はそのゾーンファイルを更新できなければなりません。
また BIND は統計情報をダンプできますので、
それもこのディレクトリに書けるようにしてやる必要があります。
これらの理由から、このディレクトリ (とその中身) の
所有者は named
ユーザにしておくべきでしょう。
# chown -R named:named /chroot/named/etc/namedb
【訳注:
具体的には、named.conf
の
"options" 宣言中の directory 文が、
これらの書きこみが行われるディレクトリになります。
これはゾーンファイルのパス指定のベースディレクトリでもあります。
Debian の流儀ですと、
この directory は /var/cache/named
になっており、
各ゾーンファイルはフルパスで指定するかたちになっています。
この場合は
# mkdir -p /chroot/named/var/cache/namedb
# chown -R named:named /chroot/named/var/cache/namedb
などとすることになるでしょう。】
BIND は /var/run
ディレクトリにも書きこみ権限を必要とします。
pid ファイルと ndc ソケットをここに作るからです。
次のコマンドでこれを可能にしてやりましょう。
# chown named:named /chroot/named/var/run
BIND が chroot jail 内部での実行を始めると、 jail 外部のファイルへは一切アクセスできなくなります。 しかし、システムの C ライブラリなど、 いくつかの重要なファイルには実行後もアクセスできなければなりません。 実際にどのライブラリが必要になるかは、お使いの UNIX OS に依存します。 最新の Linux システムなら、 以下のコマンドを利用すれば必要なファイルを 適切な場所にちゃんと配置してくるはずです。
# cd /chroot/named/lib
# cp -p /lib/libc-2.*.so .
# ln -s libc-2.*.so libc.so.6
# cp -p /lib/ld-2.*.so .
# ln -s ld-2.*.so ld-linux.so.2
こうする代わりに、BIND のバイナリを静的にリンクしてビルドし、
これを chroot jail 以下に置いて利用することも可能です。
ldconfig
も jail の内部にコピーして実行し、
jail 環境用の etc/ld.so.cache
を作りましょう。
次のコマンドがこれを行います:
# cp /sbin/ldconfig /chroot/named/bin/
# chroot /chroot/named /bin/ldconfig -v
BIND はもう一つファイルを jail の内部に必要とします。
いつもの /dev/null
です。
ここでも、このデバイスノードを作るために必要なコマンドは
システムによって異なるでしょう。
/dev/MAKEDEV
スクリプトを調べて確認してください。
システムによっては /dev/zero
が必要なこともあります。
ほとんどの Linux システムでは、以下のコマンドが使えます。
# mknod /chroot/named/dev/null c 1 3
【訳注
# chmod go+w /chroot/named/dev/null
も必要だと思います。】
最後に、さらにファイルを 2〜3、jail 内部の /etc
ディレクトリに
持ってくる必要があります。
特に /etc/localtime
(システムによっては
/usr/lib/zoneinfo/localtime
かもしれません) が、
BIND に正しい時刻でログ記録をさせるには必要です。
また named
グループの含まれる簡単な group
ファイルも作成する必要があります。
以下のコマンドがこれらの面倒を見てくれます。
# cp /etc/localtime /chroot/named/etc/
# echo 'named:x:200:' > /chroot/named/etc/group
GID (この例では 200) にご注目。
先に本当の /etc/group
で定義したものと同じにしなければなりません。
本物の囚人とは異なり、BIND はログ記録を壁に書くことはできません :-)。
通常 BIND はログを、システムのロギングデーモンである
syslogd
経由で記録します。
このタイプのログ記録は、特殊なソケットである /dev/log
を通してログエントリを送信することで行われます。
しかしこれは jail の外部にありますから、BIND からは使えません。
でもありがたいことに、これを解決する方法はいくつか存在します。
このジレンマに対する理想的な解決法には、
OpenBSD で導入された -a
スイッチをサポートする、
比較的新しいバージョンの syslogd
が必要です。
syslogd(8)
の man ページをチェックして、
自分の使っているのがこれかどうか見てください。
サポートしていれば、syslogd
を起動する際のコマンドラインに ``-a /chroot/named/dev/log
''
を追加するだけで OK です。
SysV-init をすべて使っているシステム
(Linux ディストリビューションのほとんどはそう) なら、
起動は通常 /etc/rc.d/init.d/syslog
ファイルでなされます。
例えば、私の Red Hat Linux システムでは、私は
daemon syslogd -m 0
の行を
daemon syslogd -m 0 -a /chroot/named/dev/log
と変更しました。
Caldera OpenLinux システムでは
ssd
というデーモンランチャを使っており、
これは設定を /etc/sysconfig/daemons/syslog
から読みます。
この中のオプション行を以下のように修正するだけです。
OPTIONS_SYSLOGD="-m 0 -a /chroot/named/dev/log"
同様に SuSE システムでは、
このスイッチは /etc/rc.config
ファイルに追加するのが良いそうです。
SYSLOGD_PARAMS=""
という行を
SYSLOGD_PARAMS="-a /chroot/named/dev/log"
とすれば OK です。
【訳注: Debian なら /etc/init.d/syslogd
の
SYSLOGD=""
という行を
SYSLOGD="-a /chroot/named/dev/log"
とします。】
お使いのシステムでの変更方法がわかったら、
syslogd
を再起動するだけです。kill して再び
(追加パラメータとともに) 起動してもいいですし、
SysV-init スクリプトを使って次のようにするのでも良いでしょう。
# /etc/rc.d/init.d/syslog stop
# /etc/rc.d/init.d/syslog start
再起動できたら、/chroot/named/dev
に
以下のような log
という「ファイル」ができているはずです。
srw-rw-rw- 1 root root 0 Mar 13 20:58 log
古い syslogd
を使っている場合は、
ログを取るには別の方法を見つけなければなりません。
例えば hoellogd
のような、
「プロキシ」として動作するよう設計されているプログラムも存在します。
これは chroot された BIND からログエントリを受け取り、
それを通常の /dev/log
ソケットに渡します。
あるいは、BIND を設定して、ログを syslog に送るのではなく ファイルに書きこむようにもできます。 この方法を選ぶなら、BIND の文書にあたって詳細を調べてください。