NetworkTips

Windowsで通信が思った経路を通らない【route printのメトリックとVPNの仕組み】

スポンサーラベル
VPNの仮想アダプタは自分を100 Gbpsと申告するため、自動メトリックが最小の5になり既定ルートを奪う Network

当サイトはアフィリエイト広告を利用しています。

「VPNを繋いだ途端に社内サーバーへ届かなくなった」「Hyper-Vを入れてから通信の出口が変わった」。どちらもWindowsの自動メトリックで説明がつきます。

やっかいなのは、誰も手で設定していないのに起きることです。設定画面を見ても「自動」としか書いておらず、犯人が見えません。

VPNの仮想アダプタは自分を100 Gbpsと申告するため、自動メトリックが最小の5になり既定ルートを奪う

この記事では、Windows 11(build 26200)で実測した値を使って、経路が決まる仕組みと調べ方を順に見ていきます。コマンドはすべて標準搭載で、追加インストールは不要です。

1. 結論:まず引くのは Find-NetRoute

長い出力を読む前に、「この宛先はどこから出るのか」を1行で聞くのが早いです。

# 宛先を指定すると、実際に使われる経路と送信元IPが返る
Find-NetRoute -RemoteIPAddress 8.8.8.8
IPAddress      : 192.168.10.128
InterfaceAlias : vEthernet (LAN)

route print を目で追って「たぶんこれ」と当てる必要はありません。Windowsが実際に選ぶ答えをそのまま返してくれます。

社内サーバーに届かないときは、届かない宛先と届く宛先の両方で引いて比べます。InterfaceAlias が変わっていれば経路の問題、同じなら経路以外(ファイアウォールや名前解決)が原因です。

2. route print の Metric は足し算の答え

経路の一覧を見るときは route print を使いますが、この Metric 列は2つの値の合計です。

route printのMetricはRouteMetricとInterfaceMetricの合計

実測した1行で確かめます。

Network Destination        Netmask          Gateway       Interface  Metric
     192.168.10.0    255.255.255.0         On-link    192.168.10.128    281
# 同じ経路を Get-NetRoute で見ると、内訳が分かれて返る
Get-NetRoute -DestinationPrefix 192.168.10.0/24 |
  Format-Table ifIndex, RouteMetric, InterfaceMetric
ifIndex RouteMetric InterfaceMetric
      8         256              25

256 + 25 = 281 です。route print で見た数字と、インターフェースのメトリックを直接比べると話が合いません。

ここでつまずきやすいのは、変更できるのは InterfaceMetric のほうだという点です。RouteMetric の 256 はオンリンク経路に自動で付く固定値で、触る対象ではありません。

# 優先度を上げたいインターフェースの値を小さくする(要管理者権限)
Set-NetIPInterface -InterfaceIndex 8 -InterfaceMetric 10

なお既定ルート(0.0.0.0/0)だけは RouteMetric が 0 なので、合計とインターフェースの値が一致します。既定ルートだけ見ていると、この足し算に気づけません。

3. ネット上の「メトリック表」は古い版かもしれない

自動メトリックはリンク速度だけで決まります。ところがMicrosoftの同じページに表が3つ載っています(公式ドキュメント)。

対象1 Gbps のとき
旧版(Windows XP SP2 より前)10
Windows XP SP2 以降10
Windows 10 以降(有線など)25
Windows 10 以降(無線)30

日本語の解説記事は旧版の表を引用しているものが多く、実機で 25 を見て「表と合わない」となります。Windows 10以降の表は次のとおりです。

100 Gbps 以上           5
 40〜100 Gbps          10
 10〜40 Gbps           15
  2〜10 Gbps           20
200 Mbps〜2 Gbps       25   ← 1 Gbps はここ
 80〜200 Mbps          35
 20〜80 Mbps           45

注目したいのは、無線だけ別の表になっていることです。無線は 2 Gbps 以上でも 25、500 Mbps〜2 Gbps なら 30 です。つまり同じ 1 Gbps でも有線 25 / 無線 30 となり、有線を優先する挙動が表そのものに組み込まれています。ドッキングステーションに挿すと通信が有線へ移るのは、この差です。

4. VPNが既定ルートを奪う仕組み

ここからが本題です。この端末のアダプタを一覧にします。

# リンク速度と自動メトリックの対応を並べる
Get-NetIPInterface -AddressFamily IPv4 | Sort-Object InterfaceMetric | ForEach-Object {
  $a = Get-NetAdapter -InterfaceIndex $_.ifIndex -ErrorAction SilentlyContinue
  [pscustomobject]@{
    Alias  = $_.InterfaceAlias
    # アダプタが申告しているリンク速度。ここが自動メトリックの入力になる
    Speed  = if ($a) { $a.LinkSpeed } else { '-' }
    Metric = $_.InterfaceMetric
    Auto   = $_.AutomaticMetric
  }
} | Format-Table -AutoSize
Alias                              Speed    Metric     Auto
-----                              -----    ------     ----
OpenVPN Wintun                     100 Gbps      5  Enabled
vEthernet (LAN)                    1 Gbps       25  Enabled
vEthernet (WSL (Hyper-V firewall)) 10 Gbps    5000 Disabled
vEthernet (Default Switch)         10 Gbps    5000 Disabled

