TCP OpenVPN吞吐量非常低(100Mbit端口,CPU利用率低)


27

我在两台服务器之间遇到极慢的OpenVPN传输速率。对于这个问题,我将服务器称为服务器A和服务器B。

服务器A和服务器B都在运行CentOS 6.6。两者都位于具有100Mbit线路的数据中心中,OpenVPN外部的两台服务器之间的数据传输速度接近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处理器。但是,我top在iperf测试之一中运行了一个命令,并按按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时间始终为60ms(正常)。但是,当iperf运行并推动大量流量时,ping时间变得不稳定。在开始iperf测试之前,您可以在下面看到ping时间如何稳定直到第4次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性能的任何想法?


这里的任何链接,评论有帮助吗? forums.openvpn.net/topic10593.html
马特

我已经尝试了很多建议:1.检查CPU瓶颈,2.验证不使用VPN的传输速度,3.切换压缩,4.选择更快的密码,等等。 :-/这很奇怪。除了缓慢的速度和较高的/不稳定的ping时间之外,我看不到瓶颈可能在哪里的其他迹象。
Elliot B.

两台机器都在同一数据中心中吗?同一数据中心内的60ms很高。我可能会尝试尝试,cipher none尽管我怀疑这会有所帮助。
Zoredache 2015年

@Zoredache对不起-我不清楚服务器的位置-服务器A在达拉斯,服务器B在西雅图。
Elliot B.

您检查过MTU吗?Esp:tun-mtu,fragment和mssfix参数?文档
Lenniey 2015年

Answers:


26

经过大量Google搜索和配置文件调整后,我找到了解决方案。我现在获得60Mbps的持续速度并达到80Mbps。它比我从VPN外部接收到的传输速率要慢一些,但是我认为这会达到最好的效果。

第一步是为服务器和客户端设置OpenVPN配置sndbuf 0rcvbuf 0在其中进行配置。

我在公共论坛帖子(这是俄文原始帖子的英文翻译)上看到建议后做出了更改,我将在此处引用:

它是2004年7月。发达国家的常规家庭互联网速度为256-1024 Kbit / s,较不发达国家为56 Kbit / s。Linux 2.6.7不久前已经发布,而2.6.8仅在一个月内发布,其中默认情况下将启用TCP Windows Size Scaling。OpenVPN已经积极开发了3年,几乎发布了2.0版本。其中一位开发人员决定为套接字缓冲区添加一些代码,我想统一操作系统之间的缓冲区大小。在Windows中,如果设置了自定义缓冲区大小,则适配器的MTU会出问题,因此最终将其转换为以下代码:

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

如果使用OpenVPN,则应该知道它可以在TCP和UDP上运行。如果将自定义TCP套接字缓冲区值设置为低至64 KB,则“ TCP窗口大小缩放”算法无法将“窗口大小”调整为超过64 KB。这意味着什么?这意味着,如果您要通过长链接连接到其他VPN站点,即以大约100毫秒的ping频率从美国连接到俄罗斯,则使用默认的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慢速问题!


4

经过一番尝试,我已经找到了一个很好的解决方案。就我而言,@ Elliot的回复没有帮助。进一步搜索,我发现此代码段添加了完成任务的服务器配置

sndbuf 393216
rcvbuf 393216
push "sndbuf 393216"
push "rcvbuf 393216"

我有一个在Raspberry PI3上运行的小型OpenVPN服务器,现在我获得71 Mbps的下行链路和16 Mbps的上行链路。由于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

具有OpenSSL 1.0.2l的OpenVPN 2.4.0 arm-unknown-linux-gnueabihf

感觉如此奇怪,以至于仍然存在关于缓冲区默认配置的此类问题。

[编辑]我的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>

设置缓冲区大小对我有所帮助。
罗尔夫(Rolf)'18年

您在客户端.ovpn文件中放了什么?
Patoshiパトシ

@Patoshiパトシ我已注​​释掉sndbuf和recbuf,放入了相应的密码和压缩方式,并保留了默认参数。
内核

@Kernel您能告诉我您的客户有什么吗?我正在做从香港到纽约的OpenVPN连接,它随机缓慢,有时会断开连接。我不知道为什么。
Patoshiパトシ

