0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

bind9でKASPのおと

Last updated at Posted at 2025-01-11

はじめに

bind9では、全自動ゾーン署名という機能がサポートされています。このドキュメントでは、その仕組みについて、少し紐解いています。

9.16からは、DNSSEC Key and Signing Policy(KASP)という機能がサポートされるようになりました。これは全自動ゾーン署名を置き換える仕組みで全自動ゾーン署名の機能を利用しつつ、キーの管理をbind9が行うというものです。全自動ゾーン署名を包括しているため、9.20からはKASPのみサポートされ全自動ゾーン署名固有の設定は使用できなくなります。

KASPは全自動ゾーン署名に対して以下ような機能が追加されます。

  1. キーの追加 new
  2. ゾーンの自動署名 流用
  3. キーの切り替え(新規キーの追加とロールオーバー) new
  4. ゾーンからキーの削除 流用+ゾーンの削除など状態管理 new
  5. キーの削除 new

これらの機能に対する設定は、個別に設定する方式からPolicyという一括に設定を定義した名前をゾーンで使用宣言するという方式に変更となりました。ただし全自動ゾーン署名を流用している部分では、既存の設定が残っている部分もあります。

Policy

Policyには、KSKキーにはどのタイプの暗号化方式を使うかやロールオーバーを月一回行うなど、キー関連の設定を定義します。Policyは複数持つことができ、ゾーンを定義する際、どのPolicyを使用するかを宣言します。

小規模組織の場合は、1 Policy 1ゾーンになると思いますがDNS事業者などでは、1 Policy 複数ゾーンの設定になるパターンもあると思います。おそらく、こういったケースの煩雑さを解消するためPolicyのような仕組みが導入されたのだと思います。

Policyは初期値としてdefaultが定義されています。定義内容を以下に記載します。

dnssec-policy "default" {
    keys {
         csk key-directory lifetime unlimited algorithm ecdsa256;
    };

    // Key timings (キーの切り替えなどの使用するパラメタ)
    dnskey-ttl PT1H;
    publish-safety PT1H;
    retire-safety PT1H;
    purge-keys P90D;

    // Signature timings (署名に関連のパラメタ。全自動ゾーン署名の置き換え)
    signatures-refresh P5D;
    signatures-validity P14D;
    signatures-validity-dnskey P14D;

    // Zone parameters (ゾーンに依存するパラメタ。使われた方はKey timingsと同じ)
    max-zone-ttl P1D;
    zone-propagation-delay PT5M;
    parent-ds-ttl P1D;
    parent-propagation-delay PT1H;
};

各パラメタの値の設定方法は、ISO 8601の継続時間の記述となっています。先頭のPは期間を示し、その後に間隔を定義します。P90Dは90日、PT1Hは1時間を定義しています。時間に関してだけ間隔の前にTをつけます。

Policyのうち、Key timingsとZone parametersは鍵やゾーン署名を有効にする際の余裕値(安全のため追加する時間)などとして使用されます。これについては、動きがわからないと説明しずらいので後述します。Signature timingsは全自動ゾーン署名のsig-validity-intervalやre-signなどの置き換えです。sig-signing-signaturesは、Policyでは置き換えられておらず、従来のパラメタが使用されます。

keysには、KSKやZSKの暗号アルゴリズムとロールオーバーサイクルなどを定義します。defaultの定義にあるcskはKSKとZSKを一つのキーで管理する方法でbind9のデフォルト(今後の推し)です(Combined Signing Key)。ZSKは問題ないのですが、KSKに関しては上位組織との関係があるので最後の方で再度話題にします。とりあえず最初の動作確認はCSKで行いますので、KSKとZSKで鍵を個別に作らない程度の認識で読み勧めてください。

状態管理

キーの追加や削除を自動で行うためには、そのキーがどんな状態であるのか管理する必要があります。KASPではそのキーそのものとそのキーが署名している資源レコードの状態を
管理しています。

キーの管理には、ファイルが使用され[キーファイル名].stateというファイルがキーの生成時に同時に作成されます(以降.stateファイル)。.stateファイルにはキーの状態に加え、キーが管理している資源レコードの状態も保存されます。

Kexsample.co.jp.+008+12971.key
Kexsample.co.jp.+008+12971.private
Kexsample.co.jp.+008+12971.state

キーで管理されている資源レコードには以下のような種類があります。

DNSKEYState
DNSKEY資源レコードの状態
ZRRSIGState
DNSKEY資源レコードのZSKでのRRSIGの状態
KRRSIGState
DNSKEY資源レコードのKSKでのRRSIGの状態
DSState
KSKのDSレコードの状態

これらの資源レコードの状態がそれぞれ以下のように遷移します。

RUMOURED(公開直後) -> OMNIPRESENT(各リゾルバーに周知された状態)->UNRETENTIVE(キーが未使用になろうとしている)->HIDDEN(非公開となった)

厳密には図のような状態遷移をします。

状態遷移

通常、公開されたレコードはOMNIPRESENTに遷移しようと動作します。公開され続けている間は、OMNIPRESENTを維持します。レコードが未使用となった場合は、HIDDENに遷移します。

資源レコードの状態遷移の仕組み

資源レコードの状態遷移は時間経過とともに進んでいきます。基本的な状態遷移の仕組みはRFC 7583の定義に従います。KASPは、ほぼこのRFCの説明を実現するための実装と言って良くRFCの動きの多くを実現しています。

状態遷移の動きは、例を参考にしながら把握した方が良いので以降で詳細に説明します。例に使用するPolicyはdefaultを使用します。

ZSKの新規公開

ZSKは上位組織などが絡まず、ローカル環境のみで動作が完結するので状態遷移の動きとして一番把握しやすいので、最初にZSKの動きを説明します。

最初にキー公開の動きを説明しますが、ここで説明した内容はロールオーバー時の切り替え時でも同様なので、キー公開はこの状態遷移すると思ってもらって問題ありません。

ZSKキーの公開は、RFCの3.2 ZSK Rollover Timelinesの3.2.1 Pre-publication Method
で定義された状態遷移で動作します。

ZSKの公開遷移

キーの公開は、図のように遷移するとされます。日本語は私が勝手につけた名前なので分かりにくいと思ったらRFCの方を参照してください。

Tpubは、ZSKを使って初めてゾーンが署名された時間です。今回は新規追加なので、最初にbindを起動した時間が、この時間になります。

IpubはRFCの定義では以下ようになるとされます。

$公開までのインターバル(Ipub) = 伝搬時間(Dprp) + DNSKEYのttl(TTLkey)$

KASPの実装では、Dprpは、Policyのzone-propagation-delayの定義が使用されます。
同様にTTLkeyはdnskey-ttlが使用されます。またRFCに定義がありませんが、KASPではこれに加えてpublish-safetyが加味されます。

$Ipub = zonei$-$propagation$-$delay + dnskey$-$ttl + publish$-$safety$

defalutのPolicyでは以下の値になります。

$Ipub = 5M(300sec) + 1H(3600sec) + 1H(3600sec) = 7500sec$

この様子をbindのログファイルから見てみましょう。named.runファイルを作成するため、bindの起動オプションに"-d 3"を追加します。相変わらずDebianで運用していますので、/etc/default/namedにオプションを追加して起動します。

キーの保存ディレクトリに、キーの公開鍵と秘密鍵と一緒に.stateファイルが作成されます。

Kexsample.co.jp.+013+15926.state
; This is the state of key 15926, for exsample.co.jp.
Algorithm: 13
Length: 256
Lifetime: 0
KSK: yes
ZSK: yes
Generated: 20240507080047 (Tue May  7 17:00:47 2024)
published: 20240507080047 (Tue May  7 17:00:47 2024)
Active: 20240507080047 (Tue May  7 17:00:47 2024)
publishCDS: 20240508090547 (Wed May  8 18:05:47 2024)
DNSKEYChange: 20240507080047 (Tue May  7 17:00:47 2024)
ZRRSIGChange: 20240507080047 (Tue May  7 17:00:47 2024)
KRRSIGChange: 20240507080047 (Tue May  7 17:00:47 2024)
DSChange: 20240507080047 (Tue May  7 17:00:47 2024)
DNSKEYState: rumoured
ZRRSIGState: rumoured
KRRSIGState: rumoured
DSState: hidden
GoalState: omnipresent

ここで注目するのは、DNSKEYChange,ZRRSIGChange,DNSKEYState,ZRRSIGStateです。DNSKEY資源レコードとZSKのRRSIGの状態はともに、RUMOUREDとなっています。状態遷移図の初期状態です。GoalStateは、このキーが最終的にどうなりたかを示しています。公開したのでOMNIPRESENTに遷移しようとしています。

named.runには以下のようなログが出力されています。RUMOUREDからOMNIPRESENTに遷移しようとしてましが、拒否(says no)されたのでwait時間待つというログです。

