2022年8月、ホームページを全面リニューアルしました! 情報を分かりやすくお伝えできるサイト作りを目指してまいります。

DNSフォワードエラー!

BINDには、「フォワーディング」という機能がある。これは、結構使える機能でBINDでは以下のようにnamed.confで定義する。ちなみに、ここで説明してるのは BIND8 である。

bigthunder:~# cd /etc/bind/
bigthunder:/etc/bind# more named.conf

options {
     directory “/etc/bind”;
     forwarders {
             xxx.xxx.xxx.xxx; 
← IPアドレス
     };

};

logging {
     category lame-servers { null; };
     category cname { null; };
     category security { null; };
};

zone “.” {
      type hint;
      file “named.ca”;
};

以下省略

フォワーディングは、上記の濃い青の部分のようにforwardersで指定する。さて、このフォワーディングだがどういう意味かというと、LAN側のホストの名前しか解決できないDNSサーバでWAN側のホストの名前も解決したい場合に、WAN側のDNSサーバのIPアドレスを指定して、そのサーバに名前解決を委託する機能である。つまり、DNSにクエリーを他のDNSサーバへ転送させ、そのサーバに代わりにクエリーを解決させるのである。また、この代わりに解決を依頼されたサーバがさらにクエリーを転送することもある。さて、前置きが長くなったが、このフォワーディングを俺が設定していて障害が起きたので、その内容を説明してみたい。


現象:
BINDログとして、以下のようなクエリーの警告メッセージが大量にログ出力されることがある。これは、グーグルと「再起動」すればとりあえず解決する。みたいに書いてあるけど、どのようなエラーなのかはさだかではない。したがって、俺自身が独断と偏見で原因を調べてみた。

Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (a.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (a.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (f.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (f.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (j.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (j.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (G.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (G.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (H.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (H.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (I.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (I.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (L.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (L.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (M.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (M.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (B.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (B.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (C.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (C.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (D.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (D.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (E.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (E.ROOT-SERVERS.NET)
Feb 23 10:35:40 bigthunder named[1701]: sysquery: no addrs found for root NS (k.ROOT-SERVERS.NET)

1.原因
これは、 forward first と forward only の二つのモードがあって、これを指定しないでforwarders指定のみだとデフォルトが forward first になっている。 forward first は、最初にクエリーをフォワードしてから、それが失敗すると自分自身で名前解決を始める。つまり、プロバイダのDNSサーバから一定時間に回答が得られない場合には自分でルートサーバへ問い合わせに行ってしまう。つまり、名前解決に自分でトライする訳だ。したがって、
zone “.” {
        type hint;
        file “named.ca”;
    };

みたいに自分でお決まりのワールドワイドなルートサーバを指定してると、 forwarders で指定しているプロバイダのDNSサーバがリストで同じくルートサーバを指定しているので二重にNOTIFYメッセージは送らない旨を警告してる。ご存じのように、名前解決の基本としては、キャッシュに無いクエリーの解決に対してはルートサーバへ問い合わせるのがルールとなっている。


2.対策
以下のように forwarders にプラス forward only; を使う。

options {
forward only;
forwarders {
        [プロバイダのDNSサーバ等のIPアドレス];
       };
}

つまるところ、 forward only は forwarders で指定するサーバーに問い合わせして一定時間に回答を得られなくても自分自身では勝手に名前解決することはない、つまり常にクエリーをフォワードする。したがって、zone”.”が指定されていてもルートサーバーには問い合わせすることはない。したがって、二重問い合わせは起こらないことが言えそうだ。

forward firstをもう少し詳しく説明するとBINDはフォワード先のサーバから受け取った返事を調べ、信頼できないと判断した場合、これを完全に捨ててしまう。だから、ちゃんとした理由がないまま、内部解決が失敗する可能性がある。以下の図1のように、LAN側のDNSサーバはLAN側のみの名前解決、WAN側のDNSサーバはWAN側のみの名前解決、だから勝手にLAN側のDNSサーバがWAN側の名前解決を行ったら情報が無いのでクエリーは失敗するに決まってる、逆にWAN側のDNSサーバがLAN側の名前解決を行っても同じ事が起きるはずだ。だから、必ずforward onlyを設定すれば、BINDは自分自身をスレーブサーバと思いこむので、どんなことがあってもそこへ問い合わせるようになる。

図1

以上

コメント