実際のアカウントを使わずに VPN キルスイッチを検証する方法
デコイページと予備のプロファイルでキルスイッチを検証する。各障害タイプを網羅し、curl の終了コードを読み、本当の遮断と DNS 障害を切り分ける。
キルスイッチが本当に効いているかを確かめるのに本物のアカウントは要らず、危険にさらされるのはまさに検証の側だ。このチェックは、通信がトンネルの外に出るか出ないかが決まらない短い時間帯を作るので、失っても構わないものを使うべきだ。私は今ではデコイページと予備のブラウザプロファイルで試しており、以前のブラウザとウェブメールを組み合わせた手順より明確な答えが得られる。以下ではクライアントが提示する順序、つまり設定、宛先、遷移、証拠の順にたどる。
この検証が答えるのは、この遷移のあいだにこのアプリケーションがトンネルの外のネットワークへ到達できるか、という一つの狭い問いだけだ。 残りのポリシーが妥当かどうかについては何も語らない。範囲をそこまで狭く保てば、結果は書き留める価値がある。
クライアントでスイッチとその適用範囲を探す
ネットワークの状態を変える前に、クライアントを開いて遮断設定を見つける。ベンダーによって呼び方は違い、キルスイッチ、ロックダウンモード、ネットワークロック、トンネル外の通信遮断などと呼ばれる。ラベルは、その中にあるオプションを説明してくれない。重要なのは、遮断が常時適用されるのか、アプリがトンネルの失敗を検知したときだけ適用されるのか、そしてすべてのアプリを対象にするのか選択したリストだけを対象にするのかだ。
次に、自分のクライアントが実際に実行できる遷移を列挙する。ユーザーによる切断、アプリの終了、サーバーとの通信断は、ほとんどのクライアントで別々のコード経路であり、同じ遮断ポリシーを共有していない。アプリの終了時に遮断を解除するものもある。何かが取り除くまでフィルタルールを残すものもある。想定せずに、使っているビルドのベンダーの設定リファレンスを読み、三つのうちどれを試すのかを書き留める。
プロファイルも記録する: プロトコル、アドレスファミリー、スプリットトンネリングが有効かどうか。プロファイルが一部のアプリを意図的に除外しているなら、端末全体を対象にすると言っても意味はなく、自分で設定した除外は漏えいではない。 OpenVPN Connect の設定リファレンス は、どのトグルがどの挙動を変えるのかを示す種類のページだが、ラベルはクライアントごとに異なる。
トンネルなしでも機能するデコイの宛先を選ぶ
デコイには二つの性質が要り、どちらを欠いても結果は読めなくなる。トンネルが切れていて遮断も無効のときは直接到達できなければならず、そうでなければ応答しなくなったのは単にホストが消えただけかもしれない。そしてログインもクッキーも支払いも不要であるべきで、漏えいの代償がセッションではなくログ一行で済む。
自分で管理するホスト上の静的ページが最もきれいな選択だ。素の HTTP サーバーを動かす予備の仮想マシンもほぼ同じくらい良く、公開の接続確認ページも、その可用性が自分の管理外であることを受け入れられるなら使える。アドレス、ポート、アドレスファミリー、名前解決が必要かどうかを記録しておき、どれも後で切り分ける必要が出る変数になる。
スイッチに触る前に基準を確立する。トンネルが上がっていればデコイはトンネル経由で応答し、ポリシールートが機能していることを示す。トンネルが下がっていて遮断が無効ならデコイは直接応答し、宛先が生きていることを示す。そうして初めて、遮断状態での失敗が何かを教えてくれる。
遷移を決まった順序で実行する
遷移は一度に一つずつ行い、クライアントがその間にルールを破棄して作り直すことが多いので、それぞれ数秒待って落ち着かせる。毎回同じ短いチェックを実行すれば、観察結果を比較できる:
curl -sS -o /dev/null -w 'http=%{http_code}\n' --max-time 5 http://decoy.example/
echo "curl_exit=$?"
dig +short decoy.example
curl -6 -sS -o /dev/null -w 'v6_http=%{http_code}\n' --max-time 5 http://decoy.example/
echo "curl_v6_exit=$?"
| Transition | Expected with the block on | Failure signature |
|---|---|---|
| Manual disconnect | Decoy stops answering within seconds | Decoy still returns 200 |
| Server or path failure | Blocked, with no exemption for the old endpoint | Direct access during the gap |
| Quit the app | Client-dependent; record what happens | Block disappears with the process |
| Wi-Fi to Ethernet | Block holds until the tunnel returns | Traffic flows mid-change |
アプリ終了の行は、普段クライアントを閉じないとしても独自に実行する価値がある。終了時に遮断が解除されるなら、クラッシュや強制更新でも同じ露出が生じるので、それは配備についての事実であり、自分の辛抱強さの問題ではない。Windows では同等の確認を Resolve-DnsName decoy.example と curl.exe -s -o NUL -w "%{http_code}" http://decoy.example/ で行う。
遮断と壊れたリゾルバーを切り分ける
ページが読み込めない原因はいくつもあり、そのうち一つだけがスイッチが働いている証拠だ。名前が解決できないなら、分かったのは DNS が遮断されているか壊れていることで、データ経路が遮断されていることではない。リテラルアドレスでも確認すれば、答えが名前解決に依存しなくなる。
curl の終了コードはこれらの場合を区別する。6 は名前解決の失敗、7 は接続の拒否、28 はタイムアウトだ。遮断されたルートは通常、リテラルアドレスに対するタイムアウトか拒否として現れ、DNS だけの遮断は 6 を残して他を隠す。キャッシュされたページやキャプティブポータルは目を欺くので、証拠になるのは画面ではなく終了コードだ。
リテラルアドレスを使って IPv6 でも確認を繰り返す。IPv4 を覆って IPv6 を無視する遮断は珍しくないのでメモに一行足す価値があり、トンネル外で IPv6 を無効にするクライアントなら両方のファミリーで明確に失敗するはずだ。
結果が及ぶ範囲を記録する
トンネルが戻ったら、デコイがトンネル経由で応答し、リゾルバーが答えを返し、ポリシーが置いた場所にあることを確認して復旧を確かめる。その後で実験を片付ける。一時的なファイアウォールルール、デバッグループ、テストプロファイルを残すと次の実行が混乱し、アプリより長く生き残ることがある。
一回の実行で覆えるのは一つのクライアントビルド、一つのプロファイル、一つの遷移、一つのアドレスファミリーだけだ。その四つを結果とともに書き留める:
- クライアントのビルドとプラットフォーム、設定がプロファイル単位か全体か。
- プロファイル、プロトコル、スプリットトンネルの除外設定。
- 試した遷移と、それをどう起こしたか。
- アドレスファミリーと DNS、遮断時と非遮断時の curl 終了コード。
空欄が一つでもあれば、テストは終わっていない。ローミングするならネットワーク変更の行を繰り返す。無人での再起動は ルールが戻ることを確認する ことであり、これはスイッチではなく復元順序の問題だ。クライアント更新後は手順を再実行する。トグルはほとんど変わらないのにその背後の挙動は変わるからで、デコイはそのまま残しておけばローテーションも不要で次の確認は五分で済む。