新しいホスト名とIPアドレスをDNSに登録したのに、手元ではまだ「見つからない」と返ってくる。登録に失敗したとは限りません。DNSは見つかったデータだけでなく、存在しないという応答も期限付きで保存するからです。この仕組みをネガティブキャッシュ、または否定応答のキャッシュと呼びます。[1]
ただし、「見つからない」には種類があります。名前そのものがないのか、その名前に欲しい種類のレコードがないのかで、保存した情報を使える範囲が変わります。応答の意味と残り時間を分けて見ると、DNS変更後の待ち時間を読み解きやすくなります。
簡単にまとめると?
- NXDOMAINは名前の不存在、NODATAは指定した種類のデータの不存在を表します。IPv6用のAAAAがないことだけで、IPv4用のAまでないとは判断できません。
- 基本の否定応答の保存時間は、SOAレコード自身のTTLとSOAのMINIMUMフィールドの小さい方から決まります。保存済みの不在情報は、新しいAレコードを追加しても直ちには消えません。
- 確認するのは応答の種類、問い合わせ先、残りTTLです。解決に失敗したSERVFAILや、障害時に期限切れ情報を返す仕組みは、通常の不存在応答と区別します。
「名前がない」と「その種類のデータがない」を分ける
DNSの問い合わせでは、名前だけでなく、欲しいレコードの種類も指定します。AはIPv4アドレス、AAAAはIPv6アドレスを求めるときの種類です。ここでは一般的なインターネット用のクラスINを前提に、CNAMEなどの別名の連鎖がない場合を考えます。[1]
NXDOMAINは、その名前が存在しないという応答です。一方、NODATAは名前はあるものの、指定した種類のレコードがないという意味です。NODATA専用の応答コードがあるわけではなく、コードはNOERRORで、回答欄に該当データがないことなどから判断します。[1][2]
| 応答 | 分かったこと | 別の種類を問い合わせるとき |
|---|---|---|
| NXDOMAIN | その名前がない | 同じ名前・クラスの別の種類にも、その不在情報を使える |
| NODATA | その名前に、指定した種類のデータがない | AAAAがないという情報だけでは、Aがあるかは分からない |
| SERVFAIL | サーバー側の問題などで解決を完了できない | 名前やレコードが存在しないと結論づける応答ではない |
たとえば、ある名前にAだけが登録されているなら、AAAAへのNODATAを保存していても、それだけを理由にAの問い合わせを否定してはいけません。また、NOERRORで回答欄が空という見た目だけでも即断できません。別のネームサーバーを案内する応答もあるため、管理情報を載せるAuthority欄のSOAレコードなど、応答全体を見て区別します。[2]
不存在の期限は、SOAが伝える
利用者に代わってDNSを調べるリゾルバーは、受け取った応答をキャッシュし、同じ問い合わせに再利用できます。これによって、存在しない名前への問い合わせを繰り返すたびに、そのゾーンを管理する権威サーバーまで調べ直す負担を減らせます。[1][2]
通常のAレコードなら、データと一緒にTTL、つまり保存に使える時間が付いています。ところが不存在の応答には、保存対象となるAレコード自体がありません。そこで権威サーバーは、ゾーンの管理情報を表すSOAレコードを応答に添え、そのTTLで否定応答の期限を伝えます。[2]
権威サーバーが否定応答に添えるSOAのTTLは、SOAレコード自身のTTLと、SOA内のMINIMUMフィールドの小さい方に設定されます。たとえば前者が900秒、後者が300秒なら、基本の否定応答TTLは300秒です。MINIMUMという名前から「すべてのレコードに適用する最低TTL」と受け取りやすいのですが、RFC 2308はその意味を廃し、否定応答のTTLに用いると定義しています。[2]
キャッシュから返す際には、保存していた時間を引いたTTLを添えます。問い合わせが来るたびに、最初の300秒へ戻す仕組みではありません。別のリゾルバーへ引き継がれる場合も、この残り時間が期限を伝えます。[2]
新しいAのTTLを短くしても、古い不在情報は残る
次は仕組みを確かめるための仮定例です。あるリゾルバーが09:00に、まだ存在しない名前についてTTL300秒のNXDOMAINを受け取ったとします。途中のキャッシュ削除や置換、実装によるTTLの短縮はなく、権威サーバーの内容は更新後に一致していて、正常に問い合わせられる条件です。障害時の期限切れ情報の利用も含めません。
| 時刻 | 権威サーバー側 | このリゾルバー側 |
|---|---|---|
| 09:00 | 名前はまだない | NXDOMAINを保存。残り300秒 |
| 09:01 | 名前とAを追加。新しいAのTTLは60秒 | 保存済みの不在情報は残り240秒 |
| 09:03 | Aが存在する | 同じキャッシュを使う問い合わせには、残り120秒のNXDOMAINを返し得る |
| 09:05 | Aが存在する | 通常の否定応答キャッシュは期限切れ。次の問い合わせでは改めて解決する |
09:01にAへ設定した60秒は、そのAを取得した後のキャッシュに関わる値です。それまでに保存されたNXDOMAINの残り240秒を、60秒へ書き換えるものではありません。この例では、通常の否定応答を使える期限が09:05に来るのであって、09:05に世界中の端末へ新しい情報が一斉配信されるわけでもありません。表は仕様から計算した説明で、実際のDNS環境を測定したものではありません。[1][2]
同じ名前だけに閉じないNXDOMAINの範囲
NXDOMAINには、さらに名前の階層との関係があります。RFC 8020は、ある名前が存在しなければ、その下の名前も存在しないとして扱う「NXDOMAIN cut」を定めています。たとえばfoo.exampleの不存在を保存したリゾルバーは、その有効期間中、配下のbar.foo.exampleにも、その情報に基づいてNXDOMAINを返せます。逆に、一つの配下名がないだけで、隣の名前や親までないとは判断できません。[3]
ただし同RFCには、すでに保存している配下のデータをそのTTLが切れるまで返してよいことや、DNSSECで検証されたNXDOMAINだけにこの動作を適用してよいことも書かれています。別名の連鎖がある場合は、どの名前の存在が否定されたのかも確認が必要です。最初に問い合わせた名前とは限りません。[3]
待ち時間を判断する前に、応答の種類と相手を確かめる
変更後に見つからないときは、まず名前とレコードの種類をそろえて、権威サーバーの応答と、実際に利用しているリゾルバーの応答を分けて確認します。後者がNXDOMAINまたはNODATAなら、Authority欄のSOAとそのTTLは、否定応答があとどれだけ残り得るかを判断する手掛かりです。問い合わせ先ごとに保存した時点や内容が違えば、見える結果も違い得ます。これはキャッシュの仕組みから得られる点検の順序です。
SERVFAILやタイムアウトなら、「存在しない」という応答が返った場合と同じ扱いにはできません。RFC 9520は、こうした名前解決の失敗にも、繰り返しの問い合わせを抑えるためのキャッシュを要求しています。NXDOMAINとNODATAは、有用な不存在の情報が得られた応答として、これらの解決失敗とは区別されています。単に「DNSで失敗した」とまとめず、何が返ったのかを残すことが切り分けにつながります。[4]
また、権威サーバーへ接続できないなど、期限切れの情報を更新できない場面では、古い情報を返して可用性を保つserve-staleという仕組みもあります。RFC 8767は期限切れの否定情報にも言及しています。そのため、先ほどのTTL計算を、障害時も含めた復旧時刻の保証にはできません。正常時のキャッシュ期限、障害による解決失敗、期限切れ情報の利用を分けることで、「何を待っているのか」が具体的になります。[5]
参考資料
- RFC Editor, RFC 9499: DNS Terminology、2024年3月。リゾルバー、権威サーバー、TTL、NXDOMAIN、NODATA、negative cachingの用語を参照。
- RFC Editor, RFC 2308: Negative Caching of DNS Queries (DNS NCACHE)、1998年3月。§§1〜6。不存在応答の識別、SOAから決まるTTL、保存時と返答時の扱いを参照。解決失敗に関する旧§7は下記RFC 9520の更新と区別。
- RFC Editor, RFC 8020: NXDOMAIN: There Really Is Nothing Underneath、2016年11月。§§1.1〜3.2。NXDOMAIN cut、既存キャッシュ・DNSSECの条件、別名連鎖の扱いを参照。
- RFC Editor, RFC 9520: Negative Caching of DNS Resolution Failures、2023年12月。§§2〜3。NXDOMAIN/NODATAと解決失敗の区別、失敗を保存する要件を参照。
- RFC Editor, RFC 8767: Serving Stale Data to Improve DNS Resiliency、2020年3月。§§4〜7・10。更新できない期限切れ情報の利用条件と否定情報への影響を参照。