07-May-2024 17:00:47.760 keymgr: time says no to CSK exsample.co.jp/ECDSAP256SHA256/15926 type DNSKEY state RUMOURED to state OMNIPRESENT (wait 7500 seconds)

07-May-2024 17:00:47.760 keymgr: time says no to CSK exsample.co.jp/ECDSAP256SHA256/15926 type ZRRSIG state RUMOURED to state OMNIPRESENT (wait 90300 seconds)

DNSKEY側の7500secがIpubです。計算式通り時間待ちします。一方、ZZRSIGの90300secは何でしょうか?

RFCには記述がありませんが、実装のコメントには、この値はIretを使うとあります。Iretはリタイア時に使用される時間でRFCにも記述があります。RFCの定義とコメント上、Iretは以下の定義となっています。

$Iret = 次のキーですべて再署名される遅延(Dsgn) + スレーブサーバーへの伝搬時間(Dprp) + ゾーンで定義された最大ttl(TTLsig)$

Dsgnは再署名の待ち時間で、以下の式で計算されます。

$Dsgn = signatures$-$validity - signatures$-$refresh$

この辺りの仕組みは全自動ゾーン署名と同じコードが動いているので、全自動ゾーン署名の再署名の仕組みの把握が必要ですがZSKのロールオーバーの部分で簡単に解説します。

signatures-validityとsignatures-refreshは、defaultのPolicyでは14日と5日と定義されています。この値を加味すると、90300secと合いません。先に述べたようにソース上はIretを使うとありますが実際には以下の式が使用されます。

$Iret(実装上) = スレーブサーバーへの伝搬時間(Dprp) + ゾーンで定義された最大ttl(TTLsig)$

つまり、Iretの定義からDsgnを除いた値が使用されます。上記式をKASPの実装のパラメタに変換すると以下ようになります。

$Iret(実装上) = zone$-$propagation$-$delay + max$-$zone$-$ttl + retire$-$safety$

最後のretire-safetyはKASPでの追加値です。defaultのPolicyの値に変換すると

$Iret(実装上) = 5M(300sec) + 1D(86400) + 1H(3600sec) = 90300sec$

となり、式通りの値が表示されています。

ZZRSIGのIpub相当の時間計算がなぜこのようになっているかコメント含めて説明は見つけることはできませんでしたが、実装は上記の通りです。もしかしたら、将来的にパラメタの追加などを行うつもりなのかもしれません(やめて欲しいですが..)

式だけ見ると、キャッシュサーバーが持っているゾーンの書き換えが終わるのを待ちたいということのような気がします。

Ipub時間たった後の.stateは以下のようになります。このような時間待ちの処理は、全自動ゾーン署名のkey event関連のコードを駆使して実行されます。

Kexsample.co.jp.+013+15926.state
; This is the state of key 15926, for exsample.co.jp.
Algorithm: 13
Length: 256
Lifetime: 0
KSK: yes
ZSK: yes
Generated: 20240507080047 (Tue May  7 17:00:47 2024)
published: 20240507080047 (Tue May  7 17:00:47 2024)
Active: 20240507080047 (Tue May  7 17:00:47 2024)
publishCDS: 20240508090547 (Wed May  8 18:05:47 2024)
DNSKEYChange: 20240507100547 (Tue May  7 19:05:47 2024)
ZRRSIGChange: 20240507080047 (Tue May  7 17:00:47 2024)
KRRSIGChange: 20240507100547 (Tue May  7 19:05:47 2024)
DSChange: 20240507080047 (Tue May  7 17:00:47 2024)
DNSKEYState: omnipresent
ZRRSIGState: rumoured
KRRSIGState: omnipresent
DSState: hidden
GoalState: omnipresent

DNSKEYChangeは状態遷移した時間です。ログを確認すると以下のようになっています。こんどはsays noが出力されず遷移がうまく行ったことが分かります。

07-May-2024 19:05:47.761 keymgr: CSK exsample.co.jp/ECDSAP256SHA256/15926 type DNSKEY in stable state OMNIPRESENT

DNSKEYChangeの値は、RFC上のTrdyです。このタイミングでキーは広く公開されたと判断されOMNIPRESENTにに状態遷移します。一方RFC上はTactは以下のように定義されています。

$Tact >= Trdy$

この部分をサポートする実装はありません。KASP上はTrdyが来た段階で、公開されたと判断します(事実上、$Tact = Trdy$)。

ZRRSIGのIret(実装上) が経ったとは以下の通りです。

Kexsample.co.jp.+013+15926.state
; This is the state of key 15926, for exsample.co.jp.
Algorithm: 13
Length: 256
Lifetime: 0
KSK: yes
ZSK: yes
Generated: 20240507080047 (Tue May  7 17:00:47 2024)
published: 20240507080047 (Tue May  7 17:00:47 2024)
Active: 20240507080047 (Tue May  7 17:00:47 2024)
publishCDS: 20240508090547 (Wed May  8 18:05:47 2024)
DNSKEYChange: 20240507100547 (Tue May  7 19:05:47 2024)
ZRRSIGChange: 20240508090547 (Wed May  8 18:05:47 2024)
KRRSIGChange: 20240507100547 (Tue May  7 19:05:47 2024)
DSChange: 20240508090547 (Wed May  8 18:05:47 2024)
DNSKEYState: omnipresent
ZRRSIGState: omnipresent
KRRSIGState: omnipresent
DSState: rumoured
GoalState: omnipresent

ZRRSIGChange,ZRRSIGStateの値がDNSKEYと同様に更新されています。ログにも同様にOMNIPRESENTに遷移したことが記録されています。

08-May-2024 18:05:47.767 keymgr: transition CSK exsample.co.jp/ECDSAP256SHA256/15926 type ZRRSIG state RUMOURED to state OMNIPRESENT!

KASPの状態遷移としては以上のような動きですが、この状態遷移とゾーンの署名状態は別です。ゾーンの署名状態に関しては、ほぼ全自動ゾーン署名と同じ動きをします。このため各資源レコードの状態がOMNIPRESENTになるまで署名の検証ができないというようなことはなく、起動直後でゾーンへの署名の追加は行われています。

伝搬時間などほぼ考慮する必要のないローカル環境などでは、すぐに署名検証が有効となります。この辺りの実装方法はキーの有効期限管理と署名の有効期限管理と似ていて、それぞれ独立に動作し、署名処理でKASPの計算結果などを参照することはありませんし、逆の参照もありません。

DNSSECの確認コマンドの変更

次の状態遷移を見る前に、KASP導入より変更となるコマンドについて補足します。これまでゾーンの署名で使用されているキーを確認するには以下のコマンドを使用してきました。

# rndc signing -list exsample.jp
Done signing with key 17710/RSASHA256
Done signing with key 35973/RSASHA256
#

KASPに行こうするとこのコマンドは使用できなくなります。代わりにrndc dnssec -statusというコマンドが使えるようになります。起動直後は以下のように表示されます。

# rndc dnssec -status exsample.co.jp
dnssec-policy: default
current time:  Tue May  7 17:01:20 2024

key: 15926 (ECDSAP256SHA256), CSK
  published:      yes - since Tue May  7 17:00:47 2024
  key signing:    yes - since Tue May  7 17:00:47 2024
  zone signing:   yes - since Tue May  7 17:00:47 2024

  No rollover scheduled
  - goal:           omnipresent
  - dnskey:         rumoured
  - ds:             hidden
  - zone rrsig:     rumoured
  - key rrsig:      rumoured
#

使用しているキーと資源レコードの状態が確認できます。このドキュメントでは.stateを直接参照していますが、本運用する場合はこのコマンドで状態を確認した方が良いでしょう。rndcを動く状態にしておけばサーバーにログインする必要がなくなります。

参考にZRRSIGが有効になった段階も示しておきます。

# rndc dnssec -status exsample.co.jp
dnssec-policy: default
current time:  Thu May  9 08:24:31 2024

key: 15926 (ECDSAP256SHA256), CSK
  published:      yes - since Tue May  7 17:00:47 2024
  key signing:    yes - since Tue May  7 17:00:47 2024
  zone signing:   yes - since Tue May  7 17:00:47 2024

  No rollover scheduled
  - goal:           omnipresent
  - dnskey:         omnipresent
  - ds:             rumoured
  - zone rrsig:     omnipresent
  - key rrsig:      omnipresent

#

ちなみに、rndc zonestatusの方は変更はありません。key maintenance:という項目が増えるくらいです。key eventなどのタイミングをKASPから取得ケースが追加となりますが、再署名処理など、それ以外の処理は全自動ゾーン署名と変わりありません。

KSKの新規公開

ZSKと同様にRFC上は3.3. KSK Rollover Timelinesの3.3.1. Double-KSK Methodです。

