BIND hintファイル(ルートヒントファイル)の更新
hintファイルとは
DNSは名前解決をするときに、上位のDNSサーバから問い合わせてしていく仕組みを持っている。
このとき、一番最初に問い合わせる最上位にあるDNSサーバのことを、ルートDNSサーバと呼び、現在は13組存在する。
問い合わせの仕組み上、最初に問い合わせるべき最上位のDNSサーバをあらかじめ知っておかなければ、下のDNSサーバへ問い合わせること
ができない。
そこで、現在のDNSサーバでは、あらかじめこの13組のルートDNSサーバの情報を事前に登録していて、登録されたファイルのことをhintファイル
(ルートヒントファイル)と呼んでいる。
hintファイルの更新とは
hintファイルには、.(ルート)を管理する13組のルートDNSサーバのホスト名とそのIPv4アドレス、IPv6アドレスが記載されている。
これらの情報は普遍的なものではなく、世の中のいろいろな都合によって変更されることがある。
2013年1月においては、13組のルートDNSサーバのうち、d.root-servers.netのIPv4アドレスが変更になったため、このhintファイルを更新する必要
がでてきた。
「hintファイルがない」というお宅もある
そもそもhintファイルが必要な理由は、「他のDNSサーバに問い合わせるためにルートサーバ情報が必要だから」である。
つまり、他のDNSサーバに問い合わせる必要のあるDNSサーバ(キャッシュDNSサーバ)では、hintファイルは必須の情報であるが、自分の管理して
いるゾーン情報だけを返せばよいDNSサーバ(権威DNSサーバ)は不要である。
(ただし、ログにホスト名を記録したり、ドメインでフィルタリングをしているなどで、サーバとして名前解決する必要がある場合は、/etc/resolv.confで
別のDNSサーバに問い合わせができるようにする)
そのため、権威DNSサーバのセキュリティを高めるために、hintファイルがないというDNSサーバもある。
また、フォワーダ機能で別のDNSサーバに名前解決をしているDNSサーバについても、hintファイルは不要である。
しかし、BINDではhintファイルを読み込ませなくてもルートDNSに問い合わせがいってしまう(下記1参照)ので、正確には、中身が空っぽのhintファイルを
用意して読み込ませて他のDNSサーバに問い合わせができないようにしている。
hintファイルを更新する必要があるのか?
BIND 9.8.4-P1で確認したところ、
1. hintファイルを読み込ませなくても起動するし、名前解決もできる。
  named.confで .(ルート)のzoneをコメントアウトしてnamedを再起動し、ルートのゾーン情報を読み込ませないようにした。
  その直後に、 dig @localhost www.yahoo.co.jp を実行したところ、名前解決ができた。
  tcpdumpでキャプチャしても、いきなりルートサーバに問い合わせをしている。
  ということは、内部的にあらかじめルートサーバの情報が埋め込まれているのかもしれない・・・
2. hintファイルを読み込ませても、その内容はキャッシュしない。 よって回答として返さない。
  namedを再起動した直後に、dig @localhost . ns +norecを実行。
  しかし、回答がない。
  rndc dumpdbをしてもキャッシュをしていない。
3. 最初にルートサーバに問い合わせたときに、回答されたルート情報をキャッシュする。
  2の後で、dig @localhost www.yahoo.co.jp を実行。
  その後で、dig @localhost . ns +norec を実行したところ、ルートサーバの情報を返した。
  rndc dumpdb をしたらキャッシュをしていた。
  また、DルートサーバのAレコードを確認したところ、hintファイルにある古い方ではなく、新しい方のIPv4アドレスをキャッシュしていた。
4. hintファイルの中身を1つのルートサーバだけにすると、必ず最初はそこに問い合わせる。
   a.root-servers.netの行だけにしたhintファイルを読み込ませたところ、再起動後に最初に問い合わせに行くのは必ずa.root-servers.netだった。
5. 誤ったhintファイルを読み込ませると、指定したほうに問い合わせた。
   4において、a.root-servers.netのアドレスを存在しないものに書き換えたところ、そちらに問い合わせに行って名前解決に失敗した。(SERVFAIL)
  また、アドレスを宅内のルータにしたところ、ほいほいとそちらに問い合わせに行って名前解決に成功した。
