要約

  • ZONEMD は SOA シリアルを、glue や occluded data を含むゾーン全体の正規化ダイジェストに結び付ける。転送が成功し、版番号が正しく見えるコピーでも、公開者が確定した内容と違えば検出できる。
  • DNSSEC と組み合わせればダイジェストの出所と改変を検証できるが、ポリシーの正しさや全拠点での読み込み完了までは証明しない。検証、隔離、既知の正常版への復帰、実応答の観測を一つの証拠鎖にする必要がある。

夜間の更新作業で、すべてのチェックが順調に見えた。AXFR は正常終了した。受信側はファイルを保存し、パーサーはエラーを返さなかった。SOA シリアルはリリース票に記載された値と同じだった。ところが、ある委任で必要な glue RR が一件だけ失われていた。

そのコピーは「壊れたファイル」ではない。DNS の構文として読み込めるし、シリアルも新しい。それでも、その glue に依存する名前解決は失敗し得る。監視がシリアルだけを比較していれば、異常なノードほど「最新」と表示される。

RFC 8976 が定義する ZONEMD は、ここに別の判定軸を置く。ゾーン apex の ZONEMD RR は、保存状態にあるゾーンデータ全体のメッセージダイジェストを運ぶ。受信側が同じ正規化手順で値を再計算し、公開値と比較する。シリアルが一致しても、一つの対象 RR が欠ければダイジェストは一致しない。

SOA が示す「新しさ」と、内容の同一性は別である

RFC 1035 の SOA Serial は、複製されたゾーンが更新の要否を判断するための番号である。RFC 1982 は、32 ビットの値が最大値を越えてゼロへ戻る場合を含め、有限空間での比較規則を与えた。これは中央の時計を使わずに版の順序を決める仕組みである。

Serial は全 RR から算出された識別子ではない。同じ番号の下で二つのビルド経路が異なる内容を出力することも、転送後の保存や復元で内容だけが変わることもある。SOA が残っていれば、そのコピーは期待された版に見える。

ZONEMD の RDATA にも Serial が入るのは、ダイジェストを特定のゾーン版へ明示的に結び付けるためである。残るフィールドは Scheme、Hash Algorithm、Digest である。SOA は「公開者がどの版と呼んだか」を示し、ZONEMD は「その版として公開者が確定した正規化済み全内容」を示す。どちらか一方を他方の代用にしてはならない。

この境界は転送方式とも異なる。RFC 1995 の IXFR は差分を送り、RFC 5936 の AXFR は完全なゾーンを転送する。いずれも候補コピーを届ける手段であり、後にリポジトリ、ファイル、再起動、復元、ローダーを通過したオブジェクトが公開時と同じであることを継続的に証明するものではない。

SIMPLE が揃えるのは表記ではなく DNS の意味である

ZONEMD は RR type 63 である。RFC 8976 が標準化した Scheme 1 の SIMPLE は実装必須である。Hash Algorithm 1 の SHA-384 も実装必須で、48 オクテットすべてを公開する。Algorithm 2 の SHA-512 は実装が推奨され、64 オクテットを省略しない。現在の割り当ては IANA DNS Parameters に記録されている。

SIMPLE はマスターファイルの文字列をそのままハッシュしない。コメント、空白、大文字小文字が違っても、表現する DNS データが同じなら同じ結果になる必要がある。そこで RR を圧縮なしの canonical wire format に変換し、RFC 4034 の順序に従って並べる。同じ owner name の RRset は RR TYPE の数値でも昇順にする。

対象範囲が重要である。ゾーン内の RR は、明示された例外を除いてすべて含まれる。glue も occluded data も含まれる。owner、class、type、RDATA が同じ重複 RR は一度だけ数える。ゾーン外のデータは含まない。DNSSEC 署名済みゾーンでは DNSSEC RR も対象になるが、apex の ZONEMD placeholder と、最終 ZONEMD RRset を覆う RRSIG は自己参照を避けるため除外する。

