pingは成功し、大きな転送は止まり、トンネルは自分が正常だと報告します。誰かがインターフェースのMTUを下げ、別の誰かがMSSを制限し、ときには誰も記録しない理由で問題が消えます。二つの数値は別の対象を表しているので、間違った方を変えると偶然に見える修正になります。手順はこうです。層を特定し、対応する調整を適用し、新しい接続でテストします。

二つの数値、二つの対象

MTUはリンクまたはインターフェースに属します。分割せずに渡せる最大のパケットです。MSSはTCPに属します。セグメントが運べるTCPペイロードの最大量で、TCPヘッダーとIPヘッダーの両方を除きます。IPv4を使う一般的なイーサネットリンクでは、1500バイトのMTUからよく知られた1460バイトのMSSが得られます。これらの数値は異なる層を表し、異なる仕組みで交換されます。両方ともバイトで測られ、どちらも1500の近くにあるため、混同しやすいのです。

一方はインターフェースの設定として届きます。もう一方はSYNセグメント内のオプションとして届き、あなたのインターフェースを決して見ない端点の間で交渉されます。

外側の余分な負荷はどこに乗るか

VPNは内側のパケットを別のパケットの中に入れ、外側のパケットは物理経路に収まらなければなりません。カプセル化ヘッダー、外側のIPヘッダー、トランスポートヘッダー、そして任意の認証タグは、内側のパケットが使えないバイトを消費します。トンネルインターフェースを1500のままにすると、外側のパケットは経路が運べる量を日常的に超えます。分割禁止ビットが立っていると、ルーターはそれを捨ててICMPエラーを返すはずです。そのエラーがフィルタリングされると、送信側は決して知りません。

だから障害は選択的に見えます。小さな要求は完了し、セグメントを満たすものは止まります。大きなパケットだけが捨てられるからです。pingを通すトンネルは、データを運ぶトンネルではありません。

MSSを制限する方法と適用範囲

MSSクランプは、選んだ地点を通過するときにSYNセグメントの値を書き換え、両方の端点が理由も知らずにより小さなペイロードを選ぶようにします。Linuxでは明示的なルールで適用されるmangleテーブルのターゲットであり、意図した方向のSYNパケットに当てる必要があります。トンネルインターフェースとアドレス範囲に限定してください。広いルールはトンネルに入らない通信の挙動も変えてしまいます。

効果はTCPだけです。UDPアプリケーション、QUICセッション、独自のデータグラムを組み立てるプロトコルは影響を受けません。

固定した経路で診断する

一度に一つの変数だけを動かします。自分でサイズを選んだパケットでテストし、分割禁止フラグを立てて、カーネルが結果を隠さず報告するようにします。

障害がどこで始まるかを記録します。トンネルの内側か、トンネルインターフェースか、カプセル化後の物理経路かです。次に一つの数値だけを変え、別のテストではなく同じテストを繰り返します。既存の接続は交渉済みのMSSを保持するので、ポリシーの変更は新しい接続でしか見えません。だからキャッシュされたページはどちらの方向にも何も証明しません。一つの大きなアップロードが動き始めたら、あなたが学んだのはその経路についてであり、その上のすべてのプロトコルについてではありません。

それぞれの変更が直さないもの

インターフェースのMTUを下げても、すでに確立したセッションのMSSは変わりません。MSSを制限してもUDPフローには効かず、ICMPエラーが片方向だけフィルタリングされる経路も修復しません。どの変更も問題の一つの種類を直し、残りはそのままにします。

どの調整をどこに適用し、どのテストが違いを示したかを記録してください。そうしないと次の技術者が両方を適用し、どちらが効いたのかを言えなくなります。制約が現実的で恒久的なら、それを隠すクランプより、それを反映したトンネルMTUを選んでください。どうしてもクランプするなら、ルールは範囲を絞りコメントを残してください、説明のないmangleルールは既定で恒久化するからです。

関連記事