ドメイン名を一つずつ別名へ対応させる代わりに、名前の木の一部分をまとめて別の場所へ向けたいことがあります。DNSのDNAMEは、そのためのレコードです。ただし、設定した名前自身と、その下にある名前では扱いが違います。この境界を確かめないと、「全部を移したつもりなのに、起点だけ元のまま」という状態を読み違えます。
簡単にまとめると?
- CNAMEが一つの名前を別名へ向けるのに対し、DNAMEは設定した名前の下にある子孫名を、別の枝の対応する名前へ向けます。設定した名前自身は置き換えません。
- 置換するのは名前の末尾に一致するラベルのまとまりです。api.old.example.ならapi.new.example.となり、左側のapiは残ります。似た綴りを含むだけの名前は対象になりません。
- 応答にはDNAMEと、問い合わせた名前に対応する合成CNAMEが現れます。起点のレコード、移動先の実データ、ループや長さ制限を別々に確かめる必要があります。
「設定した場所」と「その子孫」を分ける
DNSでは、ドットで区切った名前の一部分をラベルと呼びます。api.old.example.ならapi、old、exampleというラベルが並び、末尾のドットは根を示します。名前の階層をたどるときは、右側のexampleからold、その下のapiへ進みます。
レコードが置かれる名前をowner、ここでは設定元の名前と呼びます。CNAMEは、その設定元の名前でデータを探したときに、別の一つの名前へ案内します。一方DNAMEは、設定元より下にある子孫名への問い合わせを対象にします。RFC 6672はこの違いを、名前の木の一部から別の部分への案内として説明しています。[1、§1]
たとえば設定元をold.example.、転送先をnew.example.とするDNAMEを考えます。問い合わせ名がapi.old.example.なら、末尾のold.example.をnew.example.へ置き換え、api.new.example.について調べます。img.eu.old.example.なら、左にあるimg.euをそのまま残してimg.eu.new.example.になります。下の階層が一段だけである必要はありません。
文字列の部分一致ではなく、ラベルごとの置換
RFC 6672 §2.2が定めるのは、根まで続く末尾側のラベルの一致です。oldという文字を探してどこでもnewに変える処理ではありません。notold.example.は、ラベルnotoldがoldと一致しないため、先ほどのDNAMEでは置換されません。api.old.example.invalid.も、末尾がold.example.ではないので対象外です。
反対に、old.example.そのものは末尾が一致していても、DNAMEの子孫ではありません。Aレコードなどを問い合わせた場合、その名前をnew.example.へ置き換えることはありません。DNAMEという種類そのものを問い合わせれば、old.example.にあるDNAMEレコードを取得できますが、これも設定元の名前を別名へ変えることとは区別します。[1、§2.3]

この比較は、ドットで分けたラベル列で独自に計算しました。子孫の二例、設定元と同じ名前、似た綴りの名前、末尾が違う名前を分けて照合しています。実装は説明用の限られたASCII名を扱うもので、DNSパケットの解析、国際化ドメイン名の処理、問い合わせ先の探索を再現したリゾルバーではありません。
応答にCNAMEが現れても、一件ずつ登録したとは限らない
DNAMEの置換を行うサーバーは、応答のAnswer欄へ、その根拠となるDNAMEを入れます。さらに、その問い合わせ名から置換後の名前へのCNAMEを合成して加えます。[1、§3.1]
api.old.example.という問い合わせなら、概念上は「old.example. DNAME new.example.」という規則と、「api.old.example. CNAME api.new.example.」という今回の対応が一緒に見えます。後者は、管理者がすべての子孫名について個別にCNAMEを登録した証拠にはなりません。応答を作る際にDNAMEから導けるためです。
同節では、合成CNAMEのTTLを対応するDNAMEと等しくするよう定めています。TTLはキャッシュして使える時間を伝える値です。キャッシュから合成する場合は、DNAMEの経過時間を差し引いたTTLに合わせることが推奨されています。古い実装の合成CNAMEがTTL 0を返す場合も考慮され、リゾルバーは0とDNAME相当の値の双方を扱える必要があります。したがって、観測したCNAMEのTTLだけから、手作業で登録されたレコードかどうかを断定できません。
起点の情報と、枝の下の情報は同じ場所に置けない
DNAMEの設定元には、共存の制約に反しないほかの種類のレコードを置けます。ただし、同じ名前にCNAMEを置くことはできず、DNAMEも一つに限られます。さらにRFC 6672 §2.4は、DNAMEの設定元より下にリソースレコードを置いてはならないとしています。「この子だけは旧側のAを優先させる」という例外の作り方にはできません。
規則に反する下位データを含むゾーンは、サーバーが読み込みを拒否してもよく、読み込んだとしてもDNAMEの下のデータは覆い隠されます。移動先の名前を調べることで内容を得るため、移動先に必要な情報があるかが別の確認点になります。DNAMEを置いただけで、移動先へAやAAAAなどの実データがコピーされるわけではありません。
ゾーンの頂点、つまりそのゾーンの管理範囲の起点へDNAMEを置く場合も、そこで必要なSOAやNSは残ります。SOAはゾーンの管理情報、NSは権威サーバーを示します。起点自身を置換しないため、DNAMEだけでゾーン全体を完全に写すことはできません。[1、§2.3] 配下への案内が成功しても、起点への問い合わせまで同じ答えになるとは限らないのです。
移行の前に、対応する名前と終点を確かめる
比較するときは、まず設定元と同じ名前、その一段下、さらに深い名前、似た綴りで対象外の名前を分けます。次に、置換後の名前に必要な種類の情報があるかを調べます。この順に整理すると、DNAMEの対象外なのか、置換はできたが行き先に情報がないのかを切り分けられます。
置換先が元へ戻るような設定なら、DNAME同士やCNAMEとの組み合わせでループを作れます。また、左側に残るラベルと転送先を合わせてDNS名の長さが255オクテットを超えると、サーバーはYXDOMAINを返します。[1、§2.2] オクテットは8ビットの単位であり、画面に表示したドット付き文字列の文字数とは分けて数えます。独自計算では各ラベルの長さを示す1オクテットと末尾の根ラベルも数え、置換後の長さが255と256になる境界例を照合しました。これは仕様の長さ条件を確かめた計算で、実際のサーバーが返した応答ではありません。
本稿の比較はRFC 6672のDNAMEの意味と置換範囲に限定しています。製品ごとの設定画面、ゾーンの読み込み動作、DNSSEC検証、キャッシュを経た切り替わりの時間までは実測していません。名前の案内先を変えられることと、アプリケーションが移行先で正しく動くことを分け、使う実装の版と設定に応じて確かめる必要があります。
出典
- RFC Editor, RFC 6672: DNAME Redirection in the DNS(2012年6月刊行、Standards Track表記の本文)。§§1、2.1–2.4、3.1を参照。2026年10月23日に公式本文を確認。Table 1の置換条件を読み、本文の名前と図、境界計算は独自に作成。現行製品の動作検証や規格状態の追加認定を意味しない。
