Chroot-BIND HOWTO Scott Wunsch, scott at wunsch.org v1.5, 1 December 2001 中野武雄 nakano at apm.seikei.ac.jp v1.5j1, 3 January 2002 この文書は BIND 8 のネームサーバを "chroot jail" の内部で、非 root ユ ーザとして実行させるようなインストールのやり方を説明します。これによっ てセキュリティが強化され、またセキュリティが破られたときも影響を最小限 にできます。なお、この文書は BIND 9 向けに更新されました。まだ BIND 8 を使っている人は、代わりに Chroot-BIND8 HOWTO を読んでください。 ______________________________________________________________________ 目次 1. はじめに 1.1 What? 1.2 Why? 1.3 Where? 1.4 How? 1.5 おことわり 2. jail の用意 2.1 ユーザの作成 2.2 ディレクトリ構造 2.3 BIND のデータを配置する 2.4 システムのサポートファイル 2.5 ログ記録 2.5.1 理想的な解 2.5.2 別の解 2.6 パーミッションを厳しくする 3. ピカピカの BIND を新規にコンパイル・インストールする 3.1 コンパイルする 4. BIND をインストールする 4.1 バイナリをインストールする 4.2 init スクリプトを編集する。 4.3 設定を変更する 5. ジ・エンド 5.1 BIND の起動 5.2 以上! 6. 付録 - 後に BIND をアップグレードするには 7. 付録 - 謝辞 8. 付録 - 文書の配布ポリシー ______________________________________________________________________ 1. はじめに この文書は Chroot-BIND HOWTO です。最新版の置かれているマスターサイト は ``Where?'' を見てください。読者は BIND (the Berkeley Internet Name Domain) の設定方法・利用方法を既に知っているとして話を進めます。知らな い人は、まず DNS HOWTO を読むと良いでしょう。またお使いの UNIX 系シス テムにおけるコンパイル・インストールについては、読者は習熟しているもの とします。 1.1. What? この文書は、BIND のインストール時に取ることのできる、付加的なセキュリ ティ対策について説明します。まず、BIND を ``chroot jail'' の内部で動作 させるよう設定する方法について説明します。すなわち、BIND は閉じ込めら れた小さなディレクトリツリーの外部にあるファイルを見ることができなくな るのです。また、BIND を非 root ユーザで実行させるような設定も行いま す。 chroot の背後にある考え方は、とても単純です。 BIND (あるいは他のプロセ ス) を chroot jail の内部で実行すると、そのプロセスはファイルシステム のうち jail の内部しか見ることができなくなるのです。例えば、この文書で は、BIND を /chroot/named ディレクトリに chroot した状態で実行します。 BIND にとっては、このディレクトリの中身が / のように見えるのです。この ディレクトリの外部には一切アクセスできません。公開システムに ftp でロ グインしたことのある人は、おそらく既にこの chroot jail に出会ったこと があると思います。 chroot の処理は BIND 9 ではずっと簡単になったので、この文書をちょっと ずつ拡張することにして、 BIND のインストールにおける、もっと一般的なコ ツなども含めるようにしました。でも、この文書は BIND を安全にするための 完全なるガイドではありません (し、そうするつもりもありません)。この文 書に書かれていることを行っただけでは、まだネームサーバを安全にできたわ けではないのですよ! 1.2. Why? なぜ BIND を chroot jail の内部で動作させると良いのでしょうか。それ は、仮に悪い奴が BIND の穴を使ってアクセスを得たとしても、そのアクセス できる範囲を最小限に制限できるからです。 BIND を非 root ユーザ権限で動 作させるのも同じ理由からです。 これは通常言われているセキュリティ対策 (最新版を使う、アクセス制限をす る、など) の、いわば「おまけ」とみなすべきで、もちろんこれを代替するも のと考えてはいけません。 読者が DNS のセキュリティに興味をお持ちなら、他の製品を調べてみるのも 良いかもしれません。 BIND を StackGuard と共に構築すれば、 きっと安全性をより向上させてくれるでしょう。使い方は簡単です。普通の gcc と同じです。また Dan Bernstein の書いた DNScache は、BIND の代わりに利用できる安全なソ フトウェアです。【訳注: djbdns に改名し たようです】 Dan は qmail の著者でもあります。 1.3. Where? この文書の最新版は、常に Linux/Open Source Users of Regina, Sask. の web サイトより入手できます。 です。 現在はこの文書の日本語版もあり、中野武雄 nakano at apm.seikei.ac.jp が 管理しています。これは から入手できます。 BIND は the Internet Software Consortium から入手できます。この文書の執筆時点で の最新版は 9.2.0 です。 BIND 9 が使えるようになってからだいぶたち、実 際の業務に使っている人も多いようです。しかし、より保守的な人たちは、ま だ BIND 8 を使う方を好んでいるようです。もし読者が後者に属するならば、 chroot の詳細については Chroot-BIND8 HOWTO (同じ場所にあります) の方を 読んでください。でも、BIND 8 のほうが chroot をするにはずっと面倒であ ることもお忘れなく。 古いバージョンの BIND の多くには、既知のセキュリティホールがあります。 必ず最新版を使うように、気をつけてください! 1.4. How? 私はこの文書を、自分自身で chroot 環境な BIND をセットアップした経験に 基づいて書きました。私の場合は、既に BIND を (自分の Linux ディストリ ビューションの) パッケージ形式でインストールしてありました。おそらく読 者のほとんども同じでしょう。ですので、ここでは既にインストール済みの BIND から設定ファイルを移動して修正し、パッケージは削除して、新しいの をインストールすることにします。でもまだパッケージは削除しないでくださ いね。まずそこからいくつかファイルが必要になりますから。 まだ BIND をインストールしていない人でも、この文書の方法を利用すること はできます。違いは、私が既存のファイルをコピーしてくるよう指示した部分 で、そのファイルをゼロから書き起こす必要がある、というだけです。この際 には DNS HOWTO が役に立つでしょう。 1.5. おことわり これらの記述は私のシステムでは動作しましたが、読者のところでの結果は異 なるかもしれません。これは 1 つのアプローチに過ぎず、同様の設定を行う にはいろいろな方法が有り得ます (一般的なアプローチはだいたい同じになる でしょうが)。これは、私が試みた中で最初に動作したやり方だったので、こ こに書き記したにすぎません。 私の現在までに至る BIND の経験では、 Linux サーバにしかインストールを 行っていません。しかし、この文書の説明の大半は、他の種類の UNIX にも容 易に適用できるはずです。私の気付いた違いについては、できるだけ記述する つもりです。また、他のディストリビューションや他のプラットフォームを 使っている人たちからいくつか指摘を受けていますので、それらもできるだけ 含めるようにしました。 Linux を使っている人は、これらを試す前に、使っているのが 2.4 カーネル であるかどうか確認する必要があります。 -u スイッチ (非 root ユーザで動 作させる) には、この新しいカーネルが必要です。 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 からは使えません。でもありがたいことに、これを解決す る方法はいくつか存在します。 2.5.1. 理想的な解 このジレンマに対する理想的な解決法には、 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 2.5.2. 別の解 古い 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 ビットを立ててもよいでしょう (例えばプライマリゾーンファイルを変更されたくない場合など)。 3. ピカピカの BIND を新規にコンパイル・インストールする 3.1. コンパイルする chroot jail で用いる BIND 9 のコンパイルは、 BIND 8 のときよりもずっと 快適な作業となるでしょう。実のところ、しなければならないことは特に何も なく、標準的な ./configure && make だけで良いのです。 ただし IPv6 をサポートした BIND を Linux システムで作りたい場合 (--enable-ipv6) は、カーネルと glibc のバージョンを合わせなければなり ません。カーネル 2.2 なら glibc 2.1 が必要です。カーネル 2.4 なら glibc 2.2 が必要です。 BIND はこの点については非常にうるさいです。 4. BIND をインストールする もしすでに (例えば RPM などから) インストールされている BIND がある場 合は、新しいのをインストールする前にそれを削除する必要があると思いま す。 Red Hat システムでは bind と bind-util のパッケージ、そして bind- devel と caching-nameserver なども、存在していたら削除する必要があるで しょう。 もし init スクリプト (すなわち /etc/rc.d/init.d/named) があった場合 は、パッケージの削除の前に、このファイルをコピーして保存しておくほうが いいでしょう。きっとあとで役に立ちます。 BIND 8 のような、古いバージョンの BIND からアップグレードする場合は、 BIND のソースパッケージの doc/misc/migration にある、移行のための文書 を読んでおくほうがいいでしょう。移行に関する内容は、この文書では扱いま せん。単に現在動作している BIND 9 のインストールを置き換えようとしてい る、というのが本文書での想定対象です。 4.1. バイナリをインストールする これは簡単です :-) make install を実行して、おまかせするだけです。い や、本当にこれだけなんですよ! 4.2. init スクリプトを編集する。 ディストリビューションに含まれている init スクリプトがあれば、新しいバ イナリを適切なスイッチで起動するように、そいつを変更するのが最も簡単で しょう。スイッチは... (ここでドラムロール...) o -u named, これは BIND をユーザ root ではなく named で実行します。 o -t /chroot/named, これにより BIND は自分自身を (先に用意した) jail に chroot します。 o -c /etc/named.conf, これは BIND に、 jail の内部における設定ファイ ルのありかを教えます。 以下の init スクリプトは、著者が自分の Red Hat 6.0 システムで使ってい るものです。おわかりのとおり、ほとんどは Red Hat のものと変わりありま せん。わたしは rndc コマンドはまだ試していませんが、これが動かない理由 はないはずです。 ______________________________________________________________________ #!/bin/sh # # named This shell script takes care of starting and stopping # named (BIND DNS server). # # chkconfig: 345 55 45 # description: named (BIND) is a Domain Name Server (DNS) \ # that is used to resolve host names to IP addresses. # probe: true # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ ${NETWORKING} = "no" ] && exit 0 [ -f /usr/local/sbin/named ] || exit 0 [ -f /chroot/named/etc/named.conf ] || exit 0 # See how we were called. case "$1" in start) # Start daemons. echo -n "Starting named: " daemon /usr/local/sbin/named -u named -t /chroot/named -c /etc/named.conf echo touch /var/lock/subsys/named ;; stop) # Stop daemons. echo -n "Shutting down named: " killproc named rm -f /var/lock/subsys/named echo ;; status) status named exit $? ;; restart) $0 stop $0 start exit $? ;; reload) /usr/local/sbin/rndc reload exit $? ;; probe) # named knows how to reload intelligently; we don't want linuxconf # to offer to restart every time /usr/local/sbin/rndc reload >/dev/null 2>&1 || echo start exit 0 ;; *) echo "Usage: named {start|stop|status|restart|reload}" exit 1 esac exit 0 ______________________________________________________________________ syslogd での場合と同じく、現在の Red Hat 7.2 では、この過程はさらに簡 単になっています。 /etc/sysconfig/named というファイルがあり、ここで named に与える追加パラメータを定義できます。ただし Red Hat 7.2 でのデ フォルトの /etc/rc.d/init.d/named では、起動前に /etc/named.conf があ るかをチェックします。このパスは変更しなければなりません。 Caldera OpenLinux システムでは、先頭付近で定義されている変数を修正し、 以下のようにすれば OK です。 NAME=named DAEMON=/usr/local/sbin/$NAME OPTIONS="-t /chroot/named -u named -c /etc/named.conf" そして FreeBSD 4.3 では、rc.conf ファイルを編集して、次の行を追加しま す。 named_enable="YES" named_program="chroot/named/bin/named" named_flags="-u named -t /chroot/named -c /etc/namedb/named.conf" 4.3. 設定を変更する named.conf にもいくつか追加・修正を行い、いろいろなディレクトリが正し く動作するようにする必要があります。特に、以下を option セクションに追 加 (あるいはすでにあれば修正) しなければなりません。 directory "/etc/namedb"; pid-file "/var/run/named.pid"; statistics-file "/var/run/named.stats"; これらのファイルは named デーモンが読むことになるので、もちろんパスは すべて chroot jail 内部での相対位置になります。執筆の時点では、BIND 9 は前のバージョンでサポートされていた統計情報やダンプファイルの多くを未 だサポートしていません。おそらく今後はサポートされていくと思います。読 者のお使いのものがこのようなバージョンである場合は、 BIND がそれらを /var/run ディレクトリに書けるように、いくつかエントリを同じように追加 する必要があるでしょう。 5. ジ・エンド 5.1. BIND の起動 これですべての設定が終了しました。新しい、より安全な BIND を実行に移せ る時が来たわけです。 SysV 形式の init スクリプトを用いているなら、次の ように実行するだけです。 # /etc/rc.d/init.d/named start 実行前に古いバージョンの BIND が実行中だったら kill するのを忘れないよ うに。 5.2. 以上! これで安心して眠ることができますね ;-) 6. 付録 - 後に BIND をアップグレードするには さて、やっと BIND 9.1.2 がうまく chroot して、望みのとおりにチューンで きました... そうしたら、BIND 9.1.3 がリリースされ、直ちにこちらをため すべき、との腹立たしい噂が流れてきました。この新しいバージョンでも、こ こまで述べてきた長い手続き全体を繰り返さなければならないのでしょうか? いいえ。実際に必要なのは、新しいバージョンの BIND をコンパイルして、古 いものに上書きインストールするだけです。ただしその後古い版を kill し て、BIND を再起動すること。さもないと古いバージョンがそのまま実行し続 けていますから! 7. 付録 - 謝辞 この HOWTO の作成の助けとなってくださった、以下の方々に感謝します。 o Lonny Selinger は、この HOWTO の最初の版を 「テスト」してくださり、必要な手続きを飛ばしていないことを筆者に確 信させてくれました。 o Chirik , Dwayne Litzenberger , Phil Bambridge , Robert Cole , Colin MacDonald ほか、多くの皆さんがこの文書の間違い、欠落を指摘していた だき、またこの HOWOTO をより良くするための有益なアドバイスをくださ いました。 o Erik Wallin と Brian Cervenka は、jail をさらに強固にするための、優れた提案を送っ てくれました。 o Robert Dalton は、コマンド例を追加案を 提案してくださり、また BIND 9.2.0 では /dev/random が必要となること を指摘してくれました。 o Eric McCormick は FreeBSD 4.3 の情報 を送ってくれました。 o Tan Zheng Da は、作業を少々楽にしてくれる、 Red Hat 7.2 でなされた変更の詳細を教えてくれました。 そして最後に、 Chroot-BIND HOWTO を日本語に翻訳してくれた Nakano Takeo に感謝します。この翻訳は にあります。 【訳注: 翻訳にあたっては、堀田倫英さんと高橋全さんに有益なコメントをい ただきました。】 8. 付録 - 文書の配布ポリシー Copyright (C) Scott Wunsch, 2000-2001. This document may be distributed only subject to the terms set forth in the LDP licence at . This HOWTO is free documentation; you can redistribute it and/or modify it under the terms of the LDP licence. It is distributed in the hope that it will be useful, but without any warranty; without even the impled warranty of merchantability or fitness for a particular purpose. See the LDP licence for more details. 【訳注: 原文が優先されますが、参照のために翻訳を示します。 Copyright (C) Scott Wunsch, 2000-2001. この文書は にある LDP ライセンスに従 えば配布できます。 この HOWTO はフリー文書です。 LDP ライセンスの下で再配布・改変が可能で す。この文書は有益であらんことを願って配布されていますが、保証は一切あ りません。暗黙のものも含め、商用に役立つ保証もありませんし、特定の用途 に合致するかどうかもわかりません。詳細は LDP ライセンスを見てくださ い。 なお翻訳版も LDP ライセンスの下で再配布・改変可能とします。 Copyright (C) NAKANO Takeo, 2001.】