2012-01-13

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

By Taro Yamazaki  |  21:20

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


OpenSSL + AES-NIパッチを使用する

次のチューンナップとして、OpenVPN 2.1.4とIntel AES-NIパッチ適用済のOpenSSL 1.0.0aをリンクさせてみます。このパッチはFedora 12以降にはデフォルトで組み込まれています。

以前にも、「Intel AES-NIパッチを使うと、使用しない場合に比べて2倍程度のパフォーマンスを引き出せる」というレポートがありました。しかし、さらに調査を行ったところ、システムに標準で組み込まれているOpenSSLライブラリ 0.9.8e-fipsにそもそも問題があることがわかりました。OpenSSLをソースから再コンパイルすると、Intel AES-NIパッチを適用してもしなくてもパフォーマンスは2倍に向上しました。Fedora 12バージョンのOpenSSL(1.0.0-fips)以降にはこのような問題はないようです。

実験は前述の方法と同じです。サーバーは次のように設定します。
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 --cipher aes-256-cbc
クライアントは次のように設定します。
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  --cipher aes-256-cbc --remote server

この設定でのiperfの計測結果は407Mbpsとなりました。
'--tun-mtu'の値をいろいろと変えて実験してみると、次のような結果になりました(速度の単位はすべてMbpsです)。
MTUBlowfishAES256
6000310407
9000385410
12000417478
24000470540
36000510561
48000500585
60000500582
(これらの測定値については5%程度のバラつきがあります)

デフォルトのBlowfishを使用している場合は、'--tun-mtu'パラメータの最適値は36000バイトということになりました。これ以上のMTUサイズに設定しても変化はほとんどありません。また、この値はOpenSSL 0.9.8e-fipsライブラリで生成されるパフォーマンスの値とほぼ同一となっています。

AES-256を使用した場合はパフォーマンスの向上がさらに大きくなりました。最適なMTU値は48000バイトですが、MTUの設定値に関わりなく、全体的にパフォーマンスはほぼ2倍に向上します。

考察

OpenSSLをスクラッチからコンパイルすると、OpenSSLのスピードは2倍に向上します。測定は次のような方法でも行えます。
openssl speed -evp aes-256-cbc
スクラッチからコンパイルするとパフォーマンスが向上する主な要因は、CentOSに付属するOpenSSL 0.9.8e-fipsライブラリに問題がある、と考えられます。Fedora 12に付属しているOpenSSL 1.0.0-fipsではこの問題はないようです。

AES-NI対応のハードウェアでOpenSSL 1.0.0を使用する

本当のパフォーマンス向上は、Intel Xeon X5660やi5-560M CPUなどのAES-NI対応のハードウェアで見込めます。前述のセットアップを行いますが、さらに今回は次の設定を追加します。
engine aesni
サーバーは次のように設定します。
openvpn --dev tun --proto udp --port 11000 --secret secret.key 
     --ifconfig 192.168.222.11 192.168.222.10
     --tun-mtu 9000 --fragment 0 --mssfix 0 --cipher aes-256-cbc --engine aesni
クライアントは次のように設定します。
openvpn --dev tun --proto udp --port 11000 --secret secret.key 
     --ifconfig 192.168.222.10 192.168.222.11
     --tun-mtu 9000 --fragment 0 --mssfix 0  --cipher aes-256-cbc --engine aesni
     --remote server

この結果、以下のような結果となりました(速度の単位はすべてMbpsです)。
AES128AES256
X5660 -> i5-560885878
i5-560 -> X5660748543
(これらの測定値については5%程度のバラつきがあります)

まとめるとこのようになります。
  • AES-NI対応のサーバーCPUでは大幅なパフォーマンスの向上が期待できます。ギガビットLANの上限に近い値まで引き出せる可能性があります。
  • クライアントCPUはサーバーCPUに比較してそれほどの向上が期待できないようです。暗号化/復号の処理速度の違いを見てもわかるように、i5-560MのパフォーマンスはX5660のパフォーマンスには届きません。上の表の1行目はX5660がすべてのトラフィックを暗号化し、i5-560Mが復号しています。2行目はその逆です。

参考:暗号化なしの場合

参考までに、上記のテストを暗号化/署名処理なしで行ってみました。
openvpn --dev tun --proto udp --port 11000 --secret secret.key 
     --ifconfig 192.168.222.11 192.168.222.10
     --tun-mtu 9000 --fragment 0 --mssfix 0 --cipher none --auth none

iperfの結果は930Mbpsとなりました。この結果から、カーネル空間とユーザー空間が分離していることによるパフォーマンスの影響は小さく、パフォーマンスに大きく影響するのはOpenSSLの暗号化/復号処理であることがわかります。

10G ギガビットネットワーク

10Gbpsスイッチでつないだ2台のPCで、「プレーンテキスト」テスト(暗号化と署名処理を行わない)を行なっています。

iperfで調査結果は次のようになりました。
MTUspeed
"raw"15008.8 Gbps
"raw", no cksum offloading15003.8 Gbps
via tun600003.6 Gbps
via tun480002.4 Gbps
via tun90001.3 Gbps
この結果から、Linuxにおけるカーネル空間とユーザー空間の分離のパフォーマンス限界がわかります。また、TCPオフロードの重要性もわかります。TCPチェックサムをカーネル空間で計算する必要がある場合、パフォーマンスは1/2に低下してしまうのです!

この10G ギガビットネットワークでのOpenVPNのパフォーマンスについてはまだ十分に調査されていません。このネットワーク上のPCのOpenSSLの処理速度は、前述のテストで利用したサーバーよりもだいぶパフォーマンスが低いものです。残念ながら、このネットワークでは2台のAES-NI対応PCを使用することができませんでした。


Author: Taro Yamazaki

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