VPNの証明機関を差し替えることは、ファイルの入れ替えではありません。新しいCAが最初の証明書に署名した瞬間、まだ古いCAだけを信頼している検証側は判断を迫られ、新しいアンカーを決して受け取らないホストは正しい相手を拒否し続けます。両方向で壊れるのを見てきました。ゲートウェイだけが新しいCAを覚えてクライアントが覚えていない場合、新規接続は失敗する一方で、すでに確立したトンネルはそのまま残り、障害が経路の問題のように見えてしまいます。何が変わるのかを、障害が現れる順に示します。

一度の差し替え、二つの別々の変更

証明機関とは、名前と公開鍵、そして署名する秘密鍵です。検証側は「CA」という抽象を信頼しているのではありません。信頼ストアにすでに置かれている特定の証明書を信頼し、署名の連鎖がその保存された写しに届いたときだけ発行者を受理します。したがってCAの差し替えは、独立して壊れる二つのものを変えます。どのアンカーが受理されるか、そしてその下でどの相手の身元が発行されたかです。

多くのVPN配備は両方向で検証します。クライアントがゲートウェイの証明書を認証し、ゲートウェイがクライアントの証明書を認証します。クライアント側のバンドルだけを更新する切り替えでは、古いCAの身元を提示し続けるクライアントをサーバーが拒否したままになり、逆も同じくらいよく起こります。まず適用点を洗い出します。クライアントの信頼ストア、ゲートウェイの ca ファイル、その手前でTLSを終端するプロキシ、外部から端点を確認する監視です。

検証側が確認する順序

経路検証は相手の証明書から中間証明書をたどり、信頼できるアンカーに到達するまで登ります。各段階で署名を検証し、すべての証明書が有効期間内にあるかを確認し、基本制約と鍵用途が発行者に署名を許しているかを確かめます。そのうえでアプリケーションが葉の証明書を見ます。サブジェクト代替名が接続先の名前を覆っていること、拡張鍵用途がサーバー認証またはクライアント認証を許していることが必要です。

この道筋をオフラインで再現する場合、-CAfile はシステムのストアではなく、配備するバンドルそのものに向けてください。

openssl verify -CAfile new-ca.crt gateway.crt
openssl verify -CAfile new-ca.crt -untrusted intermediate.crt client.crt
openssl x509 -in gateway.crt -noout -subject -issuer -dates
openssl s_client -connect gw.example.net:443 -CAfile new-ca.crt

このコマンドが効くのは、ゲートウェイのHTTPS管理ページのような素のTLSリスナーだけです。OpenVPNの制御チャネルはTLSより前に来るため、s_clientでトンネルのハンドシェイクは覗けません。

これらのエラーの背景にある経路構築の規則は RFC 5280 第6節 にあります。一見恣意的に見える失敗を説明してくれます。誰も覚えていない期限切れの中間証明書、鍵用途が署名を禁じている証明書、検証対象のホストを除外する名前制約です。

古いトンネルが動き続ける理由

TLSもOpenVPNも、ハンドシェイクが終わった後も確立済みのセッションを生かし続けます。パケットごとに相手の証明書を再検証することはないため、変更前に接続したクライアントは、再ネゴシエーション、再接続、あるいはトンネルの切断が起きるまで通信を流し続けます。この隙間のせいで、CAの差し替えは一時間は問題なく見え、その後に最悪のタイミングで失敗します。ノートPCがスリープから復帰し、NATマッピングが期限切れになり、ゲートウェイが再起動するのです。

セッション再開は錯覚をさらに引き延ばします。TLSセッションチケットがあれば、クライアントは証明書を再送せずに戻れます。再開は経路検証を飛ばしますが、最初のハンドシェイクがすでに済ませているからです。したがって正直な試験は、新しいプロセスでの完全なハンドシェイクです。トンネルをつなぎ直すのではなくクライアントを再起動し、試験用プロファイルではチケットを無効にすることを検討してください。再開経路が壊れた連鎖を隠せないようにするためです。

静的鍵の層はこれとは別に保ってください。tls-auth は制御チャネルにHMACを加え、tls-crypt はそれを暗号化して認証します。どちらも証明書の材料を運ばないため、どちらを回しても独自の故障モードを持つ別の変更です。両者を混同する配備は、静的鍵は正常、証明書は古い、エラーメッセージはどちらにも触れないクライアントに行き着きます。

サブジェクト名を再利用する罠

後続に何も変更させないために、前任者の識別名を再利用したくなります。それは画面のうえで発行者の行を安定させ、必要な唯一の信号を壊します。サブジェクトが同じで鍵が異なる二つの証明書は名前では区別できないため、両方のアンカーを持つバンドルは検証側に二つの候補を与え、選ぶ規則を与えません。

すると経路構築が誤ったほうを選んだり、正しいアンカーがあるのに「ローカル発行者の証明書を取得できません」と報告したり、候補の順序が違うために同じバンドルを持つ別のホストで成功と失敗が分かれたりします。名前を再利用せざるを得ない場合は、移行期間中は二つのアンカーを別ファイルに保って明示的に読み込み、すべての相手が新しい発行者を提示してから統合してください。そうでなければ代替に別のコモンネームを与えます。世代や日付の接尾辞で十分で、ログとエラー文が、失敗した相手がどの機関の下で発行されたかを示します。

ネットワークを落とさない切り替え

計画的な差し替えでは、一足飛びに切り替えず、限られた期間だけ両方のアンカーを受理します。新しいCAとその中間証明書を発行し、新しいアンカーを古いものの隣に各検証側のバンドルへ入れ、その後にだけ相手の証明書をそこから発行し始めます。古い身元の相手は古いアンカーで検証され、新しい相手は新しいアンカーで動きます。

この順序で行えば、各段階は巻き戻せます。避けたい失敗は同時切り替えです。バンドル更新を逃したクライアントが、すでに古いアンカーを退役させたゲートウェイに出会い、ハンドシェイクが死に、どちらのログもどちら側が古いのかを語りません。

逆方向に退役させます。生き残る必要のある身元をすべて再発行し、それぞれが新しい連鎖を提示することを確認してから、バンドルから古いアンカーを外します。古いCAの秘密鍵は運用から外してください。まだ署名できる発行者が残っているなら、切り替えは終わっていません。証明書と発行記録は監査用に保管します。失った発行者は同じ信頼へ復元できますが、漏えいの場合は新しい身元が必要で、古いアンカーへは戻れません。

ファイル一覧ではなく結果を検証する

期待したディレクトリに信頼ファイルがあることは、ほとんど何も証明しません。アプリケーションは別の経路、別の形式、あるいは更新で置き換わるパッケージ内の写しを読むかもしれません。ファイルの有無ではなく、両端の振る舞いを確認してください。

新しい身元での新規接続が成功することを確認し、次に退役したCAが発行した身元が拒否されることを確認します。人々が飛ばすのはこの二番目の試験で、古い機関がもはやアクセスを与えないことを示す唯一の試験です。配備がCRLやOCSPに依存する場合は、新しい証明書の配布点が解決すること、問い合わせる相手から応答者に到達できることを確認してください。

最後に、一度も接続したことのないクライアントで締めます。プロファイルの状態を消し、接続し、交渉された連鎖を読みます。キャッシュされたセッションを再開する相手は、何も検証していないのに移行は成功したと朗らかに報告します。

関連記事