VPN の MTU, MSS の調整法

2005.01.23 Takaya Sakusabe

IPSecの場合

FreeBSD の IPSec による VPN の実現は gif という仮想ネットワークインタフェイスに頼っています。これは IP データグラムの中にそのまま IP データグラムを入れるものです。当然ですが、MTU は外側の IP ヘッダの分だけ小さくなってしまいます。

# ifconfig fxp0
fxp0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        options=8<VLAN_MTU>
        inet A.B.C.D netmask 0xffffff00 broadcast A.B.C.255
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
# ifconfig gif0
gif0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280
        tunnel inet A.B.C.D --> E.F.G.H
        inet W.X.Y.Z --> S.T.U.V netmask 0xffffffff 
	  

gif では MTU を指定する(仮想的に大きくすること)はできません。そこで、ports の net/tcpmssd をつかいます。tcpmssd は MSS を強制的に指定した値に書き換えてします divert 用デーモンです。

tcpmssd を /etc/rc.local を使ってOS起動時に起動します。

/usr/local/bin/tcpmssd -p <divertソケットの番号適当でよい> -m 1280

/etc/rc.firewall の中で、MSS を書き換えるパケットを tcpmssd に流し込むようにします。

        # TCP MSS adjustment
        ${fwcmd} add divert <divertソケットの番号適当でよい> tcp from <VPN先のサブネット;例:192.168.88.0/24> to <こちらのサブネット;例:192.168.99.0/24> tcpflags syn out via ${iif}

この設定を双方で対称に行います

OpenVPN の場合

OpenVPN は MTU を設定するコマンドラインオプションがありますので、それをつけて起動します。

--tun-mtu 1500 --fragment 1300 --mssfix

本当は、この三つのオプション全部は必要ないのではないかと思うのですが、試行錯誤の過程で全部つけてしまいました。

IPSec vs OpenVPN

Peerのアドレスが固定できるか否か

VPNの Peer ルータの外側のアドレスが固定できない状況というのがあります。例えば、xDSL の自宅から研究室という状況では自宅側の xDSL ルータの外側のアドレスは固定できません。あるいはモバイルです。そのような状況では IPsec は設定できません。gif によるトンネルの確立や、setkey コマンドによる IP を暗号化するか否かの決定(ポリシー)等で、IP アドレスは指定されています。一方、OpenVPN の場合はサーバ/クライアントという役割があり、VPN の確立には手順がありますので、クライアント側のアドレスは流動的でもかまいません。

性能(レイテンシ)

レイテンシに関しては IPsec に分があります。一旦、デーモンプロセスを経由する OpenVPN とカーネル内部だけで処理される IPsec ではこの差が付くのは仕方がありません。