2026年6月8日

2026年6月8日

TinyDNS から dnsmasq へ移行する手順|data を hosts 形式に自動変換し、DHCP と名前解決を1台にまとめる

djbdns(TinyDNS と dnscache)と ISC DHCP を組み合わせた古い社内サーバーは、dnsmasq 1つに置き換えると構成をかなり単純にできます。この記事では、TinyDNS の data ファイルを hosts 形式に自動変換して dnsmasq に読ませる方法と、ISC DHCP の固定割り当てを dnsmasq に移す方法、二重の DHCP サーバーを作らない切り替えの順番を説明します。data を更新すれば dnsmasq に自動で反映される仕組みにしておくと、移行期間中も今までの運用の手順を大きく変えずに済みます。

この記事が想定する構成

次のような社内サーバーを想定しています。

  • dnscache が端末からの問い合わせを受け、社内ドメイン(例では example.lan)だけを TinyDNS に回している
  • TinyDNS の data ファイルに、社内のサーバーやプリンターの名前が書かれている
  • 同じサーバー、または別のサーバーで ISC DHCP(isc-dhcp-server)が IP アドレスを配っている

ISC DHCP は、開発元の ISC が 2022 年で保守を終了したと発表しており、後継として Kea を案内しています。小規模な LAN なら、DHCP と DNS の転送・キャッシュ、社内名の応答を dnsmasq にまとめるのも現実的な選択肢です。

一方で、TinyDNS がインターネットに公開するゾーンの権威 DNS として登録されている場合は、dnsmasq への置き換えは向きません。その場合は NSD や Knot DNS などの権威 DNS 向けのソフトを検討してください。

hosts ファイル方式を選ぶ理由

dnsmasq に社内名を持たせる方法は、大きく分けて2つあります。設定ファイルに host-record= を1行ずつ書く方法と、hosts 形式のファイルを読ませる方法です。

設定ファイルに書いた内容は、dnsmasq を再起動しないと反映されません。一方、hosts ファイルは SIGHUP で読み直せるうえ、hostsdir= で指定したディレクトリに置いたファイルは、変更が自動で読み込まれます(Linux の inotify を使う機能です)。つまり、data ファイルから hosts ファイルを生成するスクリプトさえ用意すれば、「data を書き換えて make する」という TinyDNS の運用を、再起動なしでそのまま続けられます。

hosts 形式では A(IPv6 なら AAAA)と逆引きしか表せないため、CNAME・MX・TXT は設定ファイル側に書きます。これらは変更頻度が低いことが多いので、再起動が要っても困りにくいはずです。

手順1:data から hosts ファイルを生成する

まず data ファイルをバックアップし、行の種類ごとの件数を確かめます。

cp -p /etc/tinydns/root/data /root/tinydns-data.$(date +%Y%m%d)
cut -c1 /etc/tinydns/root/data | sort | uniq -c

続いて、A レコードを作る行から hosts 形式のファイルを作ります。TinyDNS では = と + の行のほか、NS を表す . や &、MX を表す @ の行でも、IP が書かれていればその名前の A レコードが作られます。

#!/bin/sh
# /etc/tinydns/root/gen-hosts.sh : data から dnsmasq 用の hosts ファイルを作る
DATA=/etc/tinydns/root/data
OUT=/etc/dnsmasq.hosts.d/tinydns.hosts
TMP=$(mktemp)

awk -F: '
  /^[=+]/                           { if ($2 != "") print $2 "\t" substr($1, 2) }
  /^[.&@]/ && $2 != "" && $3 ~ /\./ { print $2 "\t" $3 }
' "$DATA" | grep -v '\*' | sort -u > "$TMP"

# 書き換え途中のファイルを読まれないよう、最後に置き換える
chmod 644 "$TMP"
mv "$TMP" "$OUT"

いくつか注意点があります。

  • NS 名や MX 名にドットを含まない短い名前を書いた行は、TinyDNS が独自の規則で名前を補います(例:ns1 が ns1.ns.example.lan になる)。上のスクリプトはこうした行を拾わないので、tinydns-get で実際の名前を確かめて手で追加します
  • * を含むワイルドカードは hosts 形式で表せないため除外しています。必要なら設定ファイルの address= で表しますが、範囲が TinyDNS と異なる点に注意します
  • + の行は本来逆引きを作りませんが、hosts 形式では逆引きも返るようになります。同じ IP に複数の名前があるときは、逆引きでどの名前が返るかを手順4で確認します
  • % の地域別の応答や、: で始まる任意の種類のレコードは、個別に扱いを決めます

生成先のディレクトリを作り、一度実行して中身を確かめます。

sudo mkdir -p /etc/dnsmasq.hosts.d
sudo sh /etc/tinydns/root/gen-hosts.sh
cat /etc/dnsmasq.hosts.d/tinydns.hosts

TinyDNS の data ディレクトリには、data.cdb を作るための Makefile があります。そこに gen-hosts.sh の実行を追加しておけば、移行期間中は make 1回で両方が更新されます。

手順2:dnsmasq の DNS 側の設定

DNS の設定と DHCP の設定は、別のファイルに分けておきます。並行稼働のテストでは DNS 側のファイルだけを読ませ、DHCP を動かさないためです。

# /etc/dnsmasq.d/10-dns.conf
no-resolv
server=192.0.2.1          # 上流のリゾルバー(実際の値に置き換える)
domain-needed
bogus-priv
listen-address=127.0.0.1,192.168.1.53
bind-interfaces

domain=example.lan
local=/example.lan/
hostsdir=/etc/dnsmasq.hosts.d
local-ttl=300

