ゾーンサーバーは再帰検索を禁止して運用するのが普通であり、他のサーバーからのデータを内部に溜め込んだりはしない。このため、ゾーンデータさえ正しければDNSソフトウェアによる回答の差異は比較的少ないので、BINDとdjbdns(tinydns)のどちらを使ってもよいだろう。ここでは、設定ファイルが比較的読みやすいBIND9を使うことにする。先ほども説明したとおりBINDは非常に多機能で、ゾーンサーバーとしてだけ使うのには、宝の持ち腐れという意味でも、サーバーのリソースという意味でも少々(かなり?)もったいない。しかし、ゾーンサーバー専用として設定した方が設定が簡単になり、間違いや問題も少なくなるので、特に最初は無理にキャッシュなどを設定しない方がよい。
[BINDのインストール]
BINDには現在使われているものでもいくつかバージョンがある。大きくBIND4・BIND8・BIND9の三つである。BIND4は他と設定ファイルの形式が違う。BIND8とBIND9はほぼ同じであるが、BIND9はビューという機能があるのと、ゾーンファイル中のTTL(Time To Live、残存時間)の扱いが以前と多少異なっている。BIND9を避ける理由は特にないので、BIND9でよいだろう。
インストール自体は比較的簡単で、ISCのページから最新のソースを落としたら、お好みでPGP署名を確認し、tar xfvz bind-9.2.*.tar.gz で展開、bind-9.2.* ディレクトリに入って、あとは ./configure ; make し、スーパーユーザーで make install でおしまいである。デフォルトではデーモンが /usr/local/sbin/named としてインストールされ、立ち上げ時に読み込まれる設定ファイルは /etc/named.conf である。
インストールが済んだら、ブート時に立ち上がるようにしなければならない。FreeBSDでは rc.conf で指定できるのだが、FreeBSDには /usr/sbin に named が入っている(FreeBSD 4.9の場合 BIND 8.3.6。ちなみにこのnamedが使う設定ファイルは /etc/namedb/named.conf である)ため、単に named_enable を YES に設定しただけでは今インストールした named は使われない。named_program で立ち上げたい named のフルパスを指定してやる必要がある。
named_enable="YES"
named_program="/usr/local/sbin/named"
dnscacheと同じホストでnamedを動かす場合、プライマリインターフェースのポート53が空いておらず、このままではBINDがLANからの要求を受けることができない。インターフェースは一つしかないが、エイリアスという機能を使うと、一つのインターフェースに複数のIPアドレスを割り振ることができる。FreeBSDの場合、ハンドブックの「バーチャルホスト」の部分に詳しく載っている。Linuxにも同様の機能があるはずである。例えば、FreeBSDが動いているホストox.alpha.example.jp(192.0.2.2)にエイリアス192.0.2.53を割り当てたければ、/etc/rc.conf に
ifconfig_ed1="inet 192.0.2.2 netmask 255.255.255.0"
ifconfig_ed1_alias0="inet 192.0.2.53 netmask 255.255.255.255"
と書いてリブートすればよい。もちろん、ed1 の部分は実際に使っているインターフェースデバイス名に置き換える必要がある。エイリアスは二つ以上定義することもできて、その場合はalias0の部分をalias1 alias2・・・と増やしていけばよい。エイリアスのIPアドレスのネットマスクはオール1に設定する。
どちらのIPアドレスをどちらのDNSに振るかは自由である。dnschacheのIPアドレス設定は /etc/dnscahce/env/IP というファイルにサーバーが動作するIPアドレスが書いてあるので、このファイルを変更すればよい。BIND9の場合は後述する。
インストール時にもう一つやらなければならないことがある。rndcのセットアップである。rndcはRemote Name Daemon Controlの略で、これを使うとゾーンファイル・設定ファイルの読み込み直しなどが簡単にできるようになる。Remoteが付いていることから分かるように、このプログラムはネットワーク経由でネームサーバーを制御することができるが、今回はそこまでしなくてもよいだろう。そうすると設定は簡単で /usr/local/sbin/rndc-confgen -a を実行すればよい。
・・・はずなのだが、FreeBSD 4.7・FreeBSD 4.9ともこれではだめで、-r オプションでランダムデバイスを指定する必要があった。たいてい /dev/random で済むのだが、今回はそれでもだめで、/dev/urandom を使った。ランダムデバイスがどうにも調達できない場合は普通のファイルを指定できる。与えるファイルは圧縮されている方が乱数度は高くなる。
/usr/local/sbin/rndc-confgen -a -r /dev/urandom
もう一つ、できればファイアウォールによってアクセスを制限しておく。内部専用のサーバーは外から見えるべきではないからである。外からの攻撃も防ぐことができ、また、たとえ設定を間違えたとしても影響を最小限にとどめることができる。FreeBSDのipfwならば、ipfw add 番号 deny ip from any to any 53 in recv tun0 などと設定すればよい。「番号」は適切なルール番号を指定する。tun0は外部接続に使っているインターフェースを指定する。
[BINDの設定]
BINDの設定には/etc/named.confを使用する。プライマリマスタサーバーの設定は概ね以下の通りになる。
options {
directory "/var/named";
pid-file "/var/named/named.pid";
listen-on { 192.0.2.2; };
allow-transfer { none; };
notify no;
recursion no;
};
zone "alpha.example.jp" {
type master;
file "db/alpha.zone";
};
zone "2.0.192.in-addr.arpa" {
type master;
file "db/192.0.2.zone";
};
よく、BINDの設定は複雑だと言われるが、見た感じどうだろうか? 他のBINDの設定ファイルに比べてすっきりした印象を受けるはずである。キャッシュとゾーンサーバーを分けるとこれだけ簡単になるのである。
directoryはnamedの動作の基準になるディレクトリを指定する。ゾーンデータベースファイルの指定はこのディレクトリからの相対パスになり、統計情報などもこのディレクトリに出力される。ただし、PIDファイルだけは /var/run/named.pid となるので、/var/named の下に出力したければ例のように書いておかなければならない。
listen-on は問い合わせを受け付けるアドレスである。listen-on を書かなければ全インターフェースが使用される。dnscacheと同じホストでBINDを動かす場合、listen-on オプションが必要になる。正確に言うと起動順序にもよるのだが、明示的に書いておいた方がよいだろう。
次の3行はアクセス制限に関するものである。allow-transfer と notify は、ゾーン転送を許可するスレーブサーバーと、ゾーンファイルが更新されたときにスレーブサーバーに伝えるか、を示している。今回の場合、スレーブはないので明示的に止めておく。
recursion no は再帰検索の禁止である。再帰検索とは、クライアントから問い合わせを受けたときに、その問い合わせの答えを見つけるまで複数のサーバーに問い合わせを送る動作のことを指す。キャッシュサーバーは当然再帰検索しなければならないが、ゾーンサーバーは自分のゾーンにのみ責任を持てばよいので、知らないゾーンに対しては他のサーバーに問い合わせずに「知らん!」と返してよい。また、再帰検索は繰り返し多数のホストに問い合わせを送るためサーバーに負荷がかかり、不要な再帰検索要求を大量に送りつけられるとサーバーダウンの原因になるため、ゾーンサーバーでは禁止しておくのが普通である。
これで基本的なオプション設定はおしまい。あとは問い合わせを返すゾーンと、ゾーン情報の入ったゾーンファイルの名前をずらずらと指定すればよい。alpha.example.jp ゾーンはいいだろう。aplha.example.jp ドメインの問い合わせがあった場合は、alpha.zone ファイルを参照して回答を行う。
もう一つ、2.0.192.in-addr.arpa という見慣れないゾーンがある。これは、IPアドレスから名前へ逆変換するためのゾーンファイルである。DNSは名前をIPアドレスに変換するときに使われるが、IPアドレスを名前にするときにも使われる。そして、変換手順はどちらも同じものが使われる。IPアドレスの場合は in-addr.arpa ドメインから始めて、このドメインに、IPアドレスの数字を、上(左)の方から、サブドメインの名前として付加しながら検索していく。
例えば、192.0.2.3 ならば、まずルートサーバーに arpa ドメインのサーバーをたずね、arpa ドメインのサーバーに in-addr.arpa ドメインのサーバーをたずね、192.in-addr.arpa ドメインのサーバーをたずね・・・というように検索していく。したがって、192.0.2.0/24 ネットワークの名前は 2.0.192.in-addr.arpa ゾーンのサーバーに問い合わせればよいのだが、このアドレスはローカルアドレスであり、このゾーンについて権威を持ったサーバーはインターネット上にない(当たり前だ。逆にいえばだからこそ自由に名前が付けられる)。したがって、DNSを用いてLAN内のIPアドレスを名前に変換したければ、2.0.192.in-addr.arpa についての情報も持たせておかなければならない。
この他に、"." と localhost と 0.0.127.in-addr.arpa ゾーンを持たせることもある。"." はルートサーバーへたどり着くためのヒントとして常に必要なのだが、クラスINの場合はBIND内部にヒント情報を持っているため不要である。ルートサーバーのIPアドレスが変わると、キャッシュの場合は更新されたルートヒントファイルを指定する必要があるが、ゾーンサーバーの場合ヒントが使われることがないのでそのような手間も不要である。残りの二つは常に自分自身を示すアドレス 127.0.0.1 と、それに対応する慣用的な名前 localhost のためのゾーンである。しかし、これらの名前・アドレスはdnschacheが勝手に変換してくれるため、dnschacheを使う場合はこれらのゾーンは必要ない。
[ゾーンファイル]
実際に指定されたゾーンにどんなホストが存在するのかを書き示したのがゾーンファイルで、基本的にホストとアドレスの対応表だと思えばよいだろう。ゾーンファイル名は、named.conf 内の directory オプションで指定したパスを基準にした相対パスを、zone 内の file に記述する。先ほどの例だと directory が /var/named で、alpha.example.jpゾーンの file 指定は db/alpha.zone だから、alpha.example.jp ゾーンのゾーンファイルは /var/named/db/alpha.zone となる。
ゾーンファイルはリソースレコード(略してRRとも言われる)がずらずら並べられた形になっている。基本的に1行が1レコードに対応するが、SOAのように資源データのフィールド数が多く、1行が長くなる場合は、行末に ( を書くことでレコードを複数行に渡って書くことができる。
各レコードは 名前 クラス TTL タイプ 資源データ の順にデータが並んでいる。なお、クラスとTTLは省略可能で、両方書く場合はどちらを先に書いてもよい。名前はこのレコードがどの名前についての情報なのかを示す。省略記法があるが後述する。クラスはどういうアドレス空間かを示すものだが、現在のところIN(インターネット)以外に広く使われているものはない。TTLはTime To Liveの略で、残存時間のことである。タイプはこのレコードがどんな情報を示しているかを示す。資源データ(略してRDATAとも言われる)はタイプによって記述が異なる。
先ほどの例
rat.alpha.example.jp | 192.0.2.1 | ゲートウェイ gw.alpha.example.jp
|
ox.alpha.example.jp | 192.0.2.2 | DNS ns.alpha.example.jp
|
tiger.alpha.example.jp | 192.0.2.3 |
|
hare.alpha.example.jp | 192.0.2.4 |
|
dns.alpha.example.jp | 192.0.2.53 | DNSキャッシュ
|
をゾーンファイルに書いてみると、以下のようになる。
$TTL 432000
@ 3600 SOA ns.alpha.example.jp. dnsadmin.alpha.example.jp. (
2004012201 ; serial
10800 ; refresh
3600 ; retry
604800 ; expire
600 ) ; negative
NS ns
rat A 192.0.2.1
ox A 192.0.2.2
tiger A 192.0.2.3
hare A 192.0.2.4
gw A 192.0.2.1
ns A 192.0.2.2
dns A 192.0.2.53
最初の $TTL はリソースレコード中のTTLフィールドを省略した場合に使用されるTTL(デフォルトのTTL)を指定する。次の行のタイプSOAのレコードは「権威開始(Start Of Authority)」の意味である。ゾーンファイルで最初に出てくるリソースレコードは原則としてSOAレコードになる。名前が @ になっているが、名前に @ と書くと、$ORIGIN で指定した名前か、named.conf 中の対応する zone で指定されているゾーン名に置き換えられる。この名前のことを「基点名」と呼ぶ。今ならば alpha.example.jp になる。クラス IN は省略されていて、TTLが3600と指定されている。単位は秒なので、他のDNSキャッシュサーバー・クライアントがこのリソースレコードを問い合わせた場合、その結果を1時間はキャッシュに保存していてくれる。
SOAの資源データはプライマリマスタネームサーバー名、管理者メールアドレス、シリアル番号、リフレッシュ間隔、リトライ間隔、期限切れとなる時間、ネガティブキャッシュ時間 である。上の例ではシリアル番号からネガティブキャッシュ時間までが ( ) に入れられ、複数行に渡って記述されている。
プライマリマスタサーバー名は、同じゾーンで権威を持っているどのサーバーに問い合わせても、同じ名前を返すように設定する。今はネームサーバーは ns.alpha.example.jp しかないのでこれを書いておけばよい。管理者メールアドレスは通常のメールアドレスの @ を . に変えたものである。この場合だと dnsadmin@alpha.example.jp を意味することになる。なお、メールアドレスのユーザー名に . が含まれる場合、\ でエスケープしなければならない。
その後の4つはスレーブサーバーが参照するものなので今のところあまり深く考える必要はない。最後のネガティブキャッシュ時間は、他のDNSキャッシュサーバー・クライアントがこのゾーン内にない名前を検索したときに、その結果を(キャッシュ・クライアントが)何秒間保存すべきかを示している。通常はTTLよりもだいぶ短めに設定する。この例だと10分である。
なお、RFC1035ではネガティブキャッシュ時間の部分は「最小TTL」として定義されている。BIND8まではゾーンのデフォルトTTLとして扱っていた。RFC2308でネガティブキャッシュキャッシュ時間として新たに定義しなおされ、デフォルトTTLを表現するために $TTL というディレクティブが導入された。これに伴い、BIND9でのデフォルトTTLは$TTLディレクティブで指定するように変更されている。もし指定がなかった場合、BIND9.1とBIND9.2は起動時にエラーとなる。BIND9.3は警告を出した上で、SOAのネガティブキャッシュ時間に書かれている値をデフォルトのTTL時間として扱う。
もう一つ、RFC2181には「SOAのTTLは0であるべきだ」という意味のことが書かれている。想像だが、SOAにはスレーブサーバーがゾーンデータの更新を知る手がかりとなるシリアル番号が含まれており、キャッシュされてしまうと都合が悪いからだろう。しかし、実際に世の中にあるサーバーでは0になっているものは少ない。例えば、ルートサーバー a.root-servers.net に "." のSOAをたずねると、TTLは86400(1日)が返ってくる。cr.yp.toが収容されているサーバーでは2560(約40分)という値が返ってくる。返ってくる値は0ではないのだが、他のリソースレコードに比べてずいぶん短い値が返ってくる。
通常の使用ではSOAが必要な場合というのはほとんどないから、SOAに短めのTTLを設定しても、ネットワークトラフィックはほとんど影響を受けない。他のリソースレコードにはSOAに比べ頻繁に参照されるため、TTLはある程度長い値(数日程度)にしておくのが望ましい。ここでは、SOAについてはTTLを3600(1時間)として、他のリソースレコードについてはTTLを432000(5日)としてみた。なお、サーバー移転などの際には前もってこの値を小さくしておく必要がある。
次のレコードはNSレコードで、このゾーンに権威のあるネームサーバーを指定する。一つのレコードにつき一つのサーバーしか指定できないので、スレーブサーバーがある場合はNSレコードを複数書くことになる。名前が省略されているが、省略された場合は直前のレコードと同じ名前を使う。直前は@、つまり alpha.example.jp だったから、これがそのまま使われる。TTLは省略されているので、$TTLディレクティブの値432000が使用され、5日間キャッシュされる。NSレコードの資源データはネームサーバーの名前を(一つだけ)書く。ns とだけ書いてあるが、最後にピリオドがない名前は基点名が補われる。今の場合だと alpha.example.jp ドメインが補われて ns.alpha.example.jp になる。
余談だが、SOAのプライマリマスタサーバー名、管理者メールアドレスも同様に省略できるので、実は ns dnsadmin と書いてもよかったのである。が、この部分はあまり省略しないのが普通(後述)で、省略しない場合は最後にピリオド "." を付けなければならない。これを忘れるととてつもなく長い(そして変な)名前ができあがってしまう。これはゾーンファイルの中だけの話なので、named.conf の zone指定では後ろにピリオドを付けないで指定する。
NSレコードの後にはAレコードが並んでいる。これは、名前とアドレスの対応を示したものである。名前は最後にピリオドがないから基点名が補われ、例えば rat は rat.alpha.example.jp として扱われる。クラスは省略されているのでIN、TTLも省略されていて$TTLディレクティブの値が使われ、5日である。Aレコードの資源データはIPアドレスである。IPアドレスは名前ではないので後ろにピリオドは付けない。
よく見ると同じIPアドレスを持ったAレコードがあることに気づくだろう。IPアドレスは一つのAレコードにつき一つしか書けないため、一つのホストが(同じIPアドレスで)複数の名前を持つような場合、このようにして複数のホスト名を定義する。逆に、一つのホストが複数のIPアドレスを持っているような場合は、同じ名前に対して複数のAレコードを定義すればよい。続けてAレコードを書けば2行目以降の名前は省略できる。
[逆引き]
これで名前からIPアドレスへの変換のためのデータは揃った。しかし、DNSはIPアドレスから名前への変換を自動ではやってくれないので、逆引きのためのデータも書く必要がある。先ほどちょっと述べたが、逆引きの場合はIPアドレスを逆に並べて、in-addr.arpaを最後に補った名前を指定してDNSに問い合わせを出す。例えば、192.0.2.3 に対応するホスト名を調べたければ、3.2.0.192.in-addr.arpa を指定してDNSに問い合わせを出す。これはもはやIPアドレスではなく、in-addr.arpa という変なドメインに属しているという点を除けば、ns.alpha.example.jp と同様の名前として扱われる。答として tiger.alpha.example.jp というPTRレコードが返ってくるように 2.0.192.in-addr.arpa ゾーンのゾーンファイルを書く。例えば、以下のようになる。
$TTL 432000
@ 3600 SOA ns.alpha.example.jp. dnsadmin.alpha.example.jp. (
2004012201 ; serial
10800 ; refresh
3600 ; retry
604800 ; expire
600 ) ; negative
NS ns.alpha.example.jp.
1 PTR rat.alpha.example.jp.
PTR gw.alpha.example.jp.
2 PTR ox.alpha.example.jp.
PTR ns.alpha.example.jp.
3 PTR tiger.alpha.example.jp.
4 PTR hare.alpha.example.jp.
53 PTR dns.alpha.example.jp.
書き方はほとんど同じだが、いろいろ注意する点がある。SOAとNSは先ほどと同じだが、こちらのゾーンファイルは 2.0.192.in-addr.arpa ゾーンのものであるから、基点名が 2.0.192.in-addr.arpa である。したがって、SOAレコードのネームサーバー名、管理者アドレス、NSレコードの資源データに指定する名前はドメインを省略できない。うっかり省略してしまうと ns.alpha.example.jp にならず、ns.2.0.192.in-addr.arpa という変な名前ができあがってしまう。SOAレコードはコピー・ペーストして使うことが多いため、SOAのネームサーバー名・管理者アドレスはドメインを省略しないでFQDN(Fully Qualified Domain Name、完全修飾ドメイン名)を書いた方が後々間違いが少ない。後ろのピリオドを忘れないように。
以下、PTRレコードが並ぶ。PTRレコードも左側に書くのは名前なので、基点名省略の規則が適用される。したがって、1 と書くと 2.0.192.in-addr.arpa が補われて 1.2.0.192.in-addr.arpa という名前ができがる。これは、キャッシュやクライアントがIPアドレス 192.0.2.1 を問い合わせるときに使う名前になっている。これに対する答えが右側に書いてあるが、右側も名前なので基点名省略の規則が適用されるが、先ほどからしつこく述べているように基点名は 2.0.192.in-addr.arpa だから、FQDNを書かなければならない(後ろのピリオドを忘れないように)。
最初のPTRレコードの次の行(やはりPTRレコード)は名前が省略されている。省略されているのは名前なので、名前を省略した場合の規則が適用される。つまり、直前の名前がそのまま使われる。したがって、1.2.0.192.in-addr.arpa に対する定義、言い換えるとIPアドレス192.0.2.1に対する定義だということになる。よって、IPアドレス192.0.2.1は二つのPTRレコードを持ち、rat.alpha.example.jp と gw.alpha.example.jp という名前に対応する。実際に正引きの方のゾーンファイルと対応していることが分かるだろう。あとで実際にテストしてみると、ちゃんと両方の名前が返ってくることが分かるはずだ。
[起動とテスト]
これでBINDの設定ファイルは全部そろったので /usr/local/sbin/named を起動する。できればブートして確認するとよい。起動したら /var/log/message あたりを見て、エラーを出力していないかどうか確認する。
テストには nslookup / dig / host といったツールを使う。djbdns には dnsq / dnsqr などのツールが付いてくるのでこれを利用してもよい。nslookup は将来のBINDリリースからは外される予定のようだ。dig はかなり詳細な情報を、ゾーンファイルとして使える形で出力する。host は dig より簡潔な出力になる。dnsq は host に近い。hostを使う場合は host -t レコードタイプ 名前 サーバー と打つ。dnsqの場合は dnsq レコードタイプ 名前 サーバー である。-tが不要だ。ただし、ptrレコードを検索する場合、hostはIPアドレスを指定すればよいのに対し、dnsqはin-addr.arpaドメインの名前を指定しなければならないので少々面倒である。
今はDNSの設定をテストしようとしているので、DNSサーバー名は省略できない。省略してしまうとデフォルトのDNSサーバー、通常はキャッシュサーバーを見に行ってしまう。キャッシュサーバーはまだ設定を変更しておらず、今立ち上げたDNSサーバを見るようにはなっていないから、問い合わせは全部失敗するだろう。host を使う場合、hostコマンドを実行するマシン自体が試験運用中ならば、一時的に /etc/resolv.conf を書き換えればサーバー指定を省略できる。
ここではhostを使ってみることにする。これらのツールはバージョンによってかなり表示内容が違う。ソースから何も考えずにインストールすると /usr/local/bin/host になるのだが、標準でBINDが入っている場合、単に host と打つと /usr/bin/host が使われることがある。
$ host -t soa alpha.example.jp 192.0.2.2
Using domain server:
Name: 192.0.2.2
Address: 192.0.2.2#53
Aliases:
alpha.example.jp SOA ns.alpha.example.jp. dnsadmin.alpha.example.jp. 2004012201 10800 3600 604800 600
$ host -t ns ns.alpha.example.jp 192.0.2.2
Using domain server:
Name: 192.0.2.2
Address: 192.0.2.2#53
Aliases:
alpha.example.jp name server ns.alpha.example.jp.
$ host -t a ns.alpha.example.jp 192.0.2.2
Using domain server:
Name: 192.0.2.2
Address: 192.0.2.2#53
Aliases:
ns.alpha.example.jp has address 192.0.2.2
$ host -t ptr 192.0.2.1 192.0.2.2
Using domain server:
Name: 192.0.2.2
Address: 192.0.2.2#53
Aliases:
1.2.0.192.in-addr.arpa domain name pointer gw.alpha.example.jp.
1.2.0.192.in-addr.arpa domain name pointer rat.alpha.example.jp.
$
ゾーンファイルに書いた順序で確かめていくとよいだろう。つまり、soa ns a ptr と調べていく。TTLまで見たい場合は -v をつけると詳細な情報を表示してくれる。
$ host -v -t soa alpha.example.jp 192.0.2.2
Trying "alpha.example.jp"
Using domain server:
Name: 192.0.2.2
Address: 192.0.2.2#53
Aliases:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56340
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; QUESTION SECTION:
;alpha.example.jp. IN SOA
;; ANSWER SECTION:
alpha.example.jp. 3600 IN SOA ns.alpha.example.jp. dnsadmin.alpha.example.jp. 2004012201 10800 3600 604800 600
;; AUTHORITY SECTION:
alpha.example.jp. 432000 IN NS ns.alpha.example.jp.
;; ADDITIONAL SECTION:
ns.alpha.example.jp. 432000 IN A 192.0.2.2
Received 888 bytes from 192.0.2.2#53 in 16 ms
$
間違いが見つかった場合は named.conf ファイルや対応するゾーンファイルを修正し、named に修正されたことを伝える。named を再起動してもよいが、通常は rndc reload とすることで named が各種設定ファイルを読み直してくれる。なお、rndc はデフォルトで /usr/local/sbin にインストールされる。
[キャッシュの設定]
これでゾーンサーバーの設定は終わったが、このサーバーを参照しているホストはまだ一台もない。キャッシュの設定を変更して、alpha.example.jp ドメインの名前解決の場合に限り ns.alpha.example.jp(192.0.2.2) を参照するように指示する。すると、LAN内のクライアントはキャッシュサーバーを参照しているので、特に設定を変更しなくても、キャッシュを通して間接的にゾーンサーバーを参照することになる。
djbdns(dnscache)の場合、この設定は /etc/dnscache/root/servers ディレクトリに、中身が参照先のサーバーのIPアドレスであるようなファイルを、ドメイン名と同じ名前で作ることで行う。今回の例だと、
# echo 192.0.2.2 > /etc/dnscache/root/servers/alpha.example.jp
# echo 192.0.2.2 > /etc/dnscache/root/servers/2.0.192.in-addr.arpa
でよい。忘れがちだが逆引きのための設定も必要である(二行目)。サーバーは複数設定できる。その場合はサーバーのIPアドレスを一行にひとつずつ書く。
あとは dnscache プログラムを再起動する。daemontools(supervise) 下で動いている場合、本来は svc プログラムで -t オプションを指定して dnscache を制御するのだが、実は dnscache プロセスを kill するだけでよい。kill すると supervise が dnscache を勝手に再起動してくれる。もし、テストの時にresolv.confを変更していたら、キャッシュを参照するように戻すのを忘れないこと。終わったら、LAN内のクライアントから alpha.example.jp ドメインの名前が解決できることを確認する。もちろん、外部のドメインの名前も解決できるはずである。
[BINDとdnscache] 〜FreeBSDの場合〜
上の例ではdnscacheを立ち上げるために /etc/rc を直接編集したが、/etc/rc を編集せずに済む方法もある。FreeBSD4系は /etc/rc.conf で named_enable="YES" とすると、named_program で指定されたプログラムを立ち上げるようになっているが、このシェル変数にはシェルスクリプトを指定することもできる。/etc/rc.named あたりに BIND9とdnscacheを続けて立ち上げるスクリプトを書いて、/etc/rc.conf の named_programに指定してやれば、/etc/rc を書き換えなくとも目的を達成できる。
例えば、/etc/rc.named として、
#!/bin/sh
if [ -x ${named_exec:='/usr/local/sbin/named'} ] ; then
${named_exec}
else
echo " - WARNING: ${named_exec} is not found."
fi
if [ -x /command/svscanboot ] ; then
echo -n ' djb-svscan'
sh -c '/command/svscanboot &'
fi
sleep 1
exit 0
こんなシェルスクリプトを書く。実行パーミッションを立てるのを忘れないように。ちなみに、sleep 1 はnamedが立ち上がってから実際に問い合わせを受け付けるようになるまで若干間があるようなので入れてある。rcスクリプト中でローカルDNSへの問い合わせが起きると、名前の解決に失敗してしまうことがあり、その防止策である。
あとは rc.conf の中で、
named_enable="YES"
named_program="/etc/rc.named"
としてブートすれば、しかるべき時点でBIND9とdnscache(正確にはsvscanとその仲間たち)が立ち上がる。ただし、svscan管理下のデーモンが他にあると、それらもここでガサガサ立ち上がってしまう欠点がある。
[DHCPとDNS]
$GENERATEディレクティブ。ダイナミックDNS。