我有两个 Debian GNU/Linux 系统(bullseye/sid),都在端口 23456 上运行wireguard,都在 NAT 后面。两者都运行 > 5.6 的内核版本(wireguard mainlined)。
系统 A 是服务器,它在权威名称服务器中为其 Internet 域动态更新专用“A 记录”,并为其分配面向 Internet 的路由器 A(ZyWALL USG 100 防火墙)分配的正确公共 IP 地址。它每分钟这样做一次,但公共 IP 地址实际上仅在路由器/防火墙重新启动时才会更改,这基本上不会发生。
系统 B 在 VDSL 路由器 B 后面,它充当线卫客户端,指向动态更新的“A 记录”和端口 33456。路由器 B 是消费级 VDSL 路由器,它允许出站方向的所有内容,只回复入站。
路由器/防火墙 A (ZyWALL USG 100) 被配置为允许端口 23456 上的 UDP 数据包通过它并将它们转发到服务器 A。以下是相关配置屏幕:
这是服务器 A Wireguard 配置文件(此代码段中的密钥,尽管有效,但不是真实的):
[Interface]
Address = 10.31.33.100/24, fc00:31:33::1/64
ListenPort = 23456
PrivateKey = iJE/5Qy4uO55uUQg8nnDKQ/dFT1MEq+tDfFXrGNj3GY=
# PreUp = iptables -t nat -A POSTROUTING -s 10.31.33.0/24 -o enp1s0 -j MASQUERADE; ip6tables -t nat -A POSTROUTING -s fc00:31:33::/64 -o enp1s0 -j MASQUERADE
# PostDown = iptables -t nat -D POSTROUTING -s 10.31.33.0/24 -o enp1s0 -j MASQUERADE; ip6tables -t nat -D POSTROUTING -s fc00:31:33::/64 -o enp1s0 -j MASQUERADE
# Simon
[Peer]
PublicKey = QnkTJ+Qd9G5EybA2lAx2rPNRkxiQl1W6hHeEFWgJ0zc=
AllowedIPs = 10.31.33.211/32, fc00:31:33::3/128
这是客户端 B 的wireguard 配置(同样,密钥和域不是真实的):
[Interface]
PrivateKey = YA9cRlF4DgfUojqz6pK89poB71UFoHPM6pdMQabWf1I=
Address = 10.31.33.211/32
[Peer]
PublicKey = p62kU3HoXLJACI4G+9jg0PyTeKAOFIIcY5eeNy31cVs=
AllowedIPs = 10.31.33.0/24, 172.31.33.0/24
Endpoint = wgsrv.example.com:33456
PersistentKeepalive = 25
这是描述这种情况的脏图:
Client B -> LAN B -> VDSL Router B (NAT) -> the internet -> ZyWALL (NAT) -> LAN A -> Server A
在两个系统上启动wireguard 不会建立VPN 连接。在客户端激活调试消息并将 LOG 规则添加到 iptables 中,记录OUTPUT
数据包,我得到了很多这些:
[414414.454367] IN= OUT=wlp4s0 SRC=10.150.44.32 DST=1.2.3.4 LEN=176 TOS=0x08 PREC=0x80 TTL=64 ID=2797 PROTO=UDP SPT=36883 DPT=33456 LEN=156
[414419.821744] wireguard: wg0-simon: Handshake for peer 3 (1.2.3.4:33456) did not complete after 5 seconds, retrying (try 2)
[414419.821786] wireguard: wg0-simon: Sending handshake initiation to peer 3 (1.2.3.4:33456)
我已经向服务器添加了一个 LOG iptables 规则,以便诊断路由器配置问题。
root@wgserver ~ # iptables -t nat -I INPUT 1 -p udp --dport 23456 -j LOG
它记录从客户端收到的wireguard数据包(但我不知道它们是无效还是不完整):
[ 1412.380826] IN=enp1s0 OUT= MAC=6c:62:6d:a6:5a:8e:d4:60:e3:e0:23:30:08:00 SRC=37.161.119.20 DST=10.150.44.188 LEN=176 TOS=0x08 PREC=0x00 TTL=48 ID=60479 PROTO=UDP SPT=8567 DPT=23456 LEN=156
[ 1417.509702] IN=enp1s0 OUT= MAC=6c:62:6d:a6:5a:8e:d4:60:e3:e0:23:30:08:00 SRC=37.161.119.20 DST=10.150.44.188 LEN=176 TOS=0x08 PREC=0x00 TTL=48 ID=61002 PROTO=UDP SPT=8567 DPT=23456 LEN=156
所以我倾向于假设 A 路由器(ZyWALL USG 100)已正确配置为让数据包进入服务器本地网络。为了证实这个假设,我什至尝试用另一个消费级路由器替换 ZyWALL 并将服务器移动到不同的互联网连接上,但问题仍然存在,所以我确定问题不是防火墙,也不是它的具体问题网络连接。
这是服务器网络配置,以防万一:
auto lo
iface lo inet loopback
auto enp1s0
iface enp1s0 inet static
address 10.150.44.188/24
gateway 10.150.44.1
最重要的是,使用相同的客户端、相同的 VDSL 路由器(客户端)、相同的互联网连接、类似的服务器配置(显然不同的密钥和域)、类似的防火墙配置(服务器端、不同的防火墙模型)。
这可能很愚蠢,但您是否尝试创建新的服务器密钥、客户端密钥并重试?当配置文件错误时,Wireguard 可以完全这样做。
好的,你提到客户端在 VDSL 上,所以我怀疑你有 MTU 问题。
有线(现在是无线)网络连接的正常 MTU 为 1500 字节,但在 *DSL 上,PPPoE 层占用 8 个字节,使得可用的 MTU 实际上为 1492。(也有可能您的网络连接已设置为甚至更低的 MTU。)
Wireguard 的数据包开销为 80 字节,这意味着隧道 MTU 默认为 1420。尝试将其降低相同的 8 个字节,到 1412。(如果您的 MTU 已经低于 1492,则降低。)
您还需要让客户端告诉服务器在隧道数据包上降低其 MTU。这可以通过 iptables 规则来完成。
在客户端 wg0.conf 中,您将需要以下内容: