WireGuard 已连接却不能上网:从握手到 DNS 的系统排障指南
WireGuard 有握手却无法访问内网或公网?按接口、握手、AllowedIPs、转发、NAT、防火墙和 DNS 的顺序定位问题。

WireGuard 显示“已连接”却打不开内网或网站,通常不是加密算法出了问题,而是握手、路由、转发、NAT、防火墙和 DNS 中某一层没有接上。最有效的排障方法不是反复重装,而是按数据包经过的顺序逐层证明。
本文假设你已经完成基础安装。若还没有配置服务端和客户端,请先阅读Ubuntu WireGuard 完整搭建指南;如果需要密钥轮换和 DNS 泄漏防护,再看安全加固指南。
第一层:接口是否真的存在
sudo wg show ip address show wg0 ip link show wg0
先确认接口为 UP、地址正确,配置中的私钥没有意外替换。不要在工单或截图里暴露私钥。若接口不存在,查看 systemctl status wg-quick@wg0 与启动日志;此时还没有必要检查 DNS。
第二层:有没有最新握手
wg show 的 latest handshake 是第一个分叉点。完全没有握手,优先检查 Endpoint、UDP 端口、服务器安全组、防火墙和公钥是否匹配。客户端位于 NAT 后且需要长期接收流量时,WireGuard 官方建议可使用 PersistentKeepalive;不需要时不要盲目开启。
有握手但 transfer 只有单向增长,说明加密隧道存在,回程路由或防火墙更可疑。抓包时同时观察公网接口和 wg0,能确定数据包停在哪一侧:
sudo tcpdump -ni any udp port 51820 sudo tcpdump -ni wg0 host 10.0.0.2
第三层:AllowedIPs 同时是路由和访问控制
WireGuard 官方把 AllowedIPs 描述为一种 cryptokey routing table:发送时决定某个目标交给哪个 Peer,接收时又限制该 Peer 可以声称哪些源地址。客户端只访问内网时,应写内网网段;全隧道通常包含 0.0.0.0/0,如需 IPv6 还要单独处理 ::/0。重叠网段会让最长前缀匹配把流量送向意料之外的 Peer。
ip route get 10.0.0.1 ip route get 1.1.1.1 ip -6 route get 2606:4700:4700::1111
第四层:服务器能否转发
握手成功只表示两端能互相认证,不代表服务器会替客户端转发。Linux 网关需要启用相应的 IPv4/IPv6 forwarding,FORWARD 链允许 wg0 与出口接口之间的流量。若客户端要通过服务器访问公网,还要有正确的 SNAT/MASQUERADE;如果只访问已经知道 WireGuard 网段的内网,静态回程路由通常比 NAT 更透明。
sysctl net.ipv4.ip_forward sudo nft list ruleset sudo iptables -S FORWARD sudo iptables -t nat -S
不要直接复制来源不明的“清空防火墙”命令。先读取规则和计数器,临时添加最小规则验证,再把确认有效的配置写入持久化管理工具。
第五层:最后再查 DNS
如果 ping 1.1.1.1 成功而域名失败,才进入 DNS 分支。检查系统实际使用的 resolver,而不只是配置文件里写了什么。Ubuntu 使用 systemd-resolved 时,可用 resolvectl status 查看每个接口的 DNS 与路由域。分流 VPN 常见问题是内网域名应走企业 DNS,公共域名仍走本地 DNS,却被一个全局 DNS 设置全部覆盖。
一张最短排障路径
- 接口不存在:修复 wg-quick 配置或服务。
- 无握手:检查 Endpoint、UDP、公钥与入口防火墙。
- 有握手无双向流量:检查 AllowedIPs、回程路由和 FORWARD。
- 能访问隧道地址但不能上网:检查 forwarding 与 NAT。
- 能访问 IP 但不能访问域名:检查 resolver 和 DNS 分流。
- 间歇性断线:观察 MTU、NAT 超时、漫游和 keepalive,而不是先重装。
