web-dev-qa-db-ja.com

非常に低いTCP OpenVPNスループット(100Mbitポート、低いCPU使用率)

2つのサーバー間のOpenVPN転送速度が非常に遅い。この質問では、サーバーをサーバーAとサーバーBと呼びます。

サーバーAとサーバーBはどちらもCentOS 6.6を実行しています。どちらも100Mbit回線のデータセンターにあり、OpenVPN外の2台のサーバー間のデータ転送は約88Mbpsに達します。

しかし、サーバーAとサーバーBの間で確立したOpenVPN接続を介してファイルを転送しようとすると、6.5Mbps前後のスループットが得られます。

Iperfのテスト結果:

[  4] local 10.0.0.1 port 5001 connected with 10.0.0.2 port 49184
[  4]  0.0-10.0 sec  7.38 MBytes  6.19 Mbits/sec
[  4]  0.0-10.5 sec  7.75 MBytes  6.21 Mbits/sec
[  5] local 10.0.0.1 port 5001 connected with 10.0.0.2 port 49185
[  5]  0.0-10.0 sec  7.40 MBytes  6.21 Mbits/sec
[  5]  0.0-10.4 sec  7.75 MBytes  6.26 Mbits/sec

これらのOpenVPN iperfテストを除いて、両方のサーバーは実質的に完全にアイドル状態であり、負荷はありません。

サーバーAにはIP 10.0.0.1が割り当てられ、OpenVPNサーバーです。サーバーBにはIP 10.0.0.2が割り当てられており、OpenVPNクライアントです。

サーバーAのOpenVPN構成は次のとおりです。

port 1194
proto tcp-server
dev tun0
ifconfig 10.0.0.1 10.0.0.2
secret static.key
comp-lzo
verb 3

サーバーBのOpenVPN構成は次のとおりです。

port 1194
proto tcp-client
dev tun0
remote 204.11.60.69
ifconfig 10.0.0.2 10.0.0.1
secret static.key
comp-lzo
verb 3

私が気付いたこと:

1。最初に考えたのは、サーバーのCPUにボトルネックが発生していることでした。 OpenVPNはシングルスレッドであり、これらのサーバーはどちらも最速ではないIntel Xeon L5520プロセッサーを実行します。ただし、iperfテストの1つでtopコマンドを実行し、1を押してコアごとのCPU使用率を表示したところ、各コアのCPU負荷が非常に低いことがわかりました。

top - 14:32:51 up 13:56,  2 users,  load average: 0.22, 0.08, 0.06
Tasks: 257 total,   1 running, 256 sleeping,   0 stopped,   0 zombie
Cpu0  :  2.4%us,  1.4%sy,  0.0%ni, 94.8%id,  0.3%wa,  0.0%hi,  1.0%si,  0.0%st
Cpu1  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu2  :  0.0%us,  0.0%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.3%st
Cpu3  :  0.3%us,  0.0%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu4  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu5  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu6  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu7  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu8  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu9  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu10 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu11 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu12 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu13 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu14 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu15 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:    946768k total,   633640k used,   313128k free,    68168k buffers
Swap:  4192188k total,        0k used,  4192188k free,   361572k cached

2。iperfの実行中は、OpenVPNトンネルでのping時間が大幅に増加します。 iperfが実行されていない場合、トンネルのping時間は常に60ミリ秒(通常)です。しかし、iperfが実行されて大量のトラフィックを押し込むと、pingの時間が不安定になります。 iperfテストを開始した4番目のpingまでのping時間の安定性を以下に示します。

PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=60.1 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=60.1 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=60.2 ms
** iperf test begins **
64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=146 ms
64 bytes from 10.0.0.2: icmp_seq=5 ttl=64 time=114 ms
64 bytes from 10.0.0.2: icmp_seq=6 ttl=64 time=85.6 ms
64 bytes from 10.0.0.2: icmp_seq=7 ttl=64 time=176 ms
64 bytes from 10.0.0.2: icmp_seq=8 ttl=64 time=204 ms
64 bytes from 10.0.0.2: icmp_seq=9 ttl=64 time=231 ms
64 bytes from 10.0.0.2: icmp_seq=10 ttl=64 time=197 ms
64 bytes from 10.0.0.2: icmp_seq=11 ttl=64 time=233 ms
64 bytes from 10.0.0.2: icmp_seq=12 ttl=64 time=152 ms
64 bytes from 10.0.0.2: icmp_seq=13 ttl=64 time=216 ms

3。上記のように、私はOpenVPNトンネルの外でiperfを実行し、スループットは正常でした-一貫して〜88Mbps。

私が試したこと:

1。圧縮によって問題が発生する可能性があると考えたため、両方の構成からcomp-lzoを削除してOpenVPNを再起動し、圧縮をオフにしました。改善なし。

