DNSの問題として検証

問題がDNSにあると判明したので、問題のドメインに関連した名前解決の状況を調査しました。
なお、以下ではアクセスに問題があったホストとして、target.example.netを使用しています。

dig(1)による確認

DNSの問題として、まずは定番であるdig(1)を使用して状況を確認しました。

  • 対象のホストは階層は浅いドメインです。
  • 対象のホストはCNAMEレコードで登録されています。
  • そのCNAMEレコードのTTLは短め(1時間)です。

CNAMEレコードが出てくると「怪しい」というケースは少なからずありますが、今回は直接それが問題というわけではありませんでした。さらに、発生するタイミングとdig(1)の実行から以下も確認できました。

  • 名前解決の失敗は、CNAMEレコードがキャッシュにない場合で起きていました。
  • 問い合わせているDNSのキャッシュサーバーからSERVFAILのエラーが返っていました。
  • 障害の発生した直後に再度問い合わせると、何事もなかったかのように正常な結果が返りました。

SERVFAILのエラーの例を以下に示します。

; <<>> DiG 9.10.3-P3 <<>> c.mobi-connect.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 16926
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1280
;; QUESTION SECTION:
;target.example.net.		IN	A

;; Query time: 79 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sun Feb 14 19:13:58 JST 2016
;; MSG SIZE  rcvd: 47

シェルスクリプトによる検証

DNSの問題ということがはっきりしたため、簡単なシェルスクリプトを用意して発生する状況の確認をしてみました。

  • 第1引数で名前解決をしたいホスト名を指定します。
  • 第2引数はオプションで問い合わせるネームサーバーを指定します。
#!/bin/sh
log=/var/tmp/check.out
# intervalは対象のホストのリソースレコードのTTLに設定
interval=3600

unset LANG

log=/var/tmp/check.out

if [ $# -eq 0 ]; then
        echo "Usage: $(basename $0) <host>" 1>&2
        exit 1
fi
host="$1"
server="$2"

if [ -z "${server}" ]; then
        server=127.0.0.1
fi

tmp=/tmp/$host.$$
while :; do
        dig ${host} @${server} > ${tmp} 2>&1
        egrep -q 'ANSWER SECTION' ${tmp} || (cat ${tmp} >> ${log}; date 1>&2)
        sleep ${interval}
done

シェルスクリプトのintervaltarget.example.netのCNAMEレコードを得たときのTTL(Time To Live、キャッシュとして保持可能な最大時間)と同じとして、CNAMEレコードがキャッシュにない状態で再現性があることを確認できました。

named(8)のキャッシュの状態

検証に使用したシェルスクリプトを少し修正して、dig(1)で問い合わせる前後にrndc(8)を使用してnamed(8)のキャッシュを取る処理: rndc dumpdb -allを入れてみました。もちろん、rndc(8)を実行した後でキャッシュの状態を収めたファイルは名前を変更して保持するようにしていました。すると、以下のことがわかりました。

  • target.example.netに対応したexample.netのNSレコードはキャッシュに存在しています。
  • NSレコードで示されるネームサーバーについてはAAAAレコードだけが存在してAレコードは存在しません。

このような状況になると、named(8)は何故か名前解決を諦めてしまうようです。