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 を開くためです。

起動しない・答えないときの確認

よくある原因から順に確認します。

  1. 53番が使われている:journalctl -u tinydns に bind できない旨のエラーが出ます。sudo ss -lunp | grep ':53 ' で、dnsmasq や BIND、別のキャッシュDNS が同じアドレスか 0.0.0.0 で待ち受けていないかを確認し、待ち受けアドレスを分けます。
  2. IP アドレスがサーバーに付いていない:systemd.env の IP の打ち間違いや、起動時にネットワークがまだ上がっていない場合です。ip addr でアドレスを確認します。
  3. 環境変数が欠けている:IP・ROOT・UID・GID のどれかがないと、tinydns は理由を出して終了します。systemd.env の中身を確認します。
  4. data.cdb がない、または古い:make が失敗していると、新しい内容になりません。root/ で make を実行し、出力を確認します。
  5. ファイアウォール:サーバー内の 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 に対応しないため、新規の構築では保守が続く実装とも比べてから選びます。

お気軽にご相談ください

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