2026年6月7日
2026年6月7日
MaraDNS で複数ゾーンを管理する設定|mararc の csv2 とゾーンファイルの整理・追加と削除の手順
MaraDNS で複数のゾーンを扱うには、設定ファイル mararc の csv2 に「ゾーン名とゾーンファイル」の組を1行ずつ書き、ゾーンごとに csv2 形式のファイルを用意します。MaraDNS はゾーンを起動時に読み込むので、追加や変更の後は再起動が必要です。この記事では、mararc の書き方、ファイルの置き方と命名、同じ内容の複数ドメインをまとめる方法、ゾーンの追加・削除の順序、全ゾーンの一括確認までを説明します。
MaraDNS は開発者による保守リリースが続いていますが、版によって設定項目や既定値が異なることがあります(2026年10月現在)。この記事の設定名は MaraDNS 2.0 以降の書式を前提にしているので、手元の版に付属する mararc のマニュアル(man mararc や同梱の文書)と照らし合わせてください。作業前には mararc とゾーンファイル一式をバックアップします。
mararc にゾーンを並べる
mararc は、変数に値を代入していく形式の設定ファイルです。複数ゾーンは csv2 という連想配列に登録します。最初に csv2 = {} で空の配列を作ってから、1ゾーン1行で追加します。
# /etc/mararc の例
ipv4_bind_addresses = "192.0.2.1"
chroot_dir = "/etc/maradns"
csv2 = {}
csv2["example.com."] = "db.example.com"
csv2["example.net."] = "db.example.net"
csv2["example.org."] = "db.example.org"
押さえておきたい点は3つあります。
- ゾーン名は末尾のドットまで書く:
"example.com."のように書きます。ドットを忘れると、意図したゾーンとして扱われません。 - ファイル名は chroot_dir からの相対パス:MaraDNS は起動後に
chroot_dirの中に閉じこもるため、ゾーンファイルはそのディレクトリの中に置き、mararc にはそこからの名前を書きます。 - **
csv2 = {}は1回だけ**:ゾーンを追加するたびに書き足すと、それより前の登録が消えてしまいます。
ゾーンファイルの置き方と命名
ゾーンが増えると、どのファイルがどのゾーンか分からなくなりがちです。db. にゾーン名を続けるなど、ファイル名からゾーン名が一目で分かる規則にしておくと、mararc との突き合わせが楽になります。ゾーン数が多い環境では、ゾーンの一覧を別のテキストファイルで管理し、そこから mararc の csv2[...] の行を作るスクリプトを用意しておくと、登録漏れや書き間違いを防げます。
各ゾーンファイルは csv2 形式で、1行1レコードです。
# /etc/maradns/db.example.com
example.com. SOA ns1.example.com. hostmaster@example.com. 2026101801 7200 3600 604800 1800
example.com. NS ns1.example.com.
example.com. NS ns2.example.com.
ns1.example.com. A 192.0.2.1
ns2.example.com. A 198.51.100.2
example.com. A 192.0.2.10
www.example.com. +3600 A 192.0.2.10
example.com. MX 10 mail.example.com.
mail.example.com. A 192.0.2.20
SOA を省略すると MaraDNS が補ってくれる場合がありますが、複数ゾーンを管理するなら、ゾーンごとに SOA と NS を明示しておくほうが、セカンダリへの転送や外部の検査ツールで扱いやすくなります。SOA のシリアルは MaraDNS 自身の読み込みには使われませんが、セカンダリが変更を検知するために使うので、編集のたびに上げる習慣をつけておきます。
同じ内容の複数ドメインを1つのファイルにまとめる
ブランド保護のために取得した複数のドメインを、同じサーバーに向けているだけ、という場合があります。csv2 では % がゾーン名の代わりになるため、ゾーン名を書かずにレコードを書けば、1つのファイルを複数のゾーンで使い回せます。
# /etc/maradns/db.parked
% SOA ns1.example.com. hostmaster@example.com. 2026101801 7200 3600 604800 1800
% NS ns1.example.com.
% NS ns2.example.com.
% A 192.0.2.10
www.% A 192.0.2.10
# mararc
csv2["example-shop.com."] = "db.parked"
csv2["example-shop.net."] = "db.parked"
この方法なら、向け先の IP を変えるときに1つのファイルを直すだけで済みます。ただし、どれか1つのドメインだけ別の設定にしたくなったら、そのドメインには専用のファイルを用意して切り離します。% の扱いは版によって細部が異なる可能性があるので、使う前に検証用サーバーで応答を確認してください。
mararc には、登録していないあらゆるドメインに同じゾーンファイルで答える csv2_default_zonefile という設定もあります。便利そうに見えますが、自分が管理していないドメインの問い合わせにも答えることになるため、意図がはっきりしている場合以外は使わないほうが無難です。
ゾーンを追加・削除する順序
追加するとき
- ゾーンファイルを作り、mararc に
csv2[...]の行を追加します。 - MaraDNS を再起動します(後述)。
- 新しいゾーンに
dig @192.0.2.1 example.org SOA +norecで問い合わせ、flagsにaaが付いた権威のある答えが返ることを確認します。 - 最後に、ドメインの登録事業者でネームサーバーを MaraDNS に向けます。
順序を逆にして先にネームサーバーを向けると、MaraDNS がまだ答えられない間に問い合わせが届き、引けない時間ができます。
削除するときは逆の順序で、先に登録事業者でネームサーバーを別のサーバーに移し、親ゾーンの NS の TTL が切れて問い合わせが来なくなったことをログで確認してから、mararc の行とゾーンファイルを消します。
再起動と、1つの誤りで全ゾーンが止まる問題
MaraDNS は起動時にすべてのゾーンを読み込みます。そのため、1つのゾーンファイルに書式の誤りがあるだけで起動に失敗し、ほかの正常なゾーンまで答えられなくなることがあります。複数ゾーンを1台で管理するときの、いちばん大きな注意点です。
対策として、次の手順を習慣にします。
- 本番の前に、検証用サーバーで同じ mararc とゾーンファイルを使って起動し、エラーが出ないことを確かめます。mararc の
dns_portで待ち受けポートを変えられる版なら、同じサーバーの別ポートで試す方法もあります。 - 権威サーバーを2台以上用意し、1台ずつ再起動します。片方が起動に失敗しても、もう片方が答え続けます。
- 再起動の直後にログを確認します。systemd で動かしている場合は
journalctl -u maradns -n 50のように見ます(ユニット名は導入方法によって異なります)。
全ゾーンを一括で確認する
ゾーンが多いと、1つずつ確かめるのは手間です。mararc からゾーン名を取り出し、すべてに SOA を問い合わせる小さなスクリプトを用意しておくと、再起動のたびに使えます。
#!/bin/sh
# mararc の csv2["ゾーン名."] からゾーン名を取り出し、SOA に権威のある答えが返るか確認する
SERVER=192.0.2.1
grep -o 'csv2\["[^"]*"\]' /etc/mararc | sed 's/csv2\["\(.*\)"\]/\1/' | while read -r zone; do
if dig @"$SERVER" "$zone" SOA +norec | grep -q 'flags:.* aa'; then
echo "OK $zone"
else
echo "NG $zone"
fi
done
NG と表示されたゾーンは、mararc のゾーン名の綴り、ファイル名、ファイル内の名前(末尾のドットや %)を順に確認します。
まとめ
- 複数ゾーンは mararc の
csv2 = {}の後にcsv2["ゾーン名."] = "ファイル名"を1行ずつ書き、ファイルは chroot_dir の中に置きます。 - ファイル名からゾーン名が分かる規則にし、同じ内容のドメインは
%を使った共通ファイルにまとめられます。 - 追加は「ゾーンを用意して確認してから NS を向ける」、削除は「NS を外して問い合わせが止んでから消す」の順で行います。
- 1つの誤りで全ゾーンが止まらないよう、検証用サーバーで起動を確かめ、2台以上を1台ずつ再起動し、一括確認のスクリプトで応答を確認します。