2026年6月26日

2026年6月26日

DNSのSOAレコードの設定方法|7つのフィールドの意味とBINDゾーンファイルの書き方

SOAレコードは、ゾーンの「台帳の表紙」にあたるレコードで、プライマリサーバー名・管理者の連絡先・シリアル番号と、セカンダリサーバーの同期間隔、そして存在しない名前の応答をキャッシュする時間を決めています。自前でDNSを運用するなら、ゾーンを書き換えるたびにシリアル番号を上げること、そして MINIMUM フィールドが「ネガティブキャッシュのTTL」であることの2点を押さえておけば、多くのトラブルは避けられます。この記事では、7つのフィールドの意味と推奨値、BINDでのゾーンファイルの書き方、named-checkzone による検証と反映確認までを順に解説します(2026年10月現在の BIND 9 系を前提にしています)。

SOAレコードとは

SOA(Start of Authority)は、ゾーンの先頭に1つだけ置くレコードです。そのゾーンについての権威を誰が持ち、どのようにセカンダリへ複製するかを示します。dig で見ると、次のように7つの値が並んでいます。

dig +short SOA example.com
# ns1.example.com. hostmaster.example.com. 2026101701 3600 900 1209600 3600

左から MNAME、RNAME、SERIAL、REFRESH、RETRY、EXPIRE、MINIMUM の順です。時間はすべて秒単位です。

7つのフィールドの意味

MNAME:プライマリネームサーバー

ゾーンの原本を持つプライマリサーバーのホスト名です。BINDはここに書かれたサーバーを NOTIFY(ゾーン更新の通知)の送信対象から外すなどの判断に使い、動的更新(RFC 2136)のクライアントは更新要求の送り先としてこの値を参照します。NSレコードに載せない「隠しプライマリ」構成でも、MNAMEにはそのサーバー名を書くのが一般的です。末尾のドット(ns1.example.com.)を忘れると、ゾーン名が後ろに付け足されて ns1.example.com.example.com. になってしまうので注意してください。

RNAME:管理者のメールアドレス

ゾーンの管理者の連絡先ですが、@ は使えず、**最初の @ をドットに置き換えて**書きます。hostmaster@example.com なら hostmaster.example.com. です。ローカル部分にドットを含むアドレス(taro.yamada@example.com)は、最初のドットを区切りと誤解されないよう taro\.yamada.example.com. のようにバックスラッシュでエスケープします。役割アドレスとしては hostmaster が慣例で、実際にメールを受け取れるアドレスにしておきます。

SERIAL:シリアル番号

ゾーンの版番号です。セカンダリサーバーはプライマリのSERIALを問い合わせ、自分の持つ値より大きければゾーン転送(AXFR・IXFR)を行います。つまりゾーンを書き換えてもSERIALを上げなければ、セカンダリには反映されません。

形式は自由ですが、YYYYMMDDnn(日付+その日の通し番号2桁)が広く使われています。2026年10月17日の1回目の変更なら 2026101701、同じ日の2回目なら 2026101702 です。SERIALは32ビットの符号なし整数(最大4294967295)で、この形式は範囲に収まります。

大小の比較は RFC 1982 の「シリアル番号算術」で行われるため、一度大きすぎる値を入れてしまうと、単純に小さい値へ戻すことはできません。戻したい場合は、2回に分けて一周させる方法か、セカンダリ側のゾーンを消して再転送させる方法を取ります。入力ミスを防ぐため、変更のたびに値を確認する習慣をつけてください。

REFRESH:セカンダリが確認する間隔

セカンダリがプライマリのSERIALを確認しに行く間隔です。現在はプライマリが変更時に NOTIFY を送るため、通常はすぐに同期されます。REFRESHは NOTIFY が届かなかったときの保険と考え、1時間〜1日程度(3600〜86400)がよく使われます。

RETRY:失敗時の再試行間隔

REFRESHの確認に失敗したとき、次に試すまでの間隔です。REFRESHより短くするのが基本で、数分〜2時間程度(300〜7200)が目安です。

EXPIRE:セカンダリがゾーンを捨てるまでの時間

プライマリと連絡が取れない状態がこの時間続くと、セカンダリはゾーンを古いものとみなし、応答をやめます。短すぎるとプライマリの長めの障害でセカンダリまで止まり、DNS全体が引けなくなります。RFC 1912 では2〜4週間(1209600〜2419200)が推奨されています。REFRESH・RETRYより十分大きくしてください。

MINIMUM:ネガティブキャッシュのTTL

名前の由来から「レコードの最小TTL」と思われがちですが、現在の意味は違います。RFC 2308 により、MINIMUM は「その名前は存在しない(NXDOMAIN)」「その種類のレコードはない(NODATA)」という否定応答をキャッシュする時間として定義されています。厳密には、否定応答のキャッシュ時間は SOA レコード自身のTTLと MINIMUM のうち小さいほうになります。