@Patoshiパトシ我已编辑我的回复,请再次检查。尽管如此,我还是建议您尝试使用UDP,因为它可以帮助您解决服务器不稳定链接的问题。确实,这只是一个假设,我从未尝试过在这种情况下对该解决方案进行基准测试。
内核

1

根据配置,您正在使用TCP作为隧道的传输。考虑使用UDP代替TCP,因为堆叠的TCP连接会在丢包情况下造成问题。

作为参考,请参见为什么TCP上的TCP是一个坏主意


不幸的是,UDP不是我们的选择。我们需要确保我们传输的数据包按预期到达。尽管如此,我们还是在较早的时候就进行了UDP实验,但是传输速率仍然很低。
Elliot B.

6
We need to ensure that the data packets we transmit arrive as expected.并且不是由正在传输的协议处理的吗?您为什么认为您的隧道需要成为强制执行此任务的事物?
Zoredache 2015年

可能是这种情况,但是我们将OpenVPN用于远程异步DRBD实现(即文件系统复制)。数据完整性非常重要,因此即使DRBD可能具有用于验证传输完整性的内部机制,我还是希望将其保留在TCP上。无论哪种方式,当我们在UDP上使用它时,我们的吞吐量仍然很低。
Elliot B.

3
@ElliotB。由于DRBD本身使用TCP进行复制,因此如果OpenVPN UDP数据包丢失,它将重新传输。实际上,在这种情况下使用TCP,您将执行两次重传而不是一次。其中之一将被丢弃。而且您可能正在创建一个没有DRBD流量的相当长的窗口(因此甚至会导致复制中断)。一旦在路由上丢失了一些数据包,您就会发现这是多么糟糕的想法。
福克斯

@Fox感谢您提供澄清!实际上,DRBD确实使用了TCP(drbd.linbit.com/users-guide/s-prepare-network.html)。Lairsdragon早先提出的切换到UDP的建议当时并不相关,因为UDP的传输速率也非常低,但是由于实施了我上面发布的解决方案,我们确实切换到了UDP,并且又获得了几Mbps的性能提升。
Elliot B.

1

我们有两个相互连接的洲际服务器,它们之间的速度徘徊在220 Mbit / s左右。

但是,在(UDP)OpenVPN隧道内部,平均速度为21 Mbit / s,大约慢10倍。

(服务器之间存在显着的延迟:大约130毫秒,并且使用Iperf3在TCP模式下测量了传输。)

在撰写本文时,尝试了所有关于答案的建议,但没有任何帮助。

最终起到帮助作用的一件事是:

--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 0and了sndbuf 0,但至少是一个人,他们根本没有帮助。

我在以下两个方面都找到了这些建议:OpenVPN论坛中的此页面以及UDPspeeder Wiki中的此页面

另一个要注意的是:我可以使用iperf中的UDP传输来达到更高的速度,但是这样做也会导致相当高的数据包丢失。

如果您有机会需要使用VPN在两个有损链接的地方建立隧道,我建议考虑在VPN本身下使用某种前向纠错(FEC)隧道。我设法找到并使用的两个是:

  • 前面提到的UDPspeeder,它建立UDP连接。
  • kcptun,通过隧道建立TCP连接;

两者都可以极大地减少数据包丢失(首先花费更多的带宽),最终甚至导致更高的数据吞吐量,甚至增加开销,如果您问我的话,这真的很整洁。

(这是因为丢包确实会使网络特别是TCP 混乱请参见第6页。)

由于所有通常的原因,我本来希望在UDP上使用OpenVPN,但是当您同时具有超过100ms的延迟和> 10 Mbit / s的速度时,我发现很难使用UDPspeeder。

但是,kcptun几乎不需要任何调整就可以很好地工作,并且实际上确实增加了彼此之间的服务器吞吐量。=)

作为扩展,您可以在此处找到有关调整OpenVPN性能某些部分的更多详细说明。


0

对我来说,我在日本有一台带有openvpn服务器设置的VPS服务器,我的客户端连接是在纽约市的OpenVPN客户端模式下使用DDWRT。我在100mbit连接上仅获得1-2mbps。我能够对其进行优化的最好结果是5mbps,这足以满足我的需求,并且我相信它可以进行优化。

我的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

在此处输入图片说明

在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.