より近そうなサーバーを選び、接続を押すと、新しいトンネルが上がる前にブラウザーの読み込みが止まります。アイコンは接続中の状態に変わり、すべてのタブがタイムアウトするまでそのままです。この停止は通常、kill switch が設計どおりに動いている結果です。クライアントに通信を送るトンネルがない間は、通信が遮断されます。この停止が許容できるかは、その数秒間にクライアントが何をするか、そして遮断が解除されたと言ったときに本当に解除されるかで決まります。

クライアントは二つのサーバーの間で何をするか

エンドポイントの切り替えは一つのスイッチではなく、いくつもの段階です。クライアントは現在のトンネルを解体し、遮断ルールを更新し、新しいエンドポイントを名前解決してトンネルの外から到達し、その後で新しいルートを設定して遮断を解除します。体感する間隙は最初の段階と最後の段階の間にあります。

ここでは速度よりも順序が重要です。遮断ルールが新しいエンドポイントの例外より先に有効になると、クライアントはハンドシェイクを完了できず、タイムアウトまで接続中のままです。例外が古いサーバーのアドレスのコピーであれば、新しいハンドシェイクは他の外向きパケットと同じに見えて捨てられます。どちらの場合もブラウザーからは同じに見えるため、六秒後に復帰する切り替えと決して復帰しない切り替えが同じ原因を共有することがあります。

新しいエンドポイントには遮断の穴が必要です

トンネルを築くには、クライアントが物理インターフェースから新しいサーバーのアドレスとポートへパケットを送る必要があります。たとえば一般的な WireGuard プロファイルなら UDP 51820、OpenVPN なら 1194 と 443 で、これは自分のプロファイルの指定によります。その通信はこれから作るトンネルの内側ではないため、一致する許可ルールがなければ、端末全体を対象とする遮断がそれを飲み込みます。

ホスト名ベースのプロファイルでは二つ目の条件が加わります。名前解決そのものです。遮断が上がる前にエンドポイントを解決すればキャッシュされたアドレスを使えますが、プロファイルがアドレスを切り替えたりキャッシュ項目が古くなったりすると、ハンドシェイクは許可ルールが覆わないアドレスへ向かいます。IPv6 はこれを目に見える形にします。デュアルスタックのエンドポイントは A レコードと AAAA レコードの両方を公開でき、v4 アドレスだけを覆う許可ルールでは、遮断された v6 アドレスに対してクライアントが再試行し続けるからです。

オプション名と既定値はクライアントとバージョンによって異なるので、スクリーンショットから推測せず、自分のクライアントの文書化された一覧を読んでください。OpenVPN Connect の設定リファレンスは openvpn.net/connect-docs/app-settings-windows にあり、クライアントが遮断と分割トンネルのオプションをどう説明するかの一例です。

Fail-closed はスイッチではなく状態機械です

ほとんどのクライアントは遮断をファイアウォールポリシーとして三つの状態で表します。トンネルが上がり通信がトンネルを通って遮断がない状態、トンネルが下がって遮断が有効な状態、そして遷移中で遮断が有効なうえにエンドポイントへの一時的な例外がある状態です。不具合が住むのは三つ目の状態で、数秒のうちに二度変わらなければならず、そこから抜けられない様子は恒久的な遮断とまったく同じに見えます。

仕組みはプラットフォームごとに異なり、失敗の仕方も異なります。Windows Filtering Platform のフィルターには重みがあるため、許可を上回る遮断フィルターは許可が存在していてもパケットを捨て続けます。また 強制終了されたクライアントプロセスが残したフィルター は、アプリが消えた後も端末をオフラインに保つことがあります。macOS のクライアントは通常 pf ルールをアンカーに書き、そこではルールの順序と迅速な判定がどのルールを適用するかを決めます。Linux のクライアントは通常、drop ポリシーとエンドポイント・トンネルインターフェース・ループバックへの明示的な許可を備えた nftables または iptables のチェーンを管理します。Android の常時接続 VPN と VPN なしの接続を遮断するオプションはこの中で最も厳しく、OS が遮断をアプリ単位ではなく端末全体に適用します。

WireGuard には独自の注記が必要です。AllowedIPs は経路の選択子であり、遮断器ではないからです。どの宛先をトンネルに入れるかを決めますが、まだトンネルがないパケットが Wi-Fi から出るのを止めることはしません。ファイアウォールルールのない WireGuard だけの構成では、kill switch は実質的に経路の不在であり、捨てられたハンドシェイクの後に実際のパケットが物理インターフェースから出ていくことがあります。

アイコンを見るのではなく間隙を測ります

状態ランプではなくパケットを見ます。Linux では一つの端末で公開アドレスへの遅い ping を開始し、もう一つで物理インターフェース上のトンネルの転送ポートを取得します。

ping -i 0.2 -c 100 1.1.1.1 | tail -5

sudo tcpdump -ni eth0 'udp port 51820'

両方が動いている間にクライアントでサーバーを切り替えます。重要なのは三つです。ping が止まる長さ、取得結果がハンドシェイクの新しいエンドポイントへの到達を示すか、そして通信がクライアントの状態が接続済みに変わる前か後かで戻るかです。ping の間隙が先に終わるなら、遮断が早く解除されたか、表示が認める前にトンネルが上がっています。間隙が後で終わるなら、表示は楽観的すぎます。

Windows では netsh wfp show state がスナップショットを書き出し、クライアントが切断されていると主張している間にまだ存在する遮断フィルターを検索できます。macOS では sudo pfctl -sr が読み込まれたルールとその順序を一覧します。どちらかのスナップショットをクライアント自身のログと突き合わせてください。ping の時間軸が、遮断が遅れて終わったのか決して終わらなかったのかを教えてくれます。

正常な暗転と固まった遮断

ある程度の中断はこの機能の目的なので、どの設定を変える前にも切り分けを行います。

What you seeUsually meansNext check
Two or three seconds of timeouts, then normal browsingExpected fail-closed gapNothing to fix
State says connected, traffic stays deadBlock filter or route left behindFirewall snapshot, client log
One app dead while others workTCP session bound to the old exit addressRestart the app
LAN devices unreachable after the switchLAN exception not reappliedAllow-LAN or split-tunnel setting
New server hangs, the old one reconnectsPermit covers only the old addressResolved address of the new host, including AAAA

二行目か五行目に当てはまるなら、試すために kill switch を無効にしないでください。経路の不具合が漏えいに変わるからです。クライアントのサービスを再起動するか、プロセスの終了後もフィルターが残る環境では端末を再起動し、遮断が消えるかを見ます。消えるなら、不具合は遮断そのものではなく切り替え中の後始末にあります。

次の切り替えの前に四つを確認します。エンドポイントの許可がプロファイルの解決するすべてのアドレスファミリーを覆っているか、クライアントのログが遷移の完了を示すか、ping の試験がアイコンではなく間隙を測っているか、クライアントを終了すると通常の接続が戻るか。切り替え中に保ち、その後に解放する kill switch は仕事をしています。早く解放するもの、あるいは決して解放しないものは、調べる価値があります。

関連記事