2026年6月7日
2026年6月7日
TinyDNS のインストール方法|daemontools を使わず systemd で動かす手順と確認
TinyDNS(tinydns)は、daemontools を使わなくても systemd のサービスとして動かせます。djbdns をビルドして入れ、tinydns-conf でデータの置き場所を作り、待ち受けアドレスと実行ユーザーを環境変数で渡すユニットを書けば、ログは journald に入り、起動・停止は systemctl で扱えます。この記事では、daemontools を新たに入れたくない今の Linux サーバーで TinyDNS を導入し、最初のゾーンが外部から引けるところまでを、つまずきやすい点と確認方法を添えて説明します。
従来どおり daemontools(svscan・supervise・multilog)の上で動かす方法もあり、既存の djbdns 群と運用をそろえたい場合はそちらが向いています。この記事は、ほかのサービスと同じく systemd で一元管理したい場合の手順です。
導入する前に確認しておくこと
djbdns は 1.05 以降、作者による公式な更新がありません。DNSSEC に対応しておらず、標準の版には AAAA レコード専用の記号もありません(IPv6 は汎用レコードで書くか、第三者のパッチを当てた版を使います)。tinydns は UDP だけで答えるため、大きな応答を TCP で返すには axfrdns を別に動かす必要があります(2026年10月現在)。
新しく権威DNSを立てるなら、NSD・Knot DNS・PowerDNS などの保守が続いている実装も比べてください。TinyDNS を選ぶのは、既存の data ファイル資産を使い続けたい場合や、1つのテキストファイルでゾーンを管理する簡素さを重視する場合です。
あわせて次の3点を決めておきます。
- 待ち受ける IP アドレス:tinydns は1つのアドレスの UDP 53番で待ち受けます。同じサーバーでキャッシュDNS(Unbound や dnscache)も動かすなら別のアドレスにします。
0.0.0.0:53で待ち受けているソフトがあると衝突します。 - ファイルの置き場所:以下ではソースから入れた場合の
/usr/local/binと、データ用の/etc/tinydnsを使います。パッケージで入れた場合はコマンドの場所をcommand -v tinydnsで確認して読み替えてください。 - 作業する環境:本番で動いている DNS とは別の検証用サーバーで手順を一度通してから、本番に入れると安全です。
djbdns をインストールする
パッケージを使う場合
ディストリビューションによっては djbdns のパッケージがあります。提供の有無やパッケージ名、依存関係(daemontools が一緒に入るかどうか)は版によって違うので、まず検索します。
apt search djbdns # Debian・Ubuntu 系
dnf search djbdns # RHEL 系(公式リポジトリにないことが多い)
パッケージで daemontools が一緒に入っても、svscan に登録しなければ動き出すことはありません。この記事の手順では systemd 側から起動します。
ソースからビルドする場合
パッケージがない環境では、配布元(cr.yp.to)のソースからビルドします。コンパイラと make が要ります。
sudo apt install build-essential # RHEL 系なら: sudo dnf install gcc make
curl -O https://cr.yp.to/djbdns/djbdns-1.05.tar.gz
tar xzf djbdns-1.05.tar.gz
cd djbdns-1.05
# 新しい glibc で errno の宣言エラーになるのを避ける
echo 'gcc -O2 -include /usr/include/errno.h' > conf-cc
make
sudo make setup check
conf-cc の書き換えは、古いコードが errno を独自に宣言しているために起きるビルドエラーへの定番の対処です。make setup check が成功すると、tinydns・tinydns-data・tinydns-get・tinydns-conf などが /usr/local/bin に入ります。djbdns 本体のビルドに daemontools は要りません。
データの置き場所を作る
tinydns 用と、tinydns-conf が引数に求めるログ用のシステムユーザーを作ります。どちらもログインできないユーザーにします。
sudo useradd --system --no-create-home --shell /usr/sbin/nologin tinydns
sudo useradd --system --no-create-home --shell /usr/sbin/nologin dnslog
# 実行ユーザー ログ用ユーザー 作成先 待ち受けIP
sudo tinydns-conf tinydns dnslog /etc/tinydns 192.0.2.53
tinydns-conf は daemontools 用の run スクリプトや log/ も作りますが、今回は使いません。使うのは、レコードを書く root/data、それを変換する root/Makefile、レコード追加用の補助スクリプト(add-ns・add-host など)です。作成先のディレクトリがすでにあるとエラーになるので、作り直すときは古いものを退避してから実行します。
最初のゾーンを書いて data.cdb に変換します。
cd /etc/tinydns/root
sudo ./add-ns example.com 192.0.2.53
sudo ./add-host www.example.com 192.0.2.10
sudo make
ls -l data.cdb
make は内部で tinydns-data を実行します。エラーが出た場合は data.cdb が作られない(または更新されない)ので、エラーの行を直してから先に進みます。data ファイルの記号と書式は、ゾーン設定の記事で詳しく扱っています。
systemd のユニットを作る
tinydns は起動時に環境変数を読みます。IP(待ち受けアドレス)、ROOT(data.cdb のあるディレクトリ)、UID と GID(権限を落とした後の実行ユーザー)です。tinydns は root で起動して 53番を開き、ROOT に chroot してから UID・GID の権限に切り替えて動くため、ユニット自体は root で起動します。
まず環境変数のファイルを作ります。ユーザーの番号はサーバーごとに違うので、id で取得して書き込みます。
printf 'IP=%s\nROOT=%s\nUID=%s\nGID=%s\n' \
192.0.2.53 /etc/tinydns/root "$(id -u tinydns)" "$(id -g tinydns)" \
| sudo tee /etc/tinydns/systemd.env
次にユニットファイルを作ります。
# /etc/systemd/system/tinydns.service
[Unit]
Description=tinydns authoritative DNS server (djbdns)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
EnvironmentFile=/etc/tinydns/systemd.env
ExecStart=/usr/local/bin/tinydns
Restart=on-failure
RestartSec=5
NoNewPrivileges=yes
PrivateTmp=yes
ProtectHome=yes
[Install]
WantedBy=multi-user.target
tinydns はフォアグラウンドで動き続けるので Type=simple で扱えます。Restart=on-failure は、起動時にまだ IP アドレスが付いていないなどの理由で失敗したときに、少し待って起動し直すための設定です。NoNewPrivileges などの制限は、tinydns が通常の権限切り替えだけで動くことを前提に付けています。追加で制限を強める場合は、1つ足すごとに起動と応答を確認してください。
sudo systemctl daemon-reload
sudo systemctl enable --now tinydns
systemctl status tinydns --no-pager
ログを確認する
tinydns のログは、標準出力・標準エラー出力から journald に入ります。
sudo journalctl -u tinydns -f
tinydns は問い合わせを1件ごとに1行記録します。行には問い合わせ元の IP アドレスとポートが16進数で入り、続く記号の + は応答したこと、- は自分の担当外の名前だったので答えなかったことを表します。問い合わせ種別も16進数(0001 が A、000f が MX など)で並びます。
問い合わせが多いサーバーではログの量が多くなります。journald の容量上限(journald.conf の SystemMaxUse= など)を決め、流量制限で行が捨てられていないかも見ておきます。ログには問い合わせ元の IP アドレスが残るので、保存期間と閲覧できる人を決めておきます。
動作を確認する
サーバー内でのデータの確認と、ネットワーク越しの問い合わせの2段階で確認すると、どこで止まっているかが分かります。
# 1. data.cdb の中身を直接引く(root/ で実行)
cd /etc/tinydns/root
tinydns-get a www.example.com
# 2. 待ち受けの確認
sudo ss -lunp | grep ':53 '
# 3. 別のマシンから再帰なしで問い合わせる
dig @192.0.2.53 www.example.com A +norec
dig @192.0.2.53 example.com SOA +norec
dig の応答の flags に aa があれば、権威を持つサーバーとして答えています。外部から届かないときは、ファイアウォールで UDP 53番を開けます。
sudo ufw allow 53/udp # ufw の場合
sudo firewall-cmd --permanent --add-service=dns && sudo firewall-cmd --reload # firewalld の場合
レコードを変えるときは root/data を編集して make するだけで、再起動は要りません。tinydns は問い合わせのたびに data.cdb を開くためです。
起動しない・答えないときの確認
よくある原因から順に確認します。
- 53番が使われている:
journalctl -u tinydnsに bind できない旨のエラーが出ます。sudo ss -lunp | grep ':53 'で、dnsmasq や BIND、別のキャッシュDNS が同じアドレスか0.0.0.0で待ち受けていないかを確認し、待ち受けアドレスを分けます。 - IP アドレスがサーバーに付いていない:
systemd.envのIPの打ち間違いや、起動時にネットワークがまだ上がっていない場合です。ip addrでアドレスを確認します。 - 環境変数が欠けている:
IP・ROOT・UID・GIDのどれかがないと、tinydns は理由を出して終了します。systemd.envの中身を確認します。 - data.cdb がない、または古い:
makeが失敗していると、新しい内容になりません。root/でmakeを実行し、出力を確認します。 - ファイアウォール:サーバー内の
dig @192.0.2.53では答えるのに外から届かない場合は、OS とクラウド側の両方の設定を確認します。
TCP での問い合わせ(応答が大きいときの再問い合わせなど)に答えるには、axfrdns を ucspi-tcp の tcpserver 経由で動かします。axfrdns は tcpserver が渡す接続情報を前提に作られているため、systemd で動かす場合も tcpserver を起動するユニットを別に用意します。
まとめ
- TinyDNS は、djbdns を入れて
tinydns-confでデータの置き場所を作れば、daemontools なしで systemd のサービスとして動かせます。 - ユニットには
IP・ROOT・UID・GIDを環境変数で渡し、root で起動させます。tinydns は自分で chroot と権限の切り替えを行います。 - ログは journald に入り、問い合わせごとに1行記録されます。容量と保存期間を決めておきます。
- 確認は
tinydns-getと、別マシンからのdig +norecの2段階で行います。レコードの変更はmakeだけで反映されます。 - djbdns は更新が止まっており DNSSEC に対応しないため、新規の構築では保守が続く実装とも比べてから選びます。