我的家庭网络上有一个 Wireguard 服务器,它在我的所有设备上都运行良好,包括我的手机(当它连接到 Wi-Fi 时)。问题出现在我断开 Wi-Fi 连接并使用 4G 时,我的手机无法与服务器完成握手。
在我的路由器上,我将 UDP 端口 51820 转发到我的 Wireguard 服务器。在我的手机上,我使用 DNS 名称 (vpn.mydomain.tld:51820) 连接到 VPN
我已经启用 Wireguard 的内核日志记录来帮助我解决这个问题,但遗憾的是我无法找到我的设置出了什么问题。
以下是我尝试通过手机(通过 4G)连接时服务器上出现的日志
Mar 23 17:49:36 wireguard kernel: [448095.663902] wireguard: wg0: Keypair 9893 created for peer 16
Mar 23 17:49:45 wireguard kernel: [448104.009541] wireguard: wg0: Receiving handshake initiation from peer 16 (xxx.xxx.xxx.xxx:40061)
Mar 23 17:49:45 wireguard kernel: [448104.009546] wireguard: wg0: Sending handshake response to peer 16 (xxx.xxx.xxx.xxx:40061)
Mar 23 17:49:45 wireguard kernel: [448104.010284] wireguard: wg0: Keypair 9893 destroyed for peer 16
Mar 23 17:49:45 wireguard kernel: [448104.010286] wireguard: wg0: Keypair 9894 created for peer 16
Mar 23 17:49:50 wireguard kernel: [448109.069901] wireguard: wg0: Receiving handshake initiation from peer 16 (xxx.xxx.xxx.xxx:40061)
Mar 23 17:49:50 wireguard kernel: [448109.069903] wireguard: wg0: Sending handshake response to peer 16 (xxx.xxx.xxx.xxx:40061)
Mar 23 17:49:50 wireguard kernel: [448109.070073] wireguard: wg0: Keypair 9894 destroyed for peer 16
在我的手机上,我看到以下内容:
peer(...) - Sending handshake initiation
peer(...) - Handshake did not complete after 5 seconds, retrying (try 2)
peer(...) - Sending handshake initiation
peer(...) - Handshake did not complete after 5 seconds, retrying (try 2)
peer(...) - Sending handshake initiation
由于当我连接到家里的 Wi-Fi 时它工作正常,所以我不知道除了端口转发之外还要寻找什么,但据我所知它工作正常。
这是我的服务器上的 wg0.conf:
[Interface]
Address = 10.10.10.3/32
SaveConfig = true
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -d 10.10.10.0/24 -o eth0 -j MASQUERADE; iptables -t nat -A POSTROUTING ! -d 10.10.10.0/24 -o pia -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -d 10.10.10.0/24 -o eth0 -j MASQUERADE; iptables -t nat -D POSTROUTING ! -d 10.10.10.0/24 -o pia -j MASQUERADE
ListenPort = 51820
PrivateKey = [removed]
[Peer]
PublicKey = [removed]
AllowedIPs = 10.10.10.245/32
Endpoint = 10.10.10.147:60743
以及我手机上的连接文件(运行 Android 11):
[Interface]
Address = 10.10.10.245/24
DNS = 10.10.10.2
PrivateKey = [removed]
[Peer]
AllowedIPs = 0.0.0.0/0
Endpoint = vpn.mydomain.tld:51820
PersistentKeepalive = 25
PublicKey = [removed]
我已确保密钥匹配,但由于连接到我的 Wi-Fi 时连接工作正常,因此我认为配置文件不是问题的根源。
我在服务器上安装了 UFW,配置如下:
To Action From
-- ------ ----
51820/udp ALLOW Anywhere
22/tcp ALLOW Anywhere
10050 ALLOW Anywhere
51820/udp (v6) ALLOW Anywhere (v6)
22/tcp (v6) ALLOW Anywhere (v6)
10050 (v6) ALLOW Anywhere (v6)
但是我禁用了它以确保它不会干扰,但它并没有改变任何东西。目前我不知道哪里出了问题,也不知道该搜索什么来帮助我解决这个问题,所以任何帮助都会受到欢迎
编辑:我大概知道问题出在哪里了。在我的 wg0.conf 中,我的 PostUp 中有以下部分:iptables -t nat -A POSTROUTING ! -d 10.10.10.0/24 -o pia -j MASQUERADE
此行旨在将所有传出流量路由到另一条隧道,但是,它也有副作用,就是让我的 WireGuard 服务器通过另一个 IP 响应我的外部客户端(即,我从 4G 上的手机连接到 xxx.xxx.xxx.xxx,并且由于该行,它通过 yyy.yyy.yyy.yyy 响应连接请求),这就是我的客户端无法连接的原因。当我删除此路由规则时,我可以从网络外部正常连接,但是现在当然,我的流量不会通过第二条隧道重新路由。有没有办法保留此规则,或者至少保留一条类似的规则,将外部流量路由到另一个 VPN,同时通过我的 eth0 设备响应我手机的连接请求?由于我的手机将通过 4G 连接,我无法预测它将从哪个 IP 地址连接,因此我无法仅为我的手机添加类似的路由规则。
答案1
MASQUERADE
/POSTROUTING
规则不会改变某些流量的去向。路由会。问题是您有一个默认路由(或等效路由)将流量引导到隧道中pia
。
您将需要利用策略路由来处理来自 wireguard 服务器的回复流量:
# ip r add 192.168.1.1 dev eth0 table 123
# ip r add default via 192.168.1.1 table 123
# ip rule add iif lo ipproto udp sport 51820 lookup 123
第一个命令是可选的。请确保将192.168.1.1
和替换eth0
为路由器的 LAN IP 和以太网 NIC 的接口名称。(您可以从的输出中复制它们ip r
,即主表中的路由。)数字123
是任意的。将规则限制为来自主机本身iif lo
的源端口为 的 UDP 流量(但不包括来自其他主机的此类流量)。51820
答案2
在您的 Android 设备上安装 windscribe 并将其设置为 wireguard 模式,然后连接。现在检查 iptables 规则。不幸的是,我不擅长 iptables,但 mangle 表和 mark dns 中有一些东西
-A st_clear_caught_dns_accept -d 10.255.255.2/32 -p udp -m udp --dport 53 -j ACCEPT
-A st_clear_detect -m connmark --mark 0x2000000/0x2000000 -j REJECT --reject-with icmp-port-unreachable
-A st_clear_detect -m connmark --mark 0x1000000/0x1000000 -j RETURN
-A st_clear_detect -p tcp -m u32 --u32 "0x0>>0x16&0x3c@0xc>>0x1a&0x3c@0x0&0xffff0000=0x16030000&&0x0>>0x16&0x3c@0xc>>0x1a&0x3c@0x4&0xff0000=0x10000" -j CONNMARK --set-xmark 0x1000000/0x1000000
-A st_clear_detect -p udp -m u32 --u32 "0x0>>0x16&0x3c@0x8&0xffff0000=0x16fe0000&&0x0>>0x16&0x3c@0x14&0xff0000=0x10000" -j CONNMARK --set-xmark 0x1000000/0x1000000
-A st_clear_detect -m connmark --mark 0x1000000/0x1000000 -j RETURN
-A st_clear_detect -p tcp -m state --state ESTABLISHED -m u32 --u32 "0x0>>0x16&0x3c@0xc>>0x1a&0x3c@0x0&0x0=0x0" -j st_clear_caught
-A st_clear_detect -p udp -j st_clear_caught
-A st_penalty_log -j CONNMARK --set-xmark 0x1000000/0x1000000
-A st_penalty_log -j NFLOG
-A st_penalty_reject -j CONNMARK --set-xmark 0x2000000/0x2000000
-A st_penalty_reject -j NFLOG
-A st_penalty_reject -j REJECT --reject-with icmp-port-unreachable