2026年6月18日
2026年6月18日
dnsmasq から NSD へ移行する手順|ローカルレコードをゾーンファイルにし、転送は残して段階的に切り替える
dnsmasq で答えている社内向けの名前を NSD に移すときは、dnsmasq の設定行をゾーンファイルに書き換え、NSD を別ポートで動かして答えを比べ、最後に dnsmasq(または Unbound)から NSD へ問い合わせを回す、という順に進めると安全です。注意したいのは、NSD が権威 DNS 専用のソフトで、dnsmasq が兼ねていた転送・キャッシュや DHCP は引き継げないことです。この記事では、移行後の構成の決め方、レコードの対応、比較の方法、切り替えと切り戻しまでを説明します。
移行の前に:dnsmasq が担っている役割を分ける
dnsmasq は1つのプロセスで多くの役割を兼ねられるソフトです。移行の最初の作業は、手元の dnsmasq が実際に何をしているかを分けて書き出すことです。
- 転送とキャッシュ:端末からの問い合わせを上流のリゾルバーへ回し、結果をキャッシュする
- 社内の静的な名前の応答:
host-recordや/etc/hostsに書いた名前を答える - DHCP:IP アドレスを配り、端末のホスト名を DNS に自動で登録する
- そのほか:PXE 起動用の TFTP、ルーター広告など
NSD が引き受けられるのは、2つ目の「静的な名前の応答」だけです。NSD は再帰検索をしないため、端末が直接 NSD を DNS サーバーとして使うと、社外の名前が引けなくなります。また NSD は動的更新(RFC 2136)に対応していないため、DHCP で配った端末の名前を自動で登録する使い方もできません。
移行後の構成を決める
よく使われる構成は次の2つです。
- dnsmasq を残す構成:端末からの問い合わせと DHCP は dnsmasq がこれまでどおり受け、社内ゾーンの問い合わせだけを NSD に回します。変更点が少なく、段階的に移行できます
- Unbound に置き換える構成:転送とキャッシュを Unbound、社内ゾーンを NSD、DHCP を別のソフト(Kea など)に分けます。役割ごとに入れ替えられる反面、作業量は増えます
この記事では、まず前者で移行し、必要なら後から Unbound に置き換える流れで説明します。DHCP で登録される端末名は、dhcp.corp.example.com のように別のサブドメインに分けて dnsmasq に残すと、NSD のゾーンと名前がぶつかりません。
社内ゾーンの名前には、自社が持つドメインのサブドメイン(例では corp.example.com)を使うのが無難です。.local は mDNS で使われるため避け、家庭や小規模な LAN なら RFC 8375 で定められた home.arpa も選択肢になります。
手順1:dnsmasq の設定とレコードを洗い出す
作業前に、dnsmasq の設定ファイル一式をバックアップしてから、名前に関わる行を抜き出します。
sudo cp -a /etc/dnsmasq.conf /etc/dnsmasq.d /root/dnsmasq-backup/
grep -hE '^(address|host-record|cname|mx-host|srv-host|txt-record|ptr-record|addn-hosts|local|domain|server|rev-server|local-ttl)=' \
/etc/dnsmasq.conf /etc/dnsmasq.d/*.conf
no-hosts が設定されていなければ、dnsmasq は /etc/hosts の内容も答えています。addn-hosts で指定された追加の hosts ファイルも合わせて確認します。見落としやすいのはこの hosts ファイル経由の名前です。
手順2:ゾーンファイルを作る
dnsmasq の設定行は、おおむね次のようにゾーンファイルのレコードへ対応します。
host-record=名前,IP→ 正引きの A(IPv6 なら AAAA)と、逆引きゾーンの PTR の2つaddress=/名前/IP→ A。ただし dnsmasq ではその名前の配下すべてにも同じ IP を返すため、必要なら*.名前のワイルドカードも書きますcname=別名,別名先→ CNAMEmx-host=ドメイン,MX名,優先度→ MXsrv-host=_サービス._プロトコル.ドメイン,ターゲット,ポート,優先度,重み→ SRV。ゾーンファイルでは「優先度 重み ポート ターゲット」の順になるので、並び替えに注意しますtxt-record=名前,"文字列"→ TXT/etc/hostsの行 → A と PTR
dnsmasq の host-record や hosts ファイルは逆引きを自動で作りますが、NSD では逆引きゾーンを別に用意しないと PTR は返りません。
正引きゾーンの例です(/etc/nsd/zones/corp.example.com.zone)。
$ORIGIN corp.example.com.
$TTL 300
@ IN SOA ns1.corp.example.com. hostmaster.example.com. (
2026101801 ; serial(更新のたびに増やす)
3600 ; refresh
900 ; retry
1209600 ; expire
300 ) ; 否定応答のキャッシュ時間
IN NS ns1.corp.example.com.
IN MX 10 mail.corp.example.com.
IN TXT "v=spf1 mx -all"
ns1 IN A 192.168.1.53
www IN A 192.168.1.10
mail IN A 192.168.1.25
wiki IN CNAME www.corp.example.com.
_ldap._tcp IN SRV 0 100 389 dc1.corp.example.com.
dc1 IN A 192.168.1.30
逆引きゾーンの例です(/etc/nsd/zones/1.168.192.in-addr.arpa.zone)。
$ORIGIN 1.168.192.in-addr.arpa.
$TTL 300
@ IN SOA ns1.corp.example.com. hostmaster.example.com. (
2026101801 3600 900 1209600 300 )
IN NS ns1.corp.example.com.
10 IN PTR www.corp.example.com.
25 IN PTR mail.corp.example.com.
30 IN PTR dc1.corp.example.com.
53 IN PTR ns1.corp.example.com.
TTL にも違いがあります。dnsmasq は自分で答える名前の TTL を既定で 0 にしており、local-ttl を指定していなければ端末は毎回問い合わせていたはずです。ゾーンファイルの $TTL を長くすると、変更の反映がその分遅れます。最初は数分程度にしておき、運用が落ち着いてから見直すとよいでしょう。
手順3:NSD を別ポートで起動する
同じサーバーでは dnsmasq がすでに 53 番を使っているため、NSD はループバックの別ポートで待ち受けさせます。ここでは 5300 番を使います(5353 番は mDNS が使うので避けます)。
# /etc/nsd/nsd.conf
server:
ip-address: 127.0.0.1
port: 5300
zonesdir: "/etc/nsd/zones"
hide-version: yes
remote-control:
control-enable: yes
zone:
name: "corp.example.com"
zonefile: "corp.example.com.zone"
zone:
name: "1.168.192.in-addr.arpa"
zonefile: "1.168.192.in-addr.arpa.zone"
設定とゾーンの文法を確かめてから起動します。nsd-control を使うには、最初に nsd-control-setup で制御用の鍵を作ります(パッケージによっては導入時に作成済みです)。
sudo nsd-checkconf /etc/nsd/nsd.conf
sudo nsd-checkzone corp.example.com /etc/nsd/zones/corp.example.com.zone
sudo nsd-checkzone 1.168.192.in-addr.arpa /etc/nsd/zones/1.168.192.in-addr.arpa.zone
sudo nsd-control-setup
sudo systemctl restart nsd
dig @127.0.0.1 -p 5300 www.corp.example.com A
NSD のバージョンは 4 系が広く使われています(2026年10月現在)。設定項目はディストリビューションのパッケージの版で差があるため、man nsd.conf で確認してください。
手順4:dnsmasq と NSD の答えを比べる
切り替え前に、同じ名前を両方に問い合わせて結果を並べます。比べる名前は、手順1で抜き出した一覧から作ります。
# names.txt は1行に「名前 種類」
while read -r name type; do
old=$(dig @127.0.0.1 "$name" "$type" +short | sort | tr '\n' ' ')
new=$(dig @127.0.0.1 -p 5300 "$name" "$type" +short | sort | tr '\n' ' ')
[ "$old" = "$new" ] && s=OK || s=DIFF
printf '%-4s %-35s %-5s old=[%s] new=[%s]\n' "$s" "$name" "$type" "$old" "$new"
done < names.txt
逆引きは dig -x 192.168.1.10 と dig @127.0.0.1 -p 5300 -x 192.168.1.10 で比べます。DIFF が出やすいのは、hosts ファイルにしかなかった名前の書き漏れ、address 行のワイルドカード的な動き、SRV の項目の並び順です。
手順5:dnsmasq から NSD へ問い合わせを回す
比較で差がなくなったら、dnsmasq 側の静的なレコード定義を外し、該当ゾーンを NSD に回す行を追加します。
# /etc/dnsmasq.d/forward-to-nsd.conf
server=/corp.example.com/127.0.0.1#5300
rev-server=192.168.1.0/24,127.0.0.1#5300
移した名前の host-record などの行と、local=/corp.example.com/ があれば削除します。local= が残っていると、dnsmasq がそのドメインを自分で答えようとして NSD に回りません。また bogus-priv を有効にしていると、プライベートアドレスの逆引きの扱いが期待と異なる場合があるため、切り替え後に逆引きが期待どおり返るかを個別にテストします。
dnsmasq は SIGHUP では hosts ファイルなどを読み直すだけで、設定ファイルの変更は反映しません。設定を変えたら再起動します。
sudo dnsmasq --test
sudo systemctl restart dnsmasq
dig @192.168.1.53 www.corp.example.com
dig @192.168.1.53 -x 192.168.1.10
dig @192.168.1.53 www.example.org
社内名・逆引き・社外の名前の3つが引ければ切り替えは完了です。
Unbound に置き換える場合の要点
後から dnsmasq を Unbound に置き換える場合は、stub-zone で社内ゾーンを NSD に回します。Unbound は既定でループバックへ問い合わせない設定になっているため、do-not-query-localhost: no が要ります。
server:
do-not-query-localhost: no
private-domain: "corp.example.com"
domain-insecure: "corp.example.com"
local-zone: "168.192.in-addr.arpa." nodefault
domain-insecure: "168.192.in-addr.arpa."
stub-zone:
name: "corp.example.com"
stub-addr: 127.0.0.1@5300
stub-zone:
name: "1.168.192.in-addr.arpa"
stub-addr: 127.0.0.1@5300
private-domain は、プライベートアドレスを含む応答を捨てる設定(private-address)を使っている場合に、社内ゾーンを例外にするためのものです。domain-insecure は、DNSSEC の検証を有効にしているときに、署名のない社内ゾーンを検証対象から外します。
ゾーンを更新するときと切り戻し
運用に入ったら、レコードを変えるたびに次の順で作業します。シリアルを上げ忘れると、将来セカンダリを追加したときに転送されない原因になります。
sudo vi /etc/nsd/zones/corp.example.com.zone # serial を増やす
sudo nsd-checkzone corp.example.com /etc/nsd/zones/corp.example.com.zone
sudo nsd-control reload corp.example.com
問題が起きたときは、forward-to-nsd.conf を外し、バックアップしておいた dnsmasq の設定を戻して再起動すれば元の状態に戻ります。NSD は止めずに残しておけば、原因を調べてから再度切り替えられます。
まとめ
- NSD は権威 DNS 専用なので、dnsmasq の転送・キャッシュ・DHCP は残すか別のソフトに分けます。
- dnsmasq の設定行と hosts ファイルを洗い出し、正引きと逆引きのゾーンファイルに書き換えます。SRV の並び順や address 行の動きに注意します。
- NSD を別ポートで起動して全レコードの答えを比べ、
server=とrev-server=で NSD に問い合わせを回して切り替えます。 - 更新時はシリアルを上げ、
nsd-checkzoneで確かめてからnsd-control reloadします。