2026年6月12日

2026年6月12日

dnsmasq のインストール方法|53番ポートの競合を避けて、LAN 向けの DNS キャッシュとして動かすまで

dnsmasq は、Debian・Ubuntu なら apt install dnsmasq、RHEL 系(AlmaLinux・Rocky Linux など)なら dnf install dnsmasq で入ります。インストール自体は1行ですが、多くの環境では systemd-resolved などがすでに53番ポートを使っているため、そのままでは起動に失敗します。この記事では、インストール前の確認、ディストリビューションごとの導入、ポートの競合の解き方、最小限の設定、動作確認とファイアウォールまでを順に説明し、LAN 向けの DNS キャッシュ兼ローカル名の解決として動かせる状態を目指します。

パッケージ名や既定の設定ファイルの内容はディストリビューションと版によって異なります。記載は執筆時点(2026年10月現在)の情報です。本番機に入れる前に、同じ OS の検証環境で一度試すことをおすすめします。

インストールの前に決めておくこと

dnsmasq は小さなソフトですが、DNS の転送とキャッシュ、ローカル名の解決、DHCP、TFTP など多くの機能を持っています。最初に次の3点を決めておくと、設定で迷いません。

  • 用途:DNS だけを使うのか、DHCP も dnsmasq に任せるのか。この記事では DNS だけを扱います。DHCP は dhcp-range を書かない限り動かないため、ルーターの DHCP と衝突する心配はありません。
  • 待ち受けるアドレス:LAN 側のアドレス(例:192.168.1.10)と、自分自身用の 127.0.0.1 だけにします。インターネットに面したアドレスで待ち受けると、誰でも使えるオープンリゾルバーになり、DNS 増幅攻撃の踏み台にされるおそれがあります。
  • 上流の DNS:問い合わせを転送する先。プロバイダーやクラウドのリゾルバー、社内の DNS など。

手順1:53番ポートを使っているプロセスを確認する

sudo ss -lntup 'sport = :53'

よく見かけるのは次のような先客です。

  • systemd-resolved:Ubuntu などで 127.0.0.53(版によっては 127.0.0.54 も)で待ち受けています。
  • libvirt の dnsmasq:仮想マシン用のブリッジ(virbr0 など)のアドレスで、libvirt が自分用の dnsmasq を動かしています。
  • 別の DNS サーバー:BIND や Unbound がすでに入っている場合。

ここで何がいるかを把握しておくと、後の手順3で選ぶ方法が決まります。

手順2:パッケージをインストールする

Debian・Ubuntu

sudo apt update
sudo apt install dnsmasq

Debian 系では、インストール直後に dnsmasq のサービスが自動で起動しようとします。systemd-resolved が53番を使っている環境では、ここで「failed to create listening socket for port 53: Address already in use」のようなエラーが出て起動に失敗することがありますが、インストール自体は完了しています。手順3で競合を解いてから起動し直せば問題ありません。

NetworkManager や libvirt の依存で dnsmasq-base だけが入っていることもあります。これはプログラム本体だけのパッケージで、常駐サービスとして使うための設定やユニットファイルは dnsmasq パッケージに含まれます。

RHEL 系

sudo dnf install dnsmasq

RHEL 系では、インストールしてもサービスは自動では起動しません。設定を書いてから手順5で有効にします。

インストールできたら、版と組み込まれている機能を確認します。

dnsmasq --version

2行目あたりに「Compile time options」として、DNSSEC や DHCP などの対応の有無が表示されます。

手順3:53番ポートの競合を解く

方法は大きく2つあります。

方法A:待ち受けアドレスを分けて共存させる(おすすめ)

systemd-resolved は 127.0.0.53 で、dnsmasq は 127.0.0.1 と LAN 側のアドレスで待ち受ければ、同じ53番でもぶつかりません。そのためには、dnsmasq に「指定したアドレスにだけ結び付く」よう bind-interfaces を設定します(設定内容は手順4)。OS 側の設定を変えずに済むため、影響範囲がもっとも小さい方法です。libvirt の dnsmasq がいる環境でも、同じ考え方で共存できます。

方法B:systemd-resolved の待ち受けを止める

このサーバー自身の名前解決も dnsmasq に任せたい場合は、systemd-resolved のスタブリスナーを止めます。

sudo mkdir -p /etc/systemd/resolved.conf.d
printf '[Resolve]\nDNSStubListener=no\n' | sudo tee /etc/systemd/resolved.conf.d/no-stub.conf
sudo systemctl restart systemd-resolved

この方法では、/etc/resolv.conf に注意が要ります。Ubuntu では resolv.conf が 127.0.0.53 を指すファイルへのシンボリックリンクになっていることが多く、スタブを止めるとサーバー自身が名前を引けなくなります。dnsmasq を起動したあとに、resolv.conf の向き先を 127.0.0.1 にするか、systemd-resolved が上流の一覧を書き出すファイルに張り替えます。どちらがよいかは NetworkManager や netplan の使い方によって変わるため、変更前に元のリンク先をメモしておきます。

手順4:最小限の設定を書く

