WireGuard 握手成功,但办公室子网没有响应
WireGuard 已启动并能 ping 通服务器,但其局域网内的主机却不响应。请检查客户端前缀、服务器转发和回程路径。
握手完成, wg show 报告了最近的传输,服务器的隧道地址也能响应 ping。但服务器局域网内的主机却不行。三个条件必须同时成立:客户端必须把局域网前缀路由进隧道,服务器必须转发数据包,而回复需要一条回程路径。三者缺一,症状完全相同。
AllowedIPs 既是访问列表,也是路由表
在客户端上, AllowedIPs 列表既决定可以向该对端发送什么,也决定 WireGuard 安装哪些路由。只列出服务器隧道地址的对端条目只会安装一条主机路由,因此局域网目标永远不会进入隧道。添加局域网前缀是首先要核实的事,也是复制配置后最常缺失的改动。把对端扩展到默认路由是另一种设计,它还会把客户端的互联网流量一并带走。
请把主机路由和局域网前缀保留为两个独立条目。如果办公室有两个子网,两者都应列入;缺少第二个前缀会产生看似选择性、实则并非全面的故障。
[Peer] PublicKey = <server public key> Endpoint = vpn.example.net:51820 AllowedIPs = 10.66.0.1/32, 192.168.50.0/24
转发和地址转换属于服务器
服务器需要启用 IP 转发、一条接受来自隧道流量的转发规则,以及一条朝其局域网接口的地址转换规则。正是地址转换让该设计无需触碰办公网络上的每台主机就能工作。随后回复会回到服务器,而不是回到局域网从未听说过的地址。没有它,每台主机都需要一条通往隧道子网的路由和一条允许它的防火墙规则,而这在别人管理的网络中几乎不可接受。
sysctl -w net.ipv4.ip_forward=1 iptables -A FORWARD -i wg0 -j ACCEPT iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
手工添加的规则会在重启后消失,所以要用服务器配置中的 hook 命令把它们绑定到接口上。规则集比接口活得更久,正是机器最终为一个已不存在的隧道转换流量的原因。
当局域网搬了家,规则却没搬
更换路由器导致办公室子网重新编号,是这类故障的经典版本。隧道仍然在线,握手仍然新鲜,服务器后面却什么都不响应,因为转换规则仍指向旧地址。安装脚本常把服务器的局域网地址写进 POSTROUTING 规则,重新编号之后该地址在任何接口上都不存在。于是数据包被改写到一个无法响应的目标。
iptables -t nat -n -L POSTROUTING ip -br addr show
比较两份输出。接口列表里看不到的转换目标就是问题所在,一旦看见,修复只需改一行。规则可能存在于生成的 unit 中而不是 WireGuard 配置里,所以编辑后要重新加载该 unit,并确认下次启动不会覆盖你的改动。
NAT 后面的两个站点需要一个汇合点
当双方都不接受入站连接时,实用的答案是一台带公网地址、拥有两个 WireGuard 接口的小主机。每个站点向外连接,中间主机在自己的 AllowedIPs中列出每个对端的局域网,转发则在两条隧道之间搬运数据包。两个站点的防火墙都不需要改动,所以这个设计很容易推广。
站点之间的路由保留原始源地址,因此每台主机的日志仍然有意义。两条局域网重叠时,在中间主机上做转换更简单,代价是日志里失去源身份。选择之前先确定哪种性质更重要。
用四项检查把各层分开
每层只做一项检查,而不是同时改三样东西再指望成功。第一项显示每个对端的握手时长和计数器。第二项显示客户端是否真的把该目标路由进隧道。第三和第四项告诉你请求是否到达,以及到达后是否有策略把它丢弃。
wg show ip route get 192.168.50.20 tcpdump -ni wg0 icmp iptables -vnL FORWARD --line-numbers
到达却没有引发回复的请求,指向回程路径或局域网主机。从未到达的请求则指向 AllowedIPs 或客户端路由。这两种结果需要不同的修法,而抓包正是区分它们的手段。