KSKの公開遷移

TpubなどZSKと共通のキーワードは意味としてはほぼ同じです。KSKではKSK用のキーがセカンダリなどへ確実に転送された状態をTrdyと定義しています。この時間を子ゾーン発行間隔(IpubC)としています。子ゾーン発行間隔(IpubC)の式は以下の通りです。

$子ゾーン発行間隔(IpubC) = 子ゾーン伝搬遅延(DprpC) + DNSKEYのTTL(TTLkey)$

KASPはRFCの定義に従うと説明しましたが、実はKASPの実装にIpubCを使用する部分は存在しません。その代わり、ZSKのIpubが使用されます。KSKの公開の図を記載しましたが、KSKの公開部分では、この図通りの動作はせず、ZSKと同じ動きをします。

この部分についても、なぜ、このような実装になっているのかの説明を見つけることができなかったので、想像の範囲ですが、CSKを使用した場合、一つのキーでZSKとKSKの特性を表現することになります。IpubとIpubCを比較した際、Ipubの方が長いためにこちらが採用されているのではないかと想像しています。いずれにしても、実装はIpubを使用しますので、鍵の公開タイミングはKSKもZSKも同じということになります。

Tsbmは、KSKのDSレコードを上位組織へ提出した時間です。提出方法はメールやなんらかのツールなど様々だと思います。そこから上位組織の事務手続き時間として、Dregを考慮します。

実はKASPの実装ではTsbm、Dregに関する考慮はありません。このためKASPではTdryをTsbmと扱っていることになります。

KSKのDNSKEYに関するログは、先のZSKと同じです。これはCSKだから、こういう風に表示されますがKSKとZSKを分離しても同じ動きになります。

KRRSIGは、KSKを使用したZSKキーの署名ですが、基本的にKSKのDNSKEYが公開されれば署名も公開されると考えるようです。ZRRSIGGと同様に新規キー追加時にKSKのRRSIGは作成されているので、ZRRSIGと違い、素直な動きとなります。以下に該当部分のログを表示します。7500はIpubのことです。

07-May-2024 17:00:47.760 keymgr: time says no to CSK exsample.co.jp/ECDSAP256SHA256/15926 type KRRSIG state RUMOURED to state OMNIPRESENT (wait 7500 seconds)

07-May-2024 19:05:47.761 keymgr: transition CSK exsample.co.jp/ECDSAP256SHA256/15926 type KRRSIG state RUMOURED to state OMNIPRESENT!

KSKのDNSKEY,KRRSIRGの.stateに関しては、ZSKの例で提示済なので、参考にしてください。

ZSK DNSKEY,KSK DNSKEY,KRRSIGの状態遷移はIpub待ち、ZRRSIGはIretの変種の時間待つというのが新規公開時の動作です。

ZSKのロールオーバー

新規公開の状態遷移が分かったので、次にロールオーバーの状態遷移について確認していきましょう。

今の例では、CSKを使用しているのでZSKのロールオーバー=KSKのロールオーバーなのですがKSKはDSレコードなどが絡むので、別途説明します。今のCSKではZSKに注目してロールオーバーの動きを見ていきます。

KASPのZSKロールオーバーは事前公開方式が使用されます。新しい鍵と署名を事前に用意し、古い鍵を削除する方式です。RFCでは以下のように動作するとあります。

ZSKのロールオーバー遷移

現在使用しているPolicyのキーの生存期間はunlimitedとなっているので自働でロールオーバーは発生しません。このためコマンドで手動ロールオーバーを発生させます。以下のコマンドを実行します。この方法はKSKのロールオーバーなどロールオーバータイミングを手動にしたい場合は必ず使用するので、覚えておいた方が良いです。

# rndc dnssec -rollover -key 15926  exsample.co.jp

コマンド実行後のログを抜粋して説明していきます。
以下の時間にコマンドを受診しています。

10-May-2024 14:44:57.991 received control channel command 'dnssec -rollover -key 15926 exsample.co.jp'

受信と同時に現行鍵の状態がUNRETENTIVEに遷移しようとしていますがsays noなので拒否されています。これはRFCのTdeaに至っていないからです。

10-May-2024 14:44:57.995 keymgr: dnssec says no to CSK exsample.co.jp/ECDSAP256SHA256/15926 type DNSKEY state OMNIPRESENT to state UNRETENTIVE
10-May-2024 14:44:57.995 keymgr: dnssec says no to CSK exsample.co.jp/ECDSAP256SHA256/15926 type ZRRSIG state OMNIPRESENT to state UNRETENTIVE

新鍵は受信と同時に生成されています。

10-May-2024 14:44:57.995 keymgr: DNSKEY exsample.co.jp/ECDSAP256SHA256/39789 (CSK) initialize DNSKEY state to HIDDEN (policy default)
10-May-2024 14:44:57.995 keymgr: DNSKEY exsample.co.jp/ECDSAP256SHA256/39789 (CSK) initialize ZRRSIG state to HIDDEN (policy default)

その後、OMNIPRESENTなろうとして時間待ちに入ります。この辺りの動きはZSKの新規公開と同じです。

10-May-2024 14:44:57.995 keymgr: transition CSK exsample.co.jp/ECDSAP256SHA256/39789 type DNSKEY state HIDDEN to state RUMOURED!
10-May-2024 14:44:57.995 keymgr: transition CSK exsample.co.jp/ECDSAP256SHA256/39789 type ZRRSIG state HIDDEN to state RUMOURED!

10-May-2024 14:44:57.995 keymgr: time says no to CSK exsample.co.jp/ECDSAP256SHA256/39789 type DNSKEY state RUMOURED to state OMNIPRESENT (wait 7500 seconds)
10-May-2024 14:44:57.995 keymgr: time says no to CSK exsample.co.jp/ECDSAP256SHA256/39789 type ZRRSIG state RUMOURED to state OMNIPRESENT (wait 867900 seconds)

新しい鍵が追加されたので.steteファイルも2つになります。現行鍵と新鍵の.stateは以下の通りです。

Kexsample.co.jp.+013+15926.state
; This is the state of key 15926, for exsample.co.jp.
Algorithm: 13
Length: 256
Lifetime: 258550
Successor: 39789
KSK: yes
ZSK: yes
Generated: 20240507080047 (Tue May  7 17:00:47 2024)
published: 20240507080047 (Tue May  7 17:00:47 2024)
Active: 20240507080047 (Tue May  7 17:00:47 2024)
Retired: 20240510074957 (Fri May 10 16:49:57 2024)
Removed: 20240520085457 (Mon May 20 17:54:57 2024)
publishCDS: 20240508090547 (Wed May  8 18:05:47 2024)
DNSKEYChange: 20240507100547 (Tue May  7 19:05:47 2024)
ZRRSIGChange: 20240508090547 (Wed May  8 18:05:47 2024)
KRRSIGChange: 20240507100547 (Tue May  7 19:05:47 2024)
DSChange: 20240508090547 (Wed May  8 18:05:47 2024)
DNSKEYState: omnipresent
ZRRSIGState: omnipresent
KRRSIGState: omnipresent
DSState: rumoured
GoalState: hidden
Kexsample.co.jp.+013+39789.state
; This is the state of key 39789, for exsample.co.jp.
Algorithm: 13
Length: 256
Lifetime: 0
Predecessor: 15926
KSK: yes
ZSK: yes
Generated: 20240510054457 (Fri May 10 14:44:57 2024)
published: 20240510054457 (Fri May 10 14:44:57 2024)
Active: 20240510074957 (Fri May 10 16:49:57 2024)
publishCDS: 20240510074957 (Fri May 10 16:49:57 2024)
DNSKEYChange: 20240510054457 (Fri May 10 14:44:57 2024)
ZRRSIGChange: 20240510054457 (Fri May 10 14:44:57 2024)
KRRSIGChange: 20240510054457 (Fri May 10 14:44:57 2024)
DSChange: 20240510054457 (Fri May 10 14:44:57 2024)
DNSKEYState: rumoured
ZRRSIGState: rumoured
KRRSIGState: rumoured
DSState: hidden
GoalState: omnipresent

現行鍵の方はLifeTime,Successor,Retired,Removedが追加されます。LifeTimeは、この鍵が何時間生存するかを示す値で、ちょっと複雑なことをします。

先に示したIretの変種、Iret(実装上) がここでも登場します。この時間がリタイアまでの待ち時間として使用されます。Retiredは、$現在の時刻+Iret(実装上)$ として設定されます。RFC上は$Tret=Tact$ですが、実装上はTretの方が遅れることになります(ZRRSIGに合わせていると思われますが署名に関しては後述)。

default Policyだと90300secがIret(実装上)の時間なので.stateの値になります。Lifetimeは$Retired - Active$を計算して算出されます。現行鍵が有効になってからリタイアするまでの時間を結果として設定します。

