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 からの転送のどちらかに決め直します。

お気軽にご相談ください

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