トンネルが立ち上がり、ping が返り、全員が承認した。四時間後、セッションが落ち、両ピアが proposal または鍵交換のエラーを記録し、最初の推測はネットワーク側で何かが変わったというものだ。何も変わっていない。トラフィックが通るトンネルが証明したのは、二つのピアが認証の方法と最初の子アソシエーションの保護方法で一致していることであり、更新時に要求する鍵交換については何も証明していない。不一致は、この二つの出来事の間の隙間に潜んでいる。

接続できたことは PFS 設定の一致を意味しない

IKEv2 では、最初の子アソシエーションは認証の交換中に作られ、その鍵は IKE アソシエーションがすでに生成した素材から導出される。その子のために別の Diffie-Hellman 交換は行われないため、更新時にそれを要求するポリシーは立ち上げ時には試されない。

更新は別の交換だ。子アソシエーションの鍵が更新されるとき、ピアは proposal に記されたグループで新たな鍵交換を行うことがあり、これがグループ設定が初めて比較される瞬間である。したがって、一致しない二つのピアは認証し、子アソシエーションを導入し、トラフィックを通したうえで、更新で失敗しうる。

proposal 文字列のどこに不一致が潜むか

strongSwan ではグループが子の proposal に付加されるため、 aes256gcm16-prfsha256-ecp256 のような文字列は暗号方式の選択に見えるが、鍵交換の要件も併せ持つ。 aes256gcm16-prfsha256 だけを提示するピアにはその要件がなく、二つのリストは暗号では交わるが交換では食い違う。

子の proposal と IKE の proposal は別々のリストとして読む。IKE リストに現れるグループは子のリストについて何も語らず、片方を読みながらもう片方を編集するのがこれを見落とすいつもの道だ。

失敗を読む、編集したファイルではなく

交換を終わらせた notify を探す。受け入れ可能な proposal を返さない子の鍵更新は proposal リストを指し、応答がまったく返らない更新要求は経路か、待ち受けをやめたピアを指す。この二つは別の修正を要し、ログ行の文言がそれを分ける。

ディスク上の設定ではなく、実行中の設定を確認する。保存したが読み込んでいないファイルや、別の include から読み直した接続は、見えているファイルをどれだけ編集しても直らない不一致を生む。

すべて鍵更新と呼ばれる三つの出来事

IKE アソシエーションの鍵更新、IKE の再認証、子アソシエーションの鍵更新は、それぞれ別の proposal 規則を持つ別の操作である。その一つで報告された失敗は他について直接何も語らず、これらを混ぜたログは三つあるのに単一の再発障害のように読める。

ピアがどの出来事を名指ししているかに注目し、その出来事の proposal だけを確認する。リストを一つ変え、再読み込みし、同じ出来事をもう一度強制する。ログが再認証を名指しするなら、読むべきは IKE の proposal だ。子の鍵更新を名指しするなら、重要なグループを運ぶのは子の proposal である。

更新を止めることは修正ではない

鍵更新の時刻をゼロにすると失敗する交換が抑止され、トンネルは撤去されるかピアが再起動するまで生き残る。手に入れたのは長寿命の鍵と、移行・監査・ベンダー更新の際に再び遭遇する不一致である。相手側が期待するポリシーをはるかに超えて引き延ばした有効期間も同じだ。

代わりに proposal を揃える。両方のピアが実装するグループを選び、両端の子 proposal に入れ、更新ポリシーは組織が実際に要求する範囲に収める。

失敗した交換で証明する

保守時間帯に子の鍵更新時刻を短縮して、出来事が時間ではなく分で訪れるようにするか、手動で子の鍵更新を起こし、成功する更新を観察して、その中をトラフィックが流れ続けることを確認する。なぜなら 子アソシエーションは導入するがアプリケーションのフローを落とす新しいハンドシェイク は別の欠陥だからだ。

その後で通常の有効期間に戻し、失敗した記録と成功した記録の両方を残す。欲しい証明は、接続が自身のライフサイクルを生き延びること、ping を生き延びたことではない。

関連記事