この動作は現行鍵がunlimitedなので、このような処理を行っています(辻褄合わせです)。unlimitedではなく有効期限を決めた鍵の場合は鍵生成時にRetiredも設定されます。本来の使用方法はこちらだと思います。Removedは、現行鍵の署名が無くなる時間です。RetiredからIRetの時間が設定されます。

Successorは、切り替え後の鍵つまり新鍵のIDです。ロールオーバー中に次の鍵や前の鍵を参照するケースがあるので、ここに情報が保存されます。

新鍵の方は、新規公開とほぼ同じですが、Predecessorが設定されます。これは前の鍵つまり現行鍵のIDです。ここを設定することで相互参照を可能にしています(鍵の切替順序を保存している)。

この時点でゾーンの署名がどうなっているかというとゾーン自体は現行鍵で署名されたままです。新鍵のDNSKEYは署名されていますが他のノードは現行鍵のRRSIGレコードしかありません。新鍵のRRSIGが作成されるのは、再署名がされたタイミングです。また再署名の際、現行鍵は使われなくなり、結果として現行鍵のRRSIGレコードは削除されます。

IRetにはDsgnを参照しているという説明をしましたが、リタイアまでの待ち時間にDsgnが含まれるのはこの動作を保証するためです。

以前のドキュメントを読んだ方はご存じだと思いますが、新鍵を追加された段階で新鍵のゾーンの署名が行われないので、cronに頼るということを説明しました。しかしKASPの実装を見るとこの動作は意図して行われていたようです。

負荷低減を考えるなら、再署名で新鍵の署名を作った方が負荷がかかりません。しかし全自動ゾーン署名で再署名に頼る処理を行おうとすると、再署名期間を考慮して鍵の有効期限などを決める必要があり、手動で行うのは難しいと思います。KASPは、この辺りを自動化してくれるので、全自動ゾーン署名から乗り換えという流れになっているのかもしれません。

RFCにはこの部分の説明は

Dsgn is the delay needed to ensure that all existing RRsets have been re-signed with the new key.

とあるだけです。Google様によると

Dsgn は、すべての既存の RRset が新しいキーで再署名されていることを確認するために必要な遅延です。

あっさりした説明ですが、敢えて再署名という言葉を使っているのが、新鍵で署名を即時追加しないという主張なのかもしれません。

Iret(実装上)の時間が経った後のログと.stateは以下の通りです。

11-May-2024 14:49:58.068 keymgr: examine CSK exsample.co.jp/ECDSAP256SHA256/15926 type ZRRSIG in state UNRETENTIVE
Kexsample.co.jp.+013+15926.state
; This is the state of key 15926, for exsample.co.jp.
Algorithm: 13
Length: 256
Lifetime: 258550
Successor: 39789
KSK: yes
ZSK: yes
Generated: 20240507080047 (Tue May  7 17:00:47 2024)
published: 20240507080047 (Tue May  7 17:00:47 2024)
Active: 20240507080047 (Tue May  7 17:00:47 2024)
Retired: 20240510074957 (Fri May 10 16:49:57 2024)
Removed: 20240520085457 (Mon May 20 17:54:57 2024)
publishCDS: 20240508090547 (Wed May  8 18:05:47 2024)
DNSKEYChange: 20240507100547 (Tue May  7 19:05:47 2024)
ZRRSIGChange: 20240510074958 (Fri May 10 16:49:58 2024)
KRRSIGChange: 20240507100547 (Tue May  7 19:05:47 2024)
DSChange: 20240510074958 (Fri May 10 16:49:58 2024)
DNSKEYState: omnipresent
ZRRSIGState: unretentive
KRRSIGState: omnipresent
DSState: unretentive
GoalState: hidden
Kexsample.co.jp.+013+39789.state
; This is the state of key 39789, for exsample.co.jp.
Algorithm: 13
Length: 256
Lifetime: 0
Predecessor: 15926
KSK: yes
ZSK: yes
Generated: 20240510054457 (Fri May 10 14:44:57 2024)
published: 20240510054457 (Fri May 10 14:44:57 2024)
Active: 20240510074957 (Fri May 10 16:49:57 2024)
publishCDS: 20240510074957 (Fri May 10 16:49:57 2024)
DNSKEYChange: 20240510074958 (Fri May 10 16:49:58 2024)
ZRRSIGChange: 20240510054457 (Fri May 10 14:44:57 2024)
KRRSIGChange: 20240510074958 (Fri May 10 16:49:58 2024)
DSChange: 20240510074958 (Fri May 10 16:49:58 2024)
DNSKEYState: omnipresent
ZRRSIGState: rumoured
KRRSIGState: omnipresent
DSState: rumoured
GoalState: omnipresent

現行鍵のZRRSIGStateがUNRETENTIVE遷移しました。この状態になった鍵は再署名に使用されなくなります。一方DNSKEYStateの方は遷移していません。これはCSKを使用しているためで、KSKと共有のためUNRETENTIVEに遷移しません。

新鍵の方は、ZRRSIGStateはRUMOUREDのままです。これは再署名がすべて終了していないので新鍵のRRSIGがすべて作られていないためです。

Iretの説明でDsgnは、signatures-validity - signatures-refreshで計算されると述べました。この計算式で良い根拠は再署名の対象期間の決定方法にあります。

全自動ゾーン署名では再署名を、signatures-refresh日先に有効終了日があるRRSIGレコードに対して行います。その際の最大の有効終了日はsignatures-validity日先です。

ロールオーバー直前に再署名が実行された場合、default Policyの設定はsignatures-validityが14日、signatures-refreshが5日なので最大14日先の有効終了日を持つレコードが存在します。このレコードが再度、署名されるのは5日毎に署名するので14-5=9日後です。再署名処理がこのようなサイクルで動作するのでDsgnは先の計算式となります。

新鍵のZRRSIGがOMNIPRESENTになった時のログは以下です。OMNIPRESENTに遷移するのは、rollover時点からIretなのでDsngの9日に他のパラメタが足され約10日後になります。.stateのZRRSIGChange,ZRRSIGStateも更新されています。

20-May-2024 15:49:57.927 keymgr: transition CSK exsample.co.jp/ECDSAP256SHA256/39789 type ZRRSIG state RUMOURED to state OMNIPRESENT!
Kexsample.co.jp.+013+39789.state
; This is the state of key 39789, for exsample.co.jp.
Algorithm: 13
Length: 256
Lifetime: 0
Predecessor: 15926
KSK: yes
ZSK: yes
Generated: 20240510054457 (Fri May 10 14:44:57 2024)
published: 20240510054457 (Fri May 10 14:44:57 2024)
Active: 20240510074957 (Fri May 10 16:49:57 2024)
publishCDS: 20240510074957 (Fri May 10 16:49:57 2024)
DNSKEYChange: 20240510074958 (Fri May 10 16:49:58 2024)
ZRRSIGChange: 20240520064957 (Mon May 20 15:49:57 2024)
KRRSIGChange: 20240510074958 (Fri May 10 16:49:58 2024)
DSChange: 20240510074958 (Fri May 10 16:49:58 2024)
DNSKEYState: omnipresent
ZRRSIGState: omnipresent
KRRSIGState: omnipresent
DSState: rumoured
GoalState: omnipresent

現行鍵もIretが経過していますが、Iret(実装上)からIretなので、少し遅れます。新鍵が完全に再署名するための余裕という言い方もできるかもしれません。ZRRSIGChange,ZRRSIGStateの値が更新されました。状態遷移としてはこのZRRSIGは、寿命を迎えたことになります。

20-May-2024 17:54:58.940 keymgr: transition CSK exsample.co.jp/ECDSAP256SHA256/15926 type ZRRSIG state UNRETENTIVE to state HIDDEN!
Kexsample.co.jp.+013+15926.state
; This is the state of key 15926, for exsample.co.jp.
Algorithm: 13
Length: 256
Lifetime: 258550
Successor: 39789
KSK: yes
ZSK: yes
Generated: 20240507080047 (Tue May  7 17:00:47 2024)
published: 20240507080047 (Tue May  7 17:00:47 2024)
Active: 20240507080047 (Tue May  7 17:00:47 2024)
Retired: 20240510074957 (Fri May 10 16:49:57 2024)
Removed: 20240520085457 (Mon May 20 17:54:57 2024)
publishCDS: 20240508090547 (Wed May  8 18:05:47 2024)
DNSKEYChange: 20240507100547 (Tue May  7 19:05:47 2024)
ZRRSIGChange: 20240520085458 (Mon May 20 17:54:58 2024)
KRRSIGChange: 20240507100547 (Tue May  7 19:05:47 2024)
DSChange: 20240510074958 (Fri May 10 16:49:58 2024)
DNSKEYState: omnipresent
ZRRSIGState: hidden
KRRSIGState: omnipresent
DSState: unretentive
GoalState: hidden

