named が乗っ取られた場合の用心に、named を chroot 環境 (chroot jail [牢獄] とも呼ばれる) で動かす。 named から見ると、chroot 先のディレクトリがルートディレクトリ "/" に見え、それより上の階層にアクセスすることはできなくなる。 BIND は chroot の仕組みを自前で備えており、 named の起動時に "-t chroot-dir " を指定すれば、自分で自分を牢屋に入れる。持ち物は、一部を除いてこちらであらかじめ牢屋の中に移し、生活に必要な環境を整えてやらなければならない。とはいえ、 chroot メカニズムを内蔵していないプログラムを jail するよりはずっと単純だ。
※ Fedora Core 3 付属の named の man を読むと 「BIND を安全に動かしたいなら chroot はもう古い。 chroot はやめて SELinux 下で動かせ」 との旨。 BIND を SELinux で保護した場合、標準の規制状態はかなり厳しくなっているらしく、幾つかの制限が発生するとのこと。ただ、本稿のような単独のキャッシュサーバなら通常のように `fixfiles relabel' でファイルのセキュリティコンテキストを更新するだけで一応は行けそうだ。
chroot ディレクトリは /named などを作る手もあるが、ここでは /var/named を chroot ディレクトリとする。 chroot しない通常の設定とは異なり、 /var/named/var/ ディレクトリは named 専用となるので、さらにその下に named ディレクトリを作らなくてもログや PID の書き出しに問題はないのだが、設定ファイルの違いを最小限に抑えるために、元のディレクトリ構造を踏襲することにする。
※ Fedora Core 3 では、BIND の chroot ディレクトリ構造を作成するためだけに bind-chroot というパッケージが存在する。 bind-chroot パッケージをインストールすると chroot ディレクトリは /var/named/chroot となり、基本的な必要ディレクトリがその下に自動的に作られ、各種設定ファイルも勝手にコピーされるようだ。
/var/named に chroot すると仮定する。
/var/named/ named.named 700 chroot時のルート etc/ named.named 700 named.conf named.named 600 内容変更無し named.key named.named 600 内容変更無し localtime named.named 644 タイムゾーン定義 var/ named.named 700 named/ named.named 700 named.ca named.named 600 内容変更無し localhost.zone named.named 600 内容変更無し localhost.rev named.named 600 内容変更無し hoge.rev named.named 600 内容変更無し log/ named.named 700 named/ named.named 700 named_custom.log named.named 644 touchするかコピー named.log named.named 644 syslog.conf を的確に設定すれば勝手にできる run/ named.named 700 named/ named.named 700 named.pid named.named 644 勝手にできる dev/ named.named 700 null root.root 666 キャラクタデバイス random root.root 666 キャラクタデバイス log root.root 666 syslogへのソケット /etc/ rndc.conf root.root 600 移動せず rndc.key root.root 600 移動せず sysconfig/named root.root 644 小変更 sysconfig/syslog root.root 644 小変更
named を一旦ストップし、必要なディレクトリを整備して、「内容変更無し」のファイルを移動。その他のファイルは以下に説明。
chroot 環境に移行すると、/dev/ にあるデバイスファイルにもアクセスできなくなるので、mknod コマンドで獄中に新たに作ってやる。必要なのは
null と random。
null の作成行程を挙げておく:
root# file /dev/null # もともとの null のファイルタイプを調べる /dev/null: character special (1/3) # キャラクターのメジャー1/マイナー3 と分かる root# mknod -m 666 /var/named/dev/null c 1 3 # 上の結果を踏まえてデバイス作成
こうすればメジャーナンバー/マイナーナンバーを暗記しておく必要もなく確実。 random も同様に作る。
本当のところ、デバイスファイルなんかではないのだが段落構成上ここで...。 localtime はタイムゾーンを記述したバイナリファイルで、named が日付時刻関数を使用した場合に正しい出力を得るのに必要。単純にコピーしてくるだけ:
root# cp /etc/localtime /var/named/etc root# chown named.named /var/named/etc/localtime
本来なら起動スクリプトを編集して "-t /var/named" を追記するところだが、 RedHat系では /etc/sysconfig/named を1箇所いじるだけで終わり。下記の部分。
ROOTDIR="/var/named"
-t さえ要らない。 /etc/init.d/named スクリプトは、ここから $ROOTDIR を変数として読み取り、PID ファイルの書き出し場所や named.conf の検索パスも自動的に /var/named を基準とした場所にシフトしてくれる。
chroot すると syslogd との通信路も絶たれてしまうので処置が必要だ。 syslogd には chroot を見越した仕組みが用意されており、 syslogd を "-a sock_path " (Solaris では -p らしい)オプション付きで起動すれば、追加のソケットを開くようになる。 named の起動オプションと同じように、RedHat系では /etc/sysconfig/syslog を編集するだけ。
SYSLOGD_OPTIONS="....
の記述に、
-a /var/named/dev/log
を加える。既に -a が他で使われていたら `-a sock -a sock ...' のように指定。標準的な Linux カーネルでは 19 個まで OK らしい。あとは "service syslog restart" するかマシンを再起動すれば、 /var/named/dev/log ソケットができているはず。
これにてchroot jail 完了。