「example.jpそのものをCDNに向けたいので、CNAMEを書いたらエラーになりました」
「MXを追加したのに、メールが届きません」
どちらも、リソースレコードのルールを知っていれば防げるトラブルです。後者は、たった1文字(末尾のドット)が原因ということもよくあります。
第4回では、DNSメッセージの「入れ物」を見ました。第5回と第6回では、その中身であるリソースレコードを見ていきます。前編の今回は、ゾーンファイルの書き方と、ゾーンの骨格になるSOA・NS・A/AAAA・CNAMEです。メールや証明書に関わるレコードは後編で扱います。
ゾーンファイルの書き方
まずは、BINDなどで使われるゾーンファイルの書き方です。Route 53などのクラウドのDNSでも、インポート・エクスポートの形式として使われるので、読めるようにしておくと役に立ちます。
$ORIGIN example.jp.
$TTL 3600
@ IN SOA ns1.example.jp. hostmaster.example.jp. (
2026092501 ; シリアル
3600 900 1209600 900 )
IN NS ns1.example.jp.
IN NS ns2.example.jp.
IN MX 10 mail.example.jp.
@ 300 IN A 192.0.2.10
www IN CNAME example.jp.
ns1 IN A 192.0.2.53
ns2 IN A 198.51.100.53
mail IN A 192.0.2.25

読み方のルールは次のとおりです。
- 1行が1レコード:名前・TTL・クラス(IN)・タイプ・値の順。TTLを省くと
$TTLの値になる - $ORIGIN:相対名に付け足すドメイン名。@は$ORIGINそのもの(ゾーンの頂点)
- 名前の欄が空白で始まる行は、直前の行と同じ名前になる(上のNS・MXは@のもの)
- ;から行末まではコメント。
( )で1つのレコードを複数行に分けて書ける
3つ目のルールは要注意です。見やすくしようと字下げのつもりで入れた空白で、名前が変わってしまう事故が起きます。
相対名と末尾のドットの落とし穴
第2回で触れた「末尾のドット」が、ゾーンファイルでは特に効いてきます。末尾にドットが無い名前は、$ORIGINが付け足された相対名として扱われます。
| 書いた値($ORIGIN example.jp.) | 解釈される名前 | 判定 |
|---|---|---|
| www | www.example.jp. | 正しい(相対名) |
| www.example.jp. | www.example.jp. | 正しい(FQDN) |
| @ | example.jp. | 正しい(頂点) |
| www.example.jp(ドットなし) | www.example.jp.example.jp. | 誤り |
| MX 10 mail.example.jp(ドットなし) | mail.example.jp.example.jp. | 誤り(メールが届かない) |
| CNAME cdn.example.net(ドットなし) | cdn.example.net.example.jp. | 誤り(引けない) |
厄介なのは、構文としては正しいため、ドット忘れがエラーにならないことが多い点です。冒頭の「MXを追加したのにメールが届かない」の正体が、このドット忘れだったということもよくあります。
反映前にnamed-checkzoneで読み込みを確認し、反映後はdigで実際の値を確かめる、という2段構えにしましょう。
$ named-checkzone example.jp /var/named/example.jp.zone
zone example.jp/IN: loaded serial 2026092501
OK
SOA:ゾーンの「表紙」
SOA(Start Of Authority)は、ゾーンの頂点に必ず1つだけ置く、ゾーン全体の管理情報です。
| フィールド | 意味 | 値の目安 |
|---|---|---|
| MNAME | プライマリの権威DNSサーバー名 | ns1.example.jp. |
| RNAME | 管理者のメールアドレス(@を.に置き換える) | hostmaster.example.jp. |
| SERIAL | ゾーンの版番号。増えたときだけ転送される | YYYYMMDDnn(第7回) |
| REFRESH | セカンダリが更新を確認する間隔 | 3600〜86400秒(NOTIFYを使うなら長めでよい) |
| RETRY | 確認に失敗したときの再試行の間隔 | 600〜3600秒(REFRESHより短く) |
| EXPIRE | 更新できないまま、ゾーンを捨てるまでの時間 | 1209600〜2419200秒(2〜4週間、RFC 1912) |
| MINIMUM | ネガティブキャッシュのTTL | 300〜3600秒(RFC 2308は1〜3時間を例示) |
REFRESH・RETRY・EXPIREの3つは、セカンダリの動きを決めるタイマーです。

