ネームサーバーの移行は、どの管理画面でも正常に完了したように見えるのに、ウェブサイトにはアクセスできないことがあります。ドメインは有効で、新しい権威ネームサーバーは想定どおりのIPアドレスを返し、ウェブサーバーの設定も変わっていません。それでも、DNSSEC検証を行うDNSリゾルバーはSERVFAILを返します。原因としてよくあるのは、以前のDNS事業者の署名鍵を信頼するDNSSEC委任情報が残っていることです。
今回調査した障害では、通常のDNS問い合わせは失敗しましたが、DNSSEC検証を回避すると同じ問い合わせが成功しました。親ゾーンには古いDSレコードが残っていた一方、新しい権威DNSゾーンは当初署名されていませんでした。新しいゾーンに対応する鍵を公開して署名したところ、検証に使用したリゾルバーでは正常な応答が復旧しました。ここから得られる重要な教訓は、DNSSECを無効にすべきだということではありません。ネームサーバーの移行とDNSSECの信頼の連鎖の移行は、別々の作業だということです。
Aレコードが正しくてもSERVFAILになる理由
DNSは、異なる二つの問題を扱います。Aレコードは、名前に対応するIPv4アドレスを示します。一方、DNSSECは、検証を行うリゾルバーがそのDNS応答を信頼できるかどうかを判断する仕組みです。アドレス情報が正しいからといって、DNSSECの信頼の連鎖まで正しいとは限りません。
DNSSECで署名されたドメインでは、信頼の連鎖は信頼済みの親ゾーンからDS(Delegation Signer)レコードを経由し、子ゾーンのDNSKEYへとつながります。子ゾーンはDNSデータに対する署名(RRSIGレコード)を公開します。DSレコードには、認証されたDNSKEYを識別するダイジェストが含まれます。DSはAレコードでも、秘密鍵のコピーでも、一般的なゾーンファイル編集画面内の単なる設定項目でもありません。
権威ネームサーバーを変更した後も、親ゾーンが以前の署名鍵に対応するDSレコードを公開し続けることがあります。新しいゾーンに対応するDNSKEYと署名がなければ、検証リゾルバーは信頼の連鎖を完成できません。通常、この応答を不正と判定し、検証されていないアドレスを返す代わりにSERVFAILを返します。
これはHTTPの障害とは異なります。リクエストがウェブサーバーに到達する前に失敗している可能性があるためです。また、TLS証明書の有効期限切れとも別の問題です。DNSSECが検証するのはDNSデータであり、HTTPSが保護するのは、その後に確立されるブラウザーとサーバー間の通信です。
DNSSECの問題とレコードの欠落を切り分ける診断方法
最も有効な診断は、同じリゾルバーに対して同じ名前を二度問い合わせることです。まず通常の問い合わせを実行し、応答内容だけでなくステータスも確認します。
dig example.com A +noall +comments +answer
次に、DNSSEC Checking Disabled(CD)ビットをセットして同じ問い合わせを繰り返します。
dig example.com A +cdflag +noall +comments +answer
今回観測された障害では、通常の問い合わせはSERVFAILを返しましたが、CDビットを指定した問い合わせでは期待どおりのAレコードが返りました。この違いから、DNSレコードの欠落やアプリケーションの応答停止ではなく、DNSSEC検証に問題がある可能性が強く示されました。+cdflagオプションは、この機能に対応する再帰リゾルバーに、その問い合わせについて通常のDNSSEC検証を行わないよう要求するものです。これは診断用の手段であり、ブラウザー側で問題を修復したり、訪問者全体のDNSSECを無効にしたりする方法ではありません。
+shortを指定した結果が空だったからといって、それだけで結論を出さないでください。この表示形式では、該当レコードが存在しない場合も、SERVFAILが発生した場合も、何も表示されないことがあります。診断中は+commentsを残し、status: SERVFAILとstatus: NOERRORを区別できるようにします。
CDビットを使った比較だけでは、DNSSECのどの部分で失敗したのかまでは特定できません。調査すべき方向を示す診断です。リゾルバーで一時的な上流側の障害が発生している可能性もあるため、必要に応じてテストを繰り返し、親ゾーンの委任情報を確認します。
DNS管理画面だけでなく親ゾーンのDSレコードを確認する
まず、ドメインのDSレコードを確認します。
dig example.com DS +noall +comments +answer
DNSの委任経路をより詳しく調べるには、DNS階層を直接たどって問い合わせます。
dig +trace example.com DS
問い合わせ先となる親ゾーンの権威ネームサーバーは、トップレベルドメインによって異なります。重要なのは、DNSホスティングの管理画面に表示される概要ではなく、親ゾーンが実際に公開しているDSレコードセット(DS RRset)です。レジストラを移管してもネームサーバーが変わらない場合があり、逆にレジストラを変更せずにネームサーバーだけを変更することもできます。いずれの場合も、親ゾーンのDSレコードは現在有効な権威DNSゾーンと整合していなければなりません。
DSレコードには、鍵タグ、アルゴリズム、ダイジェスト種別、ダイジェストという四つの重要なフィールドがあります。鍵タグは調査時の識別に便利ですが、同じ鍵タグがあることだけではDNSKEYの一致を証明できません。ダイジェストとアルゴリズムの情報も、権威ゾーンが実際に提供している鍵に対応している必要があります。
今回の事例で決定的だったのは、親ゾーンが以前のDNSSEC信頼情報を引き続き公開していた一方で、移行先の権威DNSゾーンでは署名機能が無効と表示されていたことです。Aレコード自体は存在し、検証を回避すれば取得できました。アプリケーション設定を変更したり、同じAレコードを何度も編集したりしても、この不整合は解消しません。
壊れたDNSSEC委任を復旧する二つの方法
復旧には、正当な方法が二つあります。どちらも信頼の連鎖の不整合を解決しますが、運用上の影響は異なります。どちらかを意図的に選び、手当たり次第に切り替えることは避けてください。
方法1:古いDSを削除し、一時的に署名なしで運用する
現在のレジストラ、またはレジストラが提供するDNSSEC管理機能を通じて、親ゾーンから古いDSレコードを削除します。親ゾーンが安全な委任を要求しなくなれば、検証リゾルバーは署名のない子ゾーンを不正なものではなく、DNSSECで保護されていないゾーンとして扱えるようになります。DNSの名前解決は引き続き機能しますが、そのドメインのDNSSEC認証は一時的に失われます。
親ゾーンのDSレコードセットを確実に変更できるのであれば、緊急時にはこの方法が比較的簡単なことが多いでしょう。古いDSが再帰リゾルバーのキャッシュから期限切れになるまでは、既存の署名設定を安定した状態に保ってください。管理画面からDSを削除したという表示だけでは、変更が反映された証拠にはなりません。外部から親ゾーンのレコードを確認し、TTLによるキャッシュの残存時間も考慮します。HTTPSの動作はDNSSECの設定とは独立しています。この一時的な署名なし状態への移行については、RFC 8078でも説明されています。
方法2:新しいゾーンに署名し、対応するDSを公開する
もう一つの方法は、新しい権威DNS事業者でDNSSECを有効にし、DNSKEYの鍵情報を生成してゾーンに署名し、対応するDSレコードを親ゾーンに公開することです。これにより、検証リゾルバーは新しいDNSKEYまでの信頼できる経路を構築し、Aレコードを検証できるようになります。
実際に観測された復旧では、この方法が使われました。DNS管理画面には、鍵が生成され、ゾーンに署名が行われ、新しいDSが公開されたと表示されました。その後、親ゾーンへの問い合わせで、以前のDSに加えて新しいDSも存在することが確認できました。検証を行う再帰リゾルバーが期待どおりのAレコードを返すようになり、さらに後のテストではadフラグ付きのNOERRORも返りました。これは、そのリゾルバーがデータを認証済みと判定したことを示します。
作業の順序は重要です。DSを公開しても、それに対応するDNSKEYと有効な署名が権威DNSサービスからすでに取得できる状態でなければ意味がありません。管理画面に「公開済み」と表示されても、外部からの検証を省略してよいわけではありません。キャッシュに残ったDS、DNSKEY、RRSIG、NSレコードの影響で、リゾルバーごとに復旧のタイミングが異なる場合があります。
DSレコードが二つあっても復旧できた理由
意外だったのは、親ゾーンに古いDSと新しい有効なDSが一時的に共存していたにもかかわらず、DNSSEC検証に成功したことです。これは矛盾ではありません。DSレコードセットには複数のレコードを含めることができ、鍵の切り替え時にはよく見られます。検証リゾルバーは、すべてのDSレコードが現在使用可能な鍵を指していることまでは要求しません。適用可能なDSのいずれかを通じてDNSKEYと有効な署名につながる、正しい認証経路が一つあればよいのです。RFC 6840では、検証リゾルバーが一つの有効な経路を受け入れるべきであることが明確にされています。
だからといって、古い鍵をいつまでも残してよいわけではありません。不要になったDSは運用上の混乱を増やすため、新しい信頼の連鎖を検証できた段階で、最終的には削除すべきです。ただし、すでに検証付きの名前解決が成功している状況で、再び危険なDNSSECの初期化を行う理由にはなりません。古いDSの削除は保守作業として扱うべきです。
ここには、特に危険な管理画面の落とし穴があります。「emergency unpublish DS」という操作は、古いDSだけでなく、正常に機能している新しいDSも含めて、すべてのDSレコードを削除する意味かもしれません。同様に、DSが公開されたままゾーンの署名を無効にすると、直ちに同じ障害を再発させる可能性があります。どちらの操作も、特定の古いDSレコードだけを削除することとは異なります。管理画面で個別のレコードを指定できない場合は、一括リセットではなく、レジストラが対応する方法で対象を限定して変更してください。
権威ネームサーバーを安全に変更する手順
最も安全な移行手順は、旧DNS事業者と新DNS事業者の間で鍵を連携できるかどうかによって異なります。一時的に署名なしの期間を設ける一般的な移行では、次の順序に従うことで、今回の障害で起きた不整合を避けられます。
- 最初に移行先のゾーンを準備する。必要なA、AAAA、CNAME、MX、TXTなどのレコードをコピーします。委任先を変更する前に、新しい権威ネームサーバーへ直接問い合わせて動作を確認してください。
- 親ゾーンのDNSSEC情報を確認する。DSレコードが存在するか調べ、誰が更新できるかを把握します。自分でDNSSECを有効にした覚えがなくても確認してください。DNSサービスによっては署名を自動的に設定するためです。
- 古い署名付きゾーンが稼働している間に、古いDSを削除する。権威を持つ親ゾーンで変更を確認し、それまでキャッシュされていたDS情報が期限切れになるまで十分に待ちます。待機時間は実際に確認したTTLによって決まり、すべてのケースに共通する固定の分数ではありません。
- ネームサーバーの委任先を変更する。キャッシュされたNS委任情報が旧ネームサーバーを指している可能性がある間は、以前の権威DNSサービスを利用可能な状態に保ちます。親ゾーンのNSレコードのTTLを考慮し、異なるリゾルバーが実際にどのサーバーを参照しているか確認してください。
- DNSSECを再び有効にするか決める。新しいサービスを署名なしで運用するなら、DSを公開しないでください。署名付きで運用するなら、対応するDSを公開する前に、新しいDNSKEYと署名が正しく提供されていることを確認します。古いNS情報がキャッシュに残っている間に新たな検証不整合を起こさないよう、移行のタイミングも調整してください。
- 独立した方法で検証する。親ゾーンのDS、権威DNSのDNSKEY、通常の再帰DNS名前解決、検証リゾルバーによる認証済み応答を確認します。
DNSSECによる保護を途切れさせたくない場合は、一時的に署名なしにする方法よりも、明示的に調整された鍵ロールオーバーやマルチサイナー方式での移行が適しています。ただし、これには双方のDNS事業者が必要な鍵と署名の仕組みに対応している必要があります。古いDSのダイジェストを新しい事業者に単純にコピーしても、鍵のロールオーバーにはなりません。
移行後に確認するための簡単なチェックリスト
DNSSECに関する変更を行った後は、DNSレコードそのものと、それをリゾルバーが正しく検証できるかの両方を確認してください。
dig example.com DS +noall +comments +answer
dig example.com DNSKEY +dnssec +noall +comments +answer
dig example.com A +dnssec +noall +comments +answer
dig example.com A +cdflag +noall +comments +answer
認証済み応答を確認する際は、DNSSEC検証を行う再帰リゾルバーを使用します。その応答にNOERRORと期待どおりのAレコードがあれば、名前解決には成功しています。さらにadフラグがあれば、そのリゾルバーが自身のDNSSECポリシーに従って応答を認証したことを示します。ただし、adフラグがないことだけで検証失敗と判断することはできません。リゾルバーの機能、ポリシー、問い合わせ時のフラグによって結果が異なるためです。障害中に検証リゾルバー経由のDNSKEY問い合わせが失敗する場合は、調査の一環として、現在の権威DNSサービスにも直接問い合わせてください。
一つのリゾルバーで正常な応答が得られただけで確認を終えないでください。キャッシュによって、リゾルバーごとに異なる委任情報や鍵が一時的に残っている可能性があります。また、対応中のサポート問い合わせがあれば、その内容も更新してください。新しい有効なDSが公開された後では、以前の「すべてのDSレコードを削除する」という指示が危険になります。追加の連絡では、有効な鍵を維持することを明示し、必要であれば古いレコードだけを削除するよう依頼すべきです。
今回の障害は、ウェブサーバーのIPアドレスが間違っていたことが原因ではありません。DNS応答を提供する場所を変更したにもかかわらず、どの応答を信頼すべきかをリゾルバーに伝える情報が適切に移行されていなかったことが原因です。したがって、ネームサーバーを切り替える前に確認すべき実務上の重要な問いは、次のとおりです。親ゾーンはどのDSレコードを公開しており、移行先のDNSKEYと署名はそれらを使った検証を満たせるのか?