# hosts 形式で表せないレコード
cname=wiki.example.lan,www.example.lan
mx-host=example.lan,mail.example.lan,10
txt-record=example.lan,"v=spf1 mx -all"

local=/example.lan/ は、定義していない社内名の問い合わせを上流へ漏らさず、その場で「存在しない」と答えるための行です。local-ttl を指定しないと、dnsmasq は自分で答える名前の TTL を 0 にするため、端末からの問い合わせが増えます。設定項目は版によって追加・変更されることがあるため、手元の man dnsmasq で確認してください(2026年10月現在)。

手順3:ISC DHCP の設定を dnsmasq に移す

dhcpd.conf の主な設定は、dnsmasq の次の行に対応します。

  • subnet と range、リース時間 → dhcp-range=開始,終了,ネットマスク,リース時間
  • option routers → dhcp-option=option:router,IP
  • option domain-name-servers → 省略すると dnsmasq は自分自身を DNS サーバーとして配ります
  • host ブロックの hardware ethernet と fixed-address → dhcp-host=MAC,IP,名前
  • authoritative; → dhcp-authoritative
# /etc/dnsmasq.d/20-dhcp.conf
dhcp-range=192.168.1.100,192.168.1.199,255.255.255.0,12h
dhcp-option=option:router,192.168.1.1
dhcp-authoritative

# ISC DHCP の host ブロックから移した固定割り当て
dhcp-host=00:11:22:33:44:55,192.168.1.40,printer1
dhcp-host=00:11:22:33:44:66,192.168.1.41,printer2

固定割り当ての名前は、hosts ファイルの名前と重複させないようにします。dnsmasq は DHCP の端末が名乗ったホスト名を自動で DNS に登録しますが、hosts ファイルに同じ名前があると登録を見送る(ログに記録される)動作をするため、どちらの情報が答えられているのか分かりにくくなります。

切り替えの数日前に、ISC DHCP 側のリース時間を短くしておくと、切り替え後に端末が新しいサーバーへ早く移ります。

手順4:DNS だけを別ポートで動かして比べる

本番の TinyDNS と dnscache を動かしたまま、dnsmasq を DNS の設定だけで別ポートに起動します。DHCP の設定を読ませないことが重要です。同じセグメントで DHCP サーバーが2台動くと、端末が誤ったアドレスを受け取るおそれがあります。

dnsmasq --test --conf-file=/etc/dnsmasq.d/10-dns.conf

# 本番の 53 番と重ならない 5300 番で、前面で起動する(Ctrl+C で終了)
sudo dnsmasq --no-daemon --log-queries --port=5300 \
  --conf-file=/etc/dnsmasq.d/10-dns.conf

ポートが異なるため、dnscache が使っている 192.168.1.53 の 53 番とはぶつかりません。ディストリビューションのパッケージによっては、dnsmasq が導入直後にサービスとして自動起動していることがあるので、systemctl status dnsmasq で確かめ、動いていれば止めておきます。起動したら、生成した hosts ファイルの名前を順に問い合わせ、dnscache(TinyDNS)の答えと比べます。

while read -r ip name; do
  old=$(dig @192.168.1.53 "$name" A +short | sort | tr '\n' ' ')
  new=$(dig @127.0.0.1 -p 5300 "$name" A +short | sort | tr '\n' ' ')
  [ "$old" = "$new" ] && s=OK || s=DIFF
  printf '%-4s %-30s old=[%s] new=[%s]\n' "$s" "$name" "$old" "$new"
done < /etc/dnsmasq.hosts.d/tinydns.hosts

逆引き(dig -x)、CNAME・MX、社外の名前もあわせて確認します。

手順5:切り替えの順番

切り替えは、DHCP サーバーが2台同時に動く時間を作らない順番で行います。

# 1. ISC DHCP を止める(パッケージによってサービス名が異なる)
sudo systemctl stop isc-dhcp-server
sudo systemctl disable isc-dhcp-server

# 2. dnscache と TinyDNS を止める(daemontools の例)
sudo svc -d /service/dnscache
sudo svc -d /service/tinydns

# 3. dnsmasq を起動する
sudo systemctl enable --now dnsmasq
journalctl -u dnsmasq -n 50

起動後は、端末を1台再接続して IP アドレスと DNS サーバーを受け取れるか、dnsmasq のリースファイル(Debian 系では /var/lib/misc/dnsmasq.leases)に記録されるかを確かめます。既存の端末は、リースの更新のタイミングで順に dnsmasq に移ります。

運用:data の更新と切り戻し

移行直後は、data ファイルを正本のまま残し、更新は make で hosts ファイルを再生成する運用にしておくと、慣れた手順のまま様子を見られます。落ち着いたら、hosts ファイルを直接編集する運用に移り、data と Makefile は参照用として残します。

問題が起きたときは、dnsmasq を止め、ISC DHCP と dnscache・TinyDNS を逆の順番で起動し直します。ISC DHCP のリースファイルや data ファイルを消していなければ、元の状態に戻せます。

まとめ

  • DHCP と社内名の応答を dnsmasq 1台にまとめる構成は、社内向けの小規模な LAN に向いています。公開ゾーンの権威 DNS には別のソフトを使います。
  • data ファイルから hosts 形式のファイルを生成し、hostsdir= で読ませると、再起動なしで更新を反映できます。
  • CNAME・MX・TXT は設定ファイルに書き、短い NS 名や MX 名、ワイルドカードは個別に確認します。
  • ISC DHCP の固定割り当ては dhcp-host= に移し、テスト中は DHCP を動かさず、切り替え時も DHCP サーバーが2台動かない順番で作業します。

お気軽にご相談ください

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