NSD

ここに書いてある情報はクソ古いです。「昔の NSD はこうだったんだ」と懐しむ以外の役には立ちません。NSD 本家を見ましょう。


maya.st の情報を管理している DNS は BIND や djbdns でなく、NSD で動いております。NSD なんてぜんぜん知らない、あるいは知っていてもせいぜい名前だけ、という人が現状ではほとんどだと思われるので、ちょっとした紹介など。

NSD って?

DNS コンテンツサーバ。どこの馬の骨とも知らぬ怪しげなプロダクトではなく、13個の DNS ルートサーバの一部({h,k}.root-servers.net)を担っているという十分な実績を持っている。開発元はオランダの NLnetLabs というところ。

メリットは、速い、軽い、簡単。UNIX 系 OS では BIND8 が高速だと言われているが、その数倍のパフォーマンスが出るらしい。設定ファイルもとても簡単で、あらかじめ DNS についての知識をある程度持っているのならば、新たに勉強が必要なことはほとんどゼロ。

逆に、必要な機能のみにターゲットを絞った作りになっていて、あまり凝ったことはできないことがデメリットといえよう。まず、BIND や djbdns とは異なり、コンテンツサーバ専用で、キャッシュサーバとしては使えない。その他、ラウンドロビンができない(常に同じ順番で応答を返す)、IXFR をサポートしていない、AXFR 以外のアクセス制限ができない、ダイナミック DNS 機能がない、BIND の view 相当の機能がない、クエリーのログを取れないなど、できないことはたくさんある。しかし、DNS の基本的なサービスについては十分以上の性能で実現できるので、そんなに悲観したものではない。

その他の特徴としては、

などが挙げられる。このあたりのことはアーカイブに含まれる README や REQUIREMENT に詳しく書かれている。

インストールと設定

といっても、インストール作業はてきとーな引数とともに configure; make; make install するだけなので詳細は割愛。2.3.1 では以下のもの(と man ページ)がインストールされる。

このうち、nsd-xfer と nsd-notify は古いバージョンの NSD には存在していなかった。以前はゾーン転送は自力ではできず、BIND8 の named-xfer を借りていたし、NOTIFY はサポートされていなかった(現行バージョンでも NOTIFY は通知するだけで、NOTIFY を受け取って AXFR/IXFR を飛ばす、ということはできない)。

制御プログラムである nsdc は、中身はただのシェルスクリプトである。nsd や zonec やらを必要に応じて呼び出しているだけで、nsdc を使わないと不可能な操作があるわけではない。nsdc でできないことでも、各ツールを単独で呼び出してやれば実現できることもある。

設定ファイルは nsdc.conf と nsd.zones のふたつ。前者は nsdc が使うもので、さまざまな引数を与えて nsdc を起動したときのオプションを記述する。後者はサービスするゾーンに関する設定で、nsdc と zonec で共用する。nsd 本体の設定ファイルは存在しない。設定ファイルの書き方とかは割愛するが、BIND のようにいくつものオプションがあったりはしない。極めて簡単である。

これ以外にもちろんゾーンファイルが必要になる。基本的に BIND 互換。というか、あれは RFC1035 で規格化されている形式らしい。なので、BIND から移行するならばゾーンファイルをコピーするだけでいい。ただ、BIND はこの形式にいくつか拡張を加えていて、その独自拡張を使っているゾーンファイルはそのまま使えない。具体的には連番を生成するのに使われる $GENERATE マクロがサポートされていない。

なお、FreeBSD で ports からインストールした場合、起動スクリプトとして /usr/local/etc/rc.d/nsd.sh が作成されるが、これは nsdc.conf を無視する。nsd.sh を削除して nsdc へのシンボリックリンクで置き替えてしまった方がいいだろう。

つかいかた

nsdc

nsdc のサブコマンドでも書いておくかね。

nsdc {start|stop|restart}

nsd を起動/終了/再起動する。起動オプションは nsdc.conf に flags="..." として書く。nsd 自体の設定ファイルは存在しない。すなわち、nsd は起動時の引数だけで動作がすべて記述できるほど単純なのだ。

nsdc {reload|rebuild|notify}

rebuild はゾーンファイルをテキストからバイナリに変換する。reload はゾーンファイルを読みなおして NOTIFY を送る。どこかのゾーンを修正した場合は nsdc rebuild && nsdc reload と nsdc を2回を実行して変更を反映させる。notify は nsd.zones で NOTIFY を送るとなっているサーバすべてに通知する(reload したら自動で送られるので通常は不要)。rebuild と reload を1回のコマンドで済ます手段はないし、更新があったゾーンの slave サーバに対してのみ NOTIFY を送る、といったことはできないが、nsdc はただのシェルスクリプトなので、これが不便に思うならば、自分でその部分を書き換えればよい。

nsdc update

自分が slave となっているゾーンの master DNS の SOA を調べて、更新されていれば master からゾーンを転送し、rebuid、reload する。おそらくは cron に仕込むことになるだろう。

BIND とは異なり、SOA レコードのパラメータを見て時間が来たら勝手にゾーン転送したりするようにはなっていない。完全に無視する。また、NOTIFY を送ることはできるが、NOTIFY が届いたからといって自動でゾーンを取りにいったりもしない(syslog には載る)。運用者が指定したタイミングでのみゾーン転送される。SOA レコードの refresh 間隔を忠実に守りたいならば、そのタイミングおきに処理をおこなうような仕組みを自分で書かなければならない。NOTIFY を受けたら自動で AXFR したいならば、そういう仕組みを自分で書かなければならない。

アクセス制御

この IP アドレスからの query を無視するとか、BIND の view のような問い合わせ元によって応答を変えるような機能は nsd には実装されていない。唯一、AXFR(ゾーン転送)に対するアクセス制御は可能だが、これも nsd 本体ではなく、tcp_wrapper で実現している。つまり、ゾーン転送を許可するホストはおなじみ /etc/hosts.allow に書くことになる。example.jp ゾーンの転送を 192.0.2.100 から許可、すべてのゾーンを 192.0.2.200 から許可し、それ以外はすべて拒否する、という場合は hosts.allow に次のように書く。

axfr : 192.0.2.200 : allow
axfr-example.jp. : 192.0.2.100 : allow
ALL : ALL : deny

hosts.allow を修正しても再起動などは不要。書き換えた瞬間から有効になる。

で、使ってみてどうなのよ?

現状こちらで必要な機能については完全にサポートされているし、取り扱いの簡単さや軽さなどメリットは多く不満はまったくない。

ただ、現状ではまったく不満はないけれど、今やってないことを将来やろうとしたときに困ることがあるかもしれない。思いつくのは以下の2点。

ラウンドロビンはコンテンツサーバで対応していなくても、キャッシュサーバがラウンドロビンしてくれるので本来は必要はない。ただし、ラウンドロビンしないキャッシュ DNS(BIND で rrset-order { order fixed; }; と設定したときなど)もあるのでいちおう注意は必要である。後者は運用でカバーできる(外部ツールを作成することで実現可能なはず)のでそれほど問題ないと思うが、気になる人はやめておいた方がいいかもしれない。とはいえ、BIND8 はセキュリティが心配、BIND9 はパフォーマンスが出ない、djbdns は変態的でイヤ、というような人にとっては、NSD は非常によい選択肢になるだろう。

参考 URL

ほとんど PDF。