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 の検証とプライベートアドレスの逆引きの扱いに注意します。