WSL2 × VPN × MTU問題──“通信が不安定”をどう解決したか
はじめに
WSL2環境でVPNを利用すると、通信が不安定になることがあります。
たとえば「pingやHTTPは通るのに、TLSやSSH、git、pacmanだけが固まる」といった現象は、MTU(Maximum Transmission Unit)設定が原因であることが多いです。
私はフレッツ光を使っているためMTUが1454に設定されており、VPN(WireGuard)のカプセル化によってさらに小さくなります。
WSL2のデフォルトMTU(通常は1500)とのギャップが大きいと、通信トラブルが発生しやすくなります。
結論:解決までの流れ
1. Windows側でVPNインターフェースのMTU値を確認
まずPowerShellで以下を実行し、VPNインターフェースのMTU値を調べます。
netsh interface ipv4 show interfaces
2-1. WSL2でMTUを設定
WSL2で調べたMTU値に合わせて設定します(例:1400)。
ip link show eth0 # 現在値の確認
sudo ip link set eth0 mtu 1400
この設定で通信が改善すれば、MTU設定が問題だったと判断できます。
※この設定は一時的で、WSL2再起動後は元に戻ります。
2-2. 最適なMTU値を調査して再設定
もし改善しない場合や、VPNインターフェースのMTU値が分からない場合は、WSL2内で最適なMTU値を調べます。
for size in $(seq 1472 -4 1292); do
echo "Testing size $size"
if ping -c 1 -M do -s $size google.com > /dev/null 2>&1; then
echo "Success: $size + 28 = $((size + 28)) (MTU)"
break
fi
done
(実行結果例)
Success: 1364 + 28 = 1392 (MTU)
この値(例:1392)で設定し直します。
sudo ip link set eth0 mtu 1392
なぜMTUで問題が起きるのか
- MTUは、一度に送信できる最大パケットサイズです。
- 通信経路上で最も小さいMTUが実際の上限となります。
- VPNやPPPoEなどでカプセル化が重なると、MTUがさらに小さくなります。
- WSL2のデフォルトMTU(通常1500)が経路のMTUより大きい場合やDF(Don't Fragment)フラグが立っている場合、パケットが破棄され、通信が途切れる・遅延する・応答がなくなるなどの問題が発生します。
MTU設定の永続化
一時的な設定ではWSL2再起動で元に戻るため、永続化が必要です。
永続化方法
-
シェルの設定ファイル(zshrc, bashrc等)で実行
- シェル起動ごとに毎回実行されるため、冗長になる場合があります。
-
wsl.conf
の[boot]command
で実行- systemdが無効な場合は有効な方法です。
- systemdが有効な場合は、ネットワーク初期化前に実行されてしまう可能性があり、実行順序が保証されません。
-
systemdサービスとして登録
- systemd有効環境では、ネットワーク初期化後に確実に実行できます。
systemdサービスで自動設定
/etc/systemd/system/set-mtu.service
を作成します。
[Unit]
Description=Set MTU for network interface
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/ip link set eth0 mtu 1392
[Install]
WantedBy=multi-user.target
作成後は以下を実行します。
sudo systemctl daemon-reload
sudo systemctl enable set-mtu.service
sudo systemctl start set-mtu.service
これで再起動後も自動でMTUが設定されます。
おわりに
WSL2とVPNの組み合わせでは、MTUの設定ミスが通信トラブルのよくある原因です。
フレッツ光やWireGuardなど、MTU値が小さくなりやすい環境では、通信が途切れる・遅延する・応答がなくなる場合、まずMTU設定を見直してみてください。
Discussion