- ブラウザURL入力
- DNS名前→IP今ここ
- ルータ経路選択
- ロードバランサ振り分け
- Nginx受け口
- アプリ処理
- DB保存
第25週『名前からアドレスへ — DNSは巨大な委任の木』では名前解決の経路を辿りました。今回はその終点にある「表の1行」そのものを見ます。
まず結論
DNSのレコードは「名前・TTL・クラス・種別・値」が並んだ1行です。種別(TYPE)が決めているのは**その値をどう読むか**だけで、他の行には関わりません。だからAとAAAAは同じ名前に並べられます。
CNAMEだけが例外です。値の読み方ではなく、**その名前への問い合わせ全体を別の名前へ差し替える**指示なので、行ではなく表そのものに効きます。だから他のレコードと同居できません。
同じ名前にAとAAAAを両方置けるでしょうか。またCNAMEとAを両方置けるでしょうか。
当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。
1行に書いてあるのは5つの列だけ
第25週で、名前解決がルートから権威へ辿る経路を追いました。今回はその終点で待っている「表の1行」を見ます。
example.com. 270 IN A 104.20.23.154
名前 TTL クラス 種別 値
種別(TYPE)が決めているのは、いちばん右の値をどう読むかだけです。A なら4バイトのIPv4アドレス、AAAA なら16バイトのIPv6アドレスとして読む。種別は値に付いたラベルであって、他の行について何も言っていません。だからAとAAAAは、読み方が違う2つの値が並んでいるだけで、競合のしようがありません。
もうひとつ。同じ名前・同じ種別のレコードは、1つの集合(RRSet)として扱われます。 RFC 2181 §5.2 は、集合の中でTTLが異なることを deprecated とし、こう規定しています。
the TTLs of all RRs in an RRSet must be the same
DNSが受け渡しする最小の単位は1行ではなく、この集合です。
実物を見る — 同居と集合
macOS、DiG 9.10.6、2026-09-17 JST の実測です。値は測定時刻と地点に依存します。
$ dig +noall +answer example.com Aexample.com. 270 IN A 104.20.23.154example.com. 270 IN A 172.66.147.243$ dig +noall +answer example.com AAAAexample.com. 270 IN AAAA 2606:4700:10::ac42:93f3example.com. 270 IN AAAA 2606:4700:10::6814:179a
同じ example.com. にAが2本、AAAAが2本。種別が違えば同居でき、同じ種別なら複数持てます。
TXTだと集合であることがはっきりします。同じ測定で google.com のTXTを引くと、このときは17行返りました。
google.com. 300 IN TXT "v=spf1 include:_spf.google.com ~all"google.com. 300 IN TXT "google-site-verification=4ibFUgB-wXLQ_S7vsXVomSTVamuOXBiVAzpR5IZ87D0"google.com. 300 IN TXT "apple-domain-verification=30afIBcvSuDV2PLX"google.com. 300 IN TXT "facebook-domain-verification=22rm551cu4k0ab0bxsw536tlds4h95"(以下、計17行。TTLは17行すべて 300 で揃っていた)
17という数も中身も、設定が変われば変わります。見てほしいのはTTLで、17行すべてが 300 で揃っていました。RFC 2181 §5.2 のとおりです。
SPFと各社の所有確認が同じ集合に同居しているのは、RFC 1035 §3.3.14 が中身の意味を決めていないからです。
1つの名前に同じ種別のレコードを複数置いたとき、TTLはどうなっていなければなりませんか。
CNAMEだけが、行ではなく表に効く
ここで例外が出てきます。RFC 1034 §3.6.2 の逐語です。
If a CNAME RR is present at a node, no other data should be present; this ensures that the data for a canonical name and its aliases cannot be different. This rule also insures that a cached CNAME can be used without checking with an authoritative server for other RR types.
CNAMEがあるノードには、他のデータを置くべきでない。理由が2つ書かれています。正規名と別名でデータが食い違わないこと、そしてキャッシュしたCNAMEを、他の型について権威へ確認せずに使えることです。
現行の規定は RFC 2181 §10.1 にあります。
状態 備考CNAMEが1つある(SIG/NXT/KEY を伴ってよい) 他のデータは持てないCNAME以外のレコードが1つ以上ある 種別は何種類あってもよい名前は存在するが、レコードが無い 第25週の NODATA名前自体が存在しない 第25週の NXDOMAIN
例外として挙がる SIG / NXT / KEY は、RFC 2181 が書かれた当時のDNSSECの型名で、現行の RRSIG / NSEC / DNSKEY ではありません。
では、なぜCNAMEだけが同居できないのか。CNAMEは値の読み方の指定ではないからです。他の種別が「この値をこう読め」と言うのに対し、CNAMEは「この名前への問い合わせを、あの名前への問い合わせに差し替えろ」と言っています。効く対象が1行ではなくその名前の表そのものです。
差し替えである以上、問い合わせた種別は関係ありません。AでもMXでもTXTでも、まるごと転送先へ向きます。だとすると、同じ名前に他のレコードを置いても誰も読みに来られません。読みに来られない行を許せば、正規名と別名でデータが食い違う余地が生まれます。RFC 1034 の「this ensures that the data ... cannot be different」はこのことです。
なお RFC 2181 §10.1.1 は、CNAMEレコードの左辺を「CNAME」と呼ぶ慣用を「This is unfortunate」「an entrenched usage」と評しています。
CNAMEに別の種別を訊いてみる
差し替えが種別を問わないことも実物で見えます。
$ dig +noall +answer www.github.comwww.github.com. 2559 IN CNAME github.com.github.com. 60 IN A 20.27.177.113$ dig +noall +answer www.github.com MXwww.github.com. 3340 IN CNAME github.com.github.com. 300 IN MX 0 github-com.mail.protection.outlook.com.
Aを訊いてもMXを訊いても、まずCNAMEが返り、続いて転送先 github.com のその種別が返ります。名前サーバが差し替えを代行し、途中経過も一緒に返しています。
1つ目の応答のTTLも見てください。CNAMEが 2559、その先のAが 60 で、揃っていません。cp1 の規則は1つのRRSetの中の話で、ここは別々の2つの集合が1つの応答に入っています。「1回の応答に出るTTLは全部同じはず」と読むと誤ります。
なお、値の形が同じでも処理は同じとは限りません。PTRの値も <domain-name> ですが、RFC 1035 §3.3.12 は PTR を「These records are simple data」とし、CNAMEのような特別な処理は伴わないと明記しています。
`www.github.com` にCNAMEがあるとき、その名前にMXを問い合わせると何が返りますか。
Content-Type — バイト列に付ける外側のラベル
アプリ層『なぜ Content-Type と文字コードが要るのか』で見たとおり、受け取る側は届いたバイト列から「これは何か」を読み取れません。ラベルが無ければ、型の決定は受け取る側の推測に移ります。
ラベル 効く対象 他への干渉Content-Type その本文だけ 無しcharset その本文だけ 無し
RR の TYPE — 値に付ける読み方の指定
レコードの種別も同じ位置にあります。4バイトの値だけでは、それがIPv4アドレスなのか決まりません。TYPE が A だと名指しして読み方が決まり、その指定は並ぶ AAAA や TXT には関わりません。
ラベル 効く対象 他への干渉TYPE = A その値だけ 無しTYPE = AAAA その値だけ 無しTYPE = CNAME その名前の全体 あらゆる種別の問い合わせ
Content-Type と RR の TYPE は、どちらも「値の読み方」を決めるラベルです。ではCNAMEは、そのどちらでもありません。何が違うのでしょうか。
「ラベルが付く単位は何か」を考えてみてください。Content-Type はメッセージごと、TYPE は行ごと。CNAME は何ごとでしょうか。
図で見る — 行・集合・差し替え
- ・種別は値の読み方を決めるだけなので、A と AAAA と TXT は並列できる
- ・TTLを揃える規則は集合の中の話。またぐと揃わない
この章のまとめ
- レコードは「名前・TTL・クラス・種別・値」の1行。種別が決めるのは値の読み方だけで、他の行には干渉しない。だからAとAAAAは同居できる。
- DNSが扱う最小の単位は1行ではなく、同じ名前・同じ種別の集合(RRSet)。集合内のTTLは RFC 2181 §5.2 により全行で同一。ただし集合をまたぐと揃わない。
- CNAMEだけが値ではなく名前に効く。 種別を問わず問い合わせが転送先へ差し替わるので、他のレコードを置いても読みに来られない。RFC 1034 §3.6.2 の「no other data should be present」の理由がこれ。
- RFC 2181 §10.1 の同居例外は SIG / NXT / KEY(当時のDNSSECの型名)。現行の型名に読み替えて原文として引かない。
- 値の形が同じでも処理は同じではない。PTRは simple data(RFC 1035 §3.3.12)。
- 古い道具は型名を知らないとき、エラーではなく別の質問の答えを返すことがある。確かめる場所は
;; QUESTION SECTION:。
次回は、この規則が頂点(apex)でどう効くのかを見ます。レコード種別の語彙は、既存のクイズ群「DNS(名前解決)」の DNS III(リソースレコード)が対応しています。
自分の現場で確かめる
読んだだけでは身につきません。手元の環境で実際に見てみてください。
理解度チェック
読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。
RFC 2181 §10.1 は、CNAMEを持つ名前に同居してよいレコードの例外を挙げています。原文が挙げている型名はどれですか。
用語集(5語)
- リソースレコード (RR)
- DNSに置かれる1行。名前・TTL・クラス・種別(TYPE)・値(RDATA)から成る。種別は値をどう読むかを決める。
- RRSet
- 同じ名前・同じ種別のレコードの集合。RFC 2181 §5.2 により集合内のTTLはすべて同じ。DNSが扱う最小の単位はこの集合。
- CNAME
- 別名を正規名へ結びつけるレコード。RFC 1034 §3.6.2 は「If a CNAME RR is present at a node, no other data should be present」と規定する。その名前への問い合わせ全体を差し替える指示として働く。
- alias / canonical name
- CNAMEレコードの左辺が alias、右辺が canonical name。RFC 2181 §10.1.1 は、左辺を「CNAME」と呼ぶ慣用を「This is unfortunate」「an entrenched usage」と述べている。
- TYPE の番号
- 各レコード種別に割り当てられた数値。IANA のレジストリが管理する。A=1、CNAME=5、AAAA=28、HTTPS=65。2026-09-17 時点で99型。
出典(一次ソース)
- RFC 1034 §3.6.2 — Aliases and canonical names(CNAMEのノードに他のデータを置かない) ↗
- RFC 1035 §3.3.12 / §3.3.14 — PTR は simple data、TXT の意味は置かれたドメイン次第 ↗
- RFC 2181 §5.2 / §10.1 / §10.1.1 — RRSet の TTL、名前の4つの場合、CNAME という語の混乱 ↗
- RFC 9460 — SVCB / HTTPS RR(2023年11月) ↗
- IANA DNS Parameters — Resource Record (RR) TYPEs(機械可読版) ↗