ロールオーバー後の再署名中に、signatures-validityやsignatures-refreshを変更したらどうなるでしょうか?確認していないですが、現行鍵のRetiredやRemovedが更新されることは無いと思います。これらの値の設定は、イベント発生時のパラメタの内容で静的に計算されるのでイベント発生後に値が更新されても、そのイベントが再発生しない限り再計算されることはありません。signatures-refreshを短くしてしまう(5->3など)と、Iretの計算値が異なってしまい全ノード再署名が終わっていない状態で、新鍵に切り替わってしまいます。

別な言い方をすると、新鍵の切り替え時に、全ノードの再署名が終わっているかといった確認処理は存在せず、あくまでイベントと時間計算のみで処理が進むということです。このことから、運用を始めたら不用意にパラメタ値を見直さない方が良いです。もしどうしても必要なら、最低限ロールオーバー中は避けるべきです。

ロールオーバー中の署名の確認

ここで先に進む前に現行鍵と新鍵が存在する状態での署名の確認を行ってみます。

署名の確認は上位組織へのDSレコードの登録が行われないとできませんが、9.16以降に付属するdelvコマンドではtrust-anchorsファイルを用意することで、署名の確認が行えます。

最初に鍵のDSレコードを取得します。dnssec-dsfromkeyコマンドを使用します。

# dnssec-dsfromkey /var/cache/bind/Kexsample.co.jp.+013+15926.key
exsample.co.jp. IN DS 15926 13 2 D9601715F74AB641DC15F2F1C2724F23154F5D3605E20F4C9B82446D6990E034

次に鍵のハッシュ値を取得します。rndc dumpdb -zonesなどを使用してファイルか拾うかdigでダンプしても良いです。

exsample.co.jp.				      3600 IN DNSKEY	257 3 13 CjG0H0IjH6VFSwJgDXrIFBWK/xgJJvZz8vcNrIZy3qM4esJL5yDwo9r/ yyIOnHOyKVtdd0ZHkqLIbL7m/WijaA==

ファイルから拾った場合は、DNSKEYレコードのデータ部分に空白が含まれています。転記の際、カットします。また例はdefault Policyのアルゴリズム(ecdsa256)なので短いですが、RSA 2048などにするともっと長いです。

この2つの情報からtrust-anchorsファイルを作成します。ファイル名はtest-trust-anchors.txtとします。

test-trust-anchors.txt
trust-anchors {
  "exsample.co.jp." static-key 257 3 13 "CjG0H0IjH6VFSwJgDXrIFBWK/xgJJvZz8vcNrIZy3qM4esJL5yDwo9r/yyIOnHOyKVtdd0ZHkqLIbL7m/WijaA==";
  "exsample.co.jp." static-ds 15926 13 2 "D9601715F74AB641DC15F2F1C2724F23154F5D3605E20F4C9B82446D6990E034";
};

static-keyのハッシュ値前の3つ整数は、DNSKEYレコードの値です。static-dsのハッシュ値前の3つ整数は、dnssec-dsfromkeyの出力結果から拾います。

準備ができたので、署名の検証を行います。

# delv @localhost -a ./test-trust-anchors.txt +root=exsample.co.jp node1.exsample.co.jp
; fully validated
node1.exsample.co.jp.	3600	IN	A	192.168.1.1
node1.exsample.co.jp.	3600	IN	RRSIG	A 13 4 3600 20240518070906 20240507070047 15926 exsample.co.jp. MeZUaeJSDLULPv6aqHrA2RIGVsI7UXXSeCURD+7f3WdFtKCX4rIcKLeg 8QaI8wO59aGhJbXENY+T5Hrrf7bJeQ==
#

-aオプションにtrust-anchorsファイル名を指定し、rootをexsample.co.jpに指定します。fully validatedは署名の確認ができたということです。

次に新鍵の方のtrust-anchorsファイルを用意します。test-trust-anchors-rollover.txtとします。

test-trust-anchors-rollover.txt
trust-anchors {
  "exsample.co.jp." static-key 257 3 13 "q9A+/9QXbPygEIoSuXL6WHrJWRV6Sf1/hZAbUkWQk/IwTsVAgWepYZmF gvHxfx1KGbLHfxMOHNk6dG/4++HEfQ==";
  "exsample.co.jp." static-ds 39789 13 2 "27BF5BE397C4FA6DB0E154360F6F7A853D060DFFB9C796C6398BEE5F49D44831";
};
# delv @localhost -a ./test-trust-anchors-rollover.txt  +root=exsample.co.jp node1.exsample.co.jp
; fully validated
node1.exsample.co.jp.	3600	IN	A	192.168.1.1
node1.exsample.co.jp.	3600	IN	RRSIG	A 13 4 3600 20240518070906 20240507070047 15926 exsample.co.jp. MeZUaeJSDLULPv6aqHrA2RIGVsI7UXXSeCURD+7f3WdFtKCX4rIcKLeg 8QaI8wO59aGhJbXENY+T5Hrrf7bJeQ==
#

あれ、署名の確認ができたと出ましたね? このコマンドを打ったのはrndc dnssec -rollover -key 15926 exsample.co.jp直後辺りなので、新鍵でZSK署名はできていないはずです。+vtraceオプションで詳細を見てみましょう

# delv @localhost -a ./test-trust-anchors-rollover.txt  +root=exsample.co.jp node1.exsample.co.jp +vtrace
;; fetch: node1.exsample.co.jp/A
;; validating node1.exsample.co.jp/A: starting
;; validating node1.exsample.co.jp/A: attempting positive response validation
;; fetch: exsample.co.jp/DNSKEY
;; validating exsample.co.jp/DNSKEY: starting
;; validating exsample.co.jp/DNSKEY: attempting positive response validation
;; validating exsample.co.jp/DNSKEY: verify rdataset (keyid=39789): success
;; validating exsample.co.jp/DNSKEY: marking as secure (DS)
;; validating node1.exsample.co.jp/A: in fetch_callback_dnskey
;; validating node1.exsample.co.jp/A: keyset with trust secure
;; validating node1.exsample.co.jp/A: resuming validate
;; validating node1.exsample.co.jp/A: verify rdataset (keyid=15926): success
;; validating node1.exsample.co.jp/A: marking as secure, noqname proof not needed
; fully validated
node1.exsample.co.jp.	3600	IN	A	192.168.1.1
node1.exsample.co.jp.	3600	IN	RRSIG	A 13 4 3600 20240518070906 20240507070047 15926 exsample.co.jp. MeZUaeJSDLULPv6aqHrA2RIGVsI7UXXSeCURD+7f3WdFtKCX4rIcKLeg 8QaI8wO59aGhJbXENY+T5Hrrf7bJeQ==
# 

動きとしては、KSKは新鍵で検証していて、ZSKは現行鍵で検証を行っているようです。DNSECの検証の仕組みは細かく把握していないので、間違っている可能性がありますが、DNSKEYの署名は複数のDNSKEYがある場合、全てを混ぜて署名を行うようです。このため新鍵のDNSKEYの署名でも現行鍵のZSKの正当性が確認できるので検証ができるということのようです。

同じことがIret立った後にも言えます。この場合、新鍵のZSK署名しか無い状態ですが、DNSKEYは現行鍵で署名されたままなので現行鍵のKSKでも検証ができることになります。

この辺りの細かい仕組みを説明している、良いドキュメントが無いため、かなり自信がないです。鵜呑みにせず、ご自身でも確認してください。

運用上で考えた場合、現行鍵のKSKのDSレコードを削除するタイミングを新鍵のZSK署名が出来たタイミング(Iret経過後)とすれば問題は起こらないと思います(この動きを見ると、切り替え直後に新鍵のDSレコードだけにしても 良いような気もしますが)。

KSKのロールオーバー(DSレコードの公開とロールオーバー)

現在の状況だとKSK(CSKのKSK部分)がHIDDENに遷移していないので現行鍵が削除されることありません。KSKをロールオーバーするためには、DSレコードの状態をHIDDENにする必要があります。

KSKのロールオーバーは以下のような遷移となります。

KSKのロールオーバー遷移

KSKの公開で述べたようにKASPではTsbm,Dregの考慮がありません。このため、Tsbm=Tactです。またIpubCも存在しないためIpubが使用されます。

KSKはDSレコードが公開されないと実質的に意味ありません。しかしKASPが管理していている状態はあくまで自身ゾーン内の資源レコードがどういう状態にあるかです。このためDNSKEYやKRRSIGなどは、Ipubを経過するとOMNIPRESENTに遷移します。

この理屈はDSレコードでも同じだと思うのですが、公開が上位組織だからかKASPはDSレコードは特別扱いします。rndcに、DSレコードの公開と非公開を制御するコマンドが存在し、このコマンドが実行されない限り、OMNIPRESENT(またはHIDDEN)に遷移しません。