注意点が2つあります。
- MINIMUMの意味は変わった:RFC 1035では既定のTTLでしたが、RFC 2308でネガティブキャッシュのTTLに意味が変わりました(第3回)。古い手順書の86400をそのまま使うと、「追加したのに1日引けない」が起きます。
- EXPIREを短くしすぎない:短くしすぎると、プライマリが止まった連休中に、セカンダリが応答をやめてしまいます。
NS:ゾーンの権威DNSサーバー
NS(Name Server)レコードは、そのゾーンの権威DNSサーバーを示します。第2回で見たとおり、NSは2か所に現れます。
- 親ゾーンに置かれた、委任のためのNS
- 自分のゾーンの頂点に置くNS

両者の内容は一致させます。一致していない状態や、NSに書かれたサーバーがそのゾーンに答えない状態はlame delegationと呼ばれ、断続的な名前解決の失敗の典型的な原因です。キャッシュDNSがどのNSを選ぶかは毎回変わるので、「ときどき引けない」という症状になります。
NSのルールも押さえておきましょう。
- 値には、A/AAAAレコードで解決できるホスト名を書く
- IPアドレスを直接書くことはできず、CNAMEの名前を書くことも禁止されている(RFC 2181)
- NSのホスト名が自分のゾーンの中にあるときは、親ゾーンにグルーレコードが必要
- 可用性のため、権威DNSサーバーは少なくとも2台とし、別のネットワークや別の拠点に分けて置く(RFC 2182)
ポイント
・親の委任のNSと、子の頂点のNSを一致させる
・値はA/AAAAで引けるホスト名。IPアドレスやCNAMEは不可
・2台以上を、別のネットワーク・拠点に分けて置く
AとAAAA:DNSラウンドロビンの誤解
Aレコードは名前にIPv4アドレスを、AAAAレコードはIPv6アドレスを対応づける、最も基本的なレコードです(Aが4つで128ビット、と覚えます)。
1つの名前に複数のA/AAAAを置くことができ、これを負荷分散に使う方法をDNSラウンドロビンと呼びます。

ただし、ここには大きな誤解が潜んでいます。
- どのアドレスを使うかは、クライアントの実装しだいで、並び順どおりとは限らない
- 現在のOSやブラウザーは、複数のアドレスへ並行して接続を試すHappy Eyeballs(RFC 8305)を使うため、並び順の意味はさらに薄れている
- DNSにはヘルスチェックが無く、止まったサーバーのアドレスも返し続ける
つまり、DNSラウンドロビンを可用性の対策と考えてはいけません。1台止まっても、DNSはそのアドレスを返し続けます。止まったサーバーを外すには、ロードバランサーや、ヘルスチェック付きのDNSサービス(第10回のRoute 53のフェイルオーバーなど)を使います。
一方、別々の名前が同じIPアドレスを指すのは問題ありません。1台で複数の役割を持つ場合の、普通の書き方です。
CNAMEの制約
CNAME(Canonical NAME)は、ある名前を別の名前の別名にするレコードです。CDNやSaaSに独自ドメインを向ける公式の手順として広く使われますが、守るべき制約があります。

1. CNAMEを置いた名前には、他のレコードを置けない(RFC 1034。DNSSECの署名などを除く)
ゾーンの頂点には必ずSOAとNSがあるため、example.jpそのものにはCNAMEを置けません。冒頭の「頂点にCNAMEを書いたらエラー」はこれです。
2. MX・NS・SRVの値に、CNAMEの名前を書いてはいけない(RFC 2181 等)
3. 1つの名前に複数のCNAMEは置けない
負荷分散のつもりで2つ書くと、どちらが使われるかは決まりません。
CNAMEの先がまたCNAMEというCNAMEチェーンは、遅くなり障害の原因も増えるため避けます。値の末尾のドットも忘れないようにしましょう。CNAMEは、その名前のすべてを別の名前に置き換える、と覚えておくとルールを思い出しやすくなります。
ポイント
・CNAMEは他のレコードと共存不可。頂点には置けない
・MX・NS・SRVの値にCNAMEの名前を書かない
・1つの名前にCNAMEは1つ。チェーンは避ける
頂点を別名で向ける:ALIAS・ANAME・Route 53エイリアス
では、example.jpそのものをクラウドのロードバランサーやCDNに向けたいときは、どうすればよいのでしょうか。

