DNSサーバーには、大きく分けてキャッシュサーバーとコンテンツサーバーの2つの種類があります。

種類 説明
キャッシュサーバー DNSクライアント(リゾルバ)から送られる再帰(Recursive)問い合わせを受け、名前解決が完了するまで、それぞれの名前について他のDNSサーバーに反復(Iterative)問い合わせを行なう。その結果をDNSクライアントに返答する。また、その結果をキャッシュする。
コンテンツサーバー ドメイン名とIPアドレスの対応表を「ゾーン」という単位で管理し、自分が管理しているゾーンに対する問い合わせだけに回答する。

ここで、DNSの名前解決方法には「再帰問い合わせ」と「反復問い合わせ」の2種類があったことを思い出してください。(詳細は「DNSの仕組み」参照。)

再帰問い合わせ リゾルバからの問い合わせを受けたDNSサーバが、他のDNSサーバに問い合わせを行いその最終的な結果をリゾルバに応答する問い合わせのこと。
反復問い合わせ リゾルバから再帰問い合わせを受けたDNSサーバーが、再帰問い合わせの結果を返すために、答えを得られるまで繰り返し他のDNSサーバへ行う問い合わせのこと。

前述のとおり、再帰問い合わせを受けて、他のDNSサーバーに反復問い合わせを行なうのがキャッシュサーバーです。例えば、下図に出てくる「社内DNSサーバー」はキャッシュサーバーになり、「ルートDNSサーバー」「.comのDNSサーバー」「example.comのDNSサーバー」はコンテンツサーバーになります。
DNSの名前解決方法

DNSフォワーダ

前回までの記事で構築してきたDNSサーバーは自身が管理する「webtest01.com.」というゾーンに対する問い合わせには回答しますが、それ以外の問い合わせについては自信は管理していないので応えられません。そこで反復問い合わせを行い答えを見つけようとしていたかどうかと言えば、していません。

ただ、「webtest01.com.」以外のドメインに対する名前解決も出来ていました。では、なぜ名前解決を行えたのでしょうか。それはフォワーダ機能を使用していたからです。

named.confのoptionsステートメントで「forwarders」を指定したことを思い出してください。

# cat /etc/named.conf
options {
    directory    "/var/named";
    dump-file    "/var/named/data/cache_dump.db";
    statistics-file "/var/named/data/named_stats.txt";
    memstatistics-file "/var/named/data/named_mem_stats.txt";
    allow-query     { 127.0.0.1;
                      172.16.0.0/24;
     };
    forwarders{
            172.16.0.254;
    };

};
  ~ 省略 ~

フォワーダ機能を使用すると、自身のDNSで解決できない問い合わせをフォワーダに指定したDNSサーバーに転送することができます。上記の設定では自身が解決できない問い合わせを受けた場合、IPアドレス「172.16.0.254」に問い合わせを転送することになります。そして、転送された側で、最終的に反復問い合わせを行い、答えを返してくれます。当方の環境ではまずルータに転送され、さらにプロバイダのDNSサーバー(キャッシュサーバー)に転送されます。

DNSサーバーで取得したDNS問い合わせに対するパケットキャプチャーを見てみましょう。下記は、「172.16.0.2」のPCから当サイトのFQDNである「cos.linux-dvr.biz」に対する名前解決を行った際のパケットキャプチャーです。
DNSフォワーダパケットキャプチャ

PC(172.16.0.2)からの名前解決要求を、DNSサーバー(172.16.0.10)はルータ(172.16.0.254)へ転送し、ルータからDNSサーバーに結果が返され、DNSサーバーはその結果をPCへ返している様子が見て取れます。

キャッシュサーバーとしての設定

では、今回構築したDNSサーバーをキャッシュサーバーとして動作させるための設定を行なってみます。そのためにはnamed.confを編集します。

# vi /etc/named.conf
options {
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        allow-query     { 127.0.0.1;
                          172.16.0.0/24;
        };
        recursion yes;
        allow-recursion{
                127.0.0.1;
                172.16.0.0/24;
        };
//        forwarders{
//                172.16.0.254;
//        };

};

キャッシュサーバーとして動作させるためには、再帰問い合わせを許可してやる必要があります。

設定項目 概要
recursion 再帰問い合わせ(リカージョン)の可否を指定。
allow-recursion 再帰問い合わせを許可するホストもしくはネットワークを指定。
forwarders 自身で解決できない問い合わせを転送するフォワーダーを指定。

「recursion」をyesにして再帰問い合わせを許可します。これにより、再帰問い合わせを受けたら、その結果を返すために、反復問い合わせを行うようになります。また、「forwarders」の指定は不要となるので、コメントアウトします。

編集が完了したら、BINDを再起動させ、設定を反映させます。

# service named restart

これで設定は完了です。では、この設定で取得したDNS問い合わせに対するパケットキャプチャーを見てみましょう。下記は、「172.16.0.2」のPCから当サイトのFQDNである「cos.linux-dvr.biz」に対する名前解決を行った際のパケットキャプチャーです。
DNS反復問い合わせパケットキャプチャ

PC(172.16.0.2)からの名前解決要求を受けたDNSサーバー(172.16.0.10)は、まず「198.41.0.4」に対して問い合わせを行っていることが確認できます。「198.41.0.4」が何者かというと、その正体はルートDNSサーバーです。ルートDNSサーバーから回答を得たあと、再度別のDNSサーバーに対して要求を出し、その回答を得たらまた別のDNSサーバーに要求を出す、という動作を繰り返していることが確認できます。そして、最後にDNSサーバー(172.16.0.10)からPC(172.16.0.2)へ回答しています。

注意点

今回はサンプルのため個人で構築したDNSサーバーをキャッシュサーバーとして動作させましたが、実はこの行為、よくありません。

個人や中小企業などが家庭LAN、社内LAN用に構築したDNSサーバーの場合、プロバイダーのDNSサーバーをフォワーダとして指定することが推奨されます。その主な理由は、DNS問い合わせトラフィックを減少させるためです。

反復問い合わせを行う場合、まず、ルートDNSサーバーに問い合わせが行きます。それはつまり、ルートDNSサーバーは世界中からものすごい数のリクエストが届いているということです。

ただ、DNSサーバー(キャッシュサーバー)は一度得た回答をキャッシュしておくことができます。プロバイダのDNSサーバーはある程度まとまった数のリクエストを受けるため、反復問い合わせをしなくてもキャッシュしてある結果を返すことができます。

例えば、YahooやGoogleといった大手サイトは必ず誰かが見ています。2番目以降に問い合わせてきたクライアントに対しては全てキャッシュした結果を返してやればいいため、トラフィックが大幅に減少します。実際、通常のDNS問い合わせとその回答はほとんどがキャッシュサーバーからの回答です。

さらに、キャッシュサーバーとした場合、セキュリティの面でも好ましくありません。再帰問い合わせを許可した場合、やりようによっては悪意を持ったユーザーがでたらめなキャッシュを勝手に登録できてしまいます。それはつまり、様々な悪用ができてしまうということが容易に想像できると思います。ですので、キャッシュサーバーとして動作させる場合は、きちんとセキュリティ対策がされている必要があるということです。