【実務・中級編】 digコマンドの基本的なクエリ構造とセクション別出力結果の解析 – トラブルシューティング&ネットワーク運用監視実践ガイド

「DNSが引けない」で夜を明かさないために。digの出力を“解読”する現場の技術

ネットワーク障害の現場で、若いエンジニアから「なぜか繋がらないんです」と相談を受けるとき、決まって彼らはブラウザを叩いたり、pingを打ってパケットロスを見ていたりする。もちろんそれも大事だが、現代のインフラの9割は名前解決の裏側で死んでいると言っても過言ではない。

「名前解決が遅い」あるいは「意図しないIPが返ってくる」。この怪現象を切り分ける唯一無二の相棒が dig だ。教科書通りのコマンドを打つのは誰でもできる。重要なのは、dig が吐き出すあの無機質なテキストの「どこを見て、何を判断するか」という嗅覚だ。

今日は、百戦錬磨の現場感覚で dig の深淵を解説する。

—

1. digの出力は「4つの物語」で構成されている

dig の結果は、大きく分けて4つのセクションからなる。これらは単なるデータ列ではなく、DNSサーバーが辿った「経緯」そのものだ。

;; QUESTION SECTION:
;example.com.           IN  A

;; ANSWER SECTION:
example.com.    3600    IN  A   93.184.216.34

;; AUTHORITY SECTION:
example.com.    172800  IN  NS  a.iana-servers.net.

;; ADDITIONAL SECTION:
a.iana-servers.net. 172800  IN  A   199.43.135.53

① QUESTION SECTION:我々の問いかけ

「何を解決したいのか」がここに書かれている。ここが間違っていれば、以降のセクションはすべて無意味だ。タイプ(AなのかMXなのか)やクラス(INが一般的)を確認する。

② ANSWER SECTION:答えそのもの

ここには、DNSキャッシュサーバーや権威サーバーが返した「正解」が入る。TTL(生存期間)にも注目してほしい。もしここが空なら、それは「名前が存在しない(NXDOMAIN)」か「タイムアウト」のどちらかだ。

③ AUTHORITY SECTION:誰が管理しているのか

ここがトラブルシューティングの肝だ。このセクションには、ドメインの権威DNSサーバーの情報が記載されている。再帰的な問い合わせが失敗している場合、このセクションをヒントに、どこまで辿り着けているのかを追いかけることができる。

④ ADDITIONAL SECTION:おまけの親切

権威サーバーのIPアドレスなどがここに記載される。わざわざ別途名前解決をしなくても済むよう、DNSサーバーが気を利かせてくれているわけだ。ここが空だと、追加でDNSルックアップが発生し、パフォーマンスが劣化する。

—

2. 実務で使う「デバッグの定石」

ただ dig example.com と打つだけでは、素人だ。プロは以下のオプションで「何が起きているか」を暴く。

トレースで「迷子」を探す

どこで解決に失敗しているか、ルートサーバーから順に辿るには +trace が必須だ。

# 再帰的な解決プロセスを丸裸にする
dig example.com +trace

これは、パケットがインターネットの階層構造をどう駆け巡っているかを可視化する。途中のネームサーバーが返答を拒否していたり、ルートサーバーへの到達性が悪かったりする場合、一発で判明する。

特定のサーバーを名指しする

システムの内部DNSなのか、ISPのDNSなのか。疑わしいサーバーがあるときは、IPアドレスを直接指定する。

# 8.8.8.8に対して正当性を問う
dig @8.8.8.8 example.com +noall +answer

+noall +answer を付けることで、冗長なヘッダーを省き、純粋な回答だけを抽出できる。シェルスクリプトに組み込む際にも非常に重宝するテクニックだ。

—

3. アプリケーションコードからの「現実的」アプローチ

Web API設計やインフラ運用に携わっているなら、コード側でDNSの振る舞いを意識する必要がある。例えば、PythonでDNSを解決する場合、ライブラリ任せにするとエラーログが不親切になりがちだ。

import dns.resolver

# 特定のDNSサーバーを指定して問い合わせるコード例
resolver = dns.resolver.Resolver()
resolver.nameservers = ['8.8.8.8']  # 外部DNSを明示的に指定

try:
    answers = resolver.resolve('example.com', 'A')
    for rdata in answers:
        print(f"IP Address: {rdata.address}")
except Exception as e:
    # 接続障害なのか、DNSレコード欠落なのかをログに吐くのが肝
    print(f"DNS Resolution Failed: {e}")

APIのレスポンスが極端に遅い場合、その原因の多くは名前解決のレイテンシか、コネクションプールのDNSキャッシュが古くなっていることにある。curl でデバッグする際も、以下のように名前解決時間を計測する癖をつけておこう。

# 名前解決の時間(time_namelookup)を測定する
curl -w "DNS Time: %{time_namelookup}\n" -o /dev/null -s https://example.com

—

最後に:ネットワークは「嘘をつかない」

DNSのトラブルは、往々にして「設定ミス」か「権限委譲の不整合」だ。dig の結果を眺めていると、時折、パケットがどこで迷子になり、なぜその答えが返ってきたのかという「物語」が見えてくるようになる。

教科書を暗記するのではなく、dig の出力にある数字一つひとつが、ネットワークのどこかのルーターやサーバーからの「返答」であることを意識してほしい。それが、障害対応の最前線で冷静でいられる唯一の秘訣だ。

さあ、次は君のターミナルで dig を叩き、パケットの声を聞いてみてくれ。

コメント

タイトルとURLをコピーしました