2。以前にCPU使用率が低いことがわかっていたとしても、システムが追いつくにはデフォルトの暗号が少し強すぎるかもしれないと思いました。そこで、両方の構成(非常に軽量な暗号)にcipher RC2-40-CBCを追加して、OpenVPNを再起動しました。改善なし。

3。フラグメント、mssfix、およびmtu-tunの調整がパフォーマンスにどのように役立つかについて、さまざまなフォーラムで読みました。 この記事 で説明されているように、いくつかのバリエーションを試しましたが、やはり改善はありません。

このようなOpenVPNのパフォーマンス低下の原因となる可能性のあるアイデアはありますか?

29
Elliot B.

Googlingと設定ファイルを何度も調整した後、私は解決策を見つけました。 現在、60Mbpsの持続速度と最大80Mbpsのバーストを取得しています。VPNの外部で受信する転送速度よりも少し遅いですが、これはそれが得られるのと同じくらい良いです。

最初のステップは、サーバーとクライアントの両方のOpenVPN構成でsndbuf 0およびrcvbuf 0を設定することでした。

ここで引用する public forum post (これは Russian original post の英語訳です)でそうするよう提案されたので、私はその変更を行いました。

それは2004年7月です。先進国での通常の家庭のインターネット速度は256〜1024 Kbit/sで、発展途上国では56 Kbit/sです。 Linux 2.6.7は少し前にリリースされ、2.6.8でTCPデフォルトで有効になっているWindowsサイズスケーリングがリリースされるのは1か月だけです。OpenVPNはすでに3年間活発に開発されています、2.0バージョンがほぼリリースされています。開発者の1人がソケットバッファーのコードを追加することにしました。OS間でバッファーサイズを統一すると思います。Windowsでは、カスタムバッファーサイズが設定されている場合、アダプターのMTUで問題が発生し、最終的に変換されます次のコードに:

#ifndef WIN32
o->rcvbuf = 65536;
o->sndbuf = 65536;
#endif

OpenVPNを使用した場合は、TCPおよびUDPで動作することを知っておく必要があります。カスタムTCPソケットバッファの値を64 KBに設定した場合、= TCPウィンドウサイズスケーリングアルゴリズムはウィンドウサイズを64 KBを超えて調整できません。これはどういう意味ですか?つまり、他のVPNに接続している場合長いファットリンク上のサイト、つまりpingが約100ミリ秒の米国からロシアへのサイトでは、デフォルトのOpenVPNバッファー設定では5.12 Mbit/sを超える速度を得ることができません。少なくとも640 KBのバッファーが必要ですそのリンクを介して50 Mbit/sを取得するには、ウィンドウサイズがないためUDPはより高速に動作しますが、あまり高速には動作しません。

ご想像のとおり、最新のOpenVPNリリースでは64 KBのソケットバッファーサイズを使用しています。この問題をどのように修正すればよいですか?最良の方法は、OpenVPNがカスタムバッファーサイズを設定できないようにすることです。サーバーとクライアントの両方の構成ファイルに次のコードを追加する必要があります。

sndbuf 0
rcvbuf 0

クライアントの構成を自分で制御できない場合に、バッファサイズの調整をクライアントにプッシュする方法についても説明します。

これらの変更を行った後、スループットレートは最大20Mbpsに増加しました。その後、シングルコアでのCPU使用率が少し高いので、クライアントとサーバーの両方の構成からcomp-lzo(圧縮)を削除しました。ユーレカ!転送速度は最大60Mbps持続および80Mbpsバーストに跳ね上がりました。

これが他の誰かがOpenVPNの遅さに関する自分の問題を解決するのに役立つことを願っています!

27
Elliot B.

何度か試した後、私は良い解決策に到達しました。私の場合、@ Elliotの返信は役に立ちませんでした。もっとググって、私はこのスニペットを見つけて、仕事をしたサーバーの設定に追加しました

sndbuf 393216
rcvbuf 393216
Push "sndbuf 393216"
Push "rcvbuf 393216"

Raspberry Piで小さなOpenVPNサーバーを実行していますが、現在71 Mbpsダウンリンクと16Mbpsアップリンクを取得しています。 CPUのパワーでダウンロードが制限されています。現在、私の構成は次のとおりです。

client-to-client
duplicate-cn
keepalive 10 120
cipher AES-128-CBC
#cipher AES-256-CBC <<<---- lowers the speed to around 50Mbps, still not bad
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
tun-mtu 9000

OpenVPN 2.4.0 arm-unknown-linux-gnueabihfとOpenSSL 1.0.2l

バッファのデフォルト設定に関するそのような問題がまだ存在するのはとても奇妙に感じられます。

[編集] client.ovpnファイルは次のように構成されています。

client
dev tun
proto tcp
remote SERVER.IP.ADDRESS.HERE
resolv-retry infinite
nobind
persist-key
persist-tun
mute-replay-warnings
ns-cert-type server
tun-mtu 9000
key-direction 1
cipher AES-128-CBC
comp-lzo
verb 1
mute 20
<ca>
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN RSA PRIVATE KEY-----
[...]
-----END RSA PRIVATE KEY-----
</key>
<tls-auth>
-----BEGIN OpenVPN Static key V1-----
[...]
-----END OpenVPN Static key V1-----
</tls-auth>
4
Kernel

