2026年6月13日

2026年6月13日

djbdns から NSD へ移行する手順|NSD を axfrdns のセカンダリにして同期し、dnscache は Unbound に分けて移す

djbdns から NSD への移行では、djbdns が「権威DNSの tinydns・TCP とゾーン転送の axfrdns・キャッシュDNSの dnscache」という複数のプログラムの組み合わせである点が、最初の分かれ目になります。NSD は権威DNS専用なので、tinydns と axfrdns の役割は NSD に、dnscache の役割は同じ NLnet Labs が開発する Unbound に分けて移します。権威DNSの移行は、NSD を axfrdns のセカンダリとして動かしてゾーンを同期させておき、答えを確認してから NSD をプライマリに切り替える方法をとると、移行中に data ファイルを更新しても NSD 側に追従させられます。この記事では、その段取りと、dnscache の設定を Unbound に読み替える方法を説明します。

djbdns 本体は 1.05 以降、作者による公式な更新がなく、DNSSEC に対応していません(2026年10月現在)。NSD と Unbound はどちらも開発が続いており、ディストリビューションのパッケージで入れられます。設定項目は版によって追加や変更があるため、手元の man nsd.conf と man unbound.conf と照らし合わせてください。

手順1:djbdns の構成を棚卸しする

まず、どのプログラムがどのアドレスで動いているかを確認します。サービスディレクトリの場所(/service や /etc/service など)は環境に合わせて読み替えてください。

ls -l /service/
# それぞれが待ち受けるアドレス
cat /service/tinydns/env/IP /service/axfrdns/env/IP /service/dnscache/env/IP
  • tinydns と axfrdns → NSD に移します。NSD は UDP・TCP・ゾーン転送を1つで扱います。
  • dnscache → Unbound に移します。社内向けのキャッシュDNSとして使っている場合です。
  • walldns や rbldns を使っている場合は、NSD でも Unbound でも同じ動きにはならないため、個別に代わりを検討します。

あわせて、tinydns の data ファイルで、NSD に持っていけない書き方を使っていないかを確認します。問い合わせ元によって答えを変えるロケーション(% の行)と、決まった時刻に有効・無効が切り替わるタイムスタンプ付きのレコードは、NSD のゾーンでは表せません。

grep -n '^%' /service/tinydns/root/data

% の行がなければ、ロケーションは使われていません。data ファイルとサービスディレクトリは、作業前にまるごとコピーを取っておきます。

手順2:axfrdns で NSD への転送を許可する

NSD を動かすサーバー(ここでは 192.0.2.54)から、axfrdns へのゾーン転送を許可します。axfrdns の tcp ファイルに行を追加し、make で反映します。

# /service/axfrdns/tcp
192.0.2.54:allow,AXFR="example.com/example.net/2.0.192.in-addr.arpa"
:allow,AXFR=""
cd /service/axfrdns && sudo make

AXFR には転送を許すゾーンをスラッシュ区切りで書きます。最後の行は、ほかの相手からの TCP の問い合わせは受け付け、転送は許可しないという意味です。axfrdns が動いていない環境では、先に axfrdns-conf でサービスを作ります。

手順3:NSD をセカンダリとして動かす

NSD は、djbdns とは別のアドレスで、axfrdns からゾーンを受け取るセカンダリとして動かします。ゾーンごとの共通の設定は pattern にまとめます。

# /etc/nsd/nsd.conf
server:
    ip-address: 192.0.2.54
    hide-version: yes

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

pattern:
    name: "from-djbdns"
    zonefile: "/var/lib/nsd/%s.zone"
    request-xfr: AXFR 192.0.2.53 NOKEY

zone:
    name: "example.com"
    include-pattern: "from-djbdns"

zone:
    name: "example.net"
    include-pattern: "from-djbdns"

zone:
    name: "2.0.192.in-addr.arpa"
    include-pattern: "from-djbdns"