VPNの仮想アダプタが、自分のリンク速度を 100 Gbps と申告しています。 公式表の「100 Gbps 以上 = 5」に素直に当てはまり、メトリックは 5 になります。物理NIC側は 1 Gbps なので 25 です。

つまりVPNを接続すると、何も設定していないのに既定ルートがVPN側に移ります。AutomaticMetric は Enabled のまま、誰も手を加えていません。仮想アダプタが物理的な速度制約を持たないので、速い値を申告しているだけです。

VPN製品側で「スプリットトンネル」を設定していても、経路が1本も配られていなければWindowsはメトリックだけで判断します。 設定したつもりで効いていないときは、Get-NetRoute -DestinationPrefix 0.0.0.0/0 で既定ルートが何本あるかを数えてください。

5. Hyper-VとWSLだけメトリックが5000の理由

上の表でもう1つ目を引くのが、WSLとHyper-Vの仮想スイッチが 5000 で、しかも AutomaticMetric が Disabled になっている点です。

これは理屈が通っています。この2つは 10 Gbps を申告しているので、自動のままだと表に従って 15 になり、物理NICの 25 より優先されてしまいます。ホストの通信が仮想スイッチ側へ吸われては困るため、Microsoftが意図的に手動値へ固定しています。

逆に言えば、手動で設定されたメトリックを見たら「誰かが意図的にやった」と判断してよいということです。AutomaticMetric の列は、犯人が仕組みなのか人なのかを切り分ける手がかりになります。

6. 物理NICにIPアドレスが付いていない

Hyper-Vを有効にしていると、こういう状態になります。

ifIndex Name                 Status  LinkSpeed
     10 イーサネット 4       Up      1 Gbps      ← 物理NIC。IPv4インターフェースが無い
      8 vEthernet (LAN)      Up      1 Gbps      ← こちらにIPが付いている

物理NICは仮想スイッチにぶら下がる形になり、IPアドレスは vEthernet 側へ移ります。物理NICを見て「IPが無い、壊れた」と判断しないようにしてください。Get-NetAdapter には出るのに Get-NetIPInterface には出ない、という形で現れます。

7. tracertとpathpingは目的が違う

経路が分かったら、どこまで届いているかを見ます。

tracert -d -h 10 192.168.10.1   # -d で逆引きを省略(体感でかなり速くなる)

* が出ても障害とは限りません。 途中のルーターがICMPの応答を返さない設定は珍しくなく、その先の行で応答があれば通信自体は通っています。最終行だけを見てください。

pathping はホップごとのパケットロス率まで測れますが、既定では相当に待たされます。実測しました。

コマンド所要時間(1ホップ)
pathping -n 192.168.10.126.1秒
pathping -n -q 10 192.168.10.12.6秒

既定はホップあたり100回の問い合わせです。切り分け中に何度も回すなら -q 10 で十分で、10倍速くなります。

Computing statistics for 25 seconds...
Hop  RTT    Lost/Sent = Pct  Lost/Sent = Pct  Address
  1    3ms     0/ 100 =  0%     0/ 100 =  0%  192.168.10.1

なおtracertは行きの経路しか見ていません。戻りの経路は別で、左右対称とは限りません。片方向だけ遅いときに「tracertは正常だから問題ない」と結論づけないようにしてください。

8. 出力を人に見せる前に消すもの

route print の先頭には Interface List が付き、ここにMACアドレスが並びます。

Interface List
  8...00 11 22 33 44 55 ......Hyper-V Virtual Ethernet Adapter #2

ブログや問い合わせメール、ベンダーへの資料に貼るときは、この部分を消すか伏せ字にしてください。経路表そのものには必要のない情報です。接続先のSSID名や仮想スイッチ名が社名や拠点名になっていることもあるので、あわせて確認してください。

9. まとめ

Windowsの経路を確認する要点を整理します。

  • まず Find-NetRoute -RemoteIPAddress を引く。 実際に選ばれる経路と送信元IPが1行で返る
  • route print の Metric は RouteMetric + InterfaceMetric の合計。内訳は Get-NetRoute で見る
  • 触るのは InterfaceMetric。 RouteMetric 256 はオンリンク経路の固定値
  • メトリックの表は公式ページに3つある。 Windows 10以降は 1 Gbps で 25
  • 無線は別表で値が大きい。 有線優先が仕組みとして組み込まれている
  • VPNの仮想アダプタは 100 Gbps を申告する(実測)。だから自動で 5 になり既定ルートを奪う
  • WSLとHyper-Vの 5000 は手動設定。 AutomaticMetric の列で人為か仕組みかを切り分ける
  • 物理NICにIPが無いのはHyper-Vが原因。vEthernet 側に移っている
  • pathping は -q 10 で10倍速い(26.1秒 → 2.6秒)
  • route print の出力にはMACアドレスが含まれる。 貼る前に消す

設定画面を開いても「自動」としか出ないので、数字で確かめるのが一番速いと思います。

経路が正しいのにパケットが届かないときは、Windows標準のpktmonでパケットが落ちた場所を突き止めるで、どのコンポーネントが落としたかを調べられます。

コメント

タイトルとURLをコピーしました