構成によると、トンネルのトランスポートとしてTCPを使用しています。スタックされたTCPであるため、TCP =パケット損失の状況で問題を引き起こす接続テント。

参考として参照 (TCP以上TCP悪い考えです

1
Lairsdragon

相互にリンクする2つの大陸間サーバーがあり、サーバー間の速度は約220 Mbit/sです。

ただし、(UDP)OpenVPNトンネル内では、速度は平均で21メガビット/秒-およそ10倍遅くなります。

(サーバー間にはかなりの待ち時間があり、約130ミリ秒です。転送は、TCPモードでIperf3を使用して測定されました。)

この執筆の時点で、ここでの回答に関するすべての提案を試したが、何の助けにもならなかった。

ようやく助けになったのは、この少しだけでした。

--txqueuelen 4000

OpenVPNリファレンスマニュアルによると:

–txqueuelen n 
(Linux only) Set the TX queue length on the TUN/TAP interface. Currently defaults to 100.

サーバーとクライアントでこのパラメーターを設定した後、OpenVPNトンネルでも同じ「ダイレクトリンク」速度(約250Mbit/s)に到達できました。

私はすでにrcvbuf 0およびsndbuf 0ですが、少なくともalone、まったく役に立ちませんでした。

OpenVPNフォーラムのこのページDPspeeder wikiのこのページ の両方でこれらの推奨事項を見つけました。

別のメモ:iperfでUDP転送を使用してより高速に到達することもできましたが、そうすると、かなりのパケット損失が発生します。

VPNを使用して不可逆リンクのある2つの場所をトンネリングする必要がある場合は、VPN自体の下でなんらかのForward-Error-Correction(FEC)トンネルを使用することを検討することをお勧めします。私が何とか見つけて作業した2つは次のとおりです。

  • 前述の DPspeeder は、UDP接続をトンネリングします。
  • kcptun 、トンネルTCP接続;

どちらもパケットロス(多くの場合、帯域幅をより多く消費すること)に役立ち、最終的にはデータスループットが向上し、オーバーヘッドが追加されたとしても、それは私に尋ねると本当にすてきです。

(それは パケット損失が実際にネットワークを台無しにする可能性があるためです 、特にTCP 6ページを参照してください。)

通常の理由から、UDPでOpenVPNを使用することをお勧めしますが、100ミリ秒を超えるレイテンシと10メガビット/秒を超える速度の両方がある場合、UDPspeederを処理するのは難しいことがわかりました。

ただし、kcptunは微調整をほとんど行わなくてもうまく機能し、実際にはreallyサーバーのスループットが互いに向上しました。 =)

拡張注記 here には、OpenVPNのパフォーマンスの一部を微調整する方法についての詳細な説明があります。

1
Vinícius M

私にとって、日本ではopenvpnサーバーがセットアップされたVPSサーバーがあり、クライアント接続はニューヨークのOpenVPNクライアントモードでDDWRTを使用していました。 100メガビット接続で1〜2 mbpsしか得られませんでした。私がそれを最適化することができた最高は5 mbpsであり、それは私が信じられるようにすることができるのと同じくらい最適化されている必要なものに十分でした。

私のOpenVPNサーバー設定:

tun-mtu 9000
sndbuf 393216
rcvbuf 393216
Push "sndbuf 393216"
Push "rcvbuf 393216"
comp-lzo
txqueuelen 4000
######
port 10111
proto udp
dev tun
user nobody
group nobody
persist-key
persist-tun
keepalive 10 120
topology subnet
server x.x.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
Push "dhcp-option DNS 1.0.0.1"
Push "dhcp-option DNS 1.1.1.1"
Push "redirect-gateway def1 bypass-dhcp"
dh none
ecdh-curve prime256v1
#tls-crypt tls-crypt.key 0
crl-verify crl.pem
ca ca.crt
cert server_IzA1QdFzHLRFfEoQ.crt
key server_IzA1QdFzHLRFfEoQ.key
auth SHA256
#cipher AES-128-GCM
#cipher AES-128-CBC
#ncp-ciphers AES-128-GCM
#ncp-ciphers AES-128-CBC
#tls-server
#tls-version-min 1.2
#tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
#tls-cipher TLS-DHE-RSA-WITH-AES-128-CBC-SHA
status /var/log/openvpn/status.log
verb 3

スクリーンショットにもDDWRT OpenVPNクライアント設定が表示されています。

tun-mtu 9000
comp-lzo
##########
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
verify-x509-name server_IzA1QdFzHLRFfEoQ name
auth SHA256
auth-nocache
setenv opt block-outside-dns # Prevent Windows 10 DNS leak
verb 3

enter image description here

enter image description here

0