2026年6月6日

2026年6月6日

Unbound から NSD へ移行する手順|local-data・auth-zone をゾーンファイルにし、Unbound は再帰専用に残す

Unbound から NSD への移行は、「Unbound が持っているゾーンのデータ(local-data や auth-zone)をゾーンファイルに書き出して NSD に載せ、Unbound からは NSD へ問い合わせを回す」形で進めるのが基本です。NSD は権威DNS専用で、再帰問い合わせもキャッシュもしないため、Unbound をまるごと置き換えることはできません。この記事では、移行の対象を見極める棚卸しから、ゾーンファイルの作成、NSD の設定、Unbound の stub-zone での接続、比較と切り戻しまでを説明します。

最初に確認すること:何を NSD に移すのか

Unbound は本来、クライアントの代わりに名前解決をするキャッシュDNS(フルリゾルバー)です。一方の NSD は、自分が持っているゾーンについてだけ答える権威DNSサーバーです。この役割の違いから、「Unbound から NSD へ移行する」が意味するのは、たいてい次の2つのどちらかです。

  • 社内向けの名前を NSD に移す:Unbound の local-zone と local-data で社内のホスト名を返していたが、レコードが増えて管理しにくくなった。ゾーンファイルで管理し、セカンダリへの転送もしたい。
  • Unbound の auth-zone で公開していたゾーンを NSD に移す:Unbound 1.8 以降の auth-zone で権威の応答をしていたが、権威DNSとして専用のサーバーに分けたい。

どちらの場合も、クライアントからの再帰問い合わせを受ける役は Unbound に残ります。「Unbound をやめて NSD だけにする」と、社内のパソコンやサーバーは外部の名前を引けなくなるので注意が必要です。

棚卸しのコマンド

設定ファイルを grep するだけでは、include: で読み込んでいる別ファイルを見落としがちです。動いている Unbound から、実際に読み込まれている内容を取り出します(unbound-control を使うには remote-control の設定が必要です)。

# 設定ファイルの構文を確認しておく
sudo unbound-checkconf

# 読み込まれている local-zone とその種類
sudo unbound-control list_local_zones

# local-data の一覧(ゾーンファイルに近い形式で出力される)
sudo unbound-control list_local_data > ~/unbound-local-data.txt

# auth-zone の一覧
sudo unbound-control list_auth_zones

list_local_zones には、Unbound が最初から持っている既定のゾーン(localhost. やプライベートアドレスの逆引きなど)も出てきます。移す対象は、自分で追加したゾーンだけです。

NSD に移せない・挙動が変わる設定

local-zone には種類があり、NSD のゾーンと同じように振る舞うのは一部です。移行前に、使っている種類を確かめます。

  • static:書いた local-data だけを答え、それ以外は NXDOMAIN を返します。NSD のゾーンとほぼ同じ動きなので、そのまま移せます。
  • transparent:local-data にない名前は、通常どおり外部に問い合わせます。たとえば example.com の一部の名前だけ社内アドレスを返している場合、NSD に example.com ゾーンを作ると、書いていない名前はすべて NXDOMAIN になります。公開サイトや外部メールが引けなくなる典型的なつまずきです。この使い方は NSD に移さず、Unbound に残すほうが安全です。
  • redirect:ゾーン配下のすべての名前に同じ答えを返します。NSD ではワイルドカード(*.zone)で近い形にできますが、ゾーンの頂点の扱いなど細部が異なります。
  • refuse・deny・always_nxdomain などのブロック用の種類:権威DNSの役割ではないので、Unbound に残します。

また、access-control-view や view: で問い合わせ元ごとに答えを変えている場合、NSD にはこれに当たる機能がありません。この部分は Unbound に残すか、別の構成を検討します。

ゾーンファイルを作る

local-data から作る場合

list_local_data の出力は1行1レコードの形式なので、対象ゾーンの行を取り出せばゾーンファイルの材料になります。ただし、local-data だけで運用していたゾーンには SOA や NS がないことが多く、NSD ではこの2つが欠かせません。先頭に自分で書き足します。

ここでは社内向けの名前に home.arpa(家庭や小規模ネットワーク向けに RFC 8375 で予約された名前)の配下を使う例で示します。存在しないトップレベルドメインを勝手に作る(.local や .lan など)と、将来の名前の割り当てや mDNS と衝突するおそれがあるため、自社で持っているドメインのサブドメインか home.arpa を使うのが無難です。

; /etc/nsd/zones/office.home.arpa.zone
$TTL 3600
office.home.arpa.   IN SOA ns1.office.home.arpa. hostmaster.office.home.arpa. (
                        2026101801 ; serial
                        3600       ; refresh
                        900        ; retry
                        1209600    ; expire
                        300 )      ; negative TTL
office.home.arpa.   IN NS  ns1.office.home.arpa.
ns1                 IN A   127.0.0.1
; ここから下は list_local_data の出力から移したレコード
www                 IN A   192.168.10.20
nas                 IN A   192.168.10.30
printer             IN A   192.168.10.40

local-data-ptr で書いていた逆引きは、10.168.192.in-addr.arpa のような逆引きゾーンを別に作り、PTR レコードとして移します。

auth-zone から移す場合

auth-zone: の zonefile: で指定していたファイルは、もともと標準のゾーンファイル形式です。基本的にはコピーして NSD で読み込めます。primary: や url: で他のサーバーから取得していた場合は、NSD をセカンダリにする(request-xfr: を使う)か、取得済みのファイルを元に NSD をプライマリにするかを決めます。

