DNS (BIND9) を chroot 環境で起動

1台目の Raspberry Pi に BIND9 を chroot で設定してみる。
今回は、ちょっとだけ debian 的なものから外れている…というか、運用中のものは扱わないので参考にならないかも。


あと、参考にされるなら、今回の DNS がネットワーク的にインターネットから問い合わせが届かないローカルな場所へ設置しているということを意識して頂けると幸い。


この DNS を構築したのは、下記図の Raspberry Pi 初号機。


使用ネットワーク帯域は 192.168.1.0/24 にしている。

やったこと

BIND9 を chroot 環境で初期構築。
rndc コマンドは有効化。


最低限、稼働に必要と思われるゾーンだけなので、ローカル環境で使うドメインは別途追加してほしい。
…といっても、named.conf に管理するゾーンを書いて、localhost ゾーンでもテンプレート代わりにコピーすれば、動くだけは動く。

環境設定

まずは、必須ディレクトリの作成と権限設定。
基本的に root 権限が必要なので、最初から最後まで root で作業。
動くようになったら sudo で操作すれば良いと、潔く割り切り。

$ su -
# apt-get install -y bind9
# service bind9 stop
# mkdir -p /var/chroot/bind9/{etc/bind/files,dev,usr/lib,var/{dump,log,run},var/run/named}
# cd /var/chroot/
# chown -R root:bind bind9
# cd bind9
# chmod 775 {var,var/{{dump,log},run/named}}


次に、環境的に必須なファイルの作成とか修正とか。

# cd dev/
# mknod -m 666 full c 1 7
# mknod -m 666 null c 1 3
# mknod -m 666 random c 1 8
# mknod -m 666 urandom c 1 9
# mknod -m 666 zero c 1 5
# cd /var/chroot/bind9/etc/bind
# cp -a /etc/localtime .


次に自動起動関係の修正。

# sed -i s%"PIDFILE=.*"%"PIDFILE=/var/chroot/bind9/var/run/named/named.pid"% /etc/init.d/bind9
# grep ^PID /etc/init.d/bind9
PIDFILE=/var/chroot/bind9/var/run/named/named.pid
# sed -i s%"OPTIONS=.*"%"OPTIONS=\"-u bind -t /var/chroot/bind9/\""% /etc/default/bind9
# grep ^OPT /etc/default/bind9
OPTIONS="-u bind -t /var/chroot/bind9"


ここまでは、参照先の手順とほぼ同じ。
(微妙にディレクトリ構成が違ったりするけど、それは自分で変えた部分)


ただし、デフォルトの bind9 設定ファイルを、なーんにもコピーしてない。
なので起動すら出来ないため、イチから作る。
作るのは、binde9 の挙動と、管理するゾーン。


…の前に、rndc キーを生成しておく。

# mv /etc/bind/rndc.key /etc/bind/rndc.key.backup
# rndc-confgen > /etc/bind/rndc.conf
# cat /etc/bind/rndc.conf
# Start of rndc.conf
key "rndc-key" {
	algorithm hmac-md5;
	secret "xxxxxxxxxxxxxxxxxxxxxxx=";
};

options {
	default-key "rndc-key";
	default-server 127.0.0.1;
	default-port 953;
};
# End of rndc.conf

# Use with the following in named.conf, adjusting the allow list as needed:
# key "rndc-key" {
# 	algorithm hmac-md5;
# 	secret "xxxxxxxxxxxxxxxxxxxxxxx=";
# };
#
# controls {
# 	inet 127.0.0.1 port 953
# 		allow { 127.0.0.1; } keys { "rndc-key"; };
# };
# End of named.conf


ファイル中にある 【# End of rndc.conf】以下のコメントアウト部分は named.conf の中に書いておく内容が出力されている。
なので、named.conf にはコメントアウトを外して記載する。



ということで、ようやく named.conf へ取り掛かる。

# cd /var/chroot/bind9/etc/bind
# vi named.conf
// home network dns

acl "homenetwork" {
	127.0.0.1;
        192.168.1.0/24;
};
acl "bogon" {
	0.0.0.0/8;
	169.254.0.0/16;
	192.0.2.0/24;
	10.0.0.0/8;
	172.16.0.0/12;
	192.168.0.0/24;
	192.168.2.0/23;
	192.168.4.0/22;
	192.168.8.0/21;
	192.168.16.0/20;
	192.168.32.0/19;
	192.168.64.0/18;
	192.168.128.0/17;
	224.0.0.0/3;
};
options {
	directory "/etc/bind";
	allow-transfer { none; };
	listen-on port 53 { homenetwork; };
	dump-file "/var/dump/cache.dump.db";
	statistics-file "/var/dump/named_stats.db";
	blackhole { bogon; };
	recursion yes;
	version "unknown";
};