| 方式 | 仕組み | 頂点に置けるか | 注意 |
|---|---|---|---|
| CNAME | 別名を返し、続きはリゾルバーが解決する | 置けない | 標準の仕組み。どのDNSでも使える |
| Route 53 エイリアス | Route 53が、ALB・CloudFront等のIPアドレスをA/AAAAとして直接返す | 置ける | AWSのリソース宛ての問い合わせは無料。TTLは指定できない |
| ALIAS/ANAME、CNAMEフラット化 | 権威DNSが裏で名前を解決し、結果をA/AAAAとして返す | 置ける | 各DNS事業者の独自機能。標準化されていない |
| HTTPS レコード(AliasMode) | 頂点から別の名前へ、標準の仕組みで向ける | 置ける | 対応するクライアントだけが使う(第6回) |
つまり、頂点では、名前ではなくアドレスで答える仕組みを使います。
$ dig example.jp A +short # Route 53 エイリアスで ALB に向けた例
192.0.2.80
192.0.2.81
PS> (Resolve-DnsName example.jp -Type A).IPAddress # PowerShell で値だけ
Route 53のエイリアスは、digでは普通のAレコードとして見え、エイリアスかどうかはRoute 53の画面やAPIでしか分かりません。独自機能なので、DNS事業者を移すときは、同じ機能があるかを確認しましょう(第10回)。
ワイルドカード
最後に、ワイルドカードです。
*.example.jp. 3600 IN A 192.0.2.10
www.example.jp. 3600 IN A 192.0.2.20

abc.example.jpやa.b.example.jpのように存在しない名前の問い合わせには、*のレコードから答えが合成される(192.0.2.10)- 存在する名前には効かない:
www.example.jpのMXを聞いても、ワイルドカードは使われずNODATAになる。x.www.example.jpもNXDOMAIN(RFC 4592) example.jp(頂点そのもの)には効かない。ワイルドカード証明書*.example.jpが1階層だけに効くのとは規則が違う点にも注意
便利な反面、注意点もあります。
- 打ち間違えた名前まで引けてしまい、設定の誤りに気づきにくい。searchドメイン(第3回)と組み合わさると、意図しない名前が解決されることがある
- 外部サービスへ向けたワイルドカードのCNAMEは、サブドメインの乗っ取り(第9回)の入り口になり得る。使う範囲は最小限にする
考えてみよう
- 自社のドメイン名(例:example.jp)そのもので、クラウドのロードバランサーやCDNに向けたい場合、どのような方法がありますか。DNS事業者を変えるときの影響も考えてみましょう。
- ゾーンファイルを手で編集する運用で、ドット忘れや空白の事故を防ぐには、どんな確認の手順を入れればよいでしょうか。
- 自社の権威DNSサーバーは何台あり、それぞれどこに置かれていますか。親ゾーンのNSと一致していますか。
ヒント:この記事の「頂点を別名で向ける」「相対名と末尾のドットの落とし穴」「NS」が手がかりです。
まとめ
- ゾーンファイルは1行1レコード。空白で始まる行は直前と同じ名前
- 末尾のドット忘れはエラーにならない。named-checkzoneとdigの2段構えで確認
- SOAのMINIMUMはネガティブキャッシュのTTL。EXPIREは短くしすぎない
- NSは親と子で一致させ、2台以上を別の場所に。ずれるとlame delegation
- DNSラウンドロビンは可用性の対策ではない
- CNAMEは頂点に置けない。頂点はRoute 53エイリアスやALIASで向ける
次回(後編)は、メール(MX・SPF・DKIM・DMARC)、SRV・PTR、証明書(CAA)、そして新しいHTTPS/SVCBレコードを扱います。
連載「DNS入門」全12回
- DNSとは?名前解決の全体像と3つの登場人物
- ドメイン名の階層と委任
- 名前解決の流れ
- DNSメッセージとトランスポート
- リソースレコード 前編(この記事)
- リソースレコード 後編
- 権威DNSサーバーの運用
- コマンドで調べる
- DNSのセキュリティ
- クラウド・社内環境のDNS
- DNSトラブルシュート
- DNS設計演習

コメント