2026年6月7日
2026年6月7日
TinyDNS のセカンダリ構成方法|data.cdb の複製・axfrdns からの転送・axfr-get での受信の3通り
TinyDNS(djbdns の tinydns)には、BIND や NSD のような「プライマリから自動でゾーンを受け取るセカンダリ」の機能がありません。そのため、セカンダリを用意するには、data.cdb をそのまま複製する方法、axfrdns から他の DNS サーバーへゾーン転送する方法、axfr-get で他のプライマリからゾーンを取り込む方法の3つから、構成に合うものを選びます。この記事では、それぞれの設定手順と、つまずきやすい点、同期できているかの確かめ方を説明します。
TinyDNS のセカンダリが一般的なサーバーと違う点
一般的な権威DNSでは、プライマリが変更を NOTIFY で知らせ、セカンダリがゾーン転送(AXFR や IXFR)で取りに来ます。TinyDNS の構成要素はこれとは分担が異なります。
- tinydns:data.cdb を読んで UDP で答えるだけです。ゾーン転送の送受信も NOTIFY も行いません。
- axfrdns:tinydns と同じアドレスの TCP で待ち受け、data.cdb の内容をゾーン転送で送ります。TCP での通常の問い合わせにも答えます。
- axfr-get:他のサーバーからゾーン転送を受け、tinydns の data 形式で保存するプログラムです。
どれも TSIG(鍵によるゾーン転送の保護)には対応していません。djbdns は 1.05 以降、公式な更新がないため(2026年10月現在)、この点は今後も変わらない前提で設計します。転送は IP アドレスでの許可とファイアウォールで守ります。
3つの構成から選ぶ
| 構成 | セカンダリのソフト | 更新のきっかけ | 向いている場面 |
|---|---|---|---|
| A:data.cdb を複製 | tinydns | プライマリでの make の後にコピー | 全台を tinydns でそろえる |
| B:axfrdns から転送 | BIND・NSD・Knot など | セカンダリの SOA リフレッシュ | 他社や別チームのセカンダリを使う |
| C:axfr-get で受信 | tinydns | cron などで定期的に取得 | プライマリが BIND などで、TinyDNS を追加したい |
djbdns の作者が想定していたのは A です。B と C は、他のソフトと組み合わせる場合の方法です。
構成A:data.cdb を rsync で複製する
tinydns は data.cdb を問い合わせのたびに読むため、ファイルを置き換えれば再起動なしで新しい内容になります。プライマリで make した後に、data.cdb をセカンダリへコピーするだけで同期できます。SOA のシリアルも data.cdb に含まれるので、全台で同じ値になります。
プライマリの /etc/tinydns/root/Makefile に、コピー用のターゲットを加えます。行頭はタブです。
data.cdb: data
/usr/local/bin/tinydns-data
remote: data.cdb
rsync -az -e ssh data.cdb tinysync@198.51.100.53:/etc/tinydns/root/data.cdb
rsync -az -e ssh data.cdb tinysync@203.0.113.53:/etc/tinydns/root/data.cdb
data を編集したら make remote を実行します。data.cdb が古ければ先に作り直され、その後でセカンダリにコピーされます。
ここでのつまずきやすい点は次の3つです。
- 置き換えの途中を読ませない:rsync は既定では一時ファイルに書いてから名前を変えるため、tinydns が書きかけのファイルを読むことはありません。
--inplaceを付けるとこの性質が失われるので使いません。scp で直接上書きするのも同じ理由で避けます。 - SSH の権限を絞る:コピー専用のユーザーを作り、鍵には書き込み先を限定する設定を付けます。rsync に付属する rrsync のような仕組みで、特定のディレクトリにしか書けないようにしておくと、鍵が漏れたときの影響を小さくできます。
- TCP の応答:セカンダリにも axfrdns を置かないと、512 バイトを超える答えを TCP で取り直す問い合わせに答えられません。
構成B:axfrdns から BIND などに転送する
セカンダリに BIND や NSD、Knot DNS を使う場合は、プライマリの axfrdns からゾーン転送します。まず /etc/axfrdns/tcp で、セカンダリのアドレスに転送を許可します。
198.51.100.53:allow,AXFR="example.com/example.net"
:allow,AXFR=""
1行目はセカンダリに2つのゾーンの転送を許可し、2行目はそれ以外の相手に TCP の問い合わせだけを許可します。書き換えたら /etc/axfrdns で make を実行して tcp.cdb を作り直します。
セカンダリ側は通常のセカンダリの設定です。BIND の例を示します(古い BIND では type slave; と masters という書き方になります)。
zone "example.com" {
type secondary;
primaries { 192.0.2.53; };
file "/var/cache/bind/example.com.db";
};
この構成でもっとも気を付けたいのは、更新が伝わるまでの時間です。axfrdns は NOTIFY を送らないため、セカンダリは SOA のリフレッシュ間隔ごとにシリアルを確かめに来て、変わっていれば転送します。. の行でゾーンを定義している場合、リフレッシュの既定値は 16384 秒(約4.5時間)とされており、変更がセカンダリに届くまでそれだけかかることがあります。
反映を早めたい場合は、Z の行で SOA を明示してリフレッシュを短くします。
Zexample.com:ns1.example.com:hostmaster.example.com::1800:600:1209600:300:3600
&example.com::ns1.example.com:259200
&example.com::ns2.example.net:259200
Z の行は「ゾーン名:プライマリ名:管理者アドレス:シリアル:リフレッシュ:リトライ:有効期限:最小TTL:TTL」の順です。シリアルを空にすると、data の更新時刻が使われます。. の行は SOA も作るため、Z の行と同じゾーンに書くと SOA が2つになります。Z を使うゾーンでは、上のように NS を & の行で書きます。3番目の項目にドットを含む名前を書くと、その名前がそのまま NS として使われます。急ぎの変更では、セカンダリ側で rndc refresh example.com(BIND の場合)を実行すると、すぐに確かめに行かせられます。
構成C:axfr-get で他のプライマリから取り込む
プライマリが BIND などで、そこに TinyDNS のセカンダリを加えたい場合は、axfr-get を定期的に実行します。プライマリ側では、TinyDNS のサーバーのアドレスにゾーン転送を許可しておきます(BIND なら allow-transfer { 198.51.100.53; };)。
#!/bin/sh
# /usr/local/sbin/tinydns-pull.sh:プライマリからゾーンを取り込み、data.cdb を作り直す
set -e
PRIMARY=192.0.2.1
cd /etc/tinydns/root
for z in example.com example.net; do
tcpclient "$PRIMARY" 53 axfr-get "$z" zones/"$z".data zones/"$z".tmp
done
cat zones/*.data > data.tmp
mv data.tmp data
make
# /etc/cron.d/tinydns-pull
*/15 * * * * root /usr/local/sbin/tinydns-pull.sh 2>&1 | logger -t tinydns-pull
axfr-get は、保存済みのファイルとプライマリのシリアルが同じなら転送しない仕組みになっているため、短い間隔で動かしても負荷はあまり増えません。取り込んだ Z の行にはプライマリのシリアルが入るので、セカンダリでも同じシリアルで答えます。
注意点は、SOA の有効期限(expire)が効かないことです。一般的なセカンダリは、プライマリと連絡が取れない状態が有効期限を超えるとゾーンの応答をやめますが、この構成の tinydns は最後に取り込んだ内容をいつまでも返し続けます。set -e で途中のエラーでは data.cdb を作り直さないようにしているため、取り込みの失敗はログでしか分かりません。次の節の監視で、シリアルの遅れに気付けるようにしておきます。
同期を確かめる
どの構成でも、全台の SOA シリアルを並べて比べるのが基本の確認です。
for s in 192.0.2.53 198.51.100.53 203.0.113.53; do
printf '%s ' "$s"; dig @"$s" example.com SOA +short +norec | awk '{print $3}'
done
すべて同じ値なら同期しています。値が古いサーバーがあれば、構成Aではコピーの失敗、構成Bでは axfrdns の tcp の許可かファイアウォール(TCP 53番)、構成Cでは cron のログ、の順に確認すると原因に早くたどり着けます。この比較を定期的に実行し、一定時間以上ずれたら通知する仕組みにしておくと、気付かないまま古い答えを返し続ける状態を防げます。
作業の前には data と data.cdb のコピーを取り、まず検証用のサーバーで同期を試してから本番に入れてください。
まとめ
- tinydns にはセカンダリとしてゾーンを受け取る機能がないため、data.cdb の複製、axfrdns からの転送、axfr-get での受信の3つから選びます。
- 全台が tinydns なら、
make remoteで data.cdb を rsync する構成が単純で、シリアルも一致します。--inplaceは使いません。 - 他のソフトをセカンダリにする場合は axfrdns で転送を許可します。NOTIFY がないため、リフレッシュ間隔を
Zの行で調整します。 - axfr-get で取り込む構成では有効期限が効かないため、シリアルの監視で取り込みの失敗に気付けるようにします。
- どの構成でも、全台の SOA シリアルを定期的に比べて同期を確かめます。