WSL2 内の Ubuntu 20.04 で VPN をつないだときだけ ssh できない

1 min read読了の目安(約800字

はじめに

WSL2 内の Ubuntu 20.04.1 でインターネット上のサーバに ssh しようとしたときに、全くつながらないという事象が発生した。
これは Windows を VPN につないでいると発生する。

現象

verbose モードで ssh すると以下の場所で止まる。

$ ssh example.org -v
...
debug1: SSH2_MSG_KEXINIT sent

原因

どうも MTU が経路のどこかで食い違っているのが原因らしい。

接続元(Windows; WSL2)と接続先(VPN ルータ)の MTU が異なる場合、小さい方が採用されます。接続元から VPN ルータにパケットを送る場合に、1500バイトを超えた場合はパケット分割(フラグメント化)が起こります。
フラグメント化はスループットが落ちてしまうのに加え、経路のどこかで分割を禁止するフラグ(DF ビット)が立っていると、送信元に ICMP パケットを送って最適な MTU を教えてもらうのですが、WSL2 がなぜか ICMP パケットを受信できないみたいで、通信がずっと待ち状態になってしまうのだと思います。(ブラックホール問題)。そのためハングアップしたように見えます。

https://blog.jicoman.info/2020/12/hangup-ssh-connection-using-wsl2/

対処

Web で調べると 1400 にしろだの、1456 にしろだの言っていたが、下げてもまったく通信できなかったのでもっと下げてみた(576)らつながった。
その後 1200 にしてもつながっていたが、まずは小さくしてから上げていくのがよさそう。

$ sudo ip link set eth0 mtu 1200

まとめ

WSL2 便利〜。

この記事に贈られたバッジ