NSD を設定して起動する

社内向けの名前を移す構成では、NSD はループバックの別ポートで待ち受け、外からは直接問い合わせを受けないようにします。5353番は mDNS が使うので避け、ここでは 10053 番を使います。

# /etc/nsd/nsd.conf
server:
    ip-address: 127.0.0.1
    port: 10053
    hide-version: yes
    zonesdir: "/etc/nsd/zones"

remote-control:
    control-enable: yes
    control-interface: 127.0.0.1

zone:
    name: "office.home.arpa"
    zonefile: "office.home.arpa.zone"
sudo nsd-checkconf /etc/nsd/nsd.conf
sudo nsd-checkzone office.home.arpa /etc/nsd/zones/office.home.arpa.zone
sudo nsd-control-setup
sudo systemctl restart nsd

# NSD に直接問い合わせて、権威として答えるか確認する
dig @127.0.0.1 -p 10053 www.office.home.arpa A +norec

応答の flags に aa が付いていれば、NSD がこのゾーンの権威として答えています。auth-zone で公開していたゾーンを移す場合は、ip-address: を公開用のアドレスにし、port の指定を外します。その際、同じアドレスの53番を Unbound が使っていないかを ss -lnup で確認します。

Unbound から NSD に問い合わせを回す

NSD が答えられるようになったら、Unbound の設定を書き換えます。対象ゾーンの local-zone と local-data を削除し、代わりに stub-zone で NSD を指定します。作業前に unbound.conf と include しているファイルのコピーを取っておきます。

# /etc/unbound/unbound.conf(該当部分)
server:
    # 127.0.0.1 への問い合わせを許可する(既定では localhost には問い合わせない)
    do-not-query-localhost: no
    # home.arpa は既定の local-zone に含まれる版があるため、その扱いを外す
    local-zone: "home.arpa." nodefault
    # 社内ゾーンは DNSSEC の検証の対象外にする
    domain-insecure: "office.home.arpa."

stub-zone:
    name: "office.home.arpa."
    stub-addr: 127.0.0.1@10053

ここでつまずきやすいのは3点です。1つ目は do-not-query-localhost で、これを no にしないと Unbound は 127.0.0.1 の NSD に問い合わせず、SERVFAIL になります。2つ目は既定の local-zone です。home.arpa. やプライベートアドレスの逆引きゾーン(168.192.in-addr.arpa. など)は、Unbound が最初から自分で答える設定になっていることがあり、nodefault を書かないと stub-zone に届きません。どのゾーンが既定に含まれるかは版によって違うため、先ほどの list_local_zones の出力で確かめます。3つ目は DNSSEC で、署名されていない社内ゾーンが署名済みの親の下にある場合(自社の公開ドメインのサブドメインなど)は、domain-insecure を書かないと検証に失敗します。

sudo unbound-checkconf
sudo unbound-control reload

# クライアントと同じ経路(Unbound 経由)で引けるか
dig @192.168.10.1 www.office.home.arpa A
dig @192.168.10.1 www.example.com A

reload ではキャッシュも消えるため、切り替え直後は外部の名前解決が少し遅くなります。利用の少ない時間帯に作業すると影響を抑えられます。

切り替え前後で答えを比べる

local-data を削除する前に、移す名前の一覧を作り、Unbound の現在の答えを記録しておきます。切り替え後に同じ問い合わせをして差分を見れば、移し漏れがすぐに分かります。

# 切り替え前:名前と種類の一覧から現在の答えを保存
while read -r name type; do
  echo "$name $type $(dig @192.168.10.1 "$name" "$type" +short | sort | tr '\n' ' ')"
done < names.txt > before.txt

# 切り替え後に同じものを after.txt に保存して比べる
diff before.txt after.txt

names.txt は www.office.home.arpa A のように「名前 種類」を1行ずつ並べたファイルです。存在しない名前(nothing.office.home.arpa)で NXDOMAIN が返ることも確認します。

切り戻しと移行後の運用

問題が出たときは、保存しておいた unbound.conf を戻して unbound-control reload すれば、NSD を止めなくても元の答えに戻ります。NSD 側を直してから、もう一度切り替えれば済みます。

移行が落ち着いたら、ゾーンファイルの変更手順を「編集 → シリアルを上げる → nsd-checkzone → nsd-control reload ゾーン名」に揃えます。Unbound はゾーンの内容をキャッシュするため、TTL を長くしていると変更の反映が遅れます。急ぐときは unbound-control flush_zone office.home.arpa でそのゾーンのキャッシュだけを消せます。

設定項目の名前や既定値は Unbound・NSD の版によって変わることがあります(2026年10月現在)。本番で作業する前に、検証用のサーバーで同じ版を使って一通り試しておくと安心です。

まとめ

  • NSD は権威DNS専用のため、Unbound はクライアント向けの再帰DNSとして残し、ゾーンのデータだけを NSD に移します。
  • local-zone の種類を確かめ、static は移す、transparent やブロック用は Unbound に残す、と仕分けます。
  • local-data は list_local_data で取り出し、SOA と NS を書き足してゾーンファイルにします。
  • Unbound 側は stub-zone で NSD を指定し、do-not-query-localhost: no・nodefault・domain-insecure の3点を忘れずに設定します。
  • 切り替え前の答えを保存して比べ、unbound.conf のコピーで切り戻せるようにしておきます。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