一つのサブネットが今もVPNのデフォルトルートを迂回する理由
フルトンネル下で一つのサブネットが直接通るのは、通常はより長いプレフィックスが勝っているのであって、漏えいではありません。ハーフデフォルト、ポリシールール、プロファイル例外を確認してください。
VPNをフルトンネルに切り替えると、ほとんどの通信は従い、そこであるアドレスだけが直接応答します — プリンター、NAS、10.x 上のジャンプホストです。明白な解釈はトンネルが漏れているというもので、デフォルトルートのメトリックを下げますが何も変わりません。その失敗した試みこそが手がかりです——デフォルトルートはフォールバックであって、判決ではありません。ルート検索は メトリックを比較する前に、最長一致プレフィックスを取るので、/24 は /0 に対して、どちらにどんな数値を付けても勝ち続けます。この順序が明確になれば、漏えいは通常、誰かが意図的に入れたルートか、クライアントが決してカバーするつもりのなかったプレフィックスです。
デフォルトルートが実際に約束するもの
0.0.0.0/0 は、具体性がゼロビットで、すべての IPv4 宛先に一致します。ホストが自分のテーブルでより良く説明できないものに到達できるように存在します。192.168.1.0/24 へのルートは 24 ビットの一致を持ち、そのため 192.168.1.40 については、誰かがメトリック、管理距離、あるいはクライアントが優先度フィールドと呼ぶ何かを比較する前に勝ちます。同じ規則は Linux FIB、Windows のルーティングテーブル、macOS の背後の BSD スタックにも当てはまります。
通常の LAN では、その挙動は特長です。ローカルサブネットは直接接続され、トンネルがブラウジングを運ぶ間もプリンターは動き続け、何も誤設定されていません。問う価値のある問いは、その一つのアドレスがなぜ直接行くのかではなく、どのテーブルのどのプレフィックスがそれに一致するのか、そして誰がそれをそこに置いたのかです。
ハーフデフォルト、あるいはデフォルト項目が無傷に見える理由
最もきれいな例は redirect-gateway def1 の OpenVPN です。デフォルトを削除して置き換える代わりに、0.0.0.0/1 と 128.0.0.0/1 を追加します。このペアで IPv4 全体を覆い、各プレフィックスは /0 より長く、両方ともルーターのデフォルトをそのままにしたまま打ち勝ちます。後でルート一覧を実行すると、元のデフォルトはまだそこにあり、まだあなたのゲートウェイを指しており、インターネット宛先には決して選ばれません。
WireGuard の wg-quick はポリシールーティングで同じ結果に到達します。AllowedIPs が 0.0.0.0/0 を覆うと、独自のテーブルを作り、マークされたパケットをそこへ送り、メインテーブルの長さゼロのプレフィックスを無視するルールを追加します。メインテーブルはデフォルト項目を保ち、ルールはインターフェースが所有する通信についてトンネルテーブルを先に参照すると決めます。
どちらの設計も、トンネルの外にちょうど一本のルートを必要とします——元のゲートウェイ経由で VPN サーバー自身のアドレスへのホストルートです。これがないと、クライアントはトンネルを構築するパケットをトンネルの中で運ぼうとし、接続は決して完了しません。したがって、厳格なフルトンネルプロファイルでも、テーブルにトンネル以外のルートがあるのは正常です。疑う価値があるのは、本当に気にする宛先を覆うルートです。
メトリックは同点を決め、プレフィックスは勝者を決める
メトリックは、宛先に同じ程度一致する候補の間でだけ比較されます。Linux では ip route get 10.20.5.9 がテーブルとともに勝者を表示し、ip route show table all が候補を一覧します(ハーフデフォルトや、ルールが指すテーブルも含みます)。Windows では Find-NetRoute -RemoteIPAddress 10.20.5.9 が選択されたルートと送信元アドレスを返し、Get-NetRoute が生のテーブルを表示します — ただし実効コストはルートメトリックとインターフェースメトリックの合計なので、遅いアダプターは勝っているように見える同点を落とすことがあります。
三つのケースで、目にするものの大半を説明できます:
- 同じ宛先、/24 対 /0:メトリックが何と言おうと、/24 がプレフィックス長で勝ちます。
- 同じ宛先、異なるメトリックの二つの /24:実効メトリックの低い方が勝ちます。
- 同じ宛先、二つのテーブル、片方はポリシールールで選ばれる:ルールが先にテーブルを選び、プレフィックス比較はその中で行われます。
三番目のケースが、こうした報告の大半が行き着く先です。Linux の ip rule や Windows の VPN トラフィックフィルターは、トンネルのデフォルトを決して持たなかったテーブルへ通信を送ることがあり、メインテーブルはその間ずっと完璧に見えます。
通常、この迂回を所有しているのは誰か
テーブルではなく、プロファイルから始めます。スプリットトンネル構成やアプリごとの VPN 設定は、名前付きプレフィックスを意図的にトンネルの外に残し、一つのプライベートサブネットを保護し、一般のブラウジングを直接通す業務プロファイルは設計どおりに動いており、それを上書きすると本来強制するはずのポリシーが壊れます。Microsoft の VPN ルーティング ガイダンス も、強制トンネル通信と明示的な例外の間に同じ線を引いており、何かを編集する前の有用な照合になります。
次に、残骸を探します。もう存在しないインターフェースや、以前のネットワークのアドレスを指すルートは、ドッキングステーション、USB アダプター、コンテナブリッジが出入りした後に現れます。一度削除しても終わりではありません:NetworkManager の接続プロファイル、netplan ファイル、Windows の永続ルートは、次の接続や起動でそれを再インストールします;だから何かを編集する前に、それを所有するファイルやプロファイルを見つけます。
次に IPv6 を単独で確認します。 ip -6 route と Get-NetRoute -AddressFamily IPv6 は別々の状態、別々のデフォルト、別々のクライアント挙動を持ちます。IPv4 だけの監査は、ネイティブの IPv6 経路を静かに好むデュアルスタックホストについて何も言えず、それだけでクライアントがスプリットトンネルに見えることがあります。
アプリケーション自身の流れで確認する
アプリが実際に使う宛先を記録し、そのアプリがバインドする送信元アドレスからどの経路を取るかをシステムに尋ねます。 ip route get 10.20.5.9 from 192.168.1.40 が Linux でそれに答え、Find-NetRoute -RemoteIPAddress 10.20.5.9 とローカルアドレスが Windows でそれを行います。結果をプロファイルの主張と比べます。ブラウザーの公開 IP ページは一つのプロトコルで一つの宛先を試すだけで、苦情の元になったプライベートアドレスについては何も言いません。
違いを説明する最も狭いオブジェクトを直します。例外が承認済みならプレフィックスを書き留めて触らない;そうでなければ、デフォルトのメトリックを下げるのではなく、ルートを削除するかトンネル経由の明示的により狭いルートを追加します。メトリックを下げても長いプレフィックスには勝てず、二つの /1 ルートがインターネット経路を所有しているときにデフォルトを編集しても何も変わりません。
次にトンネルを再接続し、同じクエリを繰り返します。クライアントは接続のたびにルートを再インストールするので、次のハンドシェイクまでしか持たない変更は検証されていません。経路がまだ逸れるなら、残る容疑者はポリシールール、二番目のテーブル、クライアント側のフィルターであり、デフォルトルートではありません。
- アプリが実際に使う宛先と送信元アドレスを名指しします。
- 勝ったルートを
ip route getかFind-NetRouteで表示します。 - /1 のペアとポリシーテーブルのどちらがインターネット経路を所有しているか確認します。
- 宛先に一致する /0 より長いすべてのプレフィックスを列挙します。
- IPv6 の確認を別途繰り返します。
- 生き残ったルートを、それをインストールするファイル、プロファイル、フィルターまでたどります。
- 修正済みと呼ぶ前に、再接続してクエリを再実行します。
七つすべてがプロファイルと一致するなら、トンネルは設定されたとおりに動いており、修正はメトリックではなくプロファイルに属します。