2012-01-12

OpenVPNのスループットと最適化 - 1

By Taro Yamazaki  |  23:30

Jan Just Keijser氏の記事「Optimizing performance on gigabit networks」についてはこちらでも概要を取り上げましたが、記事全体にいろいろなヒントが含まれていますので、全文の日本語訳を掲載しています。意訳している部分もありますが、もし誤訳等に気づかれたらお知らせください。

OpenVPNのスループットを100Mbpsネットワークの上限に近づけることは比較的簡単です。この場合、VPNのスループットはネットワークそのもののスループットにかなり近づくことになります。しかし、ギガビット・ネットワークとなるとそう簡単ではありません。このページでは、VPNスループットを1Gbpsネットワークの上限に近づけるためにどんなことができるのかについて取り上げます。最後の部分では10Gbpsネットワークについても簡単に触れています。


ネットワーク構成

今回の測定は、ギガビットのネットワークスイッチに接続された数台のPCを使用して実施しています。
サーバー(2台)OS: CentOS 5.5 64bit
CPU: Intel Xeon E5440 (2.83GHz)
L2キャッシュ: 6MB
サーバーOS: CentOS 5.5 64bit
CPU: Intel Xeon E5660 (2.80GHz)
L2キャッシュ: 12MB
AES-NIサポートあり
ノートPCOS: Fedora 14 64bit
CPU: Intel i5-560M (2.66GHz)
L2キャッシュ: 3MB
AES-NIサポートあり
VPNのスループットの測定を始める前に、直接接続した場合のスループットをiperfを使って測定しておきます。その結果、940Mbpsという結果になりました。これはギガビットLANのスループットとして概ね妥当な値です。また、すべてのギガビットLAN上のすべてのスイッチのMTUサイズを1500に設定しておきます。

パケットの流れを理解する

まず、'iperf'サーバーと'iperf'クライアントの間のOpenVPNトンネルで、どのようにパケットが流れるのかを理解しておきましょう。その流れを図にすると次のようになります。


VPNサーバーのIPアドレスに'iperf'パケットを送ろうとすると、まずこのパケットはカーネルの'tun0'デバイスに入ります。このパケットはその後ユーザー空間のOpenVPNプロセスに転送され、ヘッダが除去されます。パケットはOpenSSL呼び出しによって暗号化され、署名されます。この際に使用される暗号化と署名のアルゴリズムは'--cipher'と'--auth'オプションによって指定できます。

この処理によって作られるパケットは'--fragment'と'--mssfix'オプションの設定値に基づいて分割(fragment)され、その後、暗号化されたパケットがOpenVPNサーバーに向けてネットワーク上を流れていきます。パケットを受け取ったサーバー側では、この逆の手順で処理を行うことになります。まずパケットが再構築され、復号された後、'tun0'インターフェイスに送られます。

基本構成

CentOS 5の場合、デフォルトのOpenVPNはバージョン2.1.4で、システムのOpenSSLのバージョンは0.9.8e-fipsです。

VPNトンネルの両端にあたるOpenVPNサーバー(リスナー)とOpenVPNクライアントの両方で、単純な共有秘密鍵の設定を行います。サーバーは次のように設定します。
openvpn --dev tun --proto udp --port 11000 --secret secret.key 
     --ifconfig 192.168.222.11 192.168.222.10
クライアントは次のように設定します。
openvpn --dev tun --proto udp --port 11000 --secret secret.key 
     --ifconfig 192.168.222.10 192.168.222.11 --remote server

この設定でiperfを実行すると、結果は156Mbpsとなりました。

Cipherをaes-256-cbcに設定すると、測定結果は126Mbpsに落ちます。なお、この測定結果は、E5440ベースのサーバーPC間で測定しました。

チューンナップ

次のような設定でチューンナップしてみます。
  • tunアダプタのMTUサイズ('--tun-mtu')の値を6000バイトまで増やします。これはギガビットLANでのジャンボフレームの考え方と同じです。ネットワーク上のスイッチで設定されているMTUサイズは置き換えられないことに注意してください。
  • OpenVPNの分割アルゴリズムを無効にします( '--fragment 0')。
  • OpenVPNのTCP最大セグメントサイズ設定を無効にします('--mssfix 0')。
サーバーは次のように設定します。
openvpn --dev tun --proto udp --port 11000 --secret secret.key 
     --ifconfig 192.168.222.11 192.168.222.10 --tun-mtu 6000 --fragment 0 --mssfix 0
クライアントは次のように設定します。
openvpn --dev tun --proto udp --port 11000 --secret secret.key 
     --ifconfig 192.168.222.10 192.168.222.11 --tun-mtu 6000 --fragment 0 --mssfix 0  
     --remote server

この設定で実験すると、iperfの結果は307Mbpsになりました。'--tun-mtu'の値をいろいろと変えて実験してみると、次のような結果になりました(速度の単位はすべてMbpsです)。
MTUBlowfishAES256
1500158126
6000307220
9000370249
12000416252
24000466259
36000470244
48000510247
60000488221
(これらの測定値については5%程度のバラつきがあります)

デフォルトのBlowfishを使用している場合は、'--tun-mtu'パラメータの最適値は48000バイトという結果になりました。この'--tun-mtu'設定の変更により、VPNのスループットは160Mbpsから510Mbpsに向上しました。

同様に実験すると、AES-256を使用した場合の最適値は24000バイトとなりました。

考察

「tunアダプタのMTUサイズの変更」と「OpenVPN内部の分割ルーチンの無効化」を組み合わせると、OpenVPNのスループットは大幅に向上します。これは、OpenSSLの暗号化/復号処理に大きなパケットでまとめて送ることによるパフォーマンス向上によるものと考えられます。内部の分割ルーチンを使用しない2番目の利点は、この処理をOSやカーネルのデバイスドライバに任せられることです。これらの設定はLANベースのVPNでは使用できますが、さまざまなアクセス環境が考えられる場合(モバイル接続など)には適していません。


Author: Taro Yamazaki

© 2015 yamata::memo | Distributed By My Blogger Themes | Created By BloggerTheme9
TOP