巨大的性能损失在gbit链路与ip转发/通过清除VPN隧道伪装

我的家庭计算机和远程服务器之间的IP转发有问题(来自online.net)。 我的家庭连接是1 Gbit / s的FTTH,远程服务器的带宽是2.5 Gbit / s。

上下文

我在我的家用电脑和在线的远程服务器之间运行一个清晰的 OpenVPN隧道。 目前,我没有使用任何encryption,所以我不会因为encryption而面临任何性能损失。

服务器机器:Intel Atom C2750 / 2GB RAM / SSD
客户端机器:VMware托pipe的Ubuntu服务器16.04 64位,具有8 GB RAM / SSD / Intel i5(Mac mini 2013后面)

服务器 openvpn命令:

# openvpn --dev tun --proto tcp-server --port 11000 --ifconfig 10.200.0.1 10.200.0.2 --cipher none --auth none --fragment 0 --mssfix 0 --tun-mtu 48000 --sndbuf 0 --rcvbuf 0 

客户端 openvpn命令:

  # openvpn --dev tun --proto tcp-client --port 11000 --ifconfig 10.200.0.2 10.200.0.1 --cipher none --auth none --remote dedibox --fragment 0 --mssfix 0 --tun-mtu 48000 --sndbuf 0 --rcvbuf 0 

我在远程服务器上build立了一个vsftpd服务器。 如果我通过OpenVPN隧道从远程FTP服务器上下载了一些东西,我就全速了。

 lftp [email protected]:~> pget 1GB.dat 1073741824 bytes transferred in 11 seconds (95.68 MiB/s) 

问题

问题是我想通过OpenVPN隧道从客户端访问互联网。

让我们在客户端机器上添加一个path,以便使用wget / curltesting我的下载速度。

 ip route add 62.34.91.0/24 via 10.200.0.1 

接下来,在远程服务器上允许ipv4转发:

 > # sysctl -w net.ipv4.ip_forward=1 

最后,允许VPN连接来回networking

 iptables -t nat -A POSTROUTING -s 10.200.0.0/24 -o eth0 -j MASQUERADE 

当我从客户端testing我的下载速度时:

 wget -O /dev/null http://3-ipv4.testdebit.info/fichiers/1000Mo.dat ... 2016-05-17 20:24:45 (17.7 MB/s) - '/dev/null' saved [1000000000/1000000000] 

这比使用VPN隧道从远程服务器上下载文件的时间less了5倍。

可能是什么原因 ?

  1. 从远程服务器到3-ipv4.testdebit.info网站的链接速度很慢? 不,不是,直接从远程服务器使用相同的wget,我得到225 MB / s
  2. 远程服务器无法处理1 Gbit / s同时接收和发送相同数量的数据? 是的,它可以。 我已经做了FTP服务器上的文件传输,并使用wget在远程服务器上进行同样的下载,两个传输速度都是100 MB / s。
  3. CPU开销? 根据上方,我使用了15%的CPU容量,所以我不认为这是由于CPU。
  4. iptables伪装所有的数据包? 我想是的,但我不确定。 有人可以确认/否认吗?

任何帮助,高度赞赏,这让我头痛,因为两天! 如果你需要任何日志或TCP转储,我可以给你。


编辑2016/05/22在14:09 GMT

我已经在服务器上使用tcpdump转储了TCP数据包。 所有的转储都可以在这里find: http : //163.172.210.224/dumps/

以下是每个文件的详细信息:

  • dump-server-direct-eth0.pcap转储从服务器直接http下载的eth0。 这里没有VPN使用ip转发。 使用的命令(我筛选出我的IP地址用于ssh连接): tcpdump -i eth0 '((not net XXX.XXX.XXX.XXX) and port 80)' -C 100 -vvv -w dump-server-direct-eth0.pcap

  • dump-server-forward-http-[tcp|udp]-eth0.pcap当客户端使用IP转发通过UDP / TCP OpenVPN隧道下载HTTP文件时转储​​eth0。 使用的命令(我筛选出我的IP地址用于SSH连接):
    tcpdump -i eth0 '((not net XXX.XXX.XXX.XXX) and (port 80 or port 11000))' -C 100 -vvv -w dump-server-forward-http-[tcp|udp]-eth0.pcap

  • dump-server-forward-http-[tcp|udp]-tun0.pcap同上,但是这次从tun0接口捕获。 使用的命令:
    tcpdump -i tun0 -C 100 -vvv -w dump-server-forward-http-[tcp|udp]-tun0.pcap

  • dump-server-http-through-tcp-tunnel-eth0.pcap当客户端通过UDP / TCP OpenVPN隧道下载FTP文件时转储​​eth0, 无需 IP转发。 http服务器托pipe在OpenVPN服务器本身,我使用OpenVPN服务器地址连接到服务器(10.200.0.1),所以根本没有IP转发。 使用的命令(我过滤客户端IP地址):
    tcpdump -i eth0 'net YYY.YYY.YYY.YYY' -C 100 -vvv -w dump-server-ftp-through-tcp-tunnel eth0.pcap

  • dump-server-http-through-tcp-tunnel-tun0.pcap同上,但是这次从tun0接口捕获。 使用的命令:
    tcpdump -i tun0 -C 100 -vvv -w dump-server-http-through-tcp-tunnel-tun0.pcap