今までの例では、DSレコードの状態はOMNIPRESENTにしたこともなかったので、現行鍵のDSレコードをHIDDENへ、新鍵はOMNIPRESENTに遷移してみます。

DSレコードは、上位組織への提示が必要となります。このため現在使われているKSKからDSレコードを入手する必要があります。KASPでは、この方法は特に用意されておらず、従来通りdnssec-dsfromkeyコマンドを使用します。

実行のタイミングはKSK鍵がKASPによって作成された後です。rndc dnssec -rolloverコマンドを実行したタイミングでKSK鍵の生成を確認しdnssec-dsfromkeyコマンドを実行します。今回は新鍵が対象なので以下のような感じです。

# dnssec-dsfromkey -2 Kexsample.co.jp.+013+39789

DSレコードの公開と破棄は、RFCの3.3.2. Double-DS Methodにあります。公開は以下のような状態遷移を行います。

DSの公開遷移

Tsbmは、KSKの公開で、DSレコードを上位組織へ提出した時間と説明しました。dnssec-dsfromkeyコマンドで生成した結果を上位組織へ提出することになります。

同じ説明内で、KASPではDregの考慮もないと説明しました。このためKSKが追加されると、DSレコードの状態はRUMOUREDに遷移しており、この状態はZSKでいうところのTpubなので、$Tsbm=Tpub$として扱っていることになります。

IpubPは上位組織でのDSレコードの公開間隔で以下のようになるとされます。

$DSレコード公開間隔(IpubP) = 親ゾーンの伝搬遅延(DprpP) + 親ゾーンのDSレコードのTTL(TTLds)$

KASPの実装では、DprpPをPolicyのparent-propagation-delayを使用し、TTLdsをparent-ds-ttlが使用されます。またIpubと同様に、KASP独自の加味する値があるので、これはretire-safetyが使用されます。なぜretire-safetyを使うのか、特に説明がないため理由は不明です。

$IpubP = parent$-$propagation$-$delay + parent$-$ds$-$ttl + retire$-$safety$

defalutのPolicyでは以下の値になります。

$IpubP = 1H(3600sec) + 1D(86400) + 1H(3600sec) = 93600sec$

DSレコードのロールオーバーは以下のような状態遷移を行います。

DSのロールオーバー遷移

Iretは、リタイアインターバルで、以下のようであるとされています。

$Iret = 子ゾーン伝搬遅延(DprpC) + DNSKEYのttl(TTLkey)$

KSKの公開の部分でIpubCという間隔はKASP実装上存在しないという説明をしました。DSレコードに関しても同様で子ゾーン関連の定義はKASP上は存在せず、DropCの定義は存在しません。IretはIpubPの式が使用されます。

では.stateやログを見ながら遷移の様子を確認してみましょう。DSレコードの状態を遷移させるためにコマンドを発行します。新鍵をOMNIPRESENTに遷移させ、現行鍵をHIDDENへ遷移させるには以下のコマンドを実行します。

# rndc dnssec -checkds -key 39789 published exsample.co.jp
# rndc dnssec -checkds -key 15926 withdrawn exsample.co.jp

まず新鍵の方ですが、.stateが以下のようになります

Kexsample.co.jp.+013+39789.state
; This is the state of key 39789, for exsample.co.jp.
Algorithm: 13
Length: 256
Lifetime: 0
Predecessor: 15926
KSK: yes
ZSK: yes
Generated: 20240510054457 (Fri May 10 14:44:57 2024)
published: 20240510054457 (Fri May 10 14:44:57 2024)
Active: 20240510074957 (Fri May 10 16:49:57 2024)
DSpublish: 20240521082511 (Tue May 21 17:25:11 2024)
publishCDS: 20240510074957 (Fri May 10 16:49:57 2024)
DNSKEYChange: 20240510074958 (Fri May 10 16:49:58 2024)
ZRRSIGChange: 20240520064957 (Mon May 20 15:49:57 2024)
KRRSIGChange: 20240510074958 (Fri May 10 16:49:58 2024)
DSChange: 20240510074958 (Fri May 10 16:49:58 2024)
DNSKEYState: omnipresent
ZRRSIGState: omnipresent
KRRSIGState: omnipresent
DSState: rumoured
GoalState: omnipresent

DSpublishという項目が追加されます。DSStateがOMNIPRESENTに遷移するのは、IpubP待ちます。

21-May-2024 17:25:11.471 keymgr: time says no to CSK exsample.co.jp/ECDSAP256SHA256/39789 type DS state RUMOURED to state OMNIPRESENT (wait 93600 seconds)

IpubP後のログは以下の通りです。

22-May-2024 19:25:11.466 keymgr: transition CSK exsample.co.jp/ECDSAP256SHA256/39789 type DS state RUMOURED to state OMNIPRESENT!
Kexsample.co.jp.+013+39789.state
; This is the state of key 39789, for exsample.co.jp.
Algorithm: 13
Length: 256
Lifetime: 0
Predecessor: 15926
KSK: yes
ZSK: yes
Generated: 20240510054457 (Fri May 10 14:44:57 2024)
published: 20240510054457 (Fri May 10 14:44:57 2024)
Active: 20240510074957 (Fri May 10 16:49:57 2024)
DSpublish: 20240521082511 (Tue May 21 17:25:11 2024)
publishCDS: 20240510074957 (Fri May 10 16:49:57 2024)
DNSKEYChange: 20240510074958 (Fri May 10 16:49:58 2024)
ZRRSIGChange: 20240520064957 (Mon May 20 15:49:57 2024)
KRRSIGChange: 20240510074958 (Fri May 10 16:49:58 2024)
DSChange: 20240522102511 (Wed May 22 19:25:11 2024)
DNSKEYState: omnipresent
ZRRSIGState: omnipresent
KRRSIGState: omnipresent
DSState: omnipresent
GoalState: omnipresent

DSState,DSChangeが更新され、OMNIPRESENTに遷移しました。

現行鍵の方は、コマンド実行タイミングで以下のようになります。

Kexsample.co.jp.+013+15926.state
; This is the state of key 15926, for exsample.co.jp.
Algorithm: 13
Length: 256
Lifetime: 258550
Successor: 39789
KSK: yes
ZSK: yes
Generated: 20240507080047 (Tue May  7 17:00:47 2024)
published: 20240507080047 (Tue May  7 17:00:47 2024)
Active: 20240507080047 (Tue May  7 17:00:47 2024)
Retired: 20240510074957 (Fri May 10 16:49:57 2024)
Removed: 20240520085457 (Mon May 20 17:54:57 2024)
DSRemoved: 20240521082516 (Tue May 21 17:25:16 2024)
publishCDS: 20240508090547 (Wed May  8 18:05:47 2024)
DNSKEYChange: 20240507100547 (Tue May  7 19:05:47 2024)
ZRRSIGChange: 20240520085458 (Mon May 20 17:54:58 2024)
7KRRSIGChange: 20240507100547 (Tue May  7 19:05:47 2024)
DSChange: 20240510074958 (Fri May 10 16:49:58 2024)
DNSKEYState: omnipresent
ZRRSIGState: hidden
KRRSIGState: omnipresent
DSState: unretentive
GoalState: hidden

DSRemovedが追加されました。ログには以下のように表示されます。新鍵と同様にIpubP(Iret)待ってHIDDENに遷移します。

21-May-2024 17:25:16.459 keymgr: time says no to CSK exsample.co.jp/ECDSAP256SHA256/15926 type DS state UNRETENTIVE to state HIDDEN (wait 93600 seconds)

IpubP後のログは以下の通りです。

22-May-2024 19:25:16.466 keymgr: transition CSK exsample.co.jp/ECDSAP256SHA256/15926 type DS state UNRETENTIVE to state HIDDEN!
Kexsample.co.jp.+013+15926.state
; This is the state of key 15926, for exsample.co.jp.
Algorithm: 13
Length: 256
Lifetime: 258550
Successor: 39789
KSK: yes
ZSK: yes
Generated: 20240507080047 (Tue May  7 17:00:47 2024)
published: 20240507080047 (Tue May  7 17:00:47 2024)
Active: 20240507080047 (Tue May  7 17:00:47 2024)
Retired: 20240510074957 (Fri May 10 16:49:57 2024)
Removed: 20240520085457 (Mon May 20 17:54:57 2024)
DSRemoved: 20240521082516 (Tue May 21 17:25:16 2024)
publishCDS: 20240508090547 (Wed May  8 18:05:47 2024)
DNSKEYChange: 20240522102511 (Wed May 22 19:25:11 2024)
ZRRSIGChange: 20240520085458 (Mon May 20 17:54:58 2024)
KRRSIGChange: 20240522102511 (Wed May 22 19:25:11 2024)
DSChange: 20240522102516 (Wed May 22 19:25:16 2024)
DNSKEYState: unretentive
ZRRSIGState: hidden
KRRSIGState: unretentive
DSState: hidden
GoalState: hidden

