2026年6月13日
2026年6月13日
DNSKEYレコードの競合を解消する方法|ネームサーバーごとに鍵が違う・古い鍵が残る・DSと合わないときの整理手順
DNSKEYレコードの「競合」は、同じゾーンの鍵の情報が、ネームサーバーごと、または親ゾーンのDSレコードとの間で食い違っている状態です。DNSSECを検証するキャッシュDNSは、この食い違いに当たると名前解決に失敗(SERVFAIL)するため、一部の利用者だけサイトが開かない、時々メールが届かない、といった分かりにくい症状になります。解消の基本は、ゾーンに署名する主体を1つに決め、すべてのネームサーバーが同じDNSKEYを返し、DSがその中の鍵を指す状態に戻すことです。この記事では、食い違いの見つけ方と、原因ごとの直し方を説明します。
DNSKEYの競合が起きる典型的な場面
DNSSECでは、ゾーンの公開鍵をDNSKEYレコードとして公開し、その中の鍵(通常はKSK)のハッシュを親ゾーンにDSレコードとして登録します。キャッシュDNSは、DSからDNSKEYへ、DNSKEYから各レコードの署名(RRSIG)へと信頼をたどります。
この鎖が崩れる典型的な場面は次のとおりです。
- 署名する主体が2つある:DNSサービスの自動署名を有効にしたまま、自前のBINDでも署名したゾーンを配っている。あるいは、2つのDNSサービスを併用し、それぞれが自分の鍵で署名している。
- DNSサービスを移した:移行先で新しい鍵が作られたのに、親ゾーンのDSは移行元の鍵のまま残っている。
- 鍵の交換(ロールオーバー)の途中で止まった:新しい鍵に切り替えたのに古いDSが残っている、または古い鍵を早く消しすぎた。
- セカンダリDNSの扱いが合っていない:プライマリで署名したゾーンをそのまま転送すべきところで、セカンダリ側が独自に署名し直している。
手順1:ネームサーバーごとのDNSKEYを比べる
最初に、すべての権威サーバーが同じDNSKEYを返しているかを確かめます。+multi を付けると、鍵ごとに鍵の識別番号(key id、key tag)と種類が表示されます。
# ゾーンのネームサーバー一覧
dig example.com NS +short
# ネームサーバーごとにDNSKEYを取得し、key id を並べる
for ns in $(dig example.com NS +short); do
echo "== $ns"
dig @"$ns" example.com DNSKEY +norecurse +multi +noall +answer | grep -E 'key id'
done
出力の各行には、鍵の種類(KSKまたはZSK)、アルゴリズム、key id が出ます。比べるのは次の点です。
- ネームサーバーによって key id の組み合わせが違う:署名する主体が複数ある、または同期が遅れています。
- アルゴリズムが混ざっている:移行やアルゴリズム変更の途中で、古い方式の鍵が残っている可能性があります。
- 鍵の数が想定より多い:ロールオーバーの途中か、古い鍵の削除忘れです。ロールオーバー中は新旧の鍵が並ぶのが正常なので、作業中かどうかを先に確かめます。
手順2:親ゾーンのDSと照らし合わせる
次に、親ゾーンに登録されているDSが、手順1のどの鍵を指しているかを確かめます。
# 親ゾーンのDS(値の部分は key tag・アルゴリズム・ダイジェストの種類・ダイジェストの順)
dig example.com DS +noall +answer
# 公開中のDNSKEYから計算したDS(BINDの dnssec-dsfromkey を使う例)
dig example.com DNSKEY +noall +answer | dnssec-dsfromkey -f - example.com
DSの行は key tag アルゴリズム番号 ダイジェストの種類 ダイジェスト の順に並んでいます。親ゾーンのDSの key tag が、手順1で全ネームサーバーが返したKSKの key id と一致していれば、鎖はつながっています。dnssec-dsfromkey の出力形式や既定のダイジェストはBINDのバージョンによって違うことがあるため、ダイジェストの種類をそろえて比べます。
どのネームサーバーにも無い鍵をDSが指していると、ゾーン全体が検証に失敗します。一部のネームサーバーにだけ鍵がある場合は、そのネームサーバーに問い合わせたときだけ成功するため、症状が出たり消えたりします。
手順3:検証結果を外から確かめる
食い違いが利用者からどう見えているかを、検証するキャッシュDNSで確かめます。
# 検証付きで問い合わせ。status: SERVFAIL なら検証失敗の可能性
dig @8.8.8.8 example.com A +dnssec
# 検証を止めると答えが返るなら、原因はDNSSEC
dig @8.8.8.8 example.com A +cd +short
# 検証の過程を表示(BIND付属の delv)
delv @8.8.8.8 example.com A
DNSViz のような可視化サービスを使うと、ネームサーバーごとの鍵とDSの対応が図で示され、どこで鎖が切れているかを把握しやすくなります。表示の形式はサービス側で変わることがあります(2026年10月現在)。
原因1:署名する主体が2つある
DNSサービスの自動署名と自前の署名が並んでいる、または2つのDNSサービスがそれぞれ署名している場合は、どちらか1つに決めます。
- 署名を続ける側(残す側)を決める
- 残す側の鍵を指すDSだけが親ゾーンにあることを確かめる。無ければ追加する
- もう一方の署名を止める。DNSサービスなら管理画面でDNSSECを無効にし、自前のBINDなら自動署名の設定を外す
- 止めた側のネームサーバーをNSから外すか、残す側からのゾーン転送で同じ署名済みデータを配る構成に変える
- 止めた側の鍵を指すDSが親ゾーンに残っていれば削除する
2つのDNSサービスで署名したまま併用する方法(マルチサイナー、RFC 8901)もありますが、両方のサービスが互いの鍵を公開する仕組みに対応している必要があります。対応状況はサービスによって違うため、各サービスの案内を確かめてから検討してください。
原因2:DNSサービスを移したあと、DSが古いまま
移行先で新しい鍵が作られているのに、レジストラに登録したDSが移行元の鍵のままだと、移行先のネームサーバーに切り替わった時点で検証に失敗します。
すでに失敗が起きているときの応急の対処は、レジストラの管理画面で古いDSを削除するか、移行先の鍵のDSに差し替えることです。DSのTTLが切れるまでは古いDSがキャッシュに残るため、すぐには直りません。
これから移行する場合は、次のいずれかの順序で進めると停止を避けやすくなります。
- 移行前にDSを削除し、DSのTTLとDNSKEYのTTLが切れるのを待ってから、ネームサーバーを切り替える。移行先で署名を始めたら、新しいDSを登録する
- 両方のサービスがマルチサイナーに対応しているなら、その手順に従う
原因3:ロールオーバーが途中で止まった
鍵の交換では、新しい鍵をDNSKEYに追加し、キャッシュに行き渡るのを待ってから使い始め、古い鍵を消す、という順序と待ち時間が必要です。KSKの交換では、さらに親ゾーンのDSの差し替えが入ります。
- 新しいKSKに切り替えたのに古いDSしか無い:新しい鍵のDSを登録し、DSのTTLを待ってから古いKSKを消します。
- 古い鍵を早く消しすぎた:キャッシュに古いDNSKEYや署名が残っている間は失敗が続くことがあります。古い鍵を一時的に戻せるなら戻し、TTLを待ってから改めて手順を進めます。
BINDの dnssec-policy のような自動の鍵管理を使っている場合は、手作業で鍵ファイルを消すと管理状態と食い違います。鍵の状態の確認や操作は、使っている仕組みの手順で行います。
原因4:セカンダリDNSが署名し直している
プライマリで署名したゾーンをセカンダリへ転送する構成では、セカンダリは受け取った署名済みデータをそのまま配るのが基本です。セカンダリ側でも署名が有効になっていると、別の鍵が混ざります。セカンダリの設定で再署名が無効になっているかを確かめ、手順1でプライマリと同じ key id が返ることを確認します。
作業前の準備と確認
DNSSECの変更は、失敗するとゾーン全体が引けなくなります。作業の前に、現在のDNSKEYとDSの出力を保存し、自前で署名している場合は鍵ファイルと設定をバックアップしておきます。作業後は、手順1〜3をもう一度行い、すべてのネームサーバーが同じDNSKEYを返し、DSがその中のKSKを指し、検証付きの問い合わせが成功することを確かめます。
まとめ
- DNSKEYの競合は、ネームサーバー間、またはDNSKEYとDSの間で鍵の情報が食い違っている状態です。
dig +multiで各ネームサーバーの key id を並べ、親ゾーンのDSの key tag と照らし合わせると、食い違いの場所が分かります。- 署名する主体を1つに決め、すべてのネームサーバーが同じ署名済みデータを配る状態に戻します。
- DNSサービスの移行や鍵の交換では、DSとDNSKEYのTTLを待つ順序を守ります。
- 作業前に現在の状態を保存し、作業後に検証付きの問い合わせで確かめます。