sudo mkdir -p /var/lib/nsd
sudo chown nsd:nsd /var/lib/nsd      # NSD を動かすユーザー名は環境に合わせる
sudo nsd-checkconf /etc/nsd/nsd.conf
sudo nsd-control-setup
sudo systemctl restart nsd
sudo nsd-control zonestatus example.com

request-xfr の先頭の AXFR は、差分転送(IXFR)を試さずに最初から全体の転送を求める指定です。axfrdns は差分転送を前提にした作りではないため、最初から全体の転送を指定しておくと、やり取りが単純になり、うまくいかないときの切り分けもしやすくなります。zonefile の %s はゾーン名に置き換わります。

nsd-control zonestatus でゾーンの状態が ok になり、シリアルが表示されれば、転送は成功しています。失敗している場合は、NSD のログ(journalctl -u nsd)と、axfrdns のログ(/service/axfrdns/log/main/current)の両方を見ます。axfrdns 側で接続が断られていれば tcp の書き方を、接続自体が届いていなければファイアウォールの TCP の53番ポートを確認します。

同期のタイミングを理解しておく

tinydns は変更の通知(NOTIFY)を送らないため、NSD は SOA の refresh の間隔ごとにシリアルを確かめ、上がっていれば取り直します。data ファイルの . や Z の行でシリアルを省略している場合、シリアルは data ファイルの更新時刻になり、make のたびに上がります。シリアルを固定値で書いている場合は、変更のたびに自分で上げないと NSD が気づきません。

移行中に data を更新したら、待たずに取り直させることもできます。

# tinydns 側で data を更新して make した後、NSD 側で
sudo nsd-control transfer example.com
sudo nsd-control zonestatus example.com

手順4:tinydns と NSD の答えを比べる

転送で受け取った内容は tinydns の data と同じはずですが、ワイルドカードの扱いや、ロケーションを使っていた場合の見え方は違うことがあります。両方に同じ問い合わせを送って比べます。