DSState,DSChangeが更新され、HIDDENに遷移しました。良くみると、DNSKEYState,KRRSIGState,DNSKEYChange,KRRSIGChangeも更新されています。これはDSが非公開になったことにより、UNRETENTIVEに状態遷移可能になったと判断したためです。

22-May-2024 19:25:11.466 keymgr: transition CSK exsample.co.jp/ECDSAP256SHA256/15926 type DNSKEY state OMNIPRESENT to state UNRETENTIVE!
22-May-2024 19:25:11.466 keymgr: transition CSK exsample.co.jp/ECDSAP256SHA256/15926 type KRRSIG state OMNIPRESENT to state UNRETENTIVE!

UNRETENTIVEからHIDDENに遷移するためには以下の時間待つことになっています。

22-May-2024 19:25:11.466 keymgr: time says no to CSK exsample.co.jp/ECDSAP256SHA256/15926 type DNSKEY state UNRETENTIVE to state HIDDEN (wait 3900 seconds)
22-May-2024 19:25:11.466 keymgr: time says no to CSK exsample.co.jp/ECDSAP256SHA256/15926 type KRRSIG state UNRETENTIVE to state HIDDEN (wait 3900 seconds)

3900secはIpub(IpubPではない)なのですが、publish-safetyを参照しないようです。コメントにあっさりpublish-safety見ないと書かれているだけなので、理由は不明です。

3900sec経過後のログは以下です。

22-May-2024 20:30:11.473 keymgr: transition CSK exsample.co.jp/ECDSAP256SHA256/15926 type DNSKEY state UNRETENTIVE to state HIDDEN!
22-May-2024 20:30:11.473 keymgr: transition CSK exsample.co.jp/ECDSAP256SHA256/15926 type KRRSIG state UNRETENTIVE to state HIDDEN!
Kexsample.co.jp.+013+15926.state
; This is the state of key 15926, for exsample.co.jp.
Algorithm: 13
Length: 256
Lifetime: 258550
Successor: 39789
KSK: yes
ZSK: yes
Generated: 20240507080047 (Tue May  7 17:00:47 2024)
published: 20240507080047 (Tue May  7 17:00:47 2024)
Active: 20240507080047 (Tue May  7 17:00:47 2024)
Retired: 20240510074957 (Fri May 10 16:49:57 2024)
Removed: 20240520085457 (Mon May 20 17:54:57 2024)
DSRemoved: 20240521082516 (Tue May 21 17:25:16 2024)
publishCDS: 20240508090547 (Wed May  8 18:05:47 2024)
DNSKEYChange: 20240522113011 (Wed May 22 20:30:11 2024)
ZRRSIGChange: 20240520085458 (Mon May 20 17:54:58 2024)
KRRSIGChange: 20240522113011 (Wed May 22 20:30:11 2024)
DSChange: 20240522102516 (Wed May 22 19:25:16 2024)
DNSKEYState: hidden
ZRRSIGState: hidden
KRRSIGState: hidden
DSState: hidden
GoalState: hidden

全ての状態がHIDDENとなりました。

旧鍵の削除

現在は新鍵が現行鍵になっているので、今までの鍵を旧鍵と呼ぶことにします。旧鍵はHIDDEN状態なので、DNSSEC的に何にも使われていない状態です。この状態に遷移すると、削除可能となります。

KASPでは、purge-keysの間隔を待って削除を行います。default Policyにおけるpurge-keysは90Dです。確認を90日待つのはちょっと時間がかかりすぎるので、2日程度に短縮して削除の様子を確認します。

named.confを書き換え以下ようにします。

dnssec-policy "myway" {
    purge-keys P2D;
};

zone "exsample.co.jp" {
        type master;
        file "/var/cache/bind/db.exsample.co.jp";
       dnssec-policy "myway";
       inline-signing yes; 

};

mywayというPolicyを追加し、exsample.co.jpゾーンのpolicyをmywayを参照するように変更します。

dnssec-policyはdefaultを継承しており、指定があれば上書きする仕組みです。myway Policyはpurge-keys以外はdefaultと同じです。この状態で再起動します。reloadもで可能かもしれませんが、私は確認していません。

現在使用しているpolicyはrndc dnssec -status exsample.co.jpで確認できます。

# rndc dnssec -status exsample.co.jp
dnssec-policy: myway
current time:  Thu May 23 15:02:05 2024

key: 15926 (ECDSAP256SHA256), CSK
  published:      no
  key signing:    no
  zone signing:   no

  Key has been removed from the zone
  - goal:           hidden
  - dnskey:         hidden
  - ds:             hidden
  - zone rrsig:     hidden
  - key rrsig:      hidden

key: 39789 (ECDSAP256SHA256), CSK
  published:      yes - since Fri May 10 14:44:57 2024
  key signing:    yes - since Fri May 10 14:44:57 2024
  zone signing:   yes - since Fri May 10 16:49:57 2024

  No rollover scheduled
  - goal:           omnipresent
  - dnskey:         omnipresent
  - ds:             omnipresent
  - zone rrsig:     omnipresent
  - key rrsig:      omnipresent

2日後のログに以下ように出力され、旧鍵が削除されました。

24-May-2024 21:01:58.416 keymgr: purge DNSKEY exsample.co.jp/ECDSAP256SHA256/15926 (CSK) according to policy myway

鍵の削除の時間の詳細な調査は行っていないのですが、削除処理自体は、全自動ゾーン署名の機能をそのまま使うようです。全自動ゾーン署名では、key eventがdnssec-loadkeys-interval毎(デフォルトは1時間)に発生しますが、このタイミングでキーが削除可能かを確認しています。上のログが21:01:58になっているのは、以前発生したkey eventでxx:01:58が起点に移ったためです。key event発生時刻より過去のpurge対象を削除するという処理が動くようです。

旧鍵はHIDDENになったのは、5/22 20:30:11なので、そこから2日、かつkey eventが発生する5/24 21:01:58に削除が実行されたと考えられます。

全自動ゾーン署名からの移行

公開からロールオーバーの一通りの説明をしました。どういう風に動いているか、なんとなく分かったのではないかと思います。ここでは全自動ゾーン署名からの移行の確認します。

手順としては、鍵や署名ゾーンのゾーンDBなどを削除して完全にリセットします。KSK鍵とZSK鍵を手動で生成しゾーンDBは非署名ゾーンのみとして、全自動ゾーン署名の設定で起動します。この状態で、全自動ゾーン署名により、署名ゾーンのゾーンDBが作成されますのでそこを初期値とします。/var/cache/bindは以下のよういなっています。

# ls -l
合計 2144
-rw-r--r-- 1 root root     716  6月  1  2024 Kexsample.co.jp.+008+00250.key
-rw------- 1 root root    1824  6月  1  2024 Kexsample.co.jp.+008+00250.private
-rw-r--r-- 1 root root     957  6月  1  2024 Kexsample.co.jp.+008+12971.key
-rw------- 1 root root    3316  6月  1  2024 Kexsample.co.jp.+008+12971.private
-rw-r--r-- 1 root root    1831  6月  1  2024 db.exsample.co.jp
-rw-r--r-- 1 root root     512  6月  1  2024 db.exsample.co.jp.jbk
-rw-r--r-- 1 root root   28491  6月  1  2024 db.exsample.co.jp.signed
-rw-r--r-- 1 root root   51095  6月  1  2024 db.exsample.co.jp.signed.jnl
-rw-r--r-- 1 root root     821  6月  1  2024 managed-keys.bind
-rw-r--r-- 1 root root    1856  6月  1  2024 managed-keys.bind.jnl
-rw-r--r-- 1 root root 2028557  6月  1  2024 named.run
-rw-r--r-- 1 root root   46647  6月  1  2024 named_dump.db
#

12971がKSKで、00250がZSKです。named.confは以下の通りです。

//dnssec-policy "myway" {
//    purge-keys P2D;
//};

zone "exsample.co.jp" {
        type master;
        file "/var/cache/bind/db.exsample.co.jp";
	key-directory "/var/cache/bind";
        //file "/etc/bind/db.moonrabbit.co.jp";
        // allow-transfer { 127.0.0.1; 210.172.64.81; 210.255.83.229; 218.219.224.66; };

//       dnssec-policy "myway";
        auto-dnssec maintain;
       inline-signing yes; 

};

この状態で、KASPに移行してみます。停止後、named.confを以下のように書き換えます。

dnssec-policy "myway" {
    keys {
        ksk lifetime unlimited algorithm rsasha256 4096;
        zsk lifetime unlimited algorithm rsasha256 2048;
    };
    purge-keys P2D;
};

