TT Lab
はじめる
学ぶ 学習パス コース

ネットワークトラブルシューティング

digを読む順序

TT Labで続きを見る

一言でいうと

digの出力は、上から読むのではなく、status → flags → 各セクションの順に読みます。この順序を守れば、1つの応答で原因が分かれます。

なぜ必要なのか

「DNSが使えない」という報告には、少なくとも5つの異なる状況が混ざっています。名前がそもそもないもの、そのタイプのレコードだけがないもの、リゾルバーが答えを作れないもの、サーバーが答えることを拒否するもの、そしてキャッシュが古いもの。この5つは、対応がすべて違います。そしてdigの出力を1回見れば、5つのうちどれなのかが確定します。

どう動くのか

まず応答コードを見てみましょう。

status ANSWER 実際の意味 よくある原因 次にすること
NOERROR 1個以上 名前とタイプがどちらも存在 正常 次の層へ
NOERROR 0個 名前はあるが、そのタイプがない Aはあり、AAAAはない。CNAMEだけがあり、参照先が未作成 タイプを変えて再確認
NXDOMAIN — 権威サーバーが、その名前自体がないと確定 タイプミス、未作成、searchドメインが付いた名前 権威サーバーに直接問い合わせ
SERVFAIL — リゾルバーが答えを作れない DNSSEC検証の失敗、上位の無応答、ゾーンのロード失敗 リゾルバーのログ
REFUSED — サーバーに処理する意思がない 再帰の不許可、ACL、ゾーンを持っていない 問い合わせ先が正しいか

NOERRORなのにANSWER: 0の場合が、最も紛らわしいです。名前はあるのに、そのレコードタイプだけがないのです。IPv6だけがない場合や、CNAMEは設定したのに参照先のAレコードを作っていない状況が、これに当たります。

次がflagsです。

目的別の組み合わせを使い慣れておくと便利です。

dig +short A example.com               # 값만
dig +noall +answer example.com         # 답변 섹션만 (TTL·타입 포함)
dig +noall +authority +additional example.com
dig @1.1.1.1 example.com               # 특정 서버에 직접
dig +norecurse @10.0.0.53 example.com  # 캐시에 있는지만 확인
dig -x 8.8.8.8                         # 역방향
dig -t MX example.com
dig +tcp example.com
dig +time=2 +tries=1 example.com
dig +trace example.com                 # 루트부터 위임 추적

+traceには落とし穴があります。+traceはルートから各段階を直接問い合わせるため、手元のリゾルバーを迂回します。そのため「+traceは正常なのにアプリケーションは失敗する」がよくあり、そのときの犯人は権威サーバーではなくリゾルバー区間です。

TTLとネガティブキャッシング

同じ問い合わせをリゾルバーに繰り返すと、TTLが減っていくのが見えます。一方、権威サーバーに直接尋ねると、常に元の設定値が出ます。この違いが、「キャッシュから来たのか」を判別するいちばん簡単な方法です。

存在しない名前の結果もキャッシュされます。ネガティブキャッシュの時間は、SOAのMINIMUMフィールドとSOAレコード自身のTTLのうち小さいほうの値です。そのため、レコードを新しく作ったのに、しばらくNXDOMAINが続くことが起きます。「作ったのになぜ反映されないのか」の答えは、たいていこれです。

resolv.confの数字

nameserver 10.0.0.2
search prod.svc.cluster.local svc.cluster.local cluster.local
options ndots:5 timeout:2 attempts:3 rotate

Kubernetesのndots:5は有名な落とし穴です。api.stripe.comはドットが2つなので5より小さく、searchドメイン4つを先にすべて付けて試したあとで、ようやく元の名前を問い合わせます。A/AAAAのペアで数えると、問い合わせ10件のうち8件が、NXDOMAINを受け取るために出ていきます。ただし、よくある助言とは違い、ndotsを1に下げるとクラスターが壊れます。payments.prodのようなネームスペースをまたぐ呼び出しが、すべて失敗するからです。安全な下限は2です。急ぐときは、名前の末尾にドットを1つ付けて(api.stripe.com.)FQDNであることを明示すれば、searchを飛ばします。

現場での姿

UDP 53だけが開いているファイアウォール。普段は何も問題がありません。応答が小さいからです。ところがレコードが増えたり、DNSSEC署名が付いたりして応答が512バイトを超えた瞬間、その名前だけが解決されなくなります。「特定のドメイン1つだけが使えない」という報告の原因が、ここにある場合があります。dig +notcp +bufsize=512で再現し、;; MSG SIZE rcvd:を見ます。

キャッシュを丸ごと消してはいけません。rndc flushは手っ取り早い方法ですが、その後の数分間、上位への問い合わせが急増します。問題になった名前だけをrndc flushname api.example.comで消すのが定石です。

次のラボですること

digでA/MX/NS/TXTを取り出し、TTLが減っていくのを観察し、逆引きを行い、NXDOMAIN応答からネガティブキャッシュの時間を計算します。最後に、hostsエントリを入れてgetentとdigの答えが分かれるのを表にして提出します。