2026年6月12日
2026年6月12日
dnsmasq でセカンダリ構成する手順|2台で冗長化する方法と、権威モードからゾーン転送する方法
dnsmasq は、ほかの DNS サーバーからゾーン転送(AXFR)を受け取るセカンダリサーバーにはなれません。そのため「dnsmasq でセカンダリ構成」を作るには、目的に応じて2つの方法から選びます。社内 LAN の名前解決を止めたくないなら「同じ設定の dnsmasq を2台並べる」、外部向けの権威DNSとして使うなら「dnsmasq を権威プライマリにして、BIND や NSD をセカンダリにする」です。この記事では、両方の構成手順と、DHCP を併用するときのつまずきやすい点、動作の確認方法を説明します。
先に決める:どちらの「セカンダリ」が必要か
dnsmasq は、DNS のキャッシュ・転送、/etc/hosts や DHCP の情報を使った名前解決、DHCP サーバーを1つにまとめたソフトです。BIND のように「プライマリが持つゾーンを、セカンダリが定期的にコピーする」仕組みは、dnsmasq では送る側(権威モードでの AXFR の提供)しか用意されていません。
- LAN の名前解決を冗長化したい:端末やサーバーが dnsmasq に問い合わせていて、1台が止まっても名前解決を続けたい場合です。ゾーン転送は使わず、設定ファイルを同期した2台を用意し、端末には2台とも DNS サーバーとして配ります。
- インターネット向けの権威DNSを2台にしたい:自分のドメインの権威DNSとして dnsmasq を使い、レジストラに NS を2つ以上登録したい場合です。dnsmasq の権威モード(auth-zone)でプライマリを作り、セカンダリには AXFR を受け取れる BIND・NSD・Knot DNS などを使います。
どちらの構成でも、2台は別の物理ホストや別の回線に置くと、障害がまとめて起きにくくなります。
方法1:同じ設定の dnsmasq を2台並べる
設定ファイルを2台で揃える
dnsmasq の設定は /etc/dnsmasq.conf と、conf-dir= で読み込むディレクトリ(Debian・Ubuntu 系では /etc/dnsmasq.d/)にあります。名前とアドレスの対応は /etc/hosts や addn-hosts= で指定したファイルにも書かれます。2台目には、これらのファイルを1台目と同じ内容で置きます。
手作業でコピーすると、どちらかだけ更新し忘れて答えが食い違います。設定はバージョン管理し、rsync や Ansible などで両方に配る仕組みにしておくと安全です。
# 1台目で編集した設定を2台目へ配る例(配った後に2台目で検査・再起動)
rsync -av /etc/dnsmasq.d/ dns2:/etc/dnsmasq.d/
rsync -av /etc/hosts.dnsmasq dns2:/etc/hosts.dnsmasq
ssh dns2 'sudo dnsmasq --test && sudo systemctl restart dnsmasq'
dnsmasq --test は設定ファイルの文法だけを検査するオプションで、問題がなければ syntax check OK と表示されます。検査に通ってから再起動すると、設定の誤りで2台目が止まる事態を防げます。
端末に2台目を配る
端末が DHCP でアドレスを受け取っている場合は、DHCP で配る DNS サーバーに2台とも含めます。
# 192.168.1.2 と 192.168.1.3 の2台を DNS サーバーとして配る
dhcp-option=option:dns-server,192.168.1.2,192.168.1.3
固定アドレスのサーバーでは /etc/resolv.conf(または systemd-resolved・NetworkManager の設定)に2台とも書きます。OS のリゾルバは1台目が応答しないとタイムアウトを待ってから2台目に問い合わせるので、切り替わりに数秒かかることは覚えておいてください。
DHCP を2台で動かすときの注意
dnsmasq には、2台の DHCP サーバーでリース情報を共有する仕組み(ISC DHCP や Kea のフェイルオーバーのような機能)がありません。そのため DHCP も冗長化しようとすると、次の問題が出ます。
- アドレスの重複:2台が同じ範囲を配ると、別々の端末に同じアドレスを渡す恐れがあります。2台で配る範囲を重ならないように分けます(例:1台目は .100〜.199、2台目は .200〜.249)。
- **
dhcp-authoritativeの扱い**:この設定を入れたサーバーは、自分の知らないリースの更新要求を拒否することがあります。範囲を分けて2台で配るなら、両方に入れると端末の更新が拒否されるおそれがあるため、設定の有無と挙動を検証環境で確かめてから使います。 - DHCP で登録された名前の食い違い:dnsmasq は、自分が DHCP でアドレスを配った端末の名前を DNS で答えます。2台目は1台目が配った端末の名前を知らないため、問い合わせ先によって答えが変わります。
名前の一貫性を重視するなら、DHCP は1台だけで動かし、2台目は DNS 専用(/etc/hosts や host-record= の静的な情報だけを答える)にするのが分かりやすい構成です。DHCP の端末名も2台目で引けるようにしたい場合は、端末に固定の割り当て(dhcp-host=)を設定し、その名前を host-record= で両方に書いておきます。
方法2:dnsmasq を権威プライマリにして、BIND をセカンダリにする
dnsmasq 側(プライマリ)の設定
dnsmasq の権威モードでは、auth-server= で権威として答えるインターフェースと自分のネームサーバー名を、auth-zone= で権威を持つゾーンを指定します。セカンダリへのゾーン転送は auth-sec-servers= と auth-peer= で設定します。
# /etc/dnsmasq.d/auth.conf(プライマリ 192.0.2.10)
# 権威として答える名前とインターフェース
auth-server=ns1.example.com,eth0
# 権威を持つゾーン
auth-zone=example.com
# SOA のシリアル、管理者アドレス、refresh、retry、expire
auth-soa=2026101801,hostmaster.example.com,1200,180,1209600
# NS レコードに載せるセカンダリの名前
auth-sec-servers=ns2.example.com
# ゾーン転送を許可するセカンダリのアドレス
auth-peer=192.0.2.20
# ゾーン内のレコード
host-record=ns1.example.com,192.0.2.10
host-record=ns2.example.com,192.0.2.20
host-record=www.example.com,192.0.2.80
mx-host=example.com,mail.example.com,10
host-record=mail.example.com,192.0.2.25
auth-peer= を書かずに auth-sec-servers= だけを書くと、どこからでもゾーン転送を受け付ける動作になると dnsmasq のマニュアルに記載があります。ゾーンの中身を外部に一覧されないよう、auth-peer= でセカンダリのアドレスに限定し、ファイアウォールでも TCP 53番をセカンダリからだけ許可します。dnsmasq には TSIG による転送の認証がないため、アドレスでの制限が頼りになります。
dnsmasq は、ゾーンの変更をセカンダリに知らせる NOTIFY を送りません。セカンダリは SOA の refresh の間隔(上の例では1200秒)ごとにシリアルを確認し、増えていれば転送します。レコードを変えたら auth-soa= のシリアルを上げてから dnsmasq を再起動するのを手順に入れておきます。シリアルを上げ忘れると、セカンダリは古い内容のまま答え続けます。
auth-soa= などの細かな書式や既定値は版によって変わることがあるので、作業前に手元の man dnsmasq で確認してください(2026年10月現在)。
BIND 側(セカンダリ)の設定
// /etc/bind/named.conf.local(セカンダリ 192.0.2.20)
zone "example.com" {
type secondary;
primaries { 192.0.2.10; };
file "/var/cache/bind/db.example.com";
};
古い BIND では type slave; と masters { ... }; という書き方です。どちらが使えるかは named -v で版を確認し、設定は named-checkconf で検査してから sudo systemctl reload named(ディストリビューションによっては bind9)で反映します。NSD をセカンダリにする場合は、zone: の節に request-xfr: 192.0.2.10 NOKEY を書きます。
動作を確認する
確認は「転送できるか」「両方が同じ答えを返すか」の2段階で行います。
# 1. セカンダリのサーバーから、プライマリにゾーン転送を要求する
dig @192.0.2.10 example.com AXFR
# 2. 許可していないホストから転送を試し、拒否されることを確かめる
dig @192.0.2.10 example.com AXFR # 別のホストで実行し、Transfer failed になればよい
# 3. 両方の SOA シリアルを比べる
dig @192.0.2.10 example.com SOA +norec +short
dig @192.0.2.20 example.com SOA +norec +short
# 4. 両方で同じレコードが返るか
dig @192.0.2.20 www.example.com A +norec
1 でレコードの一覧が返れば転送できています。返らない場合は、TCP 53番のファイアウォール、auth-peer= のアドレス、auth-server= で指定したインターフェースを順に確認します。3 でシリアルが違ったままなら、セカンダリのログ(journalctl -u named など)に転送失敗の理由が出ています。
方法1の構成では、端末から2台それぞれに dig @192.168.1.2 名前 と dig @192.168.1.3 名前 を実行し、同じ答えが返ることを確認します。さらに1台目の dnsmasq を止めた状態で、端末の名前解決が続くかも試しておくと、冗長化が働いていることを確かめられます。
運用で気をつけること
- 変更は2台に配って初めて完了:方法1では設定の同期、方法2では SOA シリアルの更新を、変更手順の一部として書いておきます。
- 作業前のバックアップ:設定ファイルと
/etc/hostsを控えてから変更し、本番の前に検証環境で試します。 - 権威とキャッシュを混ぜすぎない:方法2の dnsmasq をインターネットに公開する場合、再帰問い合わせ(キャッシュDNSとしての動作)を外部に開放しないよう、待ち受けるインターフェースと許可する問い合わせ元を絞ります。開放したままだと、DNS を使った攻撃の踏み台にされるおそれがあります。
まとめ
- dnsmasq はゾーン転送を受け取るセカンダリにはなれないため、目的に応じて「2台並べる」か「dnsmasq をプライマリにして別ソフトをセカンダリにする」かを選びます。
- 2台並べる構成では、設定を同期して
dnsmasq --testで検査し、DHCP で2台とも DNS サーバーとして配ります。DHCP はリースを共有できないため、1台だけで動かすと名前の食い違いを避けられます。 - 権威モードでは
auth-zone=・auth-sec-servers=・auth-peer=でゾーン転送を許可します。NOTIFY は送られないため、変更時は SOA シリアルを上げます。 digの AXFR と SOA シリアルの比較で、転送と答えの一致を確認します。