WireGuard には MTU のネゴシエーションがない。インターフェースが渡したものをそのまま暗号化して送り出し、カプセル化したパケットが経路を超えれば、見えないどこかで破棄されるか分割される。インターフェースの MTU は誰かが選ぶ必要があり、その誰かとはインターフェースを立ち上げたツールである。

候補は三つあり、混同しやすい。

値の出どころになりうる三か所

値はインターフェース設定で明示的に指定できるほか、設定ツールが経路情報から計算したり、インターフェースを所有するネットワークマネージャーが設定したりする。素の wg 呼び出しは、wg が鍵とピアしか管理しないため、そのどれもしない。MTU はネットワークインターフェースに載っているので、ip link show wg0 がその値を読む場所になる。

どれが当てはまるか分からないときは、まず MTU を読み、そのあとでインターフェースを起動したのは誰かを突き止める。

インターフェースを動かしている主体で決める

wg-quick が起動するなら、明示的な MTU 行が優先し、なければ値を計算する。ネットワークマネージャーが起動するなら、そのマネージャーのプロファイルが決める。コンテナランタイムや事業者クライアントが起動するなら、wg-quick の挙動を前提にせず、そのドキュメントを読む。

判断すべきは、抽象的にどの数値が最良かではない。実際に設定できるのはどの構成要素か、である。

既定の計算がしていること

wg-quick はピアのエンドポイントまでの経路を引き、その出力インターフェースの MTU を取り、カプセル化のオーバーヘッドを差し引く。外側が IPv4 ならおよそ 60 バイト、IPv6 ならおよそ 80 バイトだ。結果は上限で抑えられ、1500 バイトの経路なら、一つのアドレスファミリーでしか通用しない値ではなく 1420 になる。これは妥当な既定値であって、あなたの経路の計測値ではない。

後段のトンネルやモバイル回線、フィルタされた ICMP 経路までは知りようがない。

この上限は本当の問いを隠している。経路が端から端まで本当に 9000 バイトなら、1420 は性能を机の上に置き去りにするし、経路が 1400 なら 1420 はすでに大きすぎる。既定値は妥協であり、そう扱うべきものだ。

経路が自分の下で変わるとき

Ethernet から Wi-Fi、さらにスマートフォンのテザリングへと移るノート PC は、起動時のインターフェース MTU をそのまま保つ。外側の経路は今はもっと小さいかもしれず、何も再ネゴシエートしない。トンネルを入れ子にすると、各層が同じ予算から自前のオーバーヘッドを引くため、さらに悪化する。オフィスで通用した値は、空港で通用する値ではない。

最近のハンドシェイクは鍵が機能していることの証明になる。大きなパケットが収まるかどうかは何も証明しない。

一度に一つの数値だけを試す

同じアプリケーションと同じ宛先のまま、一つの値だけを変えて測る。ping -M do -s 1372 は DF ビットを立てた 1400 バイトのパケットを試すもので、これが望ましい試験の形だ。小さな要求は通り大きな要求で止まるなら、経路の問題ではなくサイズの問題である。

変えるのは MTU だけにする。複数のパケットオプションを同時にいじっても、どれが効いたのかは分からない。

そして、MTU の変更で戻り経路の欠落や転送規則、DNS の失敗が直ると期待してはいけない。それらも通信が止まる症状を出し、それぞれ独自の試験がある。wg-quick のマニュアルに自動選択の仕様がある。

関連記事