我家用电脑和远程服务器(来自 online.net)之间的 IP 转发存在问题。我家的连接是 1 Gbit/s FTTH,而远程服务器的带宽是 2.5 Gbit/s。
上下文
我正在运行清除我的家用电脑和 online.net 上的远程服务器之间建立了 OpenVPN 隧道。目前,我没有使用任何加密,因此不会因加密而面临任何性能损失。
服务器机器:Intel Atom C2750 / 2GB RAM / SSD
客户端机器:VMware 托管的 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
我在远程服务器上设置了一个 vsftpd 服务器。如果我通过 OpenVPN 隧道从远程 FTP 服务器下载某些内容,速度会非常快。
lftp [email protected]:~> pget 1GB.dat
1073741824 bytes transferred in 11 seconds (95.68 MiB/s)
问题
问题在于当我想通过 OpenVPN 隧道从客户端访问互联网时。
让我们在客户端机器上为特定网站添加一条路由,以便使用 wget/curl 测试我的下载速度。
ip route add 62.34.91.0/24 via 10.200.0.1
接下来,允许远程服务器上的 IPv4 转发:
> # sysctl -w net.ipv4.ip_forward=1
最后,允许 VPN 连接网络:
iptables -t nat -A POSTROUTING -s 10.200.0.0/24 -o eth0 -j MASQUERADE
当我从客户端测试下载速度时:
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 隧道从远程服务器下载文件时少了近 5 倍。
可能是什么原因 ?
- 从远程服务器到 3-ipv4.testdebit.info 网站的链接很慢?不慢,直接从远程服务器使用相同的 wget,我得到 225 MB/s
- 远程服务器无法以 1 Gbit/s 的速度同时接收和发送相同数量的数据?是的,它可以。我已经从服务器进行了 FTP 文件传输,并使用 wget 在远程服务器上进行了相同的下载,两次传输的速度均为 100+ MB/s。
- CPU 开销?根据 top,我使用了 15% 的 CPU 容量,所以我不认为这是由于 CPU 造成的。
- iptables 伪装所有数据包?我认为是的,但我不确定。有人可以确认/否认吗?
非常感谢您的帮助,它已经困扰我两天了!如果您需要任何日志或 TCP 转储,我可以为您提供。
编辑于 2016/05/22 14:09 GMT
我使用 tcpdump 转储了 TCP 数据包在服务器上. 所有转储均可在此处获取: http://163.172.210.224/dumps/
以下是每个文件的详细信息:
dump-server-direct-eth0.pcap
从服务器直接转储 eth0 的 http 下载。这里没有使用 VPN 也没有使用 IP 转发。使用的命令(我过滤掉了用于 ssh 连接的 IP 地址):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
当客户端通过 UDP/TCP OpenVPN 隧道下载 http 文件时,使用 IP 转发转储 eth0。使用的命令(我过滤掉用于 ssh 连接的 IP 地址):
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 服务器托管在 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 GMT
我收到的评论和回答都提到我使用 TCP 协议而不是 udp 协议与 OpenVPN 通信。正如我在上面的帖子中所说,通过 TCP VPN 隧道,我的服务器和家用电脑之间不存在速度性能问题:
lftp [email protected]:~> pget 1GB.dat
1073741824 bytes transferred in 11 seconds (95.68 MiB/s)
但是为了让每个人都满意并停止关于 tcp 与 udp 的言论,下面是一个使用 udp 的测试:
服务器:
# 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
iperf3 使用 udp vpn 隧道从服务器到客户端进行测试:
# iperf3 -c 10.200.0.2 -i 1 -p 5201 -f m -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 的速度测试服务器进行速度测试:
# 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
答案1
我快速浏览了您上次捕获的文件。我们可以立即看到端到端 TCP 会话的 RTT 约为 50ms 或更差。您的客户端正在宣传一个大约 3MB 的窗口(而不是我最初输入的 300MB)。将它们放在一起,假设 TCP 连接两端的硬件速度无限快,则绝对最大速度为 480Mbps。大概两端都不是无限快的。
所以如果我是你,我会:
接受您获得的性能(取决于实际要求)
或者:
绘制整个会话的 RTT 图表以获得准确性,
使用带宽延迟乘积来准确了解单个 TCP 流的最大带宽。
调查延迟成分来自何处(例如,在隧道服务器上安装分接头)
更新:延迟是由隧道服务器引起的。捕获文件没有明显显示这一点,但端到端延迟比我最初想象的要高得多。基于主机的捕获文件掩盖了每个数据包在服务器中花费的时间长度。理想情况下,您应该在客户端上进行捕获,我认为这会显示更高的 RTT。
dump-server-forward-http-tcp-eth0 帧 17854 就是一个例子。它包含来自互联网主机的数据,这些数据(据称)在 17856 中传输到客户端。然而,直到 18614 才确认 17856,大约 222 毫秒后。考虑到客户端的 RTT 为 40 毫秒(包括一些处理),那么服务器至少会在从互联网主机接收数据到将其发送到客户端的单程行程中添加 180 毫秒。鉴于帧 17854 显然不是物理帧,而是已重新组装(可能错误),因此到互联网主机的延迟也可能类似。
如果 RTT 为 222 毫秒,RWIN 为 3MB,则 TCP 只能传输 13.5Mbps
在我看来,好像启用了 TCP 分段卸载,并且无论出于什么原因,TCP 都在隧道服务器上进行处理,而您实际上只想转发它。现在您需要调查为什么会出现这种情况。
更新:我还注意到您说 CPU 只占 15%。如果这指的是隧道服务器,您说它是 C2750 Atom,8 核。使用多线程 CPU,任何持续的 CPU 负载达到或略高于 100% / 核心数(在您的例子中为 12.5%)都可能是单个主线程占用了一个核心。