Windows のアプリ別 VPN トリガーとスプリットトンネリング:何が分離するか
アプリで起動する Windows VPN プロファイルはトンネルを開くだけです。ルーティングされたスプリットトンネルが中に入るものを決め、両者は一つのアプリに対して別々に失敗します。
二つの Windows 設定は「設定」では同じに見えますが、動作はまったく異なります。一つはアプリ トリガー付きのコピーした VPN プロファイルで、実行ファイルを一つ起動するとトンネルが立ち上がります。もう一つはスプリットトンネルのプロファイルで、そのルート一覧がたまたまそのアプリの通信先を覆っています。前者はトンネルがいつ存在するかに答え、後者はどのパケットが入るかに答えます。マシンの残りを物理リンクのままにできるのは後者だけです。
トリガーはライフサイクルの規則であり、ルーティングの規則ではない
Add-VpnConnectionTriggerApplication 実行ファイルのパスをプロファイル名に結び付けます。そのプロセスが起動すると、リモート アクセス接続マネージャーがプロファイルをダイヤルし、 トリガー条件が終わると接続が切れることがあります。このやり取りのどこもソケットを検査しません。このコマンドレットには昇格したシェル、バイナリへの完全なパス、そして -Force 既存のエントリを置き換えるときは -Force も必要で、関連付けが残ったかは次で確認します。 Get-VpnConnectionTrigger プロンプトを信じる代わりに、Microsoft の Add-VpnConnectionTriggerApplication のリファレンス にパラメーターと例が載っています。
「トリガーが何もしない」という報告のほとんどは二つの限界で説明できます。トリガーは全ユーザー向けプロファイルを前提に作られているため、まずプロファイルのスコープを確定してください。またアプリのパスは、実際に動くバイナリと一致している必要があり、ショートカットや二つ目のプロセスを生むランチャーではいけません。もう一つの限界は仕様で、Windows が信頼済みと分類するネットワークでは、プロファイルは社外で使う想定なので、トリガーは待機したままになります。
Add-VpnConnectionTriggerApplication -Name "APP_VPN" -ApplicationID "C:\Program Files\Vendor\app.exe" -Force
Get-VpnConnectionTrigger -Name "APP_VPN" | Format-List *
Get-VpnConnection -Name "APP_VPN" | Format-List Name,ConnectionStatus,SplitTunneling,AllUserConnection
スプリットトンネルがトンネルを横切るものを決める
スプリットトンネルを無効にすると、Windows は VPN インターフェイスに低メトリックのクラスベース既定ルートを入れます。ブラウザーや更新サービスを含むすべてのソケットがそれに従うため、この構成のトリガーはプロファイルが接続している間じゅうマシン全体を動かします。トリガーはあくまでライフサイクルの規則で、影響範囲はルートから来ています。
スプリットトンネルを有効にすると、プロファイルはゲートウェイがプッシュする、または VPN インターフェイスに追加したプレフィックスだけを運びます。それ以外はすべて物理既定ルートを使い続けます。これが一般に「一つのアプリを別の出口から」と言うときの構成で、最初から最後までルーティングの判断です。
Set-VpnConnection -Name "APP_VPN" -SplitTunneling $true
Get-VpnConnection -Name "APP_VPN" | Select-Object SplitTunneling
Get-NetRoute -InterfaceAlias "APP_VPN" | Sort-Object DestinationPrefix
ルーティングされたスプリットがアプリを分離しなくなる場所
よくある失敗は、トンネルのルート一覧に決して現れない宛先です。一つのアドレスでサインインしてから CDN からストリームする、あるいは十数の回転するエンドポイントを解決するアプリは、一部の接続を VPN インターフェイスに、残りを Wi-Fi に置きます。IPv6 は別のテーブルなので、IPv4 プレフィックスだけをプッシュするプロファイルは正しく見えても、アプリの IPv6 トラフィックはローカルにとどまります。
より小さな二つの影響も同じくらい重要です。最長プレフィックス一致が優先されるので、より具体的な on-link ルート、管理ホスト向けにプッシュした /32、二つ目のアダプターのサブネットは、あなたが気にするアドレスでトンネルを上回ることがあります。名前解決もルーティングより前に起きます。プロファイルの DNS サーバーや NRPT 規則が名前を覆わない限り、アプリは物理アダプター経由で解決し、トンネルされたプレフィックスの外にあるアドレスをダイヤルし得ます。
三つの形と、それぞれが何を買うか
この表は壁に貼っておきたい部分です。判断は機能ではなく影響範囲の話だからです。アプリの宛先が列挙できる安定したプレフィックスなら、ルーティングされたスプリットは最小の足跡で分離を実現します。そうでなければ、VM や 二台目のデバイスの背後に既定ルートのプロファイルを置くことで、一つ以上のプロセスを動かす代償と引き換えに分離を保てます。
| Shape | What starts the tunnel | What enters it | Pick it when |
|---|---|---|---|
| Trigger plus routed split | Process start | Only pushed or added prefixes | The app's endpoints are stable prefixes and the host should stay direct |
| Trigger plus default route | Process start | Everything, machine-wide | You need one exit for all traffic and accept the wider scope |
| Separate VM or device | Guest boot or login | Everything inside that guest | The app's destinations rotate, or the host must keep its own public address |
どれも提供しないのは、ホスト上のソケット レベルのバインドです。クラシックな Windows VPN クライアントには「このプロセスはこのアダプターを使う」という規則がありません。トリガーとルート フィルターは別の層にあり、インターフェイスを選ぶ層はルーティング テーブルです。ガイドがコピーしたプロファイルだけでアプリ別の強制を約束しているなら、どのルートやどのフィルターが仕事をしているのか尋ねてください。
一度の手順で両方を確認する
ライフサイクルとルーティングを別々に、この順でテストします。アプリを閉じ、プロファイルが Disconnected と報告することを確認し、次にアプリを起動して状態が変わったか見ます。トンネルが上がってから、特定の宛先がどこへ行くかを尋ねるべきで、推測ではなくアプリが実際にダイヤルするアドレスを使ってください。
$app = Get-Process app | Select-Object -First 1
Get-VpnConnection -Name "APP_VPN" | Select-Object ConnectionStatus
Get-NetTCPConnection -OwningProcess $app.Id -State Established | Select-Object RemoteAddress,RemotePort
Find-NetRoute -RemoteIPAddress 203.0.113.10
Find-NetRoute その宛先を運ぶインターフェイスと次のホップを示します。そこに物理の別名が出るなら、トンネルは上がっているがそのフローには無関係です。プッシュされたプレフィックス、より具体的なルート、IPv6 の順に確認してください。状態がまったく変わらないならトリガーが発火しておらず、実行ファイルのパス、プロファイルのスコープ、VPN クライアントの操作ログの三つを見ます。
次のテストが誠実になるようきれいに戻す
まずアプリ トリガー、次にプロファイルの順に、組み立てた逆順で削除します。トリガーを残したままプロファイルを消すと次の試行を混乱させる宙ぶらりんの関連付けが残り、 Remove-VpnConnection -Force コマンドレットの外で作られた phonebook エントリは、必ずしも消えるわけではありません。
ユーザーごとのエントリはユーザーの rasphone.pbk (Roaming プロファイル配下)にあり、全ユーザーのエントリは ProgramData の下です。プロファイルのスコープに合うストアを確認し、残したプロファイルを再接続して、そのルートと DNS がまだ正しく動くことを確かめてください。そうすれば後のテストは、残った状態ではなくあなたが加えた変更を測ります。
- トンネルはプロセス起動時に立ち、ログイン時ではありません。
- VPN インターフェイスには意図したプレフィックスだけが現れます。
- アプリの実際のリモート アドレスは VPN の別名に解決されます。
- プロファイルを削除した後に宙ぶらりんのトリガーは残りません。