2026年6月8日
2026年6月8日
SOAレコードの誤設定を修正する手順|シリアル番号・RNAME・ネガティブキャッシュTTLの直し方
SOAレコードの誤設定で実害が出やすいのは、シリアル番号の更新漏れ(セカンダリに変更が伝わらない)、シリアル番号の巻き戻し、末尾ドットの付け忘れ、そして最後のフィールド(ネガティブキャッシュTTL)が長すぎて「追加したはずのレコードが引けない」状態が続くケースです。この記事では、dig で今のSOAを読み取って誤りを見つける方法と、BIND などの自前DNSサーバーで安全に直す手順、マネージドDNSを使っている場合の考え方を説明します。
SOAの各フィールドの意味をひととおり確認したい場合は、先に基本を押さえてから読むと理解しやすくなります。ここでは「すでに設定されているSOAのどこが悪いか」を見つけて直すことに絞ります。
今のSOAを読み取る
まず、権威DNSサーバーが実際に返しているSOAを確認します。+multiline を付けると、各値にフィールド名のコメントが付いて読みやすくなります。
# SOA の内容を確認
dig example.com SOA +multiline
# すべての権威サーバーの SOA(とシリアル)を一覧で比較
dig example.com +nssearch
+nssearch は、NSレコードに載っているすべてのサーバーへ順に問い合わせ、各サーバーのSOAを1行ずつ表示します。ここでシリアル番号がサーバーごとに違っていれば、ゾーン転送がうまくいっていない可能性が高いと判断できます。
SOAの値は左から次の順に並んでいます。
- MNAME: プライマリのネームサーバー名
- RNAME: 管理者のメールアドレス(
@の代わりに.で書く) - SERIAL: ゾーンのシリアル番号
- REFRESH / RETRY / EXPIRE: セカンダリが更新を確認する間隔、失敗時の再試行間隔、プライマリと通信できないまま応答を続ける期限
- MINIMUM: 現在は「存在しない」という応答をキャッシュする時間(ネガティブキャッシュTTL)として使われる値
よくある誤設定と直し方
1. シリアル番号を上げ忘れた
もっとも多いのがこれです。ゾーンファイルを編集してもシリアル番号を増やさないと、セカンダリは「変更なし」と判断して転送を行いません。その結果、プライマリに問い合わせたときだけ新しい値が返り、セカンダリからは古い値が返るため、利用者によって見える結果が変わります。
+nssearch でシリアル番号の食い違いを確認したら、プライマリのシリアル番号を増やして再読み込みします。シリアル番号は YYYYMMDDnn(日付+その日の通し番号)の形式で管理するのが一般的です。
2. シリアル番号を誤って大きくしすぎた・巻き戻した
日付の打ち間違いで年が1つ先になった、別の形式から戻そうとして値が小さくなった、という場合は単純には直せません。シリアル番号の大小比較は RFC 1982 の「シリアル番号算術」に従い、値を小さくするとセカンダリは「古いゾーン」とみなして転送しないためです。また、シリアル番号は32ビット符号なし整数なので、4294967295 を超える値(11桁の打ち間違いなど)は設定できません。
自分でセカンダリも管理している場合は、プライマリで正しい値に直したうえで、各セカンダリで強制的に全体転送させるのが手早い方法です。
# セカンダリ側で実行:シリアルの大小に関係なくゾーンを取り直す(BIND)
sudo rndc retransfer example.com
外部のセカンダリサービスを使っていて強制転送ができない場合は、2段階で戻します。たとえば誤って 2027101801 にしてしまい、本来 2026101802 にしたい場合は、次の順に進めます。
- 現在の値に 2147483647 を足した値(4174585448)に一度上げ、すべてのセカンダリに伝わったことを
+nssearchで確認する - そのあと目的の値(2026101802)に設定する。シリアル番号算術ではこの値の方が「新しい」と判定されるため、転送が行われる
足した結果が 4294967295 を超える場合は、4294967296 を引いた値を使います。
3. MNAME・RNAME の末尾ドットを付け忘れた
BINDのゾーンファイルでは、末尾にドットの無い名前にはゾーン名が自動で付け足されます。ns1.example.com と書くと ns1.example.com.example.com. として解釈されるため、dig の出力でMNAMEやRNAMEが二重になっていないかを確認します。RNAMEに @ をそのまま書いてしまう誤りもよく見られます。hostmaster@example.com は hostmaster.example.com. と書きます。
4. ネガティブキャッシュTTL(MINIMUM)が長すぎる
存在しない名前への問い合わせ結果(NXDOMAIN)は、SOAのTTLとMINIMUMのうち小さい方の時間だけキャッシュされます(RFC 2308)。ここが1日や数日になっていると、新しくサブドメインを追加する前に誰かが一度問い合わせただけで、その「存在しない」という結果がその期間残ります。
# 存在しない名前を問い合わせ、AUTHORITY セクションの SOA の TTL を見る
dig nothing-here.example.com A
AUTHORITYセクションに表示されるSOAのTTLが、実際にキャッシュされる時間の目安です。一般的には数分〜1時間程度(300〜3600秒)に設定されることが多く、レコードの追加が多い運用では短めにしておくと困りません。値を短くしても、すでにキャッシュされた結果は元の時間が過ぎるまで残る点に注意してください。
5. REFRESH・RETRY・EXPIRE の組み合わせが不自然
RETRY が REFRESH より長い、EXPIRE が短すぎる、といった組み合わせは、すぐに障害にはならなくても、プライマリ停止時の挙動に影響します。特に EXPIRE が短いと、プライマリが止まってから比較的早くセカンダリが応答をやめ、ドメイン全体が引けなくなります。EXPIRE は数週間程度に設定する例が多く見られます。NOTIFY を使って変更を即時に伝える構成なら、REFRESH は確認の保険として考えれば足ります。
6. MNAME が実際のプライマリと違う
サーバー移行後にMNAMEが古いホスト名のまま、というケースです。通常の名前解決には影響しにくいものの、動的更新(nsupdate)はMNAMEのサーバーへ送られるため、更新が失敗する原因になります。現在のプライマリ(隠しプライマリ構成ならそのサーバー名)に合わせて直します。
BINDで安全に修正する手順
作業前にゾーンファイルをコピーしてバックアップを取ります。可能なら検証用のサーバーで同じ手順を試してから本番に反映します。
; /etc/bind/zones/db.example.com(例)
$TTL 3600
@ IN SOA ns1.example.com. hostmaster.example.com. (
2026101802 ; serial
3600 ; refresh
900 ; retry
1209600 ; expire
3600 ) ; negative cache TTL
# 1. 構文とSOAの値を検査(エラーがあれば反映しない)
sudo named-checkzone example.com /etc/bind/zones/db.example.com
# 2. 対象ゾーンだけ再読み込み
sudo rndc reload example.com
# 3. プライマリの状態とシリアルを確認
sudo rndc zonestatus example.com
# 4. 全権威サーバーのシリアルがそろったか確認
dig example.com +nssearch
named-checkzone が OK と、読み込んだシリアル番号を表示すれば構文上の問題はありません。反映後にセカンダリのシリアルがそろわない場合は、ログ(journalctl -u named。環境によってはサービス名が bind9)でゾーン転送の拒否やNOTIFYの失敗が出ていないかを確認します。DNSSECで署名している場合は、署名の更新を含めた手順が必要になるので、利用している署名方式の手順に従ってください。
マネージドDNSの場合
Amazon Route 53 や Cloudflare などのマネージドDNSでは、SOAの大部分をサービス側が管理しています。編集できる範囲はサービスやプランによって異なり(2026年10月現在)、シリアル番号を利用者が気にする必要がない仕組みのものもあります。編集できる場合でも、変更が多いのはネガティブキャッシュTTLの調整です。サービスの管理画面やドキュメントで編集可否を確認し、編集できない値は無理に変えようとせず、サポートに問い合わせるのが早道です。
まとめ
dig +nssearchで全権威サーバーのシリアル番号を比べると、更新漏れや転送失敗がすぐに分かる- 編集したらシリアル番号を増やす。巻き戻した場合はセカンダリでの強制転送か、シリアル番号算術に沿った2段階の手順で戻す
- MNAME・RNAMEの末尾ドットと、RNAMEの
@の書き方を確認する - ネガティブキャッシュTTL(MINIMUM)が長いと「追加したのに引けない」状態が続く。短くしても既存のキャッシュは残る
- 反映前に
named-checkzone、反映後にrndc zonestatusと+nssearchで確認する