方永、南天紫雲

道亦有道

WireGuard直连外网的一些记录
2025年12月19日

最近配置了WireGuard直连外网,这是过程记录。

WireGuard 直接直连肯定是不行的,会被阻断。可以用一些工具对WireGuard 的数据流进行整形和加工,用到的工具是 wg-mangler

wg-mangler 这个工具可以对 WireGuard Noise 协议的 message 进行混淆和padding,能逃过某些检测。用了之后效果非常好,延迟、丢包、吞吐相比于 phantun ,均有大幅的提升,网页秒开,youtube 4k 视频的Buffer Health 稳定在7秒以上。

用了几天,发现有时会有连接不上的情况。经过观察,发现是运营商对走国外的UDP数据包在某些时段进行了drop,持续5分钟以上后自动恢复,不局限于哪个端口,可能是QoS之类。在阻断的过程中,在一台阿里云服务器上的连接是正常的(这台阿里云上的WireGuard同样用 wg-mangler 连接到远端)。

UDP被阻断的问题,有多种解法,很常见的思路就是用TCP 做 tunnel,但就像上面提到的,阿里云走国外的UDP是正常的,何不在阻断时将外网机器IP的路由切到这台阿里云呢?恢复正常后再切回来(因为这台阿里云机器的带宽很小),岂不是鱼和熊掌兼得之?

经过尝试,果然是可以的,下面是配置过程:

假设本地有一台机器A,上面跑了WireGuard,配置了两个 Peer,一个通过 wg-mangler 连到国外机器B(假设公网IP是1.2.3.4), 另一个 Peer 连接到了阿里云机器C 。

在A上配置路由

首先是修改WireGuard的配置,允许1.2.3.4 经由阿里云的那个Peer。其实就是在此Peer的allowed ips 配置上加上 1.2.3.4/32allowed ips 的意思是,WireGuard 是一个 layer 3 的VPN,每个Peer 都可以指定一个允许通过的IP 的 CIDR 列表, 相当于给IP指定哪个Peer作为下一跳。然后在主路由表上添加一条 ip route add 1.2.3.4 dev wg0wg0 是WireGuard的interface

在C上配置回程路由

C上面首先要保证配置了允许转发,也就是 net.ipv4.ip_forward=1,也要配置出口interface 的 masquerade,然后配置回程路由 ip route add 10.1.1.0/24 dev wg0,这里的10.1.1.0/24 是 WireGuard 用到的网段

测试

在A上进行测试。

ping 1.2.3.4 ,测试连通性。

执行 traceroute 1.2.3.4 ,观察路由情况。

然后删除路由 ip route del 1.2.3.4 dev wg0 ,再用 traceroute 观察路由,是否发生变化。

另一种方案

不过呢,上述的方案从A -> C -> B的链路中,A到C属于 WireGuard over WireGuard,这种套娃显然会带来不必要的开销。解法也很简单,只需在C上跑一个 wg-mangler ,这个 wg-mangler 去连B,然后A的endpoint 配置为C上面wg-mangler 的监听地址。或者在C的 nftables 上配置一个端口转发,像这样 iif eth0 udp dport 1234 dnat ip to 1.2.3.4:7788,然后A上的wg-mangler 的转发地址配置为C的地址和这个端口转发地址。这两种方式都可以正常工作,但是如果遇到了UDP阻断,需要来回地切换时,在C上跑一个wg-mangler这种方式更高效一点,因为只需热更新WireGuard peer的 endpoint 即可,WireGuard会即时生效。切换endpoint的命令: wg set wg0 peer <public key> endpoint <ip>:<port>