2026年6月7日
2026年6月7日
NSD から djbdns へ移行する手順|axfr-get でゾーンを data 形式に変換し、シリアルを引き継ぐ
NSD から djbdns(tinydns)への移行は、NSD からのゾーン転送を djbdns 付属の axfr-get で受けて tinydns の data 形式に変換し、SOA のシリアルを引き継いだうえで応答を比べてから切り替える、という順に進めると、手作業の書き換えによる誤りを避けられます。ただし djbdns は DNSSEC などに対応していないため、まず「移ってよい構成か」を確かめる必要があります。この記事では、その確認から変換、シリアルの扱い、比較、セカンダリの扱い、切り替えまでを説明します。
移行の前に:djbdns に移ると使えなくなるもの
djbdns は 1.05 以降、作者による公式な更新がありません(2026年10月現在)。NSD から移ると、次の機能が使えなくなるか、別の仕組みで補う必要があります。
- DNSSEC:tinydns は署名済みのゾーンを扱えません。
- EDNS0:UDP の応答は 512 バイトまでで、それを超える答えは TCP で取り直してもらう形になります。TCP の応答には axfrdns が必要です。
- NOTIFY と TSIG:変更をセカンダリに知らせる NOTIFY を送らず、ゾーン転送を鍵で守ることもできません。
- IPv6:配布版の tinydns は IPv6 アドレスで待ち受けません。AAAA レコード自体は汎用形式の行で返せます。
既存の djbdns の環境にまとめたい、などの理由がある場合でも、これらを受け入れられるかを先に関係者と確認してください。受け入れにくい場合は、移行そのものを見直すほうが安全です。
DNSSEC を使っているゾーンは、移行の前に署名をやめる作業が先に必要です。レジストラで DS レコードを削除し、DS の TTL が十分に過ぎてから NSD 側の署名を外します。DS が残ったまま署名のない tinydns に切り替えると、検証するリゾルバでは名前解決が失敗します。
手順1:NSD で変換用のゾーン転送を許可する
axfr-get はゾーン転送(AXFR)でゾーンを受け取るプログラムです。NSD 側で、変換作業をするホストからの転送を許可します。ここでは NSD と同じサーバーで作業し、ループバックアドレスからだけ許可する例です。
# /etc/nsd/nsd.conf の該当ゾーン(または pattern)に追加
zone:
name: example.com
zonefile: /etc/nsd/zones/example.com.zone
provide-xfr: 127.0.0.1 NOKEY
NOKEY は TSIG を使わない指定で、axfr-get は TSIG に対応していないためこの形になります。ip-address: で待ち受けるアドレスを限定している場合は、127.0.0.1 も加えてください。設定を確かめてから反映します。
sudo nsd-checkconf /etc/nsd/nsd.conf
sudo systemctl restart nsd
本番の NSD の設定に触れたくない場合は、検証用のサーバーで同じゾーンファイルを読み込んだ NSD を動かし、そこから取り出しても同じ結果が得られます。
手順2:axfr-get で data 形式に変換する
axfr-get は ucspi-tcp の tcpclient と組み合わせて使います。ゾーンごとに1ファイルずつ出力しておくと、後の確認がしやすくなります。
mkdir -p ~/djbdns-migrate/zones && cd ~/djbdns-migrate
for z in example.com example.net; do
tcpclient 127.0.0.1 53 axfr-get "$z" zones/"$z".data zones/"$z".tmp
done
出力は tinydns-data がそのまま読める形式です。SOA は Z の行、NS は & の行、A は + の行、MX は @ の行のように、tinydns の記号に置き換わります。tinydns の記号に対応しない種類(AAAA、SRV、CAA など)は : で始まる汎用形式の行になり、データ部分は \052 のような8進数の表記になります。汎用形式の行は人が読んで直すのが難しいため、変換後は書き換えずに使い、後の比較で答えを確かめるほうが誤りが入りにくくなります。
NSD のゾーンファイルにあった $ORIGIN や $INCLUDE、相対名は、転送の時点で NSD が展開しているので、変換の側で気にする必要はありません。一方、; のコメントは転送されないため、残したい説明があれば元のファイルから手で写します。
手順3:SOA のシリアルを引き継ぐ
この移行でもっとも注意が要るのがシリアルです。tinydns では、. の行でゾーンを定義すると data ファイルの更新時刻(UNIX 時刻)がシリアルになります。NSD で 2026101801 のような日付形式を使っていた場合、UNIX 時刻(2026年時点でおよそ 17億台)のほうが小さいため、切り替えた途端にシリアルが下がります。既存のセカンダリはシリアルが下がった変更を取り込まず、古い内容のまま答え続けます。
これを避けるには、axfr-get が出力した Z の行をそのまま使い、シリアルを自分で管理します。
Zの行の4番目の項目がシリアルです。変更のたびに、この値を上げてから make します。- 同じゾーンに
.の行を追加しないでください。SOA が2つ作られてしまいます。 Zの行には、リフレッシュ、リトライ、有効期限、最小 TTL も入っています。NSD 時代の値がそのまま引き継がれるので、セカンダリの構成に合わせて見直します。
NSD で UNIX 時刻のシリアルを使っていたなら、. の行に切り替えても値は下がりません。その場合も、切り替え直後のシリアルが NSD 最後の値より大きいことを dig で確かめます。
手順4:tinydns と axfrdns を用意して読み込む
新しいサーバーに tinydns をまだ入れていなければ、daemontools と djbdns を入れたうえでサービスを作ります。アドレスは例です。
sudo tinydns-conf tinydns dnslog /etc/tinydns 198.51.100.53
sudo axfrdns-conf axfrdns dnslog /etc/axfrdns /etc/tinydns 198.51.100.53
sudo ln -s /etc/tinydns /etc/service/tinydns
sudo ln -s /etc/axfrdns /etc/service/axfrdns
変換したファイルを結合して data にし、data.cdb を作ります。
cat ~/djbdns-migrate/zones/*.data | sudo tee /etc/tinydns/root/data > /dev/null
cd /etc/tinydns/root && sudo make
axfrdns は省略しないでください。DKIM や長い SPF の TXT のように 512 バイトを超える答えは、tinydns が切り詰めた印(TC フラグ)を付けて返し、問い合わせ元は TCP で取り直します。axfrdns がないと、その取り直しに答えられません。/etc/axfrdns/tcp には、まず :allow,AXFR=""(TCP の問い合わせは受けるが、ゾーン転送は許可しない)と書き、make で反映しておきます。
手順5:応答を突き合わせる
NSD から取り出したゾーンの一覧を使って、両方のサーバーに同じ問い合わせをして比べます。
#!/bin/sh
# 使い方: ./compare.sh example.com
ZONE="$1"
OLD=127.0.0.1 # NSD
NEW=198.51.100.53 # tinydns
dig @"$OLD" "$ZONE" AXFR +onesoa +nocmd +nostats \
| awk '!/^;/ && NF >= 5 { print $1, $4 }' | sort -u \
| while read -r name type; do
a=$(dig @"$OLD" "$name" "$type" +short +norec | sort)
b=$(dig @"$NEW" "$name" "$type" +short +norec | sort)
[ "$a" = "$b" ] || echo "DIFF: $name $type"
done
dig は TC フラグの付いた答えを受け取ると TCP で取り直すため、長い TXT も比較できます。DIFF が出ないこと、SOA のシリアルが同じであることを確かめたら、存在しない名前で NXDOMAIN が返るか、flags に aa が付くかも見ます。差が出た場合は、変換後のファイルの該当行と、元のゾーンファイルを並べて確認します。
手順6:セカンダリへの配信を決める
NSD のセカンダリが NOTIFY を受けて更新していた構成では、配信の方法を決め直します。
- tinydns 同士で配る:セカンダリも tinydns にし、rsync などで data.cdb をコピーします。シリアルを含めて同じ内容になります。
- axfrdns から転送する:セカンダリに NSD などを残す場合は、
tcpにそのアドレスとAXFR="example.com/example.net"のようなゾーンの一覧を書きます。NOTIFY が届かないので、セカンダリはZの行のリフレッシュ間隔で更新を確かめに来ます。反映を早めたい場合は、リフレッシュを短めにします。
手順7:切り替えと切り戻し
切り替えは、NSD が使っていた IP アドレスを tinydns に移すか、レジストラで NS を新しいサーバーに向けるかのどちらかです。前者は NS を変えずに済みますが短い中断があり、後者は中断がない代わりに反映に時間がかかります。
切り戻しに備えて、NSD のゾーンファイルと設定は消さずに残しておきます。NS を変える方法なら、旧サーバーは NS の TTL が切れるまで動かし続けます。tinydns 側でレコードを変えた場合は、NSD 側にも同じ変更を入れておかないと、戻したときに内容が古くなる点に注意してください。
まとめ
- djbdns に移ると DNSSEC・EDNS0・NOTIFY・TSIG が使えなくなるため、移ってよい構成かを最初に確かめます。DNSSEC のゾーンは先に DS を外します。
- NSD で
provide-xfr: 127.0.0.1 NOKEYを許可し、axfr-get で data 形式に変換すると、手作業の書き換えが要りません。 - 日付形式のシリアルは
Zの行のまま引き継ぎ、.の行に変えてシリアルが下がる事態を避けます。 - 512 バイトを超える答えのために axfrdns も動かし、比較では長い TXT も確かめます。
- セカンダリへの配信は data.cdb のコピーか axfrdns からの転送のどちらかに決め直します。