DNS(bind9)サーバーについて



BINDの歴史とバージョン9の特徴

 DNSが普及し始めたのは、90年代初頭、BINDのバージョン番号は4だった。5〜7は欠番で、次に登場したのが現在でも高いシェアを誇るバージョン8です。
 BIND8では設定ファイルの書式が一新されており、完全な別物であることを示すため、ファイル名がnamed.bootからnamed.confへと変更されています。ただ、配布物の中にはBIND4から移行用として変換ユーティリティnamed-bootconf.plが付属しており、設定ファイルの移行についても配慮されています。
 主要な変更ポイントとして、named.bootではサービスするゾーン名とプライマリ/セカンダリの指定、ゾーンファイルの名前程度しかせってい項目がなかったが、named.confでは多種多様なパラメータが導入され、次のような機能が追加されています。
・ダイナミックアップデート
・NOTIFY(ゾーンデータ更新時、スレーブからのポーリングを待たずにマスタが能動的にスレーブに通知する機構)
・(再帰的を含む)問い合わせやゾーン転送へのアクセス制限
 さらに、BIND8のマイナーバージョンアップで次の機構が追加されている。
・DNSSEC(レコードへの署名とTSIG(問い合わせやリクエストへの署名)
・ネガティブキャッシュ
 BIND8に続いて登場したのがバージョン9である。シェアとしてはBIND8の方が高いが、Red Hat Linuxのように標準採用するディストリビューションも出てきているので、今後普及するのは間違いないでしょう。
 BIND8と9の設定ファイルでは、BIND4と8ほど大きな違いはない。凝った設定をしていなければ設定ファイルの変更なしに移行可能なケースもあります。
 一方、実装に目を向けると、BIND8はBIND4のソースコードがベースになっているのに対して、BIND9はスクラッチで書き起こされている。そのような背景もあり、BIND9ではよりRFCに忠実な実装が心がけられています。
 機能面では、次のものが追加されている。
・IPv6トランスポートのサポート
・view機能(Split DNS:問い合わせのソースアドレスなどによってサービスするゾーンデータを切り替える)
・unix制御チャネルの廃止とinet制御チャネルの認証強化
 ここでは、IPv6のサポートについて少し補足しておこう。ゾーンデータの内容に関しては、BIND9以前でもAAAAレコードおよびニブルフォーマット注1のPTRレコードを用いたIPv6アドレスの取り扱いが実現されていました。BIND9ではさらにA6レコードとビットストリングフォーマット注2のPTRレコードが扱えるようになりました。これに加えて、IPv4の通信路でしか行えなかったDNSの問い合わせ注3が、IPv6の通信路でもサポートされるようになりました。
   注1 IPv6アドレスを16進数で表記し、16進数1桁、つまりニブル(nibble)ごとに左右を逆順
      にして「.」で区切って表記する形式。IPv4で実績のある方法をIPv6に応用していて、DNS
      の機構を素直に使っていることが利点。
   注2 IPv6アドレスを16進数で表記し、左右逆順にせずに元の順序のまま「:」を省略して、
      「\[」と「]」でくくる表現形式。
      例えば、\[x3ffe0501040702000000000000000053].ip6.arpaのようになる。PTRレコード
      に階層構造が導入でき、ISPの変更などホスト部は維持したまま、プリフィックスだけを
      リナンバするといったケースで便利な反面、複雑すぎるという難点がある。
   注3 将来的に、BIND8.4.0ではIPv6の通信路をサポートする予定である。
クライアントの働き

 一般的なアプリケーションにおいて名前解決が要求されると、正引きはgethostbyname()あるいはgetaddrinfo()というライブラリ関数を、逆引きはgethostbyaddr()あるいはgetnameinfo()というライブラリ関数を呼び出して結果を得ます。では、これらのライブラリ関数(リゾルバルーチン)は、どのようにして名前を解決しているのであろうか?
 ホスト名とIPアドレスの対応関係の情報源としては、DNS以外にも/etc/hostsファイルやNISのhostsマップなどがあります。リゾルバルーチンの古典的な実装では、設定ファイル/etc/resolv.confが存在すればDNSを使い、存在しなければ/etc/hostsから情報を取得します。一方、最近で複数の情報源を柔軟に扱えるように、/etc/hostc.confや/etc/nsswitch、/etc/svc.confなどによって、各情報源の優先順位や、検索結果が得られなかった場合に振る舞いなどを設定します。
 従って、各設定ファイルの有無や内容に応じて、しかるべき情報源から取得したデータをアプリケーションに対して返しているということになります。

リゾルバルーチンから問い合わせを処理する過程

DNSサーバーの役割

 /etc/resolv.confが存在する場合、リゾルバルーチンは同ファイルで設定されたDNSサーバーに対してUDP、あるいは(データサイズが大きければ)TCPで問い合わせを送出し、応答を得ます。リゾルバルーチンから問い合わせを受けたDNSサーバーは、根にあたるrootサーバーから順に、ツリー構造の名前空間をたどりながら目的の名前を検索していき、該当する値をリゾルバルーチンに返します。

アプリケーションから問い合わせを処理する過程

 ここで注目したいのが、リゾルバルーチンから問い合わせを受けたDNSサーバーも、別のDNSサーバーに対して問い合わせを行っている点です。つまり、DNSにおける問い合わせには、リゾルバルーチンから行われるものとDNSサーバーから行われるものの2種類があることになります。前者の動作は完全な回答を要求することから再帰的な問い合わせ(recursive query)、後者の動作は目的に近づいていくための相手の持っている回答を要求することから非再帰的な問い合わせ(non-recursive query)といいます。
 また、リゾルバから問い合わせを受けたDNSサーバーは、一般にはその名前についてオーソリティを持っておらず、非再帰的な問い合わせを繰り返すことで要求された情報を返す。これに対して、このDNSサーバーが名前解決の途中で問い合わせを行うDNSサーバーは、他のDNSサーバーに問い合わせることなく要求された情報を応答している点に注意して欲しい。
 BINDでは、namedというプログラムがリゾルバからの再帰的な要求に対する応答と、オーソリティを持つゾーンに関する問い合わせの応答を行うのに対して、djbdnsでは役割ごとにdnscasheとtinydnsという2つのプログラムで対応します。

レコードの主なタイプ

タイプ 用途
A IPv4アドレス
AAAA* IPv6アドレス
PTR アドレスからドメイン名への対応
MX メールの配送先と優先度
CNAME エイリアス(別名)と正規名対応
SOA ゾーンデータの鮮度や各種タイマーの値
NS オーソリティの所在
*AAAAはquad(クワッド)Aと読む。

DNSサーバーの設定項目

プライマリ/セカンダリとマスタ/スレーブの関係

 何らかのゾーンのオーソリティを持つDNSサーバーでは、情報を提供するのに以下の設定が必要になる。
・オーソリティを持っているゾーンの名前
・ゾーンデータ(各ゾーンの具体的な情報)

 ゾーンデータの参照方法には、ローカルホスト上のファイルを読み込む方法と別のDNSサーバーからゾーン転送と呼ばれる動作によって読み込む方法の2種類がある。前者をプライマリ、後者をセカンダリと呼びます。セカンダリはDNSサーバーの冗長性を確保する目的などで運用されます。
 プライマリ/セカンダリと似た概念として、マスタ/スレーブがあります。named.confでは、プライマリの指定にmaster、セカンダリの指定にslaveを使用するため混乱しやすいが、マスター/スレーブはゾーン転送の動作に注目した概念であり、転送元がマスター、転送先がスレーブどなります。従って、プライマリの孫、つまりセカンダリ(子)のセカンダリ(孫)という状況も考えられ、このときセカンダリ(孫)から見るとセカンダリ(子)はマスターと言うことになります。

ゾーン転送時の子プロセス作成について

 psを利用すると、複数のnamedプロセスが動作しているのが分かる場合があります。これは、ネームサーバーがゾーン転送を行うために、子プロセスを作るためです。ゾーン転送中は、ゾーンデータを取り出すネームサーバーは子プロセスを使う必要があり、ゾーンデータを提供するネームサーバーも子プロセスを使う場合があります。
 BIND4とBIND8のスレーブネームサーバーは、ゾーン転送を実行するために子プロセスを起動します。これによりスレーブネームサーバーは。子プロセスがマスタサーバーから自分のディスクに格納されると、スレーブネームサーバーは新しいデータを読み込む。子プロセスを使ってゾーン転送を行うことによって、ゾーン転送中にスレーブネームサーバーが応答しなくなるという、4.8.3より前のバージョンで見られた問題が解決されました。特に数多くのゾーンや大規模なゾーンをロードする場合には、スレーブネームサーバーは長い時間沈黙してしまい、実に不都合な状況になっていました。
 BIND9のスレーブネームサーバーは、アーキテクチャが新しくなったため、子プロセスを作らなくてもネームサーバーがゾーン転送中に沈黙しないようになっている。ネームサーバーは、ゾーン転送中でも問い合わせに応答できます。
 BIND8およびBIND9のプライマリマスタネームサーバーは、スレーブネームサーバーに対してゾーンデータを転送するために子プロセスを作ることはありません。問い合わせに応答すると同時に、ゾーン転送します。ゾーン転送の途中に、マスタサーバーがゾーンファイルから新しいゾーンデータをロードする場合には、実行中のゾーン転送を中止し、ゾーンファイルから新しいゾーンデータを読み込みます。スレーブサーバーは、マスタが新しいゾーンのロードを完了した後、もう一度ゾーン転送を試みる必要があります。
 BIND4のプライマリマスタネームサーバーは、スレーブネームサーバーに対してゾーンデータを転送するために子プロセスを起動します。これにより、ますたさーばが動作しているホストには大きな負荷がかかります。特に、大規模なゾーン転送をしたり、一度に多くのゾーンを転送したりする場合には、負荷が大きくなる。
 psコマンドにより複数のネームサーバーが動作していることが分かった場合、親プロセスと子プロセスを簡単に見分ける必要があります。スレーブネームサーバーがゾーンデータのコピーを取得するために起動した子ネームサーバーは、namedではなくnamed-xferという名前になっています。
  root  548 547  0 22:03:17 ?     0:00 named-xfer -z movie.edu
        -f /usr/tmp/NsTmp0 -s 0 -P 53 192.249.249.3
 マスタネームサーバーが起動した子ネームサーバーは、コマンドラインオプションが、ゾーンデータの転送先となるスレーブサーバーを示すようになっている。
  root 1137 1122 6 22:03:18 ?     0:00 named-xfer -zone XFR
       to [192.249.249.1]
 BIND8またはBIND9のマスタとスレーブを使っている場合には、スレーブはすぐに新しいデータを読み込みます。データが変更されてから15分以内に、プライマリマスタがスレーブにデータに変更があったことを通知するからです。4.9以降のネームサーバーを使っているのなら、スレーブネームサーバーをリロードすれば、スレーブネームサーバーはすぐに新しいデータを読み込みます。リロードは、スレーブネームサーバーのゾーンをすべて更新します。4.8.3以前のネームサーバーを使っている場合には、スレーブのバックアップゾーンデータファイルをすべて(もしくは強制的に更新したいものだけ)削除し、スレーブネームサーバーをkillしてから、新たなネームサーバーを起動します。バックアップファイルが消えているので、スレーブはすぐに新しいゾーンデータのコピーを取りに行かなければならない。

参考
・ネガティブキャッシュ
 問い合わせ先のネームサーバーが指定されたドメイン名やデータは存在しないと言う答えを返したときに、その不在情報をキャッシュしておく。ネームサーバーは、問い合わせたデータに関する機能をキャッシュすることにより、以降の問い合わせを高速化します。ちなみに、BIND8.2が出る直前にSOAレコードの最後のフィールド意味がネガティブキャッシュTTLに変更されています。BIND8.2以降ではデフォルトTTLは$TTL制御ステートメントで指定します。

・ゾーンデータファイルの起点名の変更
 BINDでは、DNSのゾーンデータファイルのデフォルトの起点名は、BIND4ではnamed.bootファイルのprimaryまたはsecondaryディレクティブの第2フィールド、BIND8または9ではnamed.confファイルのzoneステートメントの第2フィールドに指定されている名前となります。起点名とは、ゾーンデータファイルに記述された最後がドットで終わっていないすべての名前に自動的に付加されるドメイン名です。起点名は、ゾーンデータファイル中の$ORIGIN制御ステートメントで変更することができます。ゾーンデータファイル中では、$ORIGINに続いてドメイン名を記述します(完全なドメイン名を指定する場合には、最後のドットを忘れてはならない)。$ORIGINを指定すると、それ以降の最後がドットで終わっていないすべての名前に新しい起点名が付加されます。自分のネームサーバー(たとえばmovie.edu)が多くのサブドメインの責任を持っている場合には、$ORIGINステートメントで起点名を変更することによってゾーンデータファイルを簡素化できます。次に例を示します。
  $ORIGIN classics.movie.edu.
  maltese       IN  A  192.253.253.100
  casablanca    IN  A  192.253.253.101
  $ORIGIN comedy.movie.edu.
  mash          IN  A  192.253.253.200
  twins         IN  A  192.253.253.201
注意
ホスト名に使用できる文字は英数字と‐(ダッシュ)のみです。
‐(ダッシュ)は途中でのみ利用可能です。

今回想定する構成

サイト
ドメイン名 example.jp
IPv4アドレス 192.168.3.152/29
IPv4逆引きゾーン名 29/152.3.168.192.in-addr.arpa
IPv6アドレス 3ffe:501:407:200::/64
設定対象のDNSサーバー
ドメイン名(ホスト名) ns.example.jp
IPv4アドレス 192.168.3.153
IPv6アドレス 3ffe:501:407:200::53
※外部に公開するゾーンはns.myisp.ad.jp(192.168.129.1)がセカンダリとなる。

ディレクトリの構成とファイル配置

設定項目の大半をデフォルトしますが、以下については変更します。
?namedのワーキングディレクトリは/usr/local/etc/named
?IPv6の通信路の有効化
?ログのメッセージにはカテゴリとセベリティ(severity)注4を含める。
  注4 カテゴリはsyslogにおけるファシリティに対応する概念であり、namedが出力する各メッ
     セージを内容に応じていくつかに分類したもの。セベリティはsyslogのプライオリティ
     に相当するメッセージの深刻さを表す指標。
?、?、?のoptionsステートメントは以下のとおりです。
	options {
		# namedは/usr/local/etc/namedにchdir()して動作する。
		directory "/usr/local/etc/named";
		# IPv6の通信路を有効にする。
		listen-on-v6 {
			any;
		};
	};
	logging {
		# mydefaultという名前のchannelを定義する。
		channel mydefault {
			# 出力方法はsyslog経由でファシリティはdeamon。
			syslog daemon;
			# セベリティinfo以上のメッセージを出力する。
			severity info;
			# メッセージにカテゴリとセベレティを含めて記録。
			print-category yes;
			print-severity yes;
		};
		# 全てのメッセージを上で定義したmydefaultというchannelへ出力する。
		category default {
			mydefault;
		};
	};
	
    上記では、コメントを日本語で記載していますが、コメント中にESCコードや8ビットコード
    が含まれている場合の挙動についてはドキュメントの中では触れられていないので日本語の
    コメントは使用しない方がいいでしょう。
	
 named.confの用意が出来たら、/usr/local/etc/namedディレクトリを作成後、named-checkconfコマンドでファイルの内容をチェックしよう。
  # mkdir /usr/local/etc/named
  # /usr/local/sbin/named-checkconf
 設定内容に問題がなければ、何も表示されずに終了します。
 続いて、namedを制御するツールrndcを使う準備として
  # rndc-confgen -a
を実行し、namedとrndcの間で認証に用いる鍵を生成します。rndc-confgenコマンドでは。デフォルトの乱数デバイスとして/dev/randamを使用します。FreeBSD 4.xなど一部のOSでは、「/dev/randomを使用するとrndc-confgenコマンドが実用的な商用時間では終了しない」という問題があります。この場合「-r keyboard」オプションを指定してキーボードの入力によりランダムデータを発生させるか、乱数の質は落ちるが「-r /dev/urandom」オプションを指定するなどの対処が必要です。このようにして生成した鍵は、/etc/rndc.keyに保存されます。
 ここまでの作業が済んだらnamedを起動し、すぐに/var/log/messages(syslog.confの設定によっては別の適切なログファイル)の内容を見ておこう。例えば、Cシェル系では。
  # /usr/local/sbin/named &; tail -f /var/log/messages
のように実行すると、1行のコマンドラインでnamedの起動とログに出力されたメッセージを監視できる。Bシェル系の場合は、「;」を削除して実行すればよい。なお、OS付属のものと異なるディレクトリにBIDN9をインストールした場合、ここでOS付属のnamedを起動しないように注意しなければならない。namedでフルパスを指定しておけば間違いないだろう。
 無事起動しているなら、psコマンドを利用して
  # ps auxw | grep named
  root  56880  0.0  3.2  2564 1928  ??  Is    4:38PM
   0:00.10 /usr/local/sbin/named -p 10053
のようにnamedプロセスが動作していることを確認しておこう。また、rndcコマンドに「status」オプションを指定して、namedが制御チャネルを通じてrndcと通信できていることを確認しておく。出力の最終行に「server is up and running」というメッセージが表示されればOKです。
  number of zones: 6
  debug level: 0
  xfers running: 0
  xfers deferred: 0
  soa queries in progress: 0
  query logging is OFF
  server is up and running
もし、
  rndc: connect failed: connection refused
のようなエラーが表示されたら、何らかの問題が発生している。このようなときは、rndcの出力だけを見ても問題の詳細が分からないので、namedが出力しているログメッセージを見て問題箇所を修正する。
 最後に、このnamedがDNSサーバーとしてサービスを提供しているがdigコマンドなどで確認しよう。
  ; <<>> DiG 9.2.2 <<>> @localhost www.unixuser.jp
  ;; global options:  printcmd
  ;; Got answer:
  ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1223
  ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0
  ;; QUESTION SECTION:
  ;www.unixuser.jp.		IN	A
  ;; ANSWER SECTION:
  www.unixuser.jp		6855	IN	A	211.13.211.157
  ;; AUTHORITY SECTION:
  unixuser.jp		6855	IN	A	ns0.mex.ad.jp
  unixuser.jp		6855	IN	A	ns.softbankpub.co.jp
  ;; Query time: 7 msec
  ;; SERVER: ::1#10053(localhost)
  ;; WHEN: Fri Aug 22 18:12:33 2003
  ;; MSG SIZE  rcvd: 165
上記のように、実在する名前を検索し、「ANSWER SECTION」に応答が得られれば問題ない。以降でも設定例を紹介しますが、それぞれの設定が済んだところで意図どおり反映されているかどうかを必ず確認してください。

rndcによるnamedの制御

 rndcコマンドによる機能一覧は、「-help」オプションを指定することによって表示される。この中で使用頻度が高いのは、「reload」、「reconfig」、「stop」という3つのサブコマンドだろう。
  rndc: illegal option -- h
  Usage: rndc [-c config] [-s server] [-p port]
          [-k key-file ] [-y key] [-V] command
  command is one of the following:
    reload        Reload configuration file and zones.
    reload zone   [class [view]]
                  Reload a single zone.
    refresh zone  [class [view]]
                  Schedule immediate maintenance for a zone.
    reconfig      Reload configuration file and new zones only.
    stats         Write server statistics to the statistics file.
    querylog      Toggle query logging.
    dumpdb        Dump cache(s) to the dump file (named_dump.db).
    stop          Save pending updates to master files and stop the server.
    halt          Stop the server without saving pending updates.
    trace         Increment debugging level by one.
    trace level   Change the debugging level.
    notrace       Set debugging level to 0.
    flush         Flushes all of the server's caches.
    flush [view]  Flushes the server's cache for a view.
    status        Display status of the server.
    *restart      Restart the server.
  * == not yet implemented
  Version: 9.2.2
 「reload」コマンドは設定ファイル群をリロードするものだ。ゾーン名と必要に応じてクラスとviewも指定でき、この場合、該当するゾーンデータだけをリロードします。また、「reconfig」コマンドを使用すると、named.conf(とincludeされているファイル)だけをリロードし、まだ読み込まれていないゾーンデータだけを新たに読み込む(すでに読み込まれているゾーンデータはリロードしない)。この2つのコマンド、大規模サーバーにおける負荷軽減の工夫です。
 「stop」コマンドはすぐに分かると思いますが、動作中のnamedを停止させるものです。他に、ダイナミックアップデートを有効化しているときに処理途中の更新を破棄して強制終了する「halt」コマンドもあります。これに対して「stop」コマンドでは、きちんと処理を済ませてから終了します。
 ここで、/etc/rndc.keyファイルが存在する際の動作について説明します。
 rndcは、/etc/rndc.confファイル(後述)が存在せず、/etc/rndc.keyが存在すれば、そこで定義されている鍵を用いてlocalhostのnamedにアクセスします。一方、namedはnamed.confにcontrolsステートメントが存在せず、/etc/rndc.keyファイルが存在すればlocalhostからのアクセスだけを受け付けます。その際、/etc/rndc.keyで定義された鍵を用いてアクセス認証します。named.confにcontrolsステートメントが存在し、そこにkeys節のないinet制御チャネルが記述してあれば、allow節で許可した範囲からのアクセスを受け付け、同様に/etc/rndc.keyで定義されている鍵でアクセスを認証する。
 rndcコマンドでリモートのnamedを制御するには、まずnamed.confのkeyステートメントで鍵を制御した上で、controlsステートメントのパラメータによって適切な鍵情報を伴ったアクセスを許可します。
 rndc側では、rndc-confgenコマンドによって設定ファイル/etc/rndc.confを作成します。rndc-confgenコマンドを実行すると、標準出力に/etc/rndc.confのスケルトンが出力され、続いてnamed.confに含まれるべきkeyステートメントとcontrolsステートメントのスケルトンがコメントと出力される。したがって、この出力を/etc/rndc.confファイルにリダイレクトし、後半部分は行頭のコメントアウト(#)を削除してnamed.confに含めます。
  % /usr/local/sbin/rndc-confgen
  # Start of rndc.conf
  key "rndc-key" {
          algorithm hmac-md5;
          secret "qBa5wSknF3vOKW6yXIf/aQ==";
  };
  options {
          default-key "rndc-key";
          default-server  127.0.0.1;
          default-port 953;
  };
  server  127.0.0.1 {
          key "rndc-key";
  };
  # End of rndc.conf
  # Use with the following in named.conf, adjusting the allow list as needed:
  # key "rndc-key" {
  #        algorithm hmac-md5;
  #        secret "qBa5wSknF3vOKW6yXIf/aQ==";
  # };
  #
  # contorls {
  #       inet 127.0.0.1 port 953
  #               allow { 127.0.0.1; } keys { "rndc-key"; };
  # };
  # End of named.conf
    BIND9では、ポートが指定されなかった場合はデフォルトでポート953をリッスンする。
 ここで注意すべき点が1つあります。生成した鍵情報さえ分かれば、rndcを利用して誰でも該当するDNSサーバーにアクセスできることです。「-a」オプション付きでrndc-confgenを実行したときは/etc/rndc.keyをパーミッション400で生成するため、不用意に読み出させてしまう心配はありません。ただし、「-a」オプションなしに起動してリダイレクトしたいときは、/etc/rndc.confの属性に注意する必要があります。もちろん、むやみに制限をきつくしなくても、例えばwheelのメンバーはsuコマンドを実行しなくてrndcが起動できるように設定することも可能です。この観点からすると、rndc-confgenの出力の後半部分をそのままnamed.confに取りこんでおいて、named.confが誰からも参照してしまうのは好ましくありません。rndc-confgenの出力の後半部分を独立したファイル(ここではmykey)に書き出し、named.confではincludeステートメントによって取りこむ方法もあります。そして、このファイルの属性を適切に設定すれば良い。(つまり、鍵(パスワード)をrndc.confとnamed.conf(直接記述した場合)の保存するため、これらのファイルはネームサーバーを制御する権限を持たないユーザには読まれてはいけないと言うことです。)
 ここまでの設定が済んだら、named.confではcontrolsステートメントのパラメータで
  controls {
      inet * port 953
      allow { 127.0.0.1; 192.168.3.152/29; }
      keys { "rndc-key": };
  };
とループバック以外のアドレスのおいてもrndcからのアクセスを待ち受けるとともに、適切なホストからのアクセスを許可します。さらに、scpコマンドやリムーバブルメディアなど安全な方法を利用してrndc.confを別のホストにコピーすれば、リモートホスト上で動作するnamedを制御出来るようになります。
 このとき、rndcの「-s」オプションで対象サーバーを指定しても問題ありませんが、制御対象のホストが決まっているならrndc.confの中のdefault-serverで設定したほうがいいでしょ。
  options {
          default-server 192.168.3.153;
          default-port 953;
  };
 複数のネームサーバーを制御する場合は、各ネームサーバーに異なる鍵を割り当てることができます。複数の鍵を別々のkeyステートメントで定義してから、serverステートメントで異なるネームサーバーに鍵を割り当てます。
  server 127.0.0.1 {
         key "rndc-key";
  };
  server wormhole.movie.edu {
         key "wormhole-key";
  };
 rndcを実行する際には、-sオプションで制御対象のネームサーバーを指定します。
 % rndc -s wormhole.movie.edu reload
 鍵をネームサーバーに割り当てていない場合でも、コマンドラインオプションの-yを使って鍵を指定できます。
 % rndc -s wormhole.movie.edu -y rndc-wormhole reload
 ネームサーバーが標準ポート(953)以外のポートで制御メッセージをリッスンする場合は、-pオプションでポートを指定しなければならない。
 % rndc -s terminator.movie.edu -p 54 reload
BIND8および9のログ出力

 チャネルは、ログデータの出力先(syslog、ファイル、namedの標準エラー出力、ビットバケット)を指定します。
 カテゴリは、ログ出力するデータの種類を指定します。

syslogのファシリティ
ファシリティ 意味
KERN カーネルからのメッセージであり、ユーザプロセスでは発行できない
USER ユーザプロセス全般
MAIL メール関連
DAEMON 個別に定義されていないデーモンからのメッセージ
AUTH 認証関連
SYSLOG syslogd自体のメッセージ
LPR プリンタ関連
NEWS ネットニュース関連
UUCP uucp関連
CRON cronからのメッセージ
AUTHPRIV 認証関連だが、限定ユーザだけが見てもよいメッセージ
FTP fpdからのメッセージ
NTP NTP関連
SECURITY セキュリティ関連(IP firewallなど)
CONSOLE コンソールから出力されるメッセージ
LOCAL0-7 ユーザ定義用

syslogのレベル
レベル 意味
EMERG 緊急事態
ALERT すぐに対処が必要
CRIT ハードエラーなど重大なエラー
ERR エラー
WARNING 注意
NOTICE エラーではないが対応が必要
INFO 付加的な情報
DEBUG [level] デバッグ用メッセージ
DYNAMIC デバックレベルに応じたログ出力
  logging {
    channel my_syslog {
       syslog deamon;
       // syslogにはデバッグメッセージは送られていないので、
       // 重大性のレベルをdebugやdynamicに設定しても意味がない。
       // syslogの最低レベルであるinfoを使うこと。
       severity info;
    };
    channel my_file {
       file "log.msgs";
       // すべてのデバックメッセージを出力するために、
       // 重大性レベルをdynamicに設定する。
       severity dynamic;
    };
    category statistics { my_syslog; my_file; };
       // 統計データをsyslogとファイルに出力する。
    category queries { my_file; };
       // 問い合わせデータをファイルに出力する。
  };
 ただし、このままではネームサーバーを起動し、問い合わせを送ってもlog.msgsには何も書き込まれません。問い合わせをログ出力するには、ネームサーバーのデバッグ機能を有効にする必要があります。
 #ndc trace (BIND8の場合)
 #rndc trace (BIND9の場合)
 このコマンドを実行してから、ネームサーバーにいくつかの問い合わせを送ると、それらはlog.msgsに出力されるようになります。ネームサーバーの作業ディレクトリを見てみると、named.runという新しいファイルができています。このファイルにはlog.msgsに出力されないデバック情報がすべて書き込まれます。しかし、統計と問い合わせが欲しいだけで、すべてのデバック情報を必要ないのです。named.runを取り除くにはどうすればいいのだろうか?
 ここまでで、述べていない特殊なカテゴリがあります。それはdefaultです。カテゴリに対して1つもチャネルを指定しないと、BINDはdefaultカテゴリに割り当てられているチャネルにメッセージを送ります。そこで、すべてのログメッセージを破棄するよう、defaultカテゴリを変更してみよう(このために、nullというチャネルが用意されている)。
  logging {
    channel my_syslog {
       syslog deamon;
       severity info;
    };
    channel my_file {
       file "log.msgs";
       severity dynamic;
    };
    category default { null; };
    category statistics { my_syslog; my_file; };
    category queries { my_file; };
  };
 上記のように記述してから、ネームサーバーを起動し、デバッグレベルを1に設定して、いくつかの問い合わせを送ればlog.msgsに出力され、named.runは作成されますが、空になっています。
 何日かたつと、syslogに送られてくるメッセージが、それまでより少ないことに気づきました。実際に、syslogに出力されているのは統計のメッセージだけで、監視していたゾーン転送のメッセージがなくなっています。どうしたらよいのでしょうか?
 defaultカテゴリは、デフォルトではsyslogとデバックファイル(named.run)の両方にメッセージを送るように設定される。defaultカテゴリをnullチャネルに設定したため、他のsyslogメッセージも止められてしまったためです。次のように記述すればよい。
    category default { my_syslog; };
 これにより、syslogメッセージはsyslogに送られますが、デバッグメッセージやsyslogメッセージをファイルに書き込むことありません。

loggingステートメント

 以下に、loggingステートメントの構文を示します。
  logging {
    [ channel channel_name {
      ( file path_name
        [ versions ( number | unlimited ) ]
        [ size size_spec ]
      | syslog ( kern | user | mail | daemon | auth | syslog | lpr |
                 news | uucp | authpriv | ftp |
                 local0 | local1 | local2 | local3 |
                 local4 | local5 | local6 | local7 )
        null );
      [ severity ( critical | error | warning | notice |
                   info | debug [ level ] | dynamic ); ]
      [ print-category yes_or_no; ]
      [ print-severity yes_or_no; ]
      [ print-time yes_or_no; ]
    }; ]
    [ category category_name {
      channel_name; [ channel_name; ... ]
    }; ]
    ...
  };
 次に、デフォルトのチャネルを示します。管理者が望まなくても、ネームサーバーはこれらのチャネルを作成します。デフォルトのチャネルは再定義できず、新たにチャネルを追加することだけが可能です。
  channel default_syslog {
      syslog daemon;         // daemonの分類でsyslogに送る。
      severity info;         // info以上のレベルだけを送る。
  };
  channel default_debug {
      file "named.run";      // 作業ディレクトリのnamed.runに書き込む。
      severity dynamic;      // ネームサーバーの現在のデバックレベルでログ出力する。
  };
  channel default_stderr {   // strerrにデータを書き込む。
      stderr       ;         // 独自のstderrチャネルを定義できるのは
                             // BIND 9のみ。BIND 8には、default_stderr
                             // チャネルが組み込まれている。
      severity info;         // info以上のレベルだけを送る。
  };
  channel null {
      null;                  // このチャネルに送られてくるデータは全て捨てる。
  };
 BIND8のネームサーバーでdefault、panic、packet、およびeventlibの各カテゴリにチャネルを割り当てないと、次のようなデフォルトのチャネルが割り当てられます。
  logging {
      category default { default_syslog; default_debug; };
      category panic { default_syslog; default_stderr; };
      category panic { default_debug; };
      category eventlib { default_debug; };
  };
 BIND9のネームサーバーは、次のデフォルトのログ出力ステートメントを使います。
  logging {
      category default {
          default_syslog;
          default_debug;
      };
  };
 前に述べたように、defaultカテゴリはsyslogとデバックファイル(デフォルトではnamed.run)の両方にログ出力します。つまり、infoレベル以上のレベルのsyslogメッセージはすべてsyslogに送られ、デバック機能を有効にすると、syslogメッセージとデバックメッセージがnamed.runに書き込まれます。これは、BIND4の動作とほぼ同じです。

チャネルの詳細

 チャネルからの出力は、ファイル、syslog、またはnullに設定できる。

ファイルチャネル
 チャネルからファイルに出力するには、そのファイルのパス名を指定する必要があります。必要に応じて、同時に存在できるファイルのバージョン数と最大のファイルサイズを指定することができます。
 例えばバージョンを数を3に設定すると、BIND8またはBIND9はfile、file.0、file.1、file.2を用います。ネームサーバーが起動した後、あるいはreloadコマンドによってリロードした後に、file.1はfile.2、file.0はfile.1、fileはfile.0にそれぞれリネームされ、新しいコピーはfileに作られます。BINDでは、バージョン数を制限しないと、99のバージョンが作成されます。
 最大のファイルサイズを指定すると、ネームサーバーはファイルがそのサイズに達すると書き込みを停止します。versionサブステートメントとは違って、指定したファイルサイズに達しても、ファイルを交換することはない。ネームサーバーはファイルへの書き込みを単純にやめます。ファイルサイズを指定しないと、ファイルは無限に大きくなります。
 バージョン数とファイルサイズはfileサブステートメントのversionとsizeで指定します。
  logging {
    channel my_file {
       file "log.msgs" version 3 size 10k;
       severity dynamic;
    };
  };
 この例にあるように、ファイルサイズには単位指定を使うことができます。Kまたはkはキロバイト、Mまたはmはメガバイト、そしてGまたはgはギガバイトを表します。
 デバックメッセージを見たいときは、重要度のレベルをdebugまたはdynamicに設定する必要があります。デフォルトのレベルであるinfoでは、syslogメッセージだけが出力される。

syslogチャネル
 チャネルからsyslogにデータを出力する場合には、kern、user、mail、daemon、auth、syslog。lpr、news、uucp、cron、authpriv、ftp、local0、local1、local2、local3、local4、local5、local6、local7のいずれかの分類を選択します。デフォルトはdaemonであり、このデフォルトをお勧めします。
 daemonの代わりにlaocal0を使ったsyslogチャネルを例に示します。
  logging {
    channel my_syslog {
       syslog local0;         // local0の分類でsyslogに送る。
       severity info;         // info以上のレベルだけを送る。
    };
  };
stderrチャネル
 default_stderrは、ネームサーバーのstderrファイルディスクリプタにメッセージを書き込むために、あらかじめ定義されたチャネルです。

nullチャネル
 nullは破棄したいメッセージの出力先としてあらかじめ定義されているチャネルです。

チャネルのデータフォーマット
 BIND8および9のログ出力機能では、メッセージのフォーマットを制御することができる。メッセージにタイムスタンプ、カテゴリ、重要度のレベルを含めることができます。
 こららの項目をすべて含んだデバックメッセージの例を示します。
  01-Feb-1998 13:18:37.344 config: debug 1: source = db.127.0.0
 このメッセージでは、カテゴリがconfig、重要度のレベルがdebugのレベル1になっています。
 3つの項目すべてを出力するチャネル設定の例を示す。
  logging {
    channel my_file {
       file "log.msgs";
       severity debug;
       print-category yes;
       print-severity yes;
       print-time yes;
    };
  };
 ただし、syslogチャネルへのメッセージにタイムスタンプを加えてもあまり意味はありません。syslogでは、日付と時刻が自動的に挿入されるからです。

カテゴリの詳細

 BIND8および9ではカテゴリの数が非常に多い。しかも全部異なるカテゴリなのである。そのすべてを以下にリストアップします。ただし、どのカテゴリを見たいかを調べるより、すべてのログメッセージをカテゴリと重要度のレベルを含めて出力するようにネームサーバーを設定し、見たいメッセージを拾い出す方法をお勧めします。その方法を説明する前に、各カテゴリを紹介します。

BIND8のカテゴリ

default
 カテゴリに対してチャネルを指定しないと、defaultカテゴリが代わりに使われます。その意味では、defaultは全カテゴリを意味しています。しかしながら、どのカテゴリにも分類されないメッセージもあります。したがって、すべてのカテゴリに個々のチャネルを指定した場合でも、カテゴリに分類されないメッセージの出力先として、defaultカテゴリのチャネルを指定したほうがよい。
 defaultカテゴリに対してチャネルを指定しないと、次のチャネルが自動的に指定されます。
  category default { default_syslog; default_debug; };
cname
 CNAMEエラー(たとえば、「CNAMEと他のデータがある」)

config
 ハイレベルの設定ファイルの処理

db
 データベース操作

eventlib
 システムイベント。1つのファイルチャネルを参照すること。デフォルトは次の通り。
    category eventlib { default_debug; };
insist
 内部の一貫性検査の失敗

lame-servers
 誤った委任の検知

load
 ゾーンのロードに関するメッセージ

maintenance
 定期的な保守イベント(たとえば、システムの問い合わせ)

ncache
 ネガティブキャッシュのイベント

notify
 非同期ゾーン更新通知

os
 オペレーティングシステムの問題

packet
 送受信したパケットを複合化した情報。1つのファイルチャネルを参照すること。デフォルトは次の通り。
    category packet { default_debug; };
panic
 ネームサーバーの停止の原因となる問題。これらの問題は、panicカテゴリと、nativeカテゴリの両方に出力されます。デフォルトは次の通り。
    category panic { default_syslog; default_stderr; };
parser
 ローレベル設定ファイルの処理

queries
 BIND4の問い合わせログ出力に対応

response-checks
 誤った形式の応答、関連のない追加情報など

security
 許可されたリクエストと許可されなかったリクエスト

statistics
 ネームサーバー動作の定期的な報告

update
 動的更新のイベント

xfer-in
 他のネームサーバーから自分へのゾーン転送

xfer-out
 自分から他のネームサーバーへのゾーン転送

BIND9のカテゴリ

default
 BIND8と同じように、BIND9のdefaultカテゴリも、チャネルに割り当てられていない全カテゴリと一致します。ただしBIND8とは異なり、BIND9のdefaultカテゴリは、分類不能のBINDメッセージとは一致しません。これらは、次に説明するカテゴリに含まれます。

general
 generalカテゴリには、分類不能なBINDメッセージが含まれます。

client
 クライアント要求の処理

config
 設定ファイルの解析と処理

database
 BINDの内部データベースに関連するメッセージ。ゾーンデータをキャッシュレコードの格納に使われます。

dnssec
 DNSSEC署名つき応答の処理。

lame-servers
 不当な委任の検出(BIND9.1.0で再び追加されました。それまでは、不当な委任に関するメッセージはリゾルバログに出力されていました。)

network
 ネットワーク動作

notify
 非同期ゾーン更新通知

queries
 BIND8の問い合わせログ出力に対応(BIND9.1.0で追加)

resolver
 名前解決、リゾルバからの再帰問い合わせ処理を含む

security
 要求の承認/非承認

update
 動的更新イベント

xfer-in
 リモートネームサーバーからローカルネームサーバーへのゾーン転送

xfer-out
 ローカルネームサーバーからリモートネームサーバーへのゾーン転送