- Authors

- Name
- Youngju Kim
- @fjvbn20031
- はじめに
- 1. 名前解決の経路 — 一つのクエリが通る五つの区間
- 2. レコードタイプ — 何をどこに置くのか
- 3. TTL とキャッシュ — 伝播の正体
- 4. 委任とネームサーバー — 権威が分かれる地点
- 5. dig の読み方
- 6. よくある障害 — 伝播遅延、スタイルキャッシュ、CNAME の制約
- 7. DNSSEC — 何を保証し、何を保証しないのか
- 8. 社内 DNS の運用
- 9. 診断順序のまとめ
- クイズ: 理解度を確認しましょう
- おわりに
- 参考資料
- 関連記事
はじめに
障害対応の会議で「DNS の問題みたいです」という言葉が出ると、たいていそこで調査が止まります。DNS は一つのシステムではなく、性格の異なる五つの区間がつながった経路だからです。どの区間の話なのかを言わない診断は、診断になっていません。
このブログにはすでに DNS 詳解 と DNS 解決順序のデバッグ があります。前者はプロトコルの構造を、後者は Linux ホスト上の解決順序を扱います。この記事はその間を埋めます。レコードを変更し、伝播を待ち、キャッシュを消し、どの区間が犯人かを判別しなければならない運用者の視点で、手順と判断基準を整理します。
コマンドは BIND 9 系の dig、glibc のスタブリゾルバー、systemd-resolved を前提にします。この記事に出てくるオプションはすべてマニュアルと RFC 原文で確認したものだけで、根拠は末尾の参考資料に URL と確認日として残しました。
dig -v
resolvectl status
1. 名前解決の経路 — 一つのクエリが通る五つの区間
一つの名前が一つのアドレスになるまでに、次の五つの区間を通ります。各区間はそれぞれ別の理由で、別の症状を出して失敗します。
- アプリケーションとスタブリゾルバー。 プログラムが名前解決の関数を呼ぶと、システムのスタブリゾルバーが処理します。RFC 8499 はスタブリゾルバーを「自身ではすべての解決を実行できないリゾルバー。スタブリゾルバーは一般に、実際の解決機能を担う再帰リゾルバーに依存する」と定義しています。この区間には
/etc/hostsとネームサービススイッチの設定も含まれます。 - リゾルバーの選択。
/etc/resolv.confが、どのサーバーへ送るか、どの検索ドメインを付けるかを決めます。 - 再帰リゾルバーのキャッシュ。 キャッシュにあればここで終わりです。ほとんどのクエリがこの区間で終わるため、変更にまつわる事故の大半もこの区間で起きます。
- 委任をたどる。 キャッシュになければルートから始まり、TLD を経て権威サーバーまで降りていきます。RFC 1034 はこの過程を「SNAME から始めて、その親ドメイン名、祖父母、というようにルートへ向かってローカルに利用可能なネームサーバーレコードを探す」と記述し、なければルートサーバーを含む安全ベルト(safety belt)設定から出発するとしています。
- 権威サーバーの応答。 RFC 8499 の権威サーバーの定義は「ローカルの知識で DNS ゾーンの内容を知っており、したがって他のサーバーに問い合わせることなくそのゾーンに関するクエリに答えられるサーバー」です。
区間を分ける理由は、各区間を個別に問い合わせられるからです。
getent hosts api.internal.example.com
cat /etc/resolv.conf
resolvectl status
dig @127.0.0.53 api.internal.example.com
dig @10.0.0.53 api.internal.example.com
dig @ns1.example.com api.internal.example.com
getent はネームサービススイッチを通る経路で、dig はそうではありません。この二つの結果が食い違うなら、問題は DNS ではなくスタブリゾルバー区間にあります。
/etc/resolv.conf のディレクティブは次のとおりです。値はマニュアル基準です。
nameserver— クエリを送るサーバーのアドレスです。使われるのは 3 つまでです。search— 短い名前に付ける検索ドメインの一覧です。glibc 2.25 以前は 6 個・合計 256 文字が上限で、2.26 以降は制限がなくなりました。options ndots:n— 検索ドメインを付けずに最初から絶対名として問い合わせるために必要な、名前に含まれるドットの数のしきい値です。デフォルトは 1、上限は 15 です。options timeout:n— 応答を待つ時間です。デフォルト 5 秒、上限 30 秒です。options attempts:n— あきらめるまでの試行回数です。デフォルト 2 回、上限 5 回です。options rotate— 列挙されたネームサーバーをラウンドロビンで選択します。options single-request— IPv6 と IPv4 のリクエストを並列ではなく順番に送ります。
ここから二つの計算が出てきます。第一に、最初のネームサーバーが死んでいると、利用者はデフォルトのままなら 5 秒をそのまま体感します。 タイムアウトと試行回数を縮めない限り、冗長化は書類の上にしか存在しません。第二に、ndots の値が大きいと、短い名前はもちろんドットがいくつか入った名前まで検索ドメインを先に試すため、外部の名前を一つ解決するのに失敗クエリが何度も先行します。 コンテナ環境で名前解決が遅い典型的な原因がこれです。
検索リストが関与しているかどうかは、次のように切り分けられます。
dig +search api
dig +nosearch api
dig api.internal.example.com.
最後の行のように、名前の末尾にドットを付けると絶対名になり、検索リストを飛ばします。 アプリケーション設定に外部ドメインを書くとき末尾ドットを付けておくと、無駄なクエリが消えます。
2. レコードタイプ — 何をどこに置くのか
| タイプ | 収めるもの | 運用で引っかかる制約 |
|---|---|---|
| A / AAAA | IPv4 / IPv6 アドレス | 基本。両方あればクライアントが選ぶ |
| CNAME | 別名 | 同じ名前に他のデータと共存できない |
| MX | メール受信サーバー | 対象が別名であってはならない |
| NS | 下位ゾーンの権威サーバー | 対象が別名であってはならない |
| SOA | ゾーンの権威情報とネガティブキャッシュ TTL | ゾーン頂点に必ず存在する |
| TXT | 自由なテキスト | 所有確認やメールのポリシーがここに乗る |
| PTR | アドレスから名前へ | in-addr.arpa / ip6.arpa の下に置かれる |
| SRV | サービスのホストとポート | 対象が別名であってはならない |
| CAA | 証明書発行を許可する CA | 上へたどりながら探索される |
いくつかは根拠をそのまま引用しておく価値があります。
CNAME は単独でなければなりません。 RFC 1034 は「あるノードに CNAME レコードが存在する場合、他のデータが存在してはならない」と明言します。正規名と別名のデータが食い違わないようにするためです。そして RFC 8499 はゾーン頂点(apex)を「SOA とそれに対応する権威 NS レコードセットの所有者にあたる、ツリー上の地点」と定義しています。頂点には SOA と NS が必ずあるので、頂点に CNAME は置けません。 ルートドメインを CDN に向けようとして止まる事故の、正確な根拠がこれです。
NS と MX の対象は別名であってはなりません。 RFC 2181 は「NS リソースレコードの値として使われるドメイン名、および MX リソースレコードの値の一部として使われるドメイン名は、別名であってはならない」と規定します。SRV も同じです。RFC 2782 は対象について「この名前に対するアドレスレコードが一つ以上存在しなければならず、その名前は別名であってはならない」と要求します。SRV の形式は _Service._Proto.Name TTL Class SRV Priority Weight Port Target で、到達できる中で最も小さい優先度の対象を先に試し、同じ優先度の中では重みに比例して選ばれます。
CAA は上へたどって探します。 RFC 8659 は探索を「指定されたラベルから、DNS のルートは含まない地点まで DNS 名前ツリーを登り、CAA レコードセットが見つかるまで続ける」と定義します。タグは issue、issuewild、iodef があり、発行を制限するタグが一つもなければ、CAA は発行を制限しません。 「そのサブドメインに CAA を置いた覚えはないのに発行が止まった」はここから来ます。
サイズの上限も覚えておく価値があります。RFC 1035 はラベル 63 オクテット、名前 255 オクテット、UDP メッセージ 512 オクテットを上限としました。512 オクテットの制限は RFC 6891 の EDNS(0) で拡張され、要求側は OPT レコードの CLASS フィールドに、自分が再構成できる最大の UDP ペイロードサイズを書きます。この文書は出発点として 4096 オクテットを、フォールバック帯として 1280〜1410 バイトを提示しています。応答がこれより大きければ TC ビットが立ち、TCP で問い直すことになります。
3. TTL とキャッシュ — 伝播の正体
DNS にプッシュはありません。変更が広がるのではなく、キャッシュが期限切れになるのです。この一文を理解すると、伝播にまつわる事故の大半が消えます。
RFC 1034 は TTL を「レコードが破棄されるまでにどれだけ長くキャッシュされうるか」と定義します。RFC 2181 はここに実務で引っかかるルールを足します。一つのレコードセット内のすべてのレコードの TTL は同じでなければならず、サーバーは TTL の揃っていないセットを送ってはなりません。また TTL は符号なし 32 ビット値ですが最大値は 2147483647 で、最上位ビットが立った値はゼロとして扱うべきとされています。
存在しないという事実もキャッシュされます。RFC 2308 は二種類を区別します。
- NXDOMAIN — 応答コードが Name Error で、問い合わせたドメインそのものが存在しません。
- NODATA — 応答コードは NOERROR なのに、回答セクションに該当するレコードがありません。名前は存在し、そのタイプだけがない状態です。
ネガティブ応答のキャッシュ時間は、SOA の MINIMUM フィールドとSOA レコード自身の TTL のうち小さいほうです。同じ文書は実務上の推奨も残しています。「1 時間から 3 時間の値がうまく動くことが分かっており、デフォルトとして妥当である。1 日を超える値は問題を起こすことが分かっている。」打ち間違えたレコードを直したのに半日ずっと失敗し続ける状況の原因は、たいていこの値です。
変更の手順は TTL を中心に組み立てます。
- 変更予定日を基準に、既存の TTL のぶんだけ先行して TTL を下げます(たとえば 300 秒)。
- 既存の TTL が過ぎ切るまで待ちます。 この待ちを飛ばすと、下げた TTL がまだキャッシュに入っていないリゾルバーが残ります。
- レコードを変更します。
- 権威サーバーと複数のリゾルバーで、それぞれ確認します。
- 安定したら TTL を元の値に戻します。
キャッシュに残っている時間は観察できます。
dig +noall +answer +ttlunits example.com
dig +noall +answer example.com
dig @1.1.1.1 +noall +answer example.com
dig @ns1.example.com +noall +answer example.com
リゾルバーに繰り返し問い合わせると、TTL が減っていくのが見えます。 残りの秒数が、そのリゾルバーのキャッシュが切れるまでの時間です。一方、権威サーバーに直接問い合わせると常に元の設定値が返ります。
4. 委任とネームサーバー — 権威が分かれる地点
RFC 8499 は委任を「親ゾーンに子オリジンのための NS レコードセットを追加して別のゾーンを作る過程」と定義し、その境界をゾーンカット(zone cut)と呼びます。ここに、実務者が必ず知っておくべき非対称が一つあります。RFC 2181 は「ゾーンカットを示す NS レコードは、新しく作られた子ゾーンのものである」と規定します。つまり親(TLD)が持つ NS の一覧と、子ゾーンが自ら答える NS の一覧は食い違いうるし、実際の権威は子の側にあります。
ここから二つのよくある事故が出てきます。
- レジストラでネームサーバーを変えたのに反映されない。 変わったのは親の委任です。子ゾーンがいまだに古いサーバー一覧を答えていると、リゾルバーが何をキャッシュしたかで結果が分かれます。
- ネームサーバーの一覧に、実際には応答しないサーバーが混じっている。 リゾルバーは無応答のサーバーに当たると再試行するので、名前は結局解決するものの断続的に遅くなります。
グルー(glue)が必要な理由もここから来ます。RFC 1034 はゾーンの下端を示す NS レコードについて「そのゾーンの権威データではない」と述べ、委任先ネームサーバーのアドレスレコードを親が提供すると記述しています。ネームサーバーの名前が、自分が担当するゾーンの下にある場合、アドレスを知るにはそのゾーンに問い合わせる必要があり、そのゾーンに問い合わせるにはアドレスが必要という循環が生まれます。親が渡すアドレスレコードがこの循環を断ち切ります。
親と子をそれぞれ問い合わせて比べることが診断の核心です。
dig NS example.com
dig +trace example.com
dig +nssearch example.com
dig SOA example.com @ns1.example.com
dig SOA example.com @ns2.example.com
マニュアルの表現では、+trace は「ルートネームサーバーからの委任経路の追跡を切り替え」、+nssearch では「dig はそのゾーンの権威ネームサーバーを見つけようと試みます」。最後の二行ですべての権威サーバーの SOA シリアルが一致しているかを確認してください。番号がずれていればゾーン転送が遅れており、利用者は当たったサーバーによって違う答えを受け取っている最中です。
5. dig の読み方
基本形は dig @server name type です。マニュアルは三つの位置をそれぞれ「問い合わせるネームサーバーの名前または IP アドレス」「参照するリソースレコードの名前」「必要なクエリのタイプを示すもの」と説明しています。
出力はヘッダー、質問、回答、権威、追加の各セクションと統計に分かれます。読む順番は status、flags、各セクションです。
status に入る値の意味は RFC 1035 の応答コードです。
NOERROR— エラーなし。ただし回答セクションが空なら NODATA であり、名前は存在します。NXDOMAIN— Name Error。その名前は存在しません。SERVFAIL— サーバー障害。「存在しない」ではなく答えを作れなかったという意味です。上位への到達失敗と DNSSEC の検証失敗が代表的です。REFUSED— 拒否。ポリシー上答えないという意味で、再帰を許可していないリゾルバーに外から問い合わせたときに出ます。
flags に並ぶ文字にもそれぞれ意味があります。
qr— このメッセージが応答であることを示します。aa— 権威のある回答です。この文字がなければキャッシュから来た回答です。tc— 切り詰められました。TCP で問い直す必要があります。rd/ra— 再帰を要求した / 再帰が利用できる。ad— DNSSEC の検証を通過したとリゾルバーが示したものです。cd— 検証を無効にして問い合わせたという印です。
よく使う組み合わせを目的別に並べると次のようになります。
dig +short A example.com
dig +noall +answer example.com
dig +noall +authority +additional example.com
dig @1.1.1.1 example.com
dig +norecurse @10.0.0.53 example.com
dig -x 93.184.216.34
dig -t MX example.com
dig +dnssec example.com
dig +cd example.com
dig +multiline SOA example.com
dig +tcp example.com
dig +time=2 +tries=1 example.com
dig +stats example.com
dig +yaml example.com
各オプションの根拠はマニュアルの文そのままです。+short は「簡潔な回答を出すかどうかを切り替え」、+norecurse は「クエリの RD(recursion desired)ビットを無効にし」、+dnssec は「DNSSEC OK(DO)ビットを立てて DNSSEC レコードの送信を要求」し、+cd は「クエリに CD(checking disabled)ビットを立てます」。-x は「アドレスを名前に対応づける簡易逆引き」で、+time=T と +tries=T は待ち時間と試行回数を、+subnet は「指定した IP アドレスで EDNS CLIENT-SUBNET オプションを送信」します。
+norecurse の使いどころを一つ挙げておきます。リゾルバーに再帰を切って問い合わせると、そのリゾルバーのキャッシュにあるものだけが返ります。キャッシュヒットの確認や、キャッシュを温めずに状態を覗くときに使います。
逆に +trace には落とし穴があります。+trace はルートから各段階を自分で問い合わせるので、あなたのリゾルバーを迂回します。 そのため +trace は正常なのにアプリケーションは失敗する、という状況がよくあります。このとき犯人は権威サーバーではなくリゾルバー区間です。
6. よくある障害 — 伝播遅延、スタイルキャッシュ、CNAME の制約
伝播遅延。 先に見たとおり、伝播とは期限切れのことです。「48 時間かかります」という案内は、たいてい古い TTL 設定を前提にした保守的な言い方です。変更前に TTL を下げていなければ、既存の TTL のぶんだけ待つ以外に方法はありませんし、権威サーバーではすでに新しい値が返っているのに利用者だけが古い値を見ているなら、それは正常な動作です。
スタイルキャッシュ。 キャッシュは一か所にありません。少なくとも次の場所をそれぞれ確認する必要があります。
- 社内の再帰リゾルバーのキャッシュ
- ホストのローカルキャッシュ(systemd-resolved など)
- ランタイム自身のキャッシュ(一部のランタイムは独自の名前キャッシュを持ちます)
消すコマンドは階層ごとに違います。
sudo rndc flush
sudo rndc flushname api.example.com
sudo rndc flushtree example.com
sudo rndc dumpdb -cache
resolvectl flush-caches
resolvectl query api.example.com
resolvectl statistics
rndc flush は「サーバーのキャッシュをフラッシュ」し、flushname は「与えられた名前をビューの DNS キャッシュから、および該当する場合はビューのネームサーバーアドレスデータベース、不良サーバーキャッシュ、SERVFAIL キャッシュから」削除します。flushtree は「与えられた名前とそのすべてのサブドメイン」を同じ範囲から削除します。resolvectl flush-caches は「サービスがローカルに保持しているすべての DNS リソースレコードキャッシュをフラッシュします」。全体のフラッシュより先に、名前単位のフラッシュを試してください。 キャッシュを丸ごと捨てると、そのあと数分間は上位へのクエリが跳ね上がります。
CNAME の制約。 三つが繰り返されます。頂点に CNAME を置けないこと、MX と NS と SRV の対象が別名であってはならないこと、CNAME のある名前に他のレコードを併置できないこと。前の二つは仕様違反でもしばらく動いてしまうことがあるぶん危険です。動いているように見える仕様違反は、いちばん遅く、いちばん悪いタイミングで表に出ます。
NODATA を NXDOMAIN と取り違える。 status が NOERROR で回答が空なら、名前は存在します。AAAA を持たない名前に IPv6 で接続しようとするクライアントが典型例で、このとき名前ごと消して作り直すような対応には何の効果もありません。
TCP の遮断。 DNSSEC の署名やレコード数のせいで応答が大きくなると、TC ビットが立って TCP で問い直されます。ファイアウォールが UDP 53 しか開けていなければ、普段は平気なのに特定の名前でだけ失敗します。 判別は簡単です。
dig +tcp example.com
dig +dnssec +tcp example.com
名前は解決するのに接続できない。 dig が正常に応答するなら DNS 区間は無罪です。その先は接続層の問題であり、診断の道具が変わります。
7. DNSSEC — 何を保証し、何を保証しないのか
RFC 4033 の表現をそのまま移すと、DNSSEC は「ドメインネームシステムにデータ発信元認証とデータ完全性を提供」します。そして同じ文書は提供しないものを明示します。「DNSSEC は機密性、アクセス制御リスト、あるいは問い合わせ元を区別する他の手段を提供するようには設計されていない。」 さらに「DNSSEC はサービス拒否攻撃に対する保護を提供しない」と述べ、むしろ暗号演算に基づく新しい種類のサービス拒否攻撃を生むと警告しています。盗聴を防ぎたいなら別の層の対策が必要です。
レコードは四種類です。
- DNSKEY — ゾーンの公開鍵を収めます。
- RRSIG — レコードセットに対するデジタル署名です。
- DS — 親ゾーンの委任地点に置かれ、子の鍵を指します。
- NSEC — 名前やタイプが存在しないことを認証します。
信頼の連鎖は DNSKEY セットと DS セットが交互に連なり、各リンクが次を保証する構造で、検証はトラストアンカーから始まります。検証結果は四つの状態に整理されます。トラストアンカーと連鎖があり、すべての署名を検証できた Secure、署名されていないことが署名付きで証明された Insecure、署名されているはずなのに検証に失敗した Bogus、その部分が安全だと示すトラストアンカーが存在しない Indeterminate です。
運用者にとって重要なのは、失敗が SERVFAIL として現れることです。ゾーンの中身はそのままでも、署名の有効期間が過ぎれば、検証するリゾルバーでだけ照会が失敗します。検証しないリゾルバーでは何ごともなく見えます。判別は、検証を切って問い合わせることです。
dig +dnssec example.com
dig +cd example.com
delv example.com
+cd を付けたら答えが返るなら、それは DNSSEC の検証失敗です。 delv はマニュアルが「DNS クエリを送り、その結果を検証するツール」と説明する専用ツールです。
社内環境ではもう一つ引っかかります。RFC 4033 は、委任元の親から認証の連鎖が来ない署名済みゾーンを「セキュリティの島(island of security)」と呼び、そうしたゾーンは帯域外の手段で鍵を認証できる場合にのみ認証されると説明します。署名していない内部ゾーンを検証リゾルバーがどう扱うかがここに当たるため、内部ゾーンを別扱いするようリゾルバーの設定を合わせる必要があります。
8. 社内 DNS の運用
スプリットホライズン。 同じ名前に対して内側と外側で違う答えを返す構成です。便利ですが、どこから問い合わせたかで答えが変わるので、障害報告を受けたらまず報告者の位置を確認しなければなりません。 報告者が VPN につないでいたかどうかが結論を変えます。
フォワーダーか再帰か。 RFC 8499 はフォワーダーを「権威ネームサーバーの連鎖を直接使う代わりに、クエリを解決するために使われるネームサーバー」と定義します。社内リゾルバーが上位へ転送する構成なら、上位が落ちたとき社内リゾルバーは生きているのに何も答えられない状態になります。ヘルスチェックをプロセスの生存ではなく実際のクエリ成功で取るべき理由です。
リゾルバー冗長化の現実。 先に見たとおり nameserver は 3 つまでしか使われず、デフォルトのタイムアウトは 5 秒、デフォルトの試行回数は 2 回です。最初のサーバーが応答しなければ、利用者はその時間をそのまま体感します。社内標準の resolv.conf にはタイムアウトと試行回数を明記し、必要なら rotate で負荷を分散してください。
変更と検証。 ゾーンを変えたあとは、すべての権威サーバーで同じ答えが返るかを確認します。
sudo rndc reload
sudo rndc status
sudo rndc querylog on
dig SOA example.com @ns1.example.com +short
dig SOA example.com @ns2.example.com +short
sudo rndc querylog off
rndc reload は「設定ファイルとゾーンを再読み込み」し、rndc reconfig は「設定ファイルを再読み込みして新しいゾーンを読み込むが、既存のゾーンファイルは変更されていても再読み込みしない」ものです。この違いを知らないと「リロードしたのになぜ変わらないのか」が繰り返されます。querylog はクエリログの有効・無効を切り替えるもので、負荷の高いサーバーでは付けっぱなしにせず、調査の区間だけ有効にしてください。
コンテナ環境。 オーケストレーターが入れる resolv.conf には検索ドメインが複数、ndots が大きな値で入っていることが多いです。結果として外部の名前を一つ解決するのに失敗クエリが何度も先行します。アプリケーション設定の外部ドメインに末尾ドットを付けるだけで、かなりの部分が消えます。
何を監視するか。 次の四つで、たいていの事故は利用者より先に気づけます。
- すべての権威サーバーの SOA シリアルの一致
- 署名の有効期間の残り日数(署名しているなら)
- 再帰リゾルバーのクエリ遅延と SERVFAIL の比率
- ドメインと委任情報の失効日
9. 診断順序のまとめ
症状を受け取ったら次の順で絞り込みます。各段階は、前の段階を除外することに意味があります。
- アプリケーションかシステムか。
getent hostsとdigの結果を比べます。違えばスタブリゾルバー区間です。 - どのリゾルバーか。
/etc/resolv.confとresolvectl statusで実際に使っているサーバーを確認し、そのサーバーに直接問い合わせます。 - キャッシュか権威か。 リゾルバーの答えと権威サーバーの答えを比べます。違えばキャッシュであり、TTL が残り時間を教えてくれます。
- 委任か。
dig +traceと親子の NS 比較で委任を確認します。 - 検証か。 SERVFAIL なら
+cdで問い直します。答えが返れば DNSSEC の検証失敗です。 - DNS ではないのか。 名前が正常に解決するなら、この時点で DNS の調査を終了して接続層に引き渡します。
getent hosts example.com
dig +short example.com
dig @1.1.1.1 +short example.com
dig @ns1.example.com +short example.com
dig +trace example.com
dig +cd example.com
クイズ: 理解度を確認しましょう
クイズ1: dig は正常に応答するのに、アプリケーションだけが「名前が見つからない」と言います。まず何を確認しますか。
答え: スタブリゾルバーの経路です。dig はネームサービススイッチを通らず /etc/resolv.conf だけを見るため、二つの経路が異なります
解説: getent と dig を並べるところから始めます。
getent hosts api.example.com
dig +short api.example.com
cat /etc/resolv.conf
getent だけが失敗するなら、ネームサービススイッチの設定、/etc/hosts、コンテナにマウントされた resolv.conf、検索ドメインと ndots の設定を見ます。アプリケーションが独自のリゾルバーを内蔵している場合もあるので、ランタイムの名前解決設定も併せて確認してください。
クイズ2: A レコードを変えたのに、一部の利用者がいまだに古いアドレスへ向かいます。何が起きていて、次回は何を変えるべきですか。
答え: リゾルバーのキャッシュがまだ期限切れになっていません。次回は変更より前に、既存の TTL のぶんだけ先行して TTL を下げておきます
解説: DNS にプッシュはありません。変更が広がるのではなく、キャッシュが期限切れになるのです。残り時間はリゾルバーごとに違い、しかも観察できます。
dig @1.1.1.1 +noall +answer +ttlunits example.com
dig @ns1.example.com +noall +answer example.com
リゾルバー側の TTL は繰り返し問い合わせるほど減っていき、権威サーバー側は常に設定値のままです。この二つが違うのは正常です。
クイズ3: 社内リゾルバーでは SERVFAIL、公開リゾルバーでは正常です。何を疑い、どう一度で判別しますか。
答え: DNSSEC の検証失敗を疑い、検証を切って問い合わせることで判別します
解説: SERVFAIL は「その名前が存在しない」ではなく「答えを作れなかった」です。検証失敗と上位への到達失敗が代表的な原因です。
dig @10.0.0.53 example.com
dig @10.0.0.53 +cd example.com
delv example.com
+cd を付けたときに答えが返るなら、検証の段階で止まっています。署名の有効期限切れや DS の不一致をまず確認してください。+cd を付けても失敗するなら、検証ではなく到達性や上位応答の問題です。
クイズ4: ルートドメイン example.com を CDN のホスト名に向けようと CNAME を入れたら、ゾーンが拒否されました。仕様上の理由は何ですか。
答え: ゾーン頂点には SOA と NS が必ず必要ですが、CNAME は同じ名前に他のデータと共存できないからです
解説: RFC 1034 は、あるノードに CNAME があれば他のデータが存在してはならないと規定します。そしてゾーン頂点は、SOA と対応する権威 NS レコードセットの所有者として定義されます。二つのルールは同時に成り立ちません。
同じ理由で次も仕様違反です。
example.com. IN MX 10 mail-alias.example.com.
mail-alias IN CNAME real-mail.example.net.
RFC 2181 は NS と MX の対象が別名であってはならないと規定し、RFC 2782 は SRV の対象に同じ要求をしています。
クイズ5: 応答は NOERROR なのに ANSWER セクションが空です。この名前は存在しないということですか。
答え: 存在します。これは NODATA であり、名前はあって問い合わせたタイプだけがない状態です
解説: RFC 2308 は NXDOMAIN と NODATA を区別します。NXDOMAIN は名前そのものが存在しないこと、NODATA は応答コードが NOERROR なのに回答セクションに該当するレコードがないことです。
dig AAAA example.com
dig A example.com
dig ANY example.com
どちらもネガティブ応答としてキャッシュされ、その時間は SOA の MINIMUM フィールドと SOA レコード自身の TTL のうち小さいほうです。だから誤ったレコードを直しても、しばらく失敗が続くことがあります。
クイズ6: dig +trace は正しいアドレスを見せるのに、サーバー上のアプリケーションはいまだに古いアドレスへつなぎます。どこを見ますか。
答え: リゾルバー区間です。+trace はルートから自分で問い合わせるので、そのホストが実際に使うリゾルバーを迂回します
解説: +trace が正常だということは、権威サーバー側が正常だという意味にすぎません。実際の経路を再現するには、そのホストが使うリゾルバーに直接問い合わせる必要があります。
cat /etc/resolv.conf
dig @10.0.0.53 +noall +answer example.com
dig @10.0.0.53 +norecurse example.com
sudo rndc flushname example.com
+norecurse はそのリゾルバーのキャッシュにあるものだけを答えさせるので、キャッシュが原因かどうかをすぐ確認できます。ローカルキャッシュが別にあるなら、そちらも併せて消します。
おわりに
DNS の障害対応が難しいのは、難しいからではなく、どの区間を見ているのかを言わないまま話すからです。リゾルバーが答えたのか権威サーバーが答えたのか、キャッシュから来たのかいま引いたのか、検証を通ったのかどうかを毎回明示すれば、会話は一気に短くなります。
いますぐ身につけるべきものは三つです。getent と dig を並べて問い合わせ、スタブリゾルバー区間をまず除外すること、リゾルバーと権威サーバーにそれぞれ問い合わせ、キャッシュと原本を区別すること、そしてレコードを変える前に、既存の TTL のぶんだけ先行して TTL を下げておくことです。この三つだけで DNS 関連の事故の大半は消えるか、少なくとも数分でどの区間の問題かの結論が出ます。
参考資料
- RFC 1034 — Domain Names: Concepts and Facilities — 解決アルゴリズム、CNAME 単独のルール、委任とグルー、TTL の定義 (2026-08-15 確認)
- RFC 1035 — Domain Names: Implementation and Specification — メッセージのセクションとヘッダービット、応答コード、ラベル・名前・UDP サイズの上限 (2026-08-15 確認)
- RFC 8499 — DNS Terminology — スタブリゾルバー、再帰リゾルバー、権威サーバー、委任、ゾーンカット、フォワーダー、ゾーン頂点の定義 (2026-08-15 確認)
- RFC 2181 — Clarifications to the DNS Specification — レコードセット内 TTL の同一ルール、TTL の上限、NS・MX 対象の別名禁止、ゾーンカット NS の帰属 (2026-08-15 確認)
- RFC 2308 — Negative Caching of DNS Queries — NXDOMAIN と NODATA の区別、ネガティブ TTL の計算、推奨値 (2026-08-15 確認)
- RFC 4033 — DNS Security Introduction and Requirements — DNSSEC が提供するものとしないもの、四つのレコード、信頼の連鎖、検証状態 (2026-08-15 確認)
- RFC 6891 — Extension Mechanisms for DNS (EDNS(0)) — 512 オクテット制限と OPT レコード、ペイロードサイズの推奨 (2026-08-15 確認)
- RFC 8659 — DNS Certification Authority Authorization (CAA) — CAA のタグとツリー探索のルール (2026-08-15 確認)
- RFC 2782 — A DNS RR for specifying the location of services (SRV) — SRV の形式と対象の別名禁止 (2026-08-15 確認)
- BIND 9 マニュアル — dig, delv — この記事に出てくるすべての
digオプションの根拠 (2026-08-15 確認) - rndc(8) マニュアル — flush、flushname、flushtree、dumpdb、reload、reconfig、querylog (2026-08-15 確認)
- resolvectl(1) マニュアル — query、status、statistics、flush-caches (2026-08-15 確認)
- resolv.conf(5) マニュアル — nameserver と search の上限、ndots・timeout・attempts のデフォルトと最大値 (2026-08-15 確認)
- 五つの区間に分けた診断順序と、変更手順の段階分けは上の資料にそのまま出てくるものではなく、文書のルールをもとにこの記事で整理した手順です。
関連記事
- 前の記事: Linux ファイアウォールとアクセス制御 完全ガイド
- シリーズの最初: Linux 障害対応コマンド 完全ガイド
- DNS 解決順序のデバッグ — ホスト上で名前が解決される順序
- DNS 詳解 — プロトコルとメッセージ構造
- DNS とエニーキャスト — 世界中に同じアドレスを置く方式
- CIDR 計算機 — 逆引きゾーン範囲の計算
- Linux ターミナル —
digコマンドの練習