この全体性は DNSSEC と競合しない。DNSSEC は主として RRset と、応答検証に必要な存在・不存在の証拠を認証する。委任側の NS や glue など、完全なゾーン成果物として重要なデータがすべて child の通常の署名済み authoritative RRset と同じ形で守られるわけではない。ZONEMD は、完全なゾーンを受け取るサーバーやリポジトリのために、別の粒度で内容を拘束する。

代償は再計算である。SIMPLE では一件の RR 変更でもゾーン全体を走査する。RFC 8976 は、小規模または安定したゾーンには向くが、大規模または更新頻度の高いゾーンでは非現実的になり得るとする。導入判断では、ダイジェスト計算と検証の時間が更新間隔と伝播時間に対して十分小さいかを実測しなければならない。

署名済みゾーンでは生成順序もコミットメントの一部になる

DNSSEC 署名を終えた後に ZONEMD を追加すると、apex の NSEC/NSEC3 type bitmap が変わる。そこで既存の apex ZONEMD とその署名をまず削除し、DNSSEC 署名前に placeholder を挿入する。これにより、不存在証明は ZONEMD type の存在を最初から反映できる。

その後に署名を行い、正規化された RR 列から SIMPLE digest を算出する。placeholder 自体と、後で ZONEMD RRset を覆う RRSIG は計算対象外である。最終値を入れた後、その RRset の署名を作成または更新する。

さらに、ZONEMD の署名生成によって SOA Serial をもう一度進めてはならない。対応する SOA と ZONEMD は同時に公開する必要がある。コミットメントを認証する操作が対象版を変更すれば、生成した瞬間に参照先がずれるからである。

したがって、証拠として十六進文字列だけを残すのは不十分である。source snapshot、承認済みポリシー、ビルダーと署名器のリリース、Serial、Scheme、Algorithm、Digest、DNSSEC 鍵の文脈、最終公開時刻を結び付ける。そうして初めて、差異がソース、ビルド、署名、配布のどこで生まれたかを後から再生できる。

検証は「何が存在するはずか」を決めるところから始まる

受信した ZONEMD をすぐ比較するだけでは、攻撃耐性を判断できない。検証者はローカルの trust anchor と、必要なら親ゾーンの検証済み DS を使い、そのゾーンに DNSSEC が期待されるかを先に決める。基礎となる検証規則は RFC 4035 にある。

署名を期待するゾーンでは、ZONEMD RRset の存在、SOA の署名、ZONEMD の署名を検証する。DNSSEC が ZONEMD の不存在を証明した場合はダイジェスト検証を実施できない。存在するはずなのに受信ゾーンから欠けている場合、成功とは扱えない。署名検証に失敗したものを、ローカル digest が一致したという理由で checksum へ黙って格下げしてはならない。

次に構造を確認する。複数の ZONEMD RR がある場合、Scheme と Hash Algorithm の組は一意でなければならない。ローカルポリシーに反する組は無視できる。受け入れる候補ごとに、SOA と ZONEMD の Serial が完全一致し、Scheme と Algorithm が実装され、Digest 長が正しく、再計算値が受信値と一致することを確かめる。

アルゴリズム移行中は、許可された対応済みの一組が一致すれば検証は成功できる。しかし、複数を受け入れる期間の安全性は最も弱い許可アルゴリズムに制約される。移行計画には追加手順だけでなく、旧方式を削除する期限と条件が必要である。

結果には理由を伴わせるべきである。期待した ZONEMD の欠落、DNSSEC chain の不成立、Serial 不一致、組の重複、非対応方式、長さ不正、内容 mismatch は、それぞれ担当者も安全な対応も違う。一つの赤ランプにまとめれば、再試行、隔離、ロールバック、エスカレーションを選ぶ根拠が消える。

DNSSEC がなければ、攻撃者はダイジェストも作り直せる

未署名ゾーンでも ZONEMD は、転送の切断、保存媒体の破損、意図しない欠落を検出する checksum として役立つ。ただし、ゾーンを悪意を持って変更できる者は、新しい内容に合わせて Digest も再計算できる。RFC 8976 が未署名利用を実質的な攻撃対策と呼ばないのはこのためである。

