2台のピア間の OpenVPN 接続には静的鍵と TLS のどちらを使うか
OpenVPN の静的鍵モードはトラフィック鍵を更新できない。2台のピアに自動更新が必要なら TLS モードへ移行し、ポイントツーポイントの構成はそのままにしておく。
互いにしか通信しない二台のマシンでも、そのトポロジーを保ったまま交渉済みのトラフィック鍵を取得できる。ネットワークの形と保護モードは独立した選択であり、この二つを混同すると、両方のデーモンを動かしたままファイルを差し替えて静的鍵を更新しようとする人が出てくる。稼働中のペアの下で鍵ファイルを差し替えても何も更新されない。OpenVPN 2.6 が非推奨と位置づける静的鍵モードはトンネルの寿命のあいだ一つの鍵を保持するため、ディスク上のファイルとメモリ内の鍵が再び一致するのは両端を再起動した後だけである。自動更新が要件なら、保護モードを変える必要がある。
静的鍵モードにできないこと
シークレットモードでは、両方のピアが事前共有鍵を共有し、それがトンネルを直接暗号化し認証する。ハンドシェイクが存在しないため、どちらの側も新しい鍵素材を提案したり、身元を証明したり、運用者の介入なしに不一致から復旧したりする仕組みがない。どちらの性質も制御チャネルの不在に由来するもので、欠けているオプションのせいではなく、このモードに制御チャネルを加える設定フラグも存在しない。
OpenVPN 2.6 のマニュアルは、新しい鍵が生成されるまで鍵が持続すると明言している。これは実験用の接続や、文書化された更新手順を持つ固定の機器ペアには許容できるが、長期間有効な秘密が実際のリスクとなる場面では許容できない。ファイルを差し替えても稼働中のペアに新しい鍵が生まれるわけではなく、食い違う二台のピアが生まれるだけである。したがってファイルの置き換えは、更新を加えずに障害時間だけを加える。
ファイルの所持以外にピアの身元という概念もない。鍵を持つ者はすべてピアであり、トンネル内のどこにもどちら側がどちらかを記録しないため、失効は全か無かのどちらかになる。
接続を再設計せずに TLS へ移行する
TLS モードは制御チャネルを加え、それによってデータチャネルの鍵を交渉する能力も加える。ポイントツーポイントの配備では、片側がサーバーの役割を、もう片側がクライアントの役割を担うが、トポロジーは二台のピア間の接続のままで、各側は相手のエンドポイントを知っており、プールや多人数向けサービスは現れない。役割はハンドシェイクの細部であり、新しいアーキテクチャではない。
各マシンに固有の身元を与える。各側には証明書と秘密鍵、相手を検証する信頼の基点、そして誰を想定しているかを示すピア検証の規則が必要である。時間を節約するために一方のピアの秘密鍵をもう一方で再利用してはならない——それは二つの身元を一つに変え、どちらの側も個別に失効させる能力を奪う。登録の段階でこれを正しく行うべきで、後から直すということは証明書を再発行することを意味する。
保護が変わるあいだもネットワークの契約は変えない。同じトンネルのアドレス、ルート、許可されるサービスが変更の前後で適用されるべきであり、そうすれば移行中の失敗は、偽装されたルーティングの驚きではなく保護の問題として扱える。変更の前にアドレスとルートを書き留めておく——後から比較するほうが、記憶から再構成するより速い。
一部の配備では、データチャネルと一緒には更新されない独自の静的鍵で制御チャネルも保護する。その鍵はペイロードではなくハンドシェイクを守るため、漏えいするとトラフィックではなく交渉が露出する。データチャネルの素材とは別に保管し、責任者を名前で定めた交換日を与える。更新には調整された時間帯での両ピアの再起動が必要であり、だからこそ記憶ではなくカレンダーの項目に値する。
何を誰が、いつ更新するのか
TLS モードでは、更新は時間間隔・バイト数・パケット数という設定された上限によって駆動される。文書化された時間制御がほとんどの配備の頼りであり、二台のピアのうち低いほうの実効値が置き換えを開始しうるため、片側だけで引き上げても事象は先送りできない。容量に基づく上限があるのは、多忙な接続では時計よりはるかに早く鍵を使い果たすことがあるからだ。どちらの上限も健全性の確認ではなく、どちらも更新が成功したことを教えてくれない。
だからこそ、単一の設定ファイルから再交渉の繰り返しを診断するのは誤解を招く。両方のピアの設定を読み、障害を決めつけるのではなくログの遷移を見る。きれいに完了する更新は、切断ではなく制御チャネルの短いバーストのように見える。
対象を頭の中で分けておく。証明書は長期的な身元を証明し、自分が管理する日程で交換される。データチャネルの鍵は自動的に更新され、別個の認証交換が配備に必要なら、それはアカウントの方針に従い、後の交換のために独自の取り決めを要することがある。
間隔をゼロにして更新を完全に無効化することは、騒がしいログの解決策ではない。それは健全なライフサイクル事象を恒久的な鍵に変えてしまい、離れようとしていた性質へ自分を戻すことになる。
変更を受け入れる
新しい設定は、インストール済みリリースのサポートされる例から構築し、アルゴリズムやファイルパスをどこか別の場所から引き継いだ古い最小断片から作らない。両方のピアが同時に変わるように切り替えを調整し、片側が起動しない場合に備えて承認済みの復旧経路を用意する。ロールバックを試すために障害を待つのではなく、意図的に接続を落とす。練習したロールバックは、説明したロールバックより価値がある。
初期の身元検証が成功すること、意図したアプリケーションの流れが機能すること、統制された更新がトラフィックを失わずに起きることの三つを試験する。そのうえでログの遷移を、実際に何を証明するかという観点で読む——新しい鍵識別子はピアが置き換えを完了したことを意味し、トンネルが再接続したことを意味しない。一つの手順の証拠として扱い、移行が完了したと判断する前にトラフィックのカウンターを確認する。
無停止という約束が隠してしまうのは、まだ見ていない障害である。失敗する更新、期限切れの証明書、経路の不具合はどれも接続を乱しうるし、どれもきれいな試験の実行では排除されない。設計する価値のある性質はもっと狭くて有用だ——日常的な鍵の交換が、手作業のファイル差し替えでなくなることである。