設定は /etc/dnsmasq.conf に直接書くこともできますが、パッケージの更新で衝突しないよう、別ファイルに分けるのがおすすめです。Debian 系・RHEL 系とも /etc/dnsmasq.d/ を読み込む設定になっていることが多いので、grep conf-dir /etc/dnsmasq.conf などで確かめてから、/etc/dnsmasq.d/local.conf を作ります。

# /etc/dnsmasq.d/local.conf

# 待ち受け:自分自身と LAN 側のアドレスだけ
listen-address=127.0.0.1,192.168.1.10
bind-interfaces

# 上流:resolv.conf は読まず、ここに書いたサーバーへ転送する
no-resolv
server=192.0.2.53
server=198.51.100.53

# ドットの無い名前とプライベートアドレスの逆引きを上流に流さない
domain-needed
bogus-priv

# キャッシュする件数
cache-size=1000

# LAN 内の名前(home.arpa は家庭内ネットワーク向けに予約されたドメイン)
local=/home.arpa/
domain=home.arpa
host-record=nas.home.arpa,192.168.1.20
host-record=printer.home.arpa,192.168.1.30

それぞれの意味と、つまずきやすい点です。

  • **listen-address と bind-interfaces**:listen-address だけを書いた場合、127.0.0.1 は自動では待ち受けに入らないため、明示して書きます。bind-interfaces を付けないと、dnsmasq はすべてのアドレスで受けてから振り分ける動きになり、systemd-resolved と競合します。
  • **no-resolv**:dnsmasq は既定で /etc/resolv.conf から上流を読みます。手順3の方法Bで resolv.conf を 127.0.0.1 に向けると、自分自身に転送してループします。上流は server= で明示しておくほうが安全です。
  • **local=/home.arpa/**:このドメインは上流へ問い合わせず、dnsmasq が持つ情報だけで答えます。
  • **host-record**:名前とアドレスを登録し、逆引き(PTR)も自動で答えます。/etc/hosts に書いた名前も既定で答えに使われます。

手順5:文法を確認して起動する

# 文法の確認(問題なければ "syntax check OK" と表示される)
dnsmasq --test

sudo systemctl enable --now dnsmasq
sudo systemctl restart dnsmasq
systemctl status dnsmasq

起動に失敗したら、journalctl -u dnsmasq -e でログを確認します。「Address already in use」なら手順3の競合がまだ残っている、「unknown interface」なら listen-address に書いたアドレスがそのサーバーに無い、という切り分けができます。

手順6:動作を確認する

# 外部の名前(2回続けて引くと、2回目は Query time が短くなる)
dig @192.168.1.10 example.com A

# LAN 内の名前と逆引き
dig @192.168.1.10 nas.home.arpa A
dig @192.168.1.10 -x 192.168.1.20

# キャッシュの統計(dnsmasq は CHAOS クラスの TXT で統計を返す)
dig @127.0.0.1 cachesize.bind CH TXT +short
dig @127.0.0.1 hits.bind CH TXT +short

LAN 内の別の端末からも dig や nslookup で問い合わせ、答えが返るかを確かめます。返らない場合は、次のファイアウォールを確認します。

手順7:ファイアウォールで問い合わせ元を絞る

LAN からの問い合わせだけを通します。DNS は UDP と TCP の両方を使うため、両方を許可します。

# ufw(Ubuntu など)
sudo ufw allow from 192.168.1.0/24 to any port 53

# firewalld(RHEL 系):LAN 側のゾーンにだけ dns を許可する
sudo firewall-cmd --permanent --zone=internal --add-source=192.168.1.0/24
sudo firewall-cmd --permanent --zone=internal --add-service=dns
sudo firewall-cmd --reload

VPS やクラウドのサーバーに入れる場合は、事業者側のセキュリティグループやファイアウォールでも53番を外部に開けていないかを確認します。待ち受けアドレスを LAN 側に限っていても、設定の書き換えで公開アドレスに広がる事故を防ぐため、二重に絞っておくのが基本です。

端末側の設定と、元に戻す方法

LAN 内の端末に dnsmasq を使わせるには、ルーターの DHCP 設定で配る DNS サーバーを dnsmasq のアドレスにするか、端末ごとに DNS サーバーを指定します。いきなり全台を切り替えず、1台で数日使ってから広げると、問題が出ても影響が小さく済みます。

元に戻すときは、端末の DNS を元に戻してから sudo systemctl disable --now dnsmasq で止めます。手順3の方法Bを取った場合は、作成した no-stub.conf を削除して systemd-resolved を再起動し、resolv.conf のリンク先を元に戻します。パッケージを削除する場合、Debian 系の apt remove は設定ファイルを残し、apt purge は消すため、必要な設定は先にバックアップします。

まとめ

  • インストールは apt install dnsmasq または dnf install dnsmasq で済みますが、先に ss -lntup 'sport = :53' で53番の先客を確認します。
  • systemd-resolved とは、listen-address と bind-interfaces で待ち受けアドレスを分ければ共存できます。
  • 上流は no-resolv と server= で明示し、LAN 内の名前は local= と host-record で答えさせます。
  • dnsmasq --test で文法を確認してから起動し、ファイアウォールで LAN からの問い合わせだけを通します。

お気軽にご相談ください

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