KUSONEKOの見る世界

VPN通信のMTU, MSSを指定する方法

IPsecの最適MTUについて本気出して考えてみた

VPNの最適なMTUはいくつなのかを調査・計算しました。計算機も作成しています。

上記の記事でVPNの最適MTUとMSSを導きましたが、どのようにその値で通信させるかを考えます。
方法としては、以下の3つです。
  1. netshで反映させる(Windowsのみ)
  2. レジストリ変更で反映させる(Windowsのみ)
  3. iptablesのmangleやnftablesでTCPハンドシェイクのMSS値を書き換える
1と2については、Windowsでしかできないことですが、TCP以外のUDPなどにも適用されます。
3については、AndroidやiPhoneにも適用させられますが、TCPのみとなります。
しかし、実際の通信はTCPがほとんどあり、リモートデスクトップのUDP通信は、1300バイト程度なので実害は無いでしょう。

RDPで最近知ったこと - MTUと3-way UDP handshake

WIndowsのRDPについて調べていて分かったことを記載しました。

また、WindowsのVPNインターフェースのMTUは、物理インターフェースのMTUのマイナス100の値になりますが、この減少量を減らすことはできませんでした。(例えば、マイナス90は不可、マイナス110は可能)
なので、VPN最適MTUの+100以上で物理インターフェースのMTUを設定しておく必要があります。

我が家の場合、VPNの最適MTUが1374なので、物理インターフェースが1474以上である必要があります。そのためデフォルトの1500のままにしておきます。

netshでのMTU設定方法

netshコマンドで設定する方法です。
これがシンプルで分かりやすいと思います。
設定をするにはVPNを接続した状態で行います。
そうしないとコマンド結果に出てこないからです。
  1. VPN接続する
  2. コマンドプロンプトを管理者権限で立ち上げる
  3. 現在の設定を確認
    C:\Windows\system32>netsh interface ipv4 show interface
    
    Idx     Met         MTU          状態                 名前
    ---  ----------  ----------  ------------  ---------------------------
     43          35        1400  connected     VPN
     13          50        1500  connected     Wi-Fi
  4. VPN最適MTUを入力
    C:\Windows\system32>netsh interface ipv4 set interface 43 mtu=1374
    OK
  5. 設定後の確認
    C:\Windows\system32>netsh interface ipv4 show interface
    
    Idx     Met         MTU          状態                 名前
    ---  ----------  ----------  ------------  ---------------------------
     43          35        1374  connected     VPN
     13          50        1500  connected     Wi-Fi

レジストリでのMTU設定方法

レジストリでも変える方法があります。
この方法はあまり実用的ではないと思います。
  1. レジストリエディタ(regedit)を起動する
  2. 以下のキーを設定する
    キー名前値(10進数)
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NdisWan\Parameters\Protocols\0\PPPProtocolTypeREG_DWORD33
    ProtocolTypeREG_DWORD2048
    TunnelMTUREG_DWORD1374
  3. VPNを接続しなおす

iptables/nftablesでMSS値の書き換え

VPNサーバで送受信またはVPNサーバを通過するTCPのSYNとSYN ACKのMSS値をiptablesで書き換える方法です。
これにより強制的にパケットの最大サイズを変更させます。

公式wikiでは、FORWARDで適用していますが、これだとVPNサーバへのTCPセッションが対象になりません。
なので、VPNサーバのin/out全てに適用するため、以下の2行を設定しました。
iptables -t mangle -A PREROUTING -m policy --pol ipsec --dir in -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1335:1536 -j TCPMSS --set-mss 1334
iptables -t mangle -A POSTROUTING -m policy --pol ipsec --dir out -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1335:1536 -j TCPMSS --set-mss 1334
--set-mss は、書き換えたいMSS値を入れます。
--mss では、書き換え対象のMSS値です。つまり、1335~1536の間の値であれば書き換え、それ以下であればそのままとなります。

nftablesでも同様にMSS値の書き換えができます。
以下の記事で書いています。

CentOS 8 で nftables を設定してみた

CentOS 8 でnftablesを設定しました。日本(国内)からのトラフィックのみを許可、VPNのMTU/MSS最適化もしてみました。

IPsec最適MTU/MSS計算機

最適MTU/MSSの計算機を作成しました。
こちらからどうぞ。

IPsec 備忘録

IPsecパケットのフォーマットと最適MTUの計算方法をまとめ、計算機を作成しました。最適MTUを設定することでVPNが快適になるかもしれません。