编辑2016/05/19在北京时间10:31

我得到的评论和回答是关于我使用OpenVPN而不是udp使用TCP协议的事实。 正如我在上面的post中所说,我的服务器和我的家用电脑之间没有通过TCP VPN隧道的速度性能问题:

 lftp [email protected]:~> pget 1GB.dat 1073741824 bytes transferred in 11 seconds (95.68 MiB/s) 

但为了取悦所有人,停止关于tcp与udp的言论,下面是一个使用udp的testing:

服务器

 # openvpn --dev tun --proto udp --port 11000 --ifconfig 10.200.0.1 10.200.0.2 --cipher none --auth none --fragment 0 --mssfix 0 --tun-mtu 48000 --sndbuf 393216 --rcvbuf 393216 

客户

 # openvpn --dev tun --proto udp --port 11000 --ifconfig 10.200.0.2 10.200.0.1 --cipher none --auth none --fragment 0 --mssfix 0 --tun-mtu 48000 --sndbuf 393216 --rcvbuf 393216 --remote dedibox 

使用udp vpn隧道从服务器到客户端的iperf3testing:

 # iperf3 -c 10.200.0.2 -i 1 -p 5201 -fm -b 1G -u Connecting to host 10.200.0.2, port 5201 [ 4] local 10.200.0.1 port 55287 connected to 10.200.0.2 port 5201 [ ID] Interval Transfer Bandwidth Total Datagrams [ 4] 0.00-1.00 sec 111 MBytes 935 Mbits/sec 14265 [ 4] 1.00-2.00 sec 119 MBytes 1000 Mbits/sec 15258 [ 4] 2.00-3.00 sec 119 MBytes 1000 Mbits/sec 15258 [ 4] 3.00-4.00 sec 119 MBytes 1000 Mbits/sec 15260 [ 4] 4.00-5.00 sec 119 MBytes 1000 Mbits/sec 15259 [ 4] 5.00-6.00 sec 119 MBytes 1000 Mbits/sec 15258 [ 4] 6.00-7.00 sec 119 MBytes 1000 Mbits/sec 15253 [ 4] 7.00-8.00 sec 119 MBytes 1000 Mbits/sec 15266 [ 4] 8.00-9.00 sec 119 MBytes 1000 Mbits/sec 15255 [ 4] 9.00-10.00 sec 119 MBytes 1000 Mbits/sec 15262 - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams [ 4] 0.00-10.00 sec 1.16 GBytes 993 Mbits/sec 0.763 ms 141473/150989 (94%) [ 4] Sent 150989 datagrams iperf Done. 

最后,通过我的vpn隧道,从testdebit.info托pipe的客户端和速度testing服务器进行速度testing:

 # ip route add 62.34.91.3 via 10.200.0.1 # wget -O /dev/null http://3-ipv4.testdebit.info/fichiers/1000Mo.dat /dev/null 100%[============================>] 953.67M 12.4MB/s in 79s 2016-05-19 12:27:40 (12.1 MB/s) - '/dev/null' saved [1000000000/1000000000] 

结论:UDP和TCP没有区别!

正如我所说的,问题是与iptables或ipv4.ip_forwarding,但不是与OpenVPN / TCP / UDP

我已经看了你最后一个捕获文件。 我们可以立即看到端到端TCP会话上的RTT大约是50ms或更差。 你的客户正在使用一个大约3MB的窗口(而不是我最初input的300MB)。 把它们放在一起,假设TCP连接的每一端都有无限快速的硬件,那么你的绝对最大值为480Mbps。 据推测,两端都无限快。
所以如果我是你,我会:

接受你得到的performance(取决于实际的要求)

要么:

绘制整个会话中的RTT以获得准确性
使用带宽延迟产品来准确了解单个TCPstream的最大带宽。
调查延迟的组成部分来自哪里(例如通过在隧道服务器上安装水龙头)

更新:延迟是在隧道服务器上造成的。 捕获文件并不明显,但端到端的延迟比我原先想象的要高得多。 基于主机的捕获文件掩盖了每个数据包在服务器上花费的时间长度。 理想情况下,你应该抓住客户端,我认为这将显示更高的RTT。

dump-server-forward-http-tcp-eth0 frame 17854就是一个例子。 它包含来自互联网主机的数据(据推测)是在17856年传输给客户端的。然而17856直到18614,大约222ms之后才被确认。 允许对客户端进行40ms的RTT(包括一些处理),然后服务器将至less180ms添加到从互联网主机接收的单向行程中,以便将其推向客户端。 鉴于帧17854显然不是一个物理帧,但已经被重新组合(可能是错误的),对互联网主机也可能有类似的延迟。

如果RTT是222ms,RWIN是3MB,那么TCP只能提供13.5Mbps

它在我看来好像有启用TCP分段卸载,并且无论出于何种原因,当您真的只希望转发时,隧道服务器上正在处理TCP。 你现在需要调查为什么会这样。

更新:我也只是注意到你说的CPU只有15%。 如果这是指隧道服务器,那么你说它是一个C2750 Atom,8核心。 对于multithreading的CPU来说,任何持续的CPU负载或100%/内核的数量(在你的情况下为12.5%)都可能是一个内核饱和的主线程。