// /etc/bind/rndc.conf のコメントアウト部分を記述
key "rndc-key" {
	algorithm hmac-md5;
	secret "xxxxxxxxxxxxxxxxxxxxxxx=";
};

controls {
	inet 127.0.0.1 port 953
		allow { 127.0.0.1; } keys { "rndc-key"; };
};

// local contents
zone "." {type hint; file "files/named.root"; };
zone "localhost" {type master; file "files/localhost.zone"; };
zone "127.in-addr.arpa" {type master; file "files/127.in-addr.arpa"; };

// Contents
zone "example.jp" { type master; file "files/example.jp.zone"; };
zone "1.168.192.in-addr.arpa" {type master; file "files/1.168.192.in-addr.arpa"; };


とりあえず、ベースとなるファイルであれば、こんなところ?
bogon の内容は、自宅のネットワーク環境に合わせて修正する必要があるかも。


で、ゾーンの転送はしないし、応答もローカルだけ。
再帰検索は許可するけど、バージョン情報は秘匿。
bind のログ出力設定 (logging ディレクティブ)は、長くなるので省いた。
いまのところ rndc 設定も省いてある。


ここから、named.conf に書いた管理ゾーンに対応するファイルを作っていく。

# cd files
# wget http://www.internic.net/domain/named.root
# cp /etc/bind/db.local localhost.zone
# cp /etc/bind/db.127 127.in-addr.arpa
# cp localhost.zone example.jp.zone
# cp 127.in-addr.arpa 1.168.192.in-addr.arpa
# cd ../
# chown -R root:bind files

キャッシュDNSとコンテンツDNSの兼用は、普通、良くない。
良くない理由はいろいろあるんだけど、ローカルでしか利用できないように設定してあるので許してほしい。

# named-checkconf -t /var/chroot/bind9
# service bind9 start


シスログを確認

# grep named /var/log/syslog

ここで Warning とか、よくわからないメッセージが出るはず。

Warning: 'empty-zones-enable/disable-empty-zone' not set: disabling RFC 1918 empty zones
automatic empty zone: 254.169.IN-ADDR.ARPA
automatic empty zone: 2.0.192.IN-ADDR.ARPA
automatic empty zone: 100.51.198.IN-ADDR.ARPA
automatic empty zone: 113.0.203.IN-ADDR.ARPA
automatic empty zone: 255.255.255.255.IN-ADDR.ARPA
automatic empty zone: 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA
automatic empty zone: 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA
automatic empty zone: D.F.IP6.ARPA
automatic empty zone: 8.E.F.IP6.ARPA
automatic empty zone: 9.E.F.IP6.ARPA
automatic empty zone: A.E.F.IP6.ARPA
automatic empty zone: B.E.F.IP6.ARPA
automatic empty zone: 8.B.D.0.1.0.0.2.IP6.ARPA


「必要なゾーンなんだから作らなきゃダメじゃない、も〜。今回はこっちで見ておくけど、きちんとしてよね」
なんて声が聞こえてきた気がした。
ファイルは作って貰えないけど、該当する名前を問い合わせても「そんなこと聞かれたって、知らない!」という内容が応答される。


余力があれば、作るべし。
ゾーンファイルの書き方が学べるはず。
本来的に言えば、インターネットに垂れ流されては困るゾーンなので BIND 側で対処されているモノ。
欲を言えば、管理してない場合には 10.in-addr.arpa とか 168.172.in-addr.arpa ゾーンとかも作るべき。


ちなみに、名前の逆引き*1は in-addr.arpa (IPv4) と ip6.arpa (IPv6) で管理する。
つまり 0 がたくさんたくさん並んでいるゾーンは、IPv6localhost を設定している。
localhost の AAAA レコードは ::1 だけど、PTR レコードは数字の分だけ . が必要と。


それで rndc コマンドをテスト

# rndc status
# cd /var/chroot/bind9/var/dump
# ls -l
# rndc dumpdb
# less cache.dump.db
# rndc stats
# less named_stats.db


最後にチェックして、デフォルトデータを削除。

# cd /etc/bind
# mkdir backup
# mv rndc.key* bind* db.* named.conf* zones* backup
# named-checkconf -t /var/chroot/bind9
# rndc stop
# ps -ef | grep bind9
# service bind9 start
# rm -r backup


いやぁ…構造は簡単だけど、記述内容が半端なく多い…



ちなみに、最初からやり直したいときはパッケージとかディレクトリを削除する必要あり。

# cd /var/chroot
# apt-get purge bind9
# rm -r bind9
# apt-get clean
# apt-get autoclean


自宅サーバを構築したのなら、あなたもおひとついかが?

*1:正引きは ドメイン名からIPアドレス、逆引きはIPアドレスからドメイン