ここを長くしすぎると、新しいサブドメインを追加したのに「存在しない」という古い応答がキャッシュに残り、しばらく引けない状態になります。RFC 2308 では1〜3時間程度が推奨されており、頻繁にレコードを追加するゾーンでは300〜3600秒程度にしておくと扱いやすくなります。なお、ゾーン内の通常のレコードの既定TTLは、ゾーンファイル先頭の $TTL で指定します。

BINDのゾーンファイルの書き方

ここでは Debian・Ubuntu の配置(/etc/bind/)を例にします。RHEL系では /etc/named.conf と /var/named/ が一般的です。IPアドレスは説明用の予約アドレスを使っています。

; /etc/bind/db.example.com
$TTL 3600
$ORIGIN example.com.
@       IN  SOA ns1.example.com. hostmaster.example.com. (
                2026101701  ; SERIAL  (YYYYMMDDnn)
                3600        ; REFRESH (1時間)
                900         ; RETRY   (15分)
                1209600     ; EXPIRE  (2週間)
                3600        ; MINIMUM (ネガティブキャッシュ1時間)
                )

; ネームサーバー
@       IN  NS  ns1.example.com.
@       IN  NS  ns2.example.com.

; ゾーン内のネームサーバーにはアドレスが必要
ns1     IN  A   192.0.2.53
ns2     IN  A   198.51.100.53

; Web とメール
@       IN  A   192.0.2.10
www     IN  CNAME example.com.
@       IN  MX  10 mail.example.com.
mail    IN  A   192.0.2.25

書き方のポイントは次のとおりです。

  • @ は $ORIGIN(ここでは example.com.)を表す
  • 括弧で囲めば複数行に分けて書け、; 以降はコメントになる
  • NSに指定した名前がゾーン内にある場合は、そのAまたはAAAAレコードも書く(ないと検査でエラーになる)
  • 完全修飾名(FQDN)は末尾にドットを付ける

続いて、named.conf 側でゾーンを読み込ませます。

// /etc/bind/named.conf.local
zone "example.com" {
    type primary;
    file "/etc/bind/db.example.com";
    allow-transfer { 198.51.100.53; };
    also-notify { 198.51.100.53; };
};

type primary は新しいBINDで推奨されている表記で、従来の type master も引き続き使えます。allow-transfer で転送先をセカンダリに限定しておかないと、第三者にゾーンの中身を丸ごと取得される恐れがあります。

named-checkzoneで検証してから反映する

ゾーンファイルを書き換えたら、読み込む前に構文を検査します。本番のゾーンを編集するときは、事前に元のファイルをコピーしておくと、問題があったときにすぐ戻せます。

sudo cp -p /etc/bind/db.example.com /etc/bind/db.example.com.bak

named-checkzone example.com /etc/bind/db.example.com
# zone example.com/IN: loaded serial 2026101701
# OK

named-checkconf          # named.conf 側の構文検査

OK と表示され、loaded serial が今回の値になっていれば問題ありません。エラーが出た場合は行番号が表示されるので、末尾のドットの付け忘れや、括弧の閉じ忘れから確認します。検査が通ったら、ゾーンを再読み込みします。

sudo rndc reload example.com

反映の確認:プライマリとセカンダリのSERIALを比べる

最後に、各ネームサーバーへ直接問い合わせ、SERIALがそろっているかを確認します。

dig @192.0.2.53    example.com SOA +short
dig @198.51.100.53 example.com SOA +short

両方が同じSERIALを返せば同期は完了しています。セカンダリだけ古い場合は、SERIALを上げ忘れていないか、allow-transfer や ファイアウォール(TCP 53番)でゾーン転送が止められていないかを、BINDのログと合わせて確認します。外部のキャッシュサーバーに古い情報が残っている場合は、そのレコードのTTL(否定応答ならMINIMUM)が切れるまで待つ必要があります。

なお、Cloudflare や Route 53 などのマネージドDNSでは、SOAはサービス側で自動管理され、SERIALの更新も不要です。編集できる項目はサービスによって異なるため、ネガティブキャッシュの時間を変えたい場合は各サービスの設定画面を確認してください。

まとめ

  • SOAはゾーンに1つだけ置き、MNAME・RNAME・SERIAL・REFRESH・RETRY・EXPIRE・MINIMUMの7項目からなる
  • RNAMEはメールアドレスの @ をドットに置き換え、ローカル部分のドットは \. でエスケープする
  • SERIALは変更のたびに上げる。YYYYMMDDnn 形式が扱いやすく、下げることはできない
  • REFRESH > RETRY、EXPIREは2〜4週間程度と十分長くする
  • MINIMUMはRFC 2308によりネガティブキャッシュのTTL。長すぎると新しい名前がしばらく引けない
  • 変更後は named-checkzone で検査し、rndc reload のあと各サーバーのSERIALを比べて確認する

お気軽にご相談ください

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