残り数か月ある証明書と、すぐに失敗するログインは、別々の時計を持つ別々のオブジェクトを指しています。サーバーが接続を拒否するのは、参照している失効証明書のリストが独自の有効期限を過ぎているためであり、ユーザーの証明書が古くなったためではありません。ユーザー証明書を更新しても、そのリストには何の効果もありません。

二つのスケジュールを分けて考えることが診断のすべてであり、修正の形も変わってきます。

二つの時計があり、証明書はそのうち一つだけ

証明書は有効期間を持ちます。証明書失効リストは独自の有効期間に加えて発行者と署名を持ち、検証者は次回更新時刻を過ぎたリストを信頼しません。そうなると、クライアントは完全に有効な証明書を提示しているのに、サーバーはリストに関するメッセージとともに接続を切ります。ユーザーはそのメッセージを「証明書が失効した」と読み、更新申請を間違った場所へ送ってしまいます。

二つのオブジェクトは所有者も異なり、証明書は発行した CA から来ますが、リストはその CA を運用する人がスケジュールに従って生成します。ユーザーが更新することはできず、証明書を再発行してもリストを延長することはできません。

サービスが実際に読み込むリストを確認する

想定しているファイルからではなく、実行中の設定から始めます。crl-verify のパスは絶対パス、プロファイルからの相対パス、またはイメージに焼き込まれたコピーである可能性があり、検証器はそのコピーを読みます。openssl crl -in /etc/openvpn/crl.pem -noout -issuer -lastupdate -nextupdate でその場で確認し、日付をサーバーの時計と比較してください。

次に、そのファイルが本当に使われているものかを確認します。openssl crl -in /etc/openvpn/crl.pem -CAfile /etc/openvpn/ca.crt -noout で署名を確認すると、フィールドを黙って出力するのではなく検証結果を報告します、別の CA が署名したリストや、二つ目のディレクトリに残された古いコピーは、期限切れのリストとまったく同じように失敗します。

失効データベースから再生成する(ゼロからではなく)

新しいリストは、承認された署名プロセスを通じて、CA の現在の失効データベースから作らなければなりません。空のリストを生成したり、インデックスの古いバックアップから再生成したりすると、そのバックアップ以降に追加されたすべての ID の失効が静かに解除されます。これはログイン障害をセキュリティの後退に変えてしまい、症状が消えるため誰も気づきません。

生成の手順は CA の他のツールと一緒にバージョン管理下に置き、間隔と署名鍵を記憶ではなく文書化してください。コマンド、署名者、公開先を記した runbook の項目があれば十分です。そうすれば当番の誰もが、どのインデックスファイルが正式なものかを推測せずに再生成できます。リストのシリアル番号と次回更新時刻を配備記録と一緒に保存してください。

検証器が見る場所に配備する

新しいリストをサービスが読むパスにコピーし、サービスアカウントだけが読めるように所有者とモードを設定し、文書化された動作に従って再読み込みまたは再起動します。デーモンが起動時にリストをキャッシュする場合、再読み込みなしでファイルを置き換えても、実行中のプロセスが気づくことは何も変わりません。再読み込み後にプロセスが報告するタイムスタンプを確認してください。

複数のサービスがクライアントを検証している場合は、それぞれに配備します。一つのエンドポイントを更新し、もう一つを古いコピーのままにすると、二つ目に到達したユーザーにだけ現れる障害になります。それらのエンドポイントの短いリストを同じ runbook に保ってください。展開後は、コピーが届いたと仮定するのではなく、各エンドポイントが報告するリストの日付を確認します。

次の期限が来る前に見えるようにする

公開間隔を長くすると、プロセスを作らずにこのインシデントの頻度を下げられます。運用者のポリシーから間隔を選び、再生成と配備に十分な余裕を持って、配備済みリストの次回更新フィールドにアラートを設定します。アラートは、失敗するのが配備済みのコピーだからこそ、CA ホストではなく配備済みのコピーに向けてください。

配備後は両方向を検証します。許可されたユーザーが接続できること、そして既知の失効 ID が依然として失敗すること、そして二つ目の確認こそが不完全な再生成を捕まえるもので、まさにこの目的のために保持しているテストプロファイルに対してコマンド一つで済みます

関連記事