zone "exsample.co.jp" {
        type master;
        file "/var/cache/bind/db.exsample.co.jp";

       dnssec-policy "myway";
//        auto-dnssec maintain;
       inline-signing yes; 

};

PolicyのkeysはkeyIDを記述することはできないので、アルゴリズムだけ合わせます。全自動ゾーン署名はKASPから見ると外部からの手動ロールオーバーの仕組みなのでlifetime unlimitedとして、KASPのロールオーバーは禁止します。この状態で起動すると以下のようなログが出ます。

01-Jun-2024 18:08:48.949 keymgr: DNSKEY exsample.co.jp/RSASHA256/12971 (KSK) initialize DNSKEY state to OMNIPRESENT (policy myway)
01-Jun-2024 18:08:48.949 keymgr: DNSKEY exsample.co.jp/RSASHA256/12971 (KSK) initialize KRRSIG state to OMNIPRESENT (policy myway)
01-Jun-2024 18:08:48.949 keymgr: DNSKEY exsample.co.jp/RSASHA256/12971 (KSK) initialize DS state to HIDDEN (policy myway)
01-Jun-2024 18:08:48.949 keymgr: DNSKEY exsample.co.jp/RSASHA256/250 (ZSK) initialize DNSKEY state to OMNIPRESENT (policy myway)
01-Jun-2024 18:08:48.949 keymgr: DNSKEY exsample.co.jp/RSASHA256/250 (ZSK) initialize ZRRSIG state to OMNIPRESENT (policy myway)

全自動ゾーン署名で作ったKSKとZSKをKASPとしてのKSK,ZSKとして認識してくれたようです。.stateファイルも以下のように作成されます。

Kexsample.co.jp.+008+12971.state
; This is the state of key 12971, for exsample.co.jp.
Algorithm: 8
Length: 4096
Lifetime: 0
KSK: yes
ZSK: no
Generated: 20240525085120 (Sat May 25 17:51:20 2024)
published: 20240525085120 (Sat May 25 17:51:20 2024)
Active: 20240525085120 (Sat May 25 17:51:20 2024)
publishCDS: 20240526095620 (Sun May 26 18:56:20 2024)
DNSKEYChange: 20240601090848 (Sat Jun  1 18:08:48 2024)
KRRSIGChange: 20240601090848 (Sat Jun  1 18:08:48 2024)
DSChange: 20240601090848 (Sat Jun  1 18:08:48 2024)
DNSKEYState: omnipresent
KRRSIGState: omnipresent
DSState: rumoured
GoalState: omnipresent
Kexsample.co.jp.+008+00250.state
; This is the state of key 250, for exsample.co.jp.
Algorithm: 8
Length: 2048
Lifetime: 0
KSK: no
ZSK: yes
Generated: 20240525085127 (Sat May 25 17:51:27 2024)
published: 20240525085127 (Sat May 25 17:51:27 2024)
Active: 20240525085127 (Sat May 25 17:51:27 2024)
Retired: 20240627085127 (Thu Jun 27 17:51:27 2024)
Removed: 20240707095627 (Sun Jul  7 18:56:27 2024)
DNSKEYChange: 20240601090848 (Sat Jun  1 18:08:48 2024)
ZRRSIGChange: 20240601090848 (Sat Jun  1 18:08:48 2024)
DNSKEYState: omnipresent
ZRRSIGState: omnipresent
GoalState: omnipresent

KSKのDSStateはRUMOUREDのままなので、rndc dnssec -checkdsでpublishedにする必要があります。

dnssec -checkds -key 12971 published exsample.co.jp
02-Jun-2024 13:59:15.149 received control channel command 'dnssec -checkds -key 12971 published exsample.co.jp'

02-Jun-2024 13:59:15.157 keymgr: time says no to KSK exsample.co.jp/RSASHA256/12971 type DS state RUMOURED to state OMNIPRESENT (wait 93600 seconds)

03-Jun-2024 15:59:15.157 keymgr: transition KSK exsample.co.jp/RSASHA256/12971 type DS state RUMOURED to state OMNIPRESENT!

KASPへの移行は、named.confの設定変更だけでうまく行きそうです。注意が必要なのは、ZSKのロールオーバー中でZSK鍵が2つあるようなケースです、全自動ゾーン署名では、PredecessorやSuccessorなど鍵の前後関係が把握できないので、例のようにうまく行かないと思います。移行する場合は、KSK,ZSKが一つの状態になっているのを確認して、行った方が良いです。

自働ロールオーバーの設定

KASPへの移行が終了してしまえば、ロールオーバーを自動化するのは簡単です、lifetimeにその鍵の生存期間を記述するだけです。

二か月に一度に鍵をロールオーバーするには以下のようにnamed.confを修正します。

dnssec-policy "myway" {
    keys {
        ksk lifetime unlimited algorithm rsasha256 4096;
        zsk lifetime P60D algorithm rsasha256 2048;
    };
};

zone "exsample.co.jp" {
        type master;
        file "/var/cache/bind/db.exsample.co.jp";
       dnssec-policy "myway";
       inline-signing yes; 
};

この設定で再起動を行えば、60日後に自動でロールオーバーが発生します。

lifetimeの注意点は、signatures-validityより短くしないくらいだと思います。これより短くすると再署名のタイミングと合わなくなるためおかしな署名状態で破棄がされてしまう可能性があります。

上記設定でテスト実行していますが、うまくロールオーバーされました。結果は、これまでのログと一緒なので割愛しますが、KASPでの自働ロールオーバーは本当に簡単です。

RFC 7344

ZSKは、自動ロールオーバーが簡単になりましたがKSKはどうなるでしょうか?KSKはDSレコードの公開手順が必要なので、Policyでunlimited以外を指定できないような気がします。

実は、RFC7344でDSキーを自動的に公開する仕組みというのが定義されています。大まかに言うと、最初のDSレコードの公開は従来通りの方法で行いますが、一度上位組織でDSレコードが公開された後は、署名の信頼関係が上位組織と確立しているので、外部でDSレコードをやり取りするのではなく、自組織のゾーンでDSレコードを公開してしまおうという方式です。自ゾーンで公開されたDSレコードは上位組織が定期的に確認して、今までのDSレコード公開のように公開します。

全てのやり取りが署名で確認されていますので、改竄される可能性は低いでしょう。

この仕様では資源レコードとしてCDSとCDNSKEYを使用します。KASPは、この実装も含まれており、CDS,CDNSKEYは自動生成されています。defaultのPolicyがKSKのロールオーバー前提のCSKになっているのは、こういった経緯があります。

但し、これを行うためには上位組織の対応が必要です。現時点(2025/1)でRFC 7344をサポートしている国内組織はIIJしかないようです。さすがIIJ、さすが『インターネットの利用と仕組み』。

私の上位組織も確認したら、知らないと言われました。(知らないというか、DSレコードはWebで登録する仕組みですって言われました。対応予定とかそういうの全然なしに...)

このため、私の環境では試せないのでこれ以上は深追いはしてません。もしこれが一般的になったら、DNSSECの運用は完全に自動化されて内容を知らない人でも定期的なロールオーバー運用が可能になるのではないでしょうか

感想

いかがだったでしょうか?私的にはかなり良い感じだと思いました。全自動ゾーン署名では、どう使うか悩むという話をしましたが、その時に感じた不満点を概ね解消していると思います。さらにRFC7344の採用が進めば、DNSSECはインストールして最初の非署名ゾーン作って起動しておしまいという、DNSSEC導入前のサーバー運用に戻れるような気がします。

ただやっぱりパラメタの使い方とかが、ドキュメントだけじゃ良くわからないと感じました。どうロールオーバーするのかも、良くわからないので心配で使えませんでした。RFC 7583に従うと言っているわりには、RFC通り実装されていない部分も多々あって、中を調べないで資料ベースだけで把握しようとしていたら怒り狂っているような気もします。

とりあえず、このドキュメントで動作については整理できたので、私の管理する組織は近いうちにKASPに移行しようと思います。また気づいた点が出たら更新します。でも暫くは、多分typoの修正だと思うのでストックされた奇特な方はそのつもりでお願いします。

また全自動ゾーン署名は廃止になりますので、前のドキュメントを参考にされたりして、全自動ゾーン署名に対応された方は、移行を検討してください。知り合いで、全自動ゾーン署名を使っている方を知っていたら声を掛けてあげてください。お願いします。

あとがき

昔、新世紀エヴァンゲリオンの考察同人誌というのを読んだことがあって、”あとがき”みたいな部分に、”この本を書く上でいろいろなことを調べた(死海文書?とか)。異論や反論があるなら、最低限自分と同じレベルの調査を行ってからじゃないと聞く耳持たない。”というようなことが書いてあって同人誌っていうのは凄い世界だなぁと思いました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?