次のページ 前のページ 目次へ

2. jail の用意

2.1 ユーザの作成

「はじめに」で述べたように、 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 にしてあります。

2.2 ディレクトリ構造

次に、chroot jail に使用するディレクトリ構造を作ってあげる必要があります。 ここが BIND の生活の場となるわけです。 これはファイルシステムのどこでも構いません。 非常に神経質な人は、独立したボリューム (パーティション) に置きたいとさえ思うかもしれませんね。 ここでは /chroot/named を使います。 まず以下のようなディレクトリ構造を作ってください。

/chroot
  +-- named
       +-- dev
       +-- etc
       |    +-- namedb
       |         +-- slave
       +-- var
            +-- run

(Linux システムなどで) GNU の mkdir を使っている人は、 次のようにすればこのディレクトリ構造が作れます。

# mkdir -p /chroot/named
# cd /chroot/named
# mkdir -p dev etc/namedb/slave var/run

2.3 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/

BIND は通常 namedb ディレクトリへの書きこみ権限を必要とします。 しかしセキュリティを厳しくするために、これは許さないことにしましょう。 お使いの DNS があるゾーンをスレーブでサービスする場合は、 BIND はそのゾーンファイルを更新できなければなりません。 すなわちこれらのファイルには別のディレクトリに保存させるようにして、 そこに BIND からの書き込みアクセスを許すかたちにします。

# chown -R named:named /chroot/named/etc/namedb/slave

ここで、スレーブゾーンは全部このディレクトリに移動するのを忘れないこと。 また、それに応じて named.conf の変更も必要になります。

BIND は /var/run ディレクトリへも書きこみ権限を必要とします。 pid ファイルと統計情報をここに作るからです。 次のコマンドでこれを可能にしてやりましょう。

# chown named:named /chroot/named/var/run

2.4 システムのサポートファイル

BIND が chroot jail 内部での実行を始めると、 jail 外部のファイルへは一切アクセスできなくなります。 しかし、いくつかの重要なファイルには実行後もアクセスできなければ なりません。ただし BIND 8 に比べるとだいぶ少ないですが。

BIND が jail の内部に必要とするファイルのひとつに、 いつものあれ、/dev/null があります。 ここで、このデバイスノードを作るために必要なコマンドは システムによって異なることがあります。 /dev/MAKEDEV スクリプトを調べて確認してください。 システムによっては /dev/zero が必要なこともあります。 BIND 9.2.0 リリース予定版では、 /dev/random が必要だという報告もあります。 ほとんどの Linux システムでは、以下のコマンドが使えます。

# mknod /chroot/named/dev/null c 1 3
# mknod /chroot/named/dev/random c 1 8
# chmod 666 /chroot/named/dev/{null,random}

FreeBSD 4.3 では次のようになります。

# mknod /chroot/named/dev/null c 2 2
# mknod /chroot/named/dev/random c 2 3
# chmod 666 /chroot/named/dev/{null,random}

他にも jail 内部の /etc ディレクトリに必要なファイルがあります。 BIND に正しい時刻でログ記録をさせるには、 /etc/localtime (システムによっては /usr/lib/zoneinfo/localtime かもしれません) をここにコピーする必要があります。 以下のコマンドがこの面倒を見てくれます。

# cp /etc/localtime /chroot/named/etc/

2.5 ログ記録

本物の囚人とは異なり、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
と変更しました。

面白いことに Red Hat 7.2 では、 見たところ Red Hat はこの処理をもっと簡単にしています。 現在は /etc/sysconfig/syslog というファイルがあり、 ここには syslogd に余分に与えるパラメータを定義できるのです。

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 です。

そして最後に (といっても重要性の順ではないですよ) FreeBSD 4.3 では、 rc.conf ファイルを編集して次の行を追加すればよいそうです。

syslogd_flags="-s -l /chroot/named/dev/log"
-s はセキュリティ上の問題から与えるもので、 デフォルトの設定の一部です。 -l は、別のログノードが置かれているローカルなパス名です。

【訳注: 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 の文書にあたって詳細を調べてください。

2.6 パーミッションを厳しくする

まず最初に、/chroot ディレクトリ全体へのアクセスを、 ばっさり root ユーザのみに限ってしまいましょう。 もちろん、こうしたい人ばかりではないでしょう。 特に他のソフトウェアをこのツリー以下にインストールしていて、 この変更がそのソフトには適切でないような場合にはそうですね。

# chown root /chroot
# chmod 700 /chroot

同じく /chroot/named へのアクセスは、 named ユーザにのみ限ってしまって大丈夫です。

# chown named:named /chroot/named
# chmod 700 /chroot/named

もっと厳しくしたい場合は、 Linux システムなら ext2 ファイルシステムにあるファイルやディレクトリの属性を、 chattr というツールで immutable (不変) にすることもできます。

# cd /chroot/named
# chattr +i etc etc/localtime var

同様に FreeBSD 4.3 でこれらを immutable にしたいなら、 chflags を調べてみましょう。 例えば次のようにすれば、/chroot/named/etc ディレクトリ以下のすべてを immutable にできます。

# chflags schg /chroot/named/etc/*(*).

これらを dev ディレクトリにも施せれば良いのでしょうが、 残念ながらこうすると syslogd がここに dev/log ソケットを作れなくなってしまいます。 jail の内部にある他のファイルに immutable ビットを立ててもよいでしょう (例えばプライマリゾーンファイルを変更されたくない場合など)。


次のページ 前のページ 目次へ