Linux VPN 网关性能莫名下降

Linux VPN 网关性能莫名下降

我使用 Wireguard 为我和我的家人运行一个个人 VPN 网络。几年前出于好奇心开始使用它,但后来变得非常有用并开始发展。我创建了一个概述,链接在这里:网络概述

一切都运行良好,直到最近我的 ISP 决定将我从传统的 DSL 切换到同轴电缆 (DOCSIS) 连接。因此,概览图中标记为“ISP Shitbox A”的设备发生了变化。在这样做的同时,我决定购买并添加另一个路由器(即“Fritz!Box 4060”),因为新的“ISP Shitbox A”没有足够的配置选项来满足我的需求。

因此,在网络的“zrh”部分,设备被分配了新的本地 IP 地址,我必须更改一些路由才能使其正常工作,但乍一看似乎没问题。然后我不幸地注意到,我的 VPN 性能严重下降。我在这里说的不是百分之几,而是从 20+ MByte/s 到每秒只有几千字节(通常导致 HTTP 连接超时)。但更具体地说:

在 zrh 网络中,我有一个 Raspberry Pi(“zrh-02”,运行 Raspberry Pi OS Lite 11),它充当 VPN 网关,将 zrh 网络连接到 ams 网络(或更详细地说,我将其命名为“ams-01”的 VPS,Ubuntu Server 22.04)。我在 fra 网络中还有另一个 Raspberry Pi(“fra-01”,Raspberry Pi OS Lite 11),它充当对应物并将 fra 网络连接到 ams 网络。(图表左侧网络的黄色和蓝色部分与问题无关,但为了完整性我将它们包括在内。)

我做了一些研究,发现由于 zrh ISP 连接的底层技术发生了变化,我应该检查一下 zrh-02 网关的 MTU。为了进行测试,我直接将客户端 A.1 连接到 ams-01(使用相同的物理连接,但不是网关 zrh-02,而是设备上的 wireguard 客户端/应用程序),并在那里摆弄 MTU。事实上,将其降低(在本例中为 1384)似乎可以提高连接质量(速度比迁移前快约 75%,这是一个可以接受的维度——我认为迁移前的连接质量通常要好一些,因为我注意到那里的延迟略高,与 VPN 无关)。

不幸的是,在 zrh-02 上也将 MTU 设置为 1384 也无法解决该问题。但是:当对来自 zrh-02 本身的流量进行速度测试时,它与来自客户端 A.1 的速度一样快(当直接连接到 ams-01 时)。所以我做了一些测试(使用 iperf3)。当在下文中提到“快”时,我指的是 10+ MByte/s,“慢”指的是 5-100 KByte/s(我不认为确切的数字很重要;因为差距太大了)。zrh
-02->fra-01:快
fra-01->zrh-02:快
zrh-03->fra-01:缓慢
zrh-03->zrh-02:快速
fra-01->zrh-03:快速

由此我得出结论,MTU 不是(唯一的)问题,但我的 zrh-02 网关 RasPi 似乎在某种程度上配置错误:似乎只有从 zrh 通过 zrh-02 路由到 ams/fra 的流量很慢(即使相反方向的流量似乎也不受影响)。 (补充说明:zrh-* 设备位于同一台交换机上,每个端口都有 1 GBit/s。在所有情况下,Ping 都有效,在任何情况下都不会超过最大值 ~60ms。跟踪路由没有显示任何不期望的内容。在缓慢的情况下,zrh-03->fra-01:1. 192.168.177.1、2. zrh-02、3. 10.49.0.1、4. 192.168.188.78 - 仅此而已)

我的第一个猜测是,我添加到 zrh 网络中的“Fritz!Box 4060”可能在 IPv6 方面有一些不同的默认值,也许一些网络参与者试图使用这个,然后只回退到 IPv4。但据我所知,这应该只会影响建立 TCP 连接所需的时间,而不会影响之后的吞吐量。尽管如此,我还是尝试在 zrh-02、zrh-03 和 Fritz!Box 4060 上完全禁用 IPv6,但没有效果。

这(终于!)引出了我的问题:有什么想法吗,还有什么可能配置错误?