6. 中身を空にしたhintファイルを読み込ませたところ、名前解決に失敗した。
   namedを再起動してもエラーは出なかった。 
   しかし、問い合わせを行ったところ、どこにも問い合わせをすることなくすぐに名前解決に失敗した。(SERVFAIL)
   ただし、そのDNSサーバが管理しているドメインの問い合わせは回答を返した。
ということで、
hintファイルを改ざんすると、サービスの(事実上の)停止や偽のDNSサーバへの誘導が可能なようなので、更新はしたほうが良い。
プライミング(priming)
上記のような結果は、BINDにプライミングという仕組みが用いられているからである。
DNSにおけるプライミングとは、最初にルートDNSサーバに問い合わせる時にhintファイルを参照し、ルートDNSサーバからの回答に含まれる
ルートDNSサーバの情報(NSレコードやAレコード、AAAAレコード)をキャッシュし、それ以降ルートDNSサーバに問い合わせるときはその情報を
使う仕組みのことをいう。
それによって、最新のルートDNSサーバ情報を保持することができる。
よって、hintファイルに登録されている情報をユーザに返すことはしないし、hintファイルの一部の情報が間違っていてもすぐに問題になることは無い。
しかし、どうしても最初に問い合わせるときにはhintファイルを参照するので、hintファイルが古すぎると最初の問い合わせが上手くできなかったり、
hintファイル自体を改ざんされると別のDNSサーバへ誘導される問題がある。
hintファイル更新に関するログ
同じbind-9.6-ESV-R5であっても、ログが大量にバカみたいに死ぬほどでるサーバと、ひとつもログをださないサーバがあるが、その違いは不明。
ただし、家のサーバ(BIND 9.8.4-P1)ではログが表示されていなかったので、試しにrndc reloadをしたが何も変わらなかった。
しかし、service named restart をしたらいきなりログが出始めた。(キャッシュしていたルートDNSの情報がクリアされたから?)
# tail /var/named/chroot/var/log/named/named.info
09-Feb-2013 17:11:01.417 general: warning: checkhints: d.root-servers.net/A (199.7.91.13) missing from hints
09-Feb-2013 17:11:01.417 general: warning: checkhints: d.root-servers.net/A (128.8.10.90) extra record in hints
09-Feb-2013 17:11:11.815 general: warning: checkhints: d.root-servers.net/A (199.7.91.13) missing from hints
09-Feb-2013 17:11:11.815 general: warning: checkhints: d.root-servers.net/A (128.8.10.90) extra record in hints
ログの意味は、
警告:hintファイルをチェックしろ。d.root-servers.netのAレコード (199.7.91.13)がhintファイルに見当たらんよ。
警告:hintファイルをチェックしろ。d.root-servers.netのAレコード (128.8.10.90)がhintファイルには余分だぜ。
hintファイルを取得する
1箇所の変更程度(今回であれば、d.root-servers.netのAレコード)であれば、わざわざhintファイルを取得しなくてもviコマンドで編集すれば良いが、
hintファイル全体が最新の状態かどうか良く分からない場合は、hintファイル全体を入れ替えた方がよい。
hintファイルはネットでも公開されているが、digコマンドを使った方が明らかに早い。
# dig +noall +answer +add +bufsize=4096 @a.root-servers.net . ns | sort > db.cache.new ルートサーバの情報を取得
不要な情報は取得しないようにするために、+noall +answer +addを付加
また応答が切り詰められないように+bufsize付加
問い合わせ先はAルートサーバ以外のルートサーバでも良い
# cat db.cache.new 取得した内容
.          518400 IN NS a.root-servers.net. 最低限必要なのは13つのルートサーバのNSレコードとAレコード
.          518400 IN NS b.root-servers.net. AAAAレコードについてはあっても良いが、DNSサーバがIPv6で
.          518400 IN NS c.root-servers.net. 接続されていないのであれば削除しても問題ない
.          518400 IN NS d.root-servers.net.
.          518400 IN NS e.root-servers.net.
.          518400 IN NS f.root-servers.net.
.          518400 IN NS g.root-servers.net.
.          518400 IN NS h.root-servers.net.
.          518400 IN NS i.root-servers.net.
.          518400 IN NS j.root-servers.net.
.          518400 IN NS k.root-servers.net.
.          518400 IN NS l.root-servers.net.
.          518400 IN NS m.root-servers.net.
a.root-servers.net. 3600000 IN A 198.41.0.4
a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
b.root-servers.net. 3600000 IN A 192.228.79.201
c.root-servers.net. 3600000 IN A 192.33.4.12
d.root-servers.net. 3600000 IN A 199.7.91.13
d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
e.root-servers.net. 3600000 IN A 192.203.230.10
f.root-servers.net. 3600000 IN A 192.5.5.241
f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
g.root-servers.net. 3600000 IN A 192.112.36.4
h.root-servers.net. 3600000 IN A 128.63.2.53
h.root-servers.net. 3600000 IN AAAA 2001:500:1::803f:235
i.root-servers.net. 3600000 IN A 192.36.148.17
i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
j.root-servers.net. 3600000 IN A 192.58.128.30
j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
k.root-servers.net. 3600000 IN A 193.0.14.129
k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
l.root-servers.net. 3600000 IN A 199.7.83.42
l.root-servers.net. 3600000 IN AAAA 2001:500:3::42
m.root-servers.net. 3600000 IN A 202.12.27.33
m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
# named-checkzone . db.cache.new 文法チェック
zone ./IN: has 0 SOA records 左記の2行であれば問題なし
zone ./IN: not loaded due to errors.
hintファイルの文法チェック
named-checkzoneでhintファイルの文法チェックを行う。
named-checkconfでは、hintファイルの内容が文法的に正しくなくてもエラーは出さないが、namedの再読み込み/再起動前にはしたほうが良い。
hintファイルが文法的に正しい場合
# named-checkzone . db.cache 文法チェック
zone ./IN: has 0 SOA records 左記の2行であれば問題なし
zone ./IN: not loaded due to errors.
hintファイルが文法的におかしい場合
# named-checkzone . db.cache 現在のhintファイルの14行目に不要な行を入れた
dns_master_load: db.cache:15: unexpected end of line named-checkzoneではエラーがでるが、named-checkconfではエラーがでない
dns_master_load: db.cache:14: unexpected end of input
zone ./IN: loading from master file db.cache failed: unexpected end of input
zone ./IN: not loaded due to errors.
# named-checkconf /var/named/chroot/etc/named.conf
# rndc reload この状態で再読み込み実施  当然エラーになる
rndc: 'reload' failed: unexpected end of input
# tail /var/named/chroot/var/log/named/named.info エラーの内容は named-checkzoneのものと同じ
09-Feb-2013 19:13:37.723 general: info: received control channel command 'reload'
09-Feb-2013 19:13:37.724 general: info: loading configuration from '/etc/named.conf'
09-Feb-2013 19:13:37.724 general: info: using default UDP/IPv4 port range: [1024, 65535]
09-Feb-2013 19:13:37.725 general: info: using default UDP/IPv6 port range: [1024, 65535]
09-Feb-2013 19:13:37.726 general: info: sizing zone task pool based on 8 zones
09-Feb-2013 19:13:37.726 general: error: dns_master_load: local/db.cache:15: unexpected end of line
09-Feb-2013 19:13:37.726 general: error: dns_master_load: local/db.cache:14: unexpected end of input
09-Feb-2013 19:13:37.726 general: error: could not configure root hints from 'local/db.cache': unexpected end of input
09-Feb-2013 19:13:37.726 general: error: reloading configuration failed: unexpected end of input
# service named restart 当然 namedの再起動でも起動に失敗する
named を停止中: . [ OK ]
named を起動中: [失敗]
# tail /var/log/messages
Feb 9 19:19:28 vm-centos62 named[6340]: starting BIND 9.8.4-P1 -u named -t /var/named/chroot
Feb 9 19:19:28 vm-centos62 named[6340]: built with '--prefix=/usqr'
'--exec_prefix=/usr' '--localstatedir=/var' '--sysconfdir=/etc' '--disable-openssl-version-check'
--enable-ipv6' '--enable-threads' '--enable-chroot'
Feb 9 19:19:28 vm-centos62 named[6340]: ----------------------------------------------------
Feb 9 19:19:28 vm-centos62 named[6340]: BIND 9 is maintained by Internet Systems Consortium,
Feb 9 19:19:28 vm-centos62 named[6340]: Inc. (ISC), a non-profit 501(c)(3) public-benefit
Feb 9 19:19:28 vm-centos62 named[6340]: corporation. Support and training for BIND 9 are
Feb 9 19:19:28 vm-centos62 named[6340]: available at https://www.isc.org/support
Feb 9 19:19:28 vm-centos62 named[6340]: ----------------------------------------------------
Feb 9 19:19:28 vm-centos62 named[6340]: adjusted limit on open files from 1024 to 1048576
Feb 9 19:19:28 vm-centos62 named[6340]: found 2 CPUs, using 2 worker threads
Feb 9 19:19:28 vm-centos62 named[6340]: using up to 4096 sockets
Feb 9 19:19:28 vm-centos62 named[6340]: loading configuration from '/etc/named.conf'
Feb 9 19:19:28 vm-centos62 named[6340]: using default UDP/IPv4 port range: [1024, 65535]
Feb 9 19:19:28 vm-centos62 named[6340]: using default UDP/IPv6 port range: [1024, 65535]
Feb 9 19:19:28 vm-centos62 named[6340]: listening on IPv4 interface lo, 127.0.0.1#53
Feb 9 19:19:28 vm-centos62 named[6340]: listening on IPv4 interface eth0, 192.168.24.133#53
Feb 9 19:19:28 vm-centos62 named[6340]: listening on IPv4 interface eth1, 192.168.24.139#53
Feb 9 19:19:28 vm-centos62 named[6340]: generating session key for dynamic DNS
Feb 9 19:19:28 vm-centos62 named[6340]: sizing zone task pool based on 8 zones
Feb 9 19:19:28 vm-centos62 named[6340]: dns_master_load: local/db.cache:15: unexpected end of line
Feb 9 19:19:28 vm-centos62 named[6340]: dns_master_load: local/db.cache:14: unexpected end of input
Feb 9 19:19:28 vm-centos62 named[6340]: could not configure root hints from 'local/db.cache': unexpected end of input
Feb 9 19:19:28 vm-centos62 named[6340]: loading configuration: unexpected end of input
Feb 9 19:19:28 vm-centos62 named[6340]: exiting (due to fatal error)
Feb 9 10:19:05 esxi51.example.co.jp Hostd: [3A819B90 verbose 'Cimsvc'] Ticket issued for CIMOM version 1.0, user root
hintファイルの更新をする
1. hintファイルの場所の確認
久々にBINDに触るのでファイルの場所が良く分からないということ、たまにありますよね。
場所を知っている人はここは無視。
# ps -ef | grep named psコマンドの結果から、namedはchroot環境(/var/named/chroot)で
named 2624 1 0 18:04 ? 00:00:00 /usr/sbin/named -u named -t /var/named/chroot 動いているので、/var/named/chrootのetc/named.confを確認
# more /var/named/chroot/etc/named.conf named.confでhintファイルの場所を確認
directory "/var/named";
zone "." { ヒントファイルは、zone "." で、 type hintで設定しているのでこれを検索
type hint;
file "local/db.cache"; ファイル名は何でも良い 自分はdb.cacheにしている
};
chroot環境、directory、fileで指定した場所から、
ヒントファイルは、
/var/named/chroot/var/named/local/db.cacheであることが分かった
# cd /var/named/chroot/var/named/local hintファイルの確認
# ls -ltr db.cache*
-rw-r-----. 1 root named 1545 12月 8 11:21 2012 db.cache
# grep -i d.root db.cache とりあえずd.rootサーバの現在の設定を確認
.          518400 IN NS d.root-servers.net. 今回は、IPv4アドレスが変更になるということで
d.root-servers.net. 3600000 IN A 128.8.10.90 128.8.10.90 → 199.7.91.13 にする必要がある
d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
2. hintファイルの更新 
(1) hintファイル丸ごと変更する場合
# dig +noall +answer +add +bufsize=4096 @a.root-servers.net . ns | sort > db.cache.new digコマンドを使って、a.root-serverからルートサーバの情報を取得
(問い合わせ先はa.rootサーバでなくても別のルートサーバでも良い)
# more db.cache.new 中身を確認
# named-checkzone . db.cache.new 文法チェック
zone ./IN: has 0 SOA records この2行は問題ないので無視
zone ./IN: not loaded due to errors.
# ls -ltr db.cache* 所有権とパーミッションをあわせる
-rw-r-----. 1 root named 1545 12月 8 11:21 2012 db.cache 自分のDNSサーバでは、書き込みはrootだけにし、
-rw-r--r-- 1 root root 1550 2月 9 18:28 2013 db.cache.new namedグループは読み込みOK、他は読み込みNGにしている
# chown root:named db.cache.new
# chmod 640 db.cache.new
# ls -ltr db.cache*
-rw-r-----. 1 root named 1545 12月 8 11:21 2012 db.cache
-rw-r----- 1 root named 1550 2月 9 18:28 2013 db.cache.new
# mv db.cache db.cache.20130209 現在のdb.cacheを別名に変更し、新しく取得したファイルをdb.cacheに変更
# mv db.cache.new db.cache
# ls -ltr db.cache*
-rw-r----- 1 root named 1545 12月 8 11:21 2012 db.cache.20130209
-rw-r----- 1 root named 1550 2月 9 18:28 2013 db.cache
# named-checkconf /var/named/chroot/etc/named.conf とりあえずnamed-checkconfも実施
(2) hintファイルを編集する場合
# ls -ltr db.cache* 現在のhintファイルをコピー
-rw-r-----. 1 root named 1545 12月 8 11:21 2012 db.cache 所有権とパーミッションは同じにするので、 -p オプションをつけておく
# cp -pi db.cache db.cache.20130209
# ls -ltr db.cache*
-rw-r----- 1 root named 1545 12月 8 11:21 2012 db.cache.20130209
-rw-r-----. 1 root named 1545 12月 8 11:21 2012 db.cache
# vi db.cache viコマンドで編集
d.root-servers.net. 3600000 IN A 199.7.91.13 128.8.10.90 を 199.7.91.13 に変更
# diff db.cache db.cache.20130209 差分確認
< d.root-servers.net. 3600000 IN A 199.7.91.13
---
> d.root-servers.net. 3600000 IN A 128.8.10.90
# named-checkzone . db.cache 文法チェック
zone ./IN: has 0 SOA records この2行は問題ないので無視
zone ./IN: not loaded due to errors
# named-checkconf /var/named/chroot/etc/named.conf とりあえずnamed-checkconfも実施
3. 再読み込み(または再起動)を実施
最新のルートDNSサーバがキャッシュされているのであれば、再読み込み( rndc reload )でも良い。
しかし、大量の警告ログが出て困っていたり、キャッシュをクリアしても問題ないようであれば、再起動 (service named restart)が望ましい。
# ps -ef | grep named 再読み込み前に確認
named 8552 1 0 20:04 ? 00:00:00 /usr/sbin/named -u named -t /var/named/chroot
# service named restart namedの再起動実施
named を停止中: . [ OK ] (自宅のDNSサーバなので再起動させた)
named を起動中: [ OK ]
# ps -ef | grep named namedが起動していることを確認
named 2719 1 0 13:34 ? 00:00:00 /usr/sbin/named -u named -t /var/named/chroot
# tail /var/named/chroot/var/log/named/named.info ログの確認
# tail /var/log/messages ※ named.infoの方は、named.confで指定したログ
# grep checkhints /var/named/chroot/var/log/named/named.info checkhintsのログがでていないことを確認
ただしすぐに出るとは限らない(どういったタイミングででるか不明)
# dig @localhost www.yahoo.co.jp 適当なところを指定して名前解決できるか確認(サービスの正常性確認)