awk '!/^;/ && NF>=5 {print $1, $4}' /var/lib/nsd/*.zone | sort -u > names.txt

while read -r name type; do
  a=$(dig @192.0.2.53 "$name" "$type" +norec +short | sort)
  b=$(dig @192.0.2.54 "$name" "$type" +norec +short | sort)
  [ "$a" = "$b" ] || echo "DIFF: $name $type"
done < names.txt

/var/lib/nsd/*.zone がまだ書き出されていない場合は、sudo nsd-control write を実行するとゾーンファイルに書き出されます。存在しない名前で NXDOMAIN が返るか、ワイルドカードのある名前で同じ答えが返るかも確認します。

手順5:NSD をプライマリに切り替える

答えが一致したら、NSD をセカンダリからプライマリに変えます。この時点からは data ファイルではなく、NSD のゾーンファイルを編集する運用になるので、data の更新は止めます。

# 受け取った最新の内容をファイルに書き出し、編集用の場所にコピーする
sudo nsd-control write
sudo mkdir -p /etc/nsd/zones
sudo cp /var/lib/nsd/*.zone /etc/nsd/zones/

nsd.conf の pattern から request-xfr を外し、zonefile を編集用の場所に向けます。

pattern:
    name: "from-djbdns"
    zonefile: "/etc/nsd/zones/%s.zone"

各ゾーンファイルの SOA シリアルを、2026101801 のような日付の形式に書き換えます。tinydns が使っていた UNIX 時刻より大きな値になるので、ほかのセカンダリがあっても値の後退と誤解されません。書き換えたら検査して、NSD を再起動します。

sudo nsd-checkzone example.com /etc/nsd/zones/example.com.zone
sudo nsd-checkconf /etc/nsd/nsd.conf && sudo systemctl restart nsd
dig @192.0.2.54 example.com SOA +norec +short

続いて、問い合わせの向き先を NSD に移します。tinydns のアドレスを NSD に引き継ぐ場合は、tinydns と axfrdns を止め、OS の再起動で起動しないよう down ファイルを置いてから、ip-address を元のアドレスに変えて NSD を再起動します。

sudo svc -d /service/tinydns /service/axfrdns
sudo touch /service/tinydns/down /service/axfrdns/down

別のアドレスのまま使う場合は、レジストラで NS とグルーレコードを NSD のアドレスに変え、親ゾーンの NS の TTL が切れるまで tinydns も同じ内容で動かし続けます。どちらの場合も、切り替えの数日前に NS と主要なレコードの TTL を短くしておくと、問題があったときに戻しやすくなります。

手順6:dnscache を Unbound に移す

dnscache の設定は、ファイルの置き場所ごとに Unbound の設定項目に読み替えられます。

  • **env/IP(待ち受けるアドレス)** → interface:
  • **root/ip/ のファイル名(利用を許す相手)** → access-control:。root/ip/192.168.1 は 192.168.1.0/24 allow に当たります。
  • **root/servers/@(ルートサーバーの一覧)** → Unbound は既定でルートサーバーの情報を持っているため、通常は書かなくてかまいません。
  • **root/servers/社内ドメイン(社内の権威サーバーに直接聞く設定)** → stub-zone:。
  • **env/FORWARDONLY を設定している場合**(上位のリゾルバーに任せる設定) → forward-zone:。
# /etc/unbound/unbound.conf.d/migrate.conf(置き場所はディストリビューションに合わせる)
server:
    interface: 192.168.1.53
    access-control: 192.168.1.0/24 allow
    access-control: 127.0.0.0/8 allow

stub-zone:
    name: "corp.example.com"
    stub-addr: 192.0.2.54
sudo unbound-checkconf
sudo systemctl restart unbound
dig @192.168.1.53 www.example.org A
dig @192.168.1.53 intranet.corp.example.com A

dnscache と違い、多くのディストリビューションの Unbound は DNSSEC の検証が有効な状態で提供されています。社内専用のゾーンが、署名された公開ゾーンの下にある場合は、検証に失敗して名前が引けないことがあります。その場合は domain-insecure: でそのゾーンを検証の対象から外します。また、プライベートアドレスの逆引きゾーンは Unbound が既定で空の応答を返すため、社内の権威サーバーに逆引きを任せるには、local-zone: "168.192.in-addr.arpa." nodefault のような設定が別に要ります。

dnscache から Unbound への切り替えも、アドレスの引き継ぎ(dnscache を止めて down を置く)か、DHCP で配る DNS サーバーのアドレスの変更で行います。権威DNSとキャッシュDNSは別の日に切り替えると、問題が出たときに原因を切り分けやすくなります。

切り戻しと後片付け

問題が出たら、down ファイルを消して svc -u で tinydns・axfrdns・dnscache を起動し直し、NSD と Unbound を止めれば元に戻ります。data ファイル、data.cdb、サービスディレクトリは、切り戻しの必要がなくなるまで消さずに残します。落ち着いたら、axfrdns の tcp に追加した行を含めて djbdns の設定を片付け、NSD のゾーンファイルをバージョン管理に入れて「編集 → シリアルを上げる → nsd-checkzone → nsd-control reload ゾーン名」の手順で運用します。

まとめ

  • djbdns の役割は、tinydns と axfrdns を NSD に、dnscache を Unbound に分けて移します。walldns・rbldns・ロケーション・タイムスタンプは個別に代わりを考えます。
  • NSD を axfrdns のセカンダリ(request-xfr: AXFR)として動かすと、移行中の data の更新にも追従でき、nsd-control transfer ですぐに取り直せます。
  • 答えを比べてから、nsd-control write で書き出したゾーンを編集用の場所に移し、request-xfr を外してプライマリに切り替えます。シリアルは日付の形式に変えます。
  • dnscache の root/ip は access-control、root/servers は stub-zone や forward-zone に読み替え、DNSSEC の検証とプライベートアドレスの逆引きの扱いに注意します。

お気軽にご相談ください

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