DNSSEC を併用すると、SOA と ZONEMD を trust anchor まで認証し、コミットメントの削除や改変を検出できる。それでも証明するのは、認証された公開者がその内容を確定したという事実だけである。正規の公開者が誤った委任を承認すれば、暗号的には完全に正しい ZONEMD を作れる。ダイジェストは所有権、変更要求の妥当性、アプリケーションの安全性を判定しない。

転送経路の認証も別の証拠である。RFC 8945 の TSIG は共有秘密を使い、AXFR/IXFR などの DNS transaction の相手と完全性を守る。しかし、転送後にファイルがコピー、復元、再ロードされる間、古い transaction MAC がゾーン全体へ付随し続けるわけではない。ZONEMD は経路終了後もオブジェクト自体を再検証できるようにする。

署名済みの証拠にも時間境界がある。親の DS が撤去されたり trust anchor が変わったりすると、ZONEMD の RRSIG が期間内に見えても、過去の chain を再検証できない場合がある。長期保存する activation receipt には、その時点の信頼文脈も含める必要がある。

誤ったゾーンを拒否することは、サービスを拒否することにもなる

候補ゾーンを staging で検証し、不一致ならロードしない。これは ZONEMD の最も直接的な利益であり、破損コピーが authoritative state へ昇格するのを防ぐ。

同時に、新しい可用性依存を作る。公開ミス、canonicalization の実装差、単一 RR の欠落は、検証時点では意図的改ざんと区別しにくい。厳格な拒否は正しい RR まで含むゾーン全体を使えなくする。複数プロバイダーが異なる対応をすれば、利用者は場所によって異なる generation を見る。

RFC 8976 はこの脆弱性を明記し、最初は warning、経験を得た後に error とする段階導入を示す。ICANN RZERC003 も、root zone への導入を Root Zone Maintainer、root server operator、実装者、ローカルコピー利用者の協調事項として扱った。root の判断をそのまま他ゾーンへ移すのではなく、強制化が複数の障害領域を変えるという点を学ぶべきである。

運用状態は少なくとも三つに分ける。検証済み候補は activation eligible になる。不一致候補は quarantine し、既に検証済みの旧 generation を期限付きで継続する。信頼 chain 障害など、内容差か判断できない場合は、権限を持つ担当者が fail-open または fail-closed を期限付きで選ぶ。

旧版継続にも限界がある。既知の完全性は保てるが、変更が積み重なるほど stale になる。refresh、expire、更新頻度、影響範囲に基づき staleness budget を決める。ロールバックは、旧オブジェクトの保存、再検証、再ロード、実応答での確認までを事前に試験しておく。

ステージングの成功を、配信の証明と呼ばない

権威 DNS は複数事業者と多数の anycast 拠点へ分散できる。RFC 8901 が扱う multi-provider 環境では、一台の検証成功は全体のロード完了を意味しない。reload API の成功も、プロセスがその版を応答している証明ではない。一つの観測地点から得た SOA は、別の catchment を覆わない。

activation receipt は五つの境界を連結する。公開側では source、Serial、署名済み Digest。転送・保管側では保存物の識別子、size、local hash、custody event。検証側では期待 DNSSEC 状態、trust anchor、許可方式、計算値、理由。activation 側では新旧 generation、承認または隔離、ロード結果。runtime 側では SOA、ZONEMD、対象 RR の実応答である。

canary を SOA だけにすると、最初の盲点を再現する。委任に敏感な名前、選定した glue、署名 RRset、negative answer を含め、応答した authoritative identity と観測ネットワークを残す。RFC 8806 に基づく hyperlocal root なら、公開 root fleet の状態ではなく、ローカルコピーと refresh path 自身の証拠が必要である。

復旧完了には負の証拠も要る。拒否した Digest と generation が staging eligibility、稼働プロセス、サンプル応答から消えたことを確認する。正しい版が一部で見えた事実だけでは、取り残されたノードが誤った版を配信していないとは言えない。

情報源