更多参考:
来自 zrh-02 的 iptables -L:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     icmp --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
DOCKER-USER  all  --  anywhere             anywhere
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (2 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             172.18.0.3           tcp dpt:domain
ACCEPT     udp  --  anywhere             172.18.0.3           udp dpt:domain
ACCEPT     tcp  --  anywhere             172.18.0.2           tcp dpt:https
ACCEPT     tcp  --  anywhere             172.18.0.2           tcp dpt:http

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

Chain DOCKER-USER (1 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere

来自 zrh-02 的 ip 路由:

default via 192.168.177.1 dev eth0 proto dhcp src 192.168.177.11 metric 202 mtu 1500
10.49.0.0/16 dev wg0 scope link
(public IP of ams-01) dev wg0 scope link
169.254.0.0/16 dev veth080a326 scope link src 169.254.119.196 metric 209
169.254.0.0/16 dev vetha933199 scope link src 169.254.229.232 metric 211
172.16.253.86 dev wg0 scope link
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
172.18.0.0/16 dev br-bbdeb14a7bce proto kernel scope link src 172.18.0.1
192.168.177.0/24 dev eth0 proto dhcp scope link src 192.168.177.11 metric 202 mtu 1500
192.168.188.0/24 dev wg0 scope link

从 zrh-02 中 cat /etc/wireguard/wg0.conf:

[Interface]
PrivateKey = (redacted)
Address = 10.49.0.11
DNS =  172.16.253.86
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE; iptables -A INPUT -p icmp -j ACCEPT
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; iptables -t nat -D POSTROUTING -o wg0 -j MASQUERADE; iptables -D INPUT -p icmp -j ACCEPT
MTU = 1384

[Peer]
PublicKey = (redacted)
PresharedKey = (redacted)
AllowedIPs = 192.168.188.0/24, 10.49.0.0/16, 172.16.253.86/32, (public IP of ams-02)/32
Endpoint = (public IP of ams-01):51820
PersistentKeepalive = 25

来自 zrh-02 的 ifconfig:

br-bbdeb14a7bce: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 172.18.255.255
        inet6 fe80::42:4aff:febf:5a71  prefixlen 64  scopeid 0x20<link>
        ether 02:42:4a:bf:5a:71  txqueuelen 0  (Ethernet)
        RX packets 109066  bytes 12276335 (11.7 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 97743  bytes 17850048 (17.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:37:59:e5:b5  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.177.11  netmask 255.255.255.0  broadcast 192.168.177.255
        inet6 fe80::815b:d516:d548:42d3  prefixlen 64  scopeid 0x20<link>
        inet6 2a02:aa12:a87e:3b6:6b2d:cfa9:5b20:1cfb  prefixlen 64  scopeid 0x0<global>
        ether dc:a6:32:48:2d:74  txqueuelen 1000  (Ethernet)
        RX packets 345104  bytes 60403645 (57.6 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 174448  bytes 39141821 (37.3 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 11  bytes 1722 (1.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 11  bytes 1722 (1.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth080a326: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 169.254.119.196  netmask 255.255.0.0  broadcast 169.254.255.255
        inet6 fe80::84fc:4d80:c0ff:87c1  prefixlen 64  scopeid 0x20<link>
        ether e6:fc:45:96:c1:13  txqueuelen 0  (Ethernet)
        RX packets 108227  bytes 13566490 (12.9 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 98381  bytes 18072087 (17.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

vetha933199: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 169.254.229.232  netmask 255.255.0.0  broadcast 169.254.255.255
        inet6 fe80::609c:a3ff:fe93:71d4  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::61fa:14fb:96c6:ec72  prefixlen 64  scopeid 0x20<link>
        ether 62:9c:a3:93:71:d4  txqueuelen 0  (Ethernet)
        RX packets 6  bytes 701 (701.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 753  bytes 250040 (244.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wg0: flags=209<UP,POINTOPOINT,RUNNING,NOARP>  mtu 1384
        inet 10.49.0.11  netmask 255.255.255.255  destination 10.49.0.11
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 1000  (UNSPEC)
        RX packets 418  bytes 46076 (44.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 425  bytes 244724 (238.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

答案1

任何时候,如果您的网关与 WireGuard(或任何其他)连接使用与其本地站点(例如您的 zrh-02)不同的 MTU,您都需要在网关上设置 MSS 限制防火墙规则。使用 iptables 时,类似以下规则即可解决问题:

iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

这将确保尝试使用 WireGuard 连接的其他主机(如您的 zrh-03)知道它们也必须生成更小的 TCP 数据包以避免碎片化。

相关内容