2026年7月5日
2026年7月5日
NSレコードの仕組みとゾーン委任の設定|BINDで委任を書く手順と全ネームサーバーの確認方法
ゾーンの委任は、親ゾーンに書く NS レコード(必要ならグルーレコードも)と、委任先の子ゾーンが返す NS・SOA がそろい、さらに「列挙したすべてのネームサーバーが同じ内容を権威を持って答える」ことで初めて成り立ちます。この記事では、自前の権威 DNS(BIND)でサブドメインを委任する場面を例に、親ゾーン・子ゾーンの書き方、作業の順番、ネームサーバーを1台ずつ確かめる方法と、食い違いが起きたときの直し方を解説します。レジストラや DNS サービスの画面での設定ではなく、ゾーンファイルを自分で書く人向けの内容です。
委任の応答を読んでみる
委任の仕組みは、親ゾーンのサーバーが返す応答を見ると理解しやすくなります。dev.example.com を別のサーバーに委任している親ゾーン(example.com)の権威 DNS に、再帰なし(+norec)で問い合わせると、次のような応答が返ります。
$ dig @ns1.example.com api.dev.example.com A +norec
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 2
;; AUTHORITY SECTION:
dev.example.com. 3600 IN NS ns1.dev.example.com.
dev.example.com. 3600 IN NS ns2.example.net.
;; ADDITIONAL SECTION:
ns1.dev.example.com. 3600 IN A 192.0.2.53
読み取れるポイントは3つです。
- ANSWER が空で、AUTHORITY に NS が入っている:「この名前の答えは持っていないので、こちらのサーバーに聞いてください」という案内(リファーラル)です
- **flags に
aaが無い**:親ゾーンが返す委任の NS は、権威ある答えではありません。子ゾーンの NS こそが正式な情報で、親側はその写しという位置づけです - ADDITIONAL に ns1.dev.example.com の IP アドレスがある:これがグルーレコードです。委任先の名前が委任されるゾーンの内側にあるため、親が IP アドレスを添えないと誰もたどり着けません。
ns2.example.netのように外側の名前にはグルーは付きません
キャッシュ DNS は、この案内を受けて委任先に問い合わせ直し、そこで初めて aa 付きの答えを得ます。親側の NS と子側の NS のどちらを優先して覚えるかはリゾルバーの実装によって違うため、両者が食い違っていると、利用者のリゾルバーごとに結果が変わる、原因の分かりにくい不具合になります。
作業の順番:子ゾーンを先に作る
委任は「子ゾーンを用意して動作を確認する → 親ゾーンに NS を追加する」の順に進めます。先に親へ NS を書くと、子ゾーンが応答できるまでの間、委任先が答えない状態(レームデリゲーション)になり、その間に問い合わせたリゾルバーには失敗がキャッシュされることがあります。
作業前には、親ゾーンのファイルと BIND の設定ファイルをコピーしてバックアップを取っておきます。
子ゾーンを用意する
委任先のプライマリ(ここでは ns1.dev.example.com、192.0.2.53)に、子ゾーンのファイルを作ります。
$TTL 3600
@ IN SOA ns1.dev.example.com. hostmaster.example.com. (
2026101801 ; serial
3600 ; refresh
900 ; retry
1209600 ; expire
300 ) ; negative cache TTL
IN NS ns1.dev.example.com.
IN NS ns2.example.net.
ns1 IN A 192.0.2.53
api IN A 192.0.2.80
子ゾーンにも NS を書き、親に書く予定の NS と同じ並びにします。ns1 の A レコードは、子ゾーン側にも正式なデータとして置きます。
BIND の設定(named.conf などに読み込まれるファイル)には、プライマリとセカンダリをそれぞれ次のように書きます。ファイルの置き場所はディストリビューションによって異なり、Debian・Ubuntu では /etc/bind/、RHEL 系では /var/named/ 周辺がよく使われます。
// プライマリ(192.0.2.53)側
zone "dev.example.com" {
type primary;
file "/etc/bind/zones/db.dev.example.com";
allow-transfer { 198.51.100.20; };
also-notify { 198.51.100.20; };
};
// セカンダリ(ns2.example.net、198.51.100.20)側
zone "dev.example.com" {
type secondary;
file "/var/cache/bind/db.dev.example.com";
primaries { 192.0.2.53; };
};
primary・secondary・primaries は比較的新しい BIND で使える書き方で、古い版では master・slave・masters と書きます。手元の版で使える表記は named -v で版を確かめたうえで、公式ドキュメントを参照してください(2026年10月現在)。
反映前に named-checkconf と named-checkzone dev.example.com /etc/bind/zones/db.dev.example.com で文法とゾーンの中身を検査し、問題がなければ rndc reload で読み込みます。外部に公開する権威 DNS では、recursion no; を設定して再帰問い合わせを受け付けないようにしておくと、第三者に踏み台として使われる危険を避けられます。
この段階で、まだ委任されていない子ゾーンに IP アドレスで直接問い合わせ、答えが返るかを確認します。
dig @192.0.2.53 dev.example.com SOA +norec
dig @198.51.100.20 dev.example.com SOA +norec
両方の応答に aa フラグがあり、SOA のシリアルが一致していれば、セカンダリへの転送まで済んでいます。
親ゾーンに委任を書く
子ゾーンが答えることを確かめたら、親ゾーン example.com のファイルに NS とグルーを追加します。
; dev.example.com を委任する
dev IN NS ns1.dev.example.com.
dev IN NS ns2.example.net.
ns1.dev IN A 192.0.2.53 ; グルー(委任先の内側の名前なので必要)
書くときの注意点は次のとおりです。
- 親ゾーンの SOA シリアルを上げる:上げ忘れると、セカンダリが変更を取りに来ず、親ゾーンのネームサーバーの間で委任の有無が食い違います
- 委任した名前より下に、ほかのレコードを残さない:
devやapi.devの A レコードが親ゾーンに残っていても、委任後は使われません。どちらが正しいか分からなくなるので削除します - NS の値は A/AAAA を持つホスト名にする:IP アドレスや CNAME の名前は NS の値に使えません
- グルーは内側の名前の分だけ:外側の
ns2.example.netのアドレスは親に書きません
親ゾーンも named-checkzone で検査してから rndc reload します。
すべてのネームサーバーに1台ずつ問い合わせる
委任の確認でよくある見落としは、いつも使うリゾルバー経由で1回引けたことに満足してしまうことです。リゾルバーは列挙された NS のどれかを選んで聞くため、1台だけ壊れていると「ときどき引けない」状態になります。親が返す NS と、それぞれの NS の答えを並べて確かめます。
ZONE=dev.example.com
# 親ゾーンのネームサーバーが返す委任情報(AUTHORITY と ADDITIONAL)
for p in ns1.example.com ns2.example.com; do
echo "== parent: $p"
dig @"$p" "$ZONE" NS +norec +noall +authority +additional
done
# 委任先を1台ずつ:aa フラグ、SOA シリアル、NS の並び
for ns in 192.0.2.53 198.51.100.20; do
echo "== child: $ns"
dig @"$ns" "$ZONE" SOA +norec | grep -E "flags:|IN[[:space:]]+SOA"
dig @"$ns" "$ZONE" NS +norec +short
dig @"$ns" "$ZONE" SOA +norec +tcp +short
done
見るべき項目は4つです。
- 親ゾーンのネームサーバー同士で、返す NS とグルーが同じか
- 委任先のすべてが応答し、
aaフラグを立てているか - SOA のシリアルが全台で一致しているか
- TCP(
+tcp)でも応答するか。ゾーン転送や大きな応答では TCP の53番ポートを使うため、ファイアウォールで UDP だけ開けていると、普段は動いて見えても転送や一部の問い合わせで失敗します
最後に dig +trace api.dev.example.com で、ルートから順に委任をたどれることを確かめれば、外から見た動作も確認できます。
食い違いが見つかったときの直し方
セカンダリのシリアルが古い:プライマリ側でシリアルを上げたか、allow-transfer と also-notify にセカンダリの IP アドレスが入っているか、TCP の53番ポートが通るかを順に確認します。BIND では rndc zonestatus dev.example.com でゾーンの状態を、ログで転送の成否を確かめられます。
親と子で NS の並びが違う:ネームサーバーを追加・廃止したとき、片側だけを直したケースがほとんどです。両方のゾーンを同じ内容にそろえ、それぞれシリアルを上げます。
グルーの IP アドレスが古い:ネームサーバーの IP アドレスを変えたときは、子ゾーンの A レコードと親ゾーンのグルーの両方を書き換えます。ドメイン全体のネームサーバーを自分のドメイン内の名前で運用している場合、親側のグルーはレジストラの管理画面(ホスト名の登録など)で変更します。
委任先が応答しない:委任先でゾーンが読み込まれていない、named-checkzone のエラーで読み込みに失敗している、といった状態です。ログを確認し、直したら子ゾーン、親ゾーンの順に再確認します。使わなくなった委任は、親ゾーンから NS を消しておきます。向き先の DNS サービスを解約した後も NS が残っていると、第三者にそのゾーンを作られてしまう危険があります。
まとめ
- 委任は、親ゾーンの NS(とグルー)、子ゾーンの NS・SOA、全ネームサーバーの応答の3つがそろって成り立つ
- 親が返す NS には
aaが付かず、正式な情報は子ゾーン側にある。両者は同じ内容にそろえる - 子ゾーンを作って全台の応答を確かめてから、親ゾーンに NS を追加する
- 変更のたびに SOA シリアルを上げ、
named-checkzoneで検査してから読み込む - 確認は1台ずつ。
aaフラグ、シリアルの一致、NS の並び、TCP での応答を見る