ノート PC がオフィスの Wi-Fi からスマートフォンのテザリングへ移り、トンネルは数秒だけ持ちこたえ、そのあとインターフェースが接続中と主張したまま通信が止まります。サーバー側では、ステータス一覧が古いパブリックアドレスを表示し続けます。これが float の存在する状況であり、同時に、実際の動作よりはるかに多くを期待してしまう状況でもあります。境界を正しく押さえれば、戸惑う停止は一行の設定変更か、まったく別の調査に変わります。

float が緩めるもの、決して緩めないもの

通常、セッションは開始時の外向きアドレスとポートと話し続け、ほかのどこかから届くパケットは無視されます。float オプションは、ピアがすでに自分を証明したあとにこの厳格な結び付きを外すので、変化した送信元マッピングでも同じセッションを継続でき、破棄されません。暗号の検査は何も変わりません。鍵、証明書、そして HMAC 保護は、設定されたとおりに保たれます。

これはパケットごとの判断であり、誰が接続できるかという方針ではありません。新しいアドレスからパケットを送ってくる未知の機械は何も証明しておらず、そのパケットは他の未認証トラフィックと同じように破棄されます。記録されたピアアドレスを動かせるのは、セッション自身の認証を通るトラフィックだけであり、だからこそクライアントが移動する環境では float を有効のままにしておいて安全なのです。

内側のトンネルについても何も述べていません。移動した外向きアドレスは トンネルアドレスを再割り当てせず、プールも変えず、ピアに新しい何かへのアクセスも与えません。トンネルの内側では、移動の前後で同じ識別子と同じ押し出されたルートが適用されます。移動はデータチャネルを再ネゴシエーションもしないので、ネゴシエーション済みの暗号と鍵はそのまま続きます。

セッションを動かすパケットは認証を通らなければならない

設定されたリモートに対して通常どおりセッションを開始すれば、マッピングが変わったときに何が起きるかは float が扱います。途中で番号を振り直す携帯事業者、ポートマッピングを書き換える NAT ゲートウェイ、上流リンクを切り替えるノート PC はどれも同じ形を生みます。新しいタプルからの認証済みパケットが、まだ古いほうを信じているセッションに届くのです。

float が機能しているかを問われたとき、有用な証拠は完了したハンドシェイクと、そのあとに受け入れられた送信元の変化であり、アドレスだけについてのログ一行ではありません。古い外向きアドレスと新しい外向きアドレスを、生き残ったセッションと関連づけ、そのうえで通信が実際にトンネルを抜けて続いたことを確認します。

移動ではなくセッションが死ぬ場合、新しいアドレスから届いたパケットは認証に失敗したか、そもそも届いていません。クライアント側から見るとどちらも同じに見えます。サーバー側では、パブリックインターフェースでのキャプチャが、設定に触る前にどちらなのかを教えてくれます。

探索はまったく別の仕組み

float はタイマーで名前を解決せず、動的 DNS レコードも追いません。サーバーのホスト名が新しいアドレスに解決され始めても、待機中のクライアントにはそれに気づく理由も、新しいエンドポイントから認証するパケットもありません。その問題は再接続のロジック、クライアント自身の再試行の振る舞い、そして DNS に属するもので、float ではありません。

オプションをもう一度足しても、新しいアドレスへの経路がないことを補えません。ピアが黙っていれば助けにもなりません。黙ったピアは何かを動かす認証済みパケットを決して送らないからです。

下位のファイアウォールにも発言権があります。古い外向きエンドポイントだけを許可するルールは、OpenVPN がそれを見る前に変更後のアドレスを遮断し、クライアント側の設定ではどうにもなりません。許可アドレスのライフサイクルを独立した作業として見直してください。ルールを任意の送信元へ広げるのは、小さな問題を大きな問題と交換することです。

NetworkManager がプロファイルを所有している場合

コマンドラインのプロファイルとインポートした接続は別々の設定であり、片方を編集してももう片方には触れません。オプションが非対応だと決めつける前に、保存済みプロファイルが実際にどの種類のプラグインを使い、その値がどこに住んでいるかを確かめます。何かを調べたり変更したりするときに重要な識別子は、プロファイルの UUID です。

元のインポートファイルではなく、保存済みの接続を調べます。.ovpn ファイルに残った行は、有効なマネージャーがそれを適用していなければ何も証明しませんし、あるオプションのチェックボックスがないエディターも、プロトコルの能力について何も証明しません。

振る舞いを足すためにパッケージ済みのプラグインにパッチを当てないでください。ましてや無関係なコンポーネントの過去バージョン向けに書かれた diff は使わないことです。インストール済みの統合が本当にその設定を表現できないなら、正しい一手は対応済みのプロファイルか、配備の所有者が承認した別のクライアント経路です。

遷移を仮定せず証明する

障害が起きるとおりにテストを実行します。接続し、トンネル越しの通信を確認し、外向きアドレスを強制的に変え、そのうえで三つを確認します。セッションがまだ存在すること、記録されたピアアドレスが動いたこと、実際の要求が今も宛先に届くことです。三つに満たないものは部分的な答えです。

テスト中は復旧経路を確保しておいてください。移動の実験は、作業中のマシンを身動きできなくする癖があるからです。シリアルコンソールや帯域外の経路があれば、失敗したテストは現地訪問ではなく五分の復旧になります。

最後に、実際に試した事例だけを説明してください。セッション中のアドレス変更が成功したことは、DNS 移行や別のクライアント実装、作り直したプロファイルが同じように振る舞う証拠ではありません。link-options のドキュメントはこのオプションの範囲を正確に述べています。テストログには、その範囲のどこまでを実際に覆ったのかを書くべきです。

関連記事