MTU / MSS を最適化する

ルーターを語る上で避けて通れないのが MTU / MSS ですね。自分も L2TPv3 によるレイヤー2 VPN を設定したのを機に、きちっと計算してみました。

MTU / MSS とは

MTU は通信インターフェースが通せる最大データサイズ、 MSS は TCP/IP の通信の際のデータ(ペイロード)の最大サイズです。例えば大抵の LAN のインターフェースである Ethernet の場合 MTU は 1500 バイトです。その Ethernet で TCP/IP のパケットを流す場合、 MSS は大抵の場合

MTU – IP ヘッダ – TCP ヘッダ
= 1500 – 20 – 20
= 1460

となります。パケットの大きさが MTU の大きさを超えると不必要にパケットが分割され、通信が遅くなります。そのようなオーバーヘッドを避けるには、ルーターで適切に MTU / MSS を設定してやる必要があります。

実は MTU はきちんと設定しなくても TCP 通信では大抵の場合自動調整されますが、「あるサイトは見られるけど、別のあるサイトはブラウザーが固まったようになって見られない」という問題が出ている場合は、そのサイトへの経路上に ICMP をブロックするルーターがあり、経路の最小 MTU がうまく調整されないことが原因だったりします。この場合も自分のルーターで MTU / MSS を適切に設定してやることにより解消できたりします。

どういうときに使うのか

例えばフレッツの PPPoE (IPv4) を使う場合、 MTU は 1454 以下 ( MSS 1414 以下 ) でないと通信に問題が出る場合があります。なので自宅のルーターにフレッツの PPPoE を認証させる時は、一緒に MTU も 1454 と設定します。また、その際ルーターに経路上の MTU がわからなくても MSS を強制的に設定する MSS Clamping の機能ある場合、 MSS Clamping を 1414 にしておくときちんと通信できるようになったりします。

そしてパケットの複雑なカプセル化を伴う VPN を使う場合、 MSS を適正な値に設定することは大変重要です。

しかしどんなプロトコルを使って、何をどうカプセル化するかによって、 MTU / MSS は色々変わります。自分が使っているパターンで最も複雑な、レイヤー2 VPN の「 TCP/IP over Ethernet over L2TPv3 over IPsec over フレッツ PPPoE over Ethernet 」ではどの値が最適なのか知りたかったので、腰を落ち着けて計算してみました。 MTU はこのページにあるように Ping でコツコツ調べるのが王道ですが、 L2TPv3 トンネルはレイヤー2通信をうまく扱うよう設計されたせいか、大きなパケットが来ると空気を読んで分割してくれたりしちゃうようです。なので、計算しないとダメそうです。

MTU / MSS の計算例

TCP/IP over
Ethernet
Ethernet MTU 1500
IP 20
TCP 20
= MSS 1460

もっとも基本的な例です。世の中のほとんどの Ethernet ポートの MTU はデフォルトで 1500 になっています。なので、フレッツを使っている、もしくは特定のサイトを見るときに MTU / MSS を小さくしないと問題がでる、等の場合以外は何も設定を変える必要がないかもしれません。

TCP/IP over
フレッツ PPPoE over
Ethernet
Ethernet MTU 1500
フレッツ内 IP 20
フレッツ内 UDP 8
フレッツ内 L2TP 16
認証用 PPP 2
= フレッツ PPPoE MTU 1454
IP 20
TCP 20
= フレッツ PPPoE MSS 1414

フレッツの IPv4 PPPoE を使っている場合の例です。フレッツ PPPoE 経由でルーターから発信されるパケットは、まず6バイトの PPPoE ヘッダと2バイトの PPP ヘッダが付いた状態で送信されます。その後収容局ルーターが PPPoE ヘッダを除去し、代わりに IP + UDP + L2TP ヘッダを付けます。この部分で MTU = 1500 を超えないよう、ルーターの PPPoE MTU を 1454 にするのが望ましいです。

TCP/IP over
IPsec (ESP) over
フレッツ PPPoE
PPPoE MTU 1454
IP (IPsec) 20
SPI 4
シーケンス番号 4
初期化ベクトル (AES 256) 16
ESP 認証データ (SHA 1) 12
= ここまでの小計 1398
= 1398 以下で最大の 16 の倍数 1392
Padding (0)
Padding 長 1
プロトコル (次ヘッダ) 1
= IPsec 用仮想 MTU 1390
IP 20
TCP 20
= IPsec MSS 1350

TCP/IP のパケットが IPsec のトンネルモードでカプセル化されてる場合の、 ESP パケットから考えた MTU / MSS の例です。この場合の IPsec ESP アルゴリズム / ハッシュには aes256 / sha1 を使いました。 NAT-T 等を使っている場合は、さらに UDP ヘッダの8バイト分を引く必要があります。ここでは下記のサイトを参考にしました。
IPsec/IKEに関するFAQ
IPSec通信におけるTCP MSS調整機能

TCP/IP over
GRE over
IPsec (ESP) over
フレッツ PPPoE
PPPoE MTU 1454
IP (IPsec) 20
SPI 4
シーケンス番号 4
初期化ベクトル (AES 256) 16
ESP 認証データ (SHA 1) 12
= ここまでの小計 1398
= 1398 以下で最大の 16 の倍数 1392
Padding (0)
Padding 長 1
プロトコル (次ヘッダ) 1
= IPsec 用仮想 MTU 1390
IP (GRE) 20
GRE 4
= GRE MTU 1366
IP 20
TCP 20
= GRE MSS 1326

TCP/IP のパケットを GRE でカプセル化し、それが IPsec のトンネルモードでカプセル化されてる場合の例です。

TCP/IP over
Ethernet over
L2TPv3 (UDP) over
IPsec (ESP) over
フレッツ PPPoE
PPPoE MTU 1454
IP (IPsec) 20
SPI 4
シーケンス番号 4
初期化ベクトル (AES 256) 16
ESP 認証データ (SHA 1) 12
= ここまでの小計 1398
= 1398 以下で最大の 16 の倍数 1392
Padding (0)
Padding 長 1
プロトコル (次ヘッダ) 1
= IPsec 用仮想 MTU 1390
IP (L2TPv3) 20
UDP (L2TPv3) 8
L2TPv3 12
Ethernet 14
= L2TPv3 MTU 1336
IP 20
TCP 20
= L2TPv3 MSS 1296

これが「 TCP/IP over Ethernet over L2TPv3 over IPsec over フレッツ PPPoE over Ethernet 」の結果と相成りました。 TCP/IP のパケットを含んだ Ethernet フレームを L2TPv3 でカプセル化し、それを IPsec のトンネルモードでカプセル化し、それを PPPoE でカプセル化し・・マトリョーシカ何個分でしょうか。ともかく、パケットをルーターでフラグメントさせないためには MSS を 1296 以下にすれば良さそうです。シスコのサイトなどを見ると、そこからさらに余裕をもって小さくすることが推奨されており、自分の環境では保守的に MSS 1240 にしています。この計算はどうも自信がないので、間違いを見つけた方は是非お知らせください。


yabe.jp » Gadgets » MTU / MSS を最適化する