服务公告

服务公告 > 综合新闻 > WireGuard:故障排查

WireGuard:故障排查

发布时间:2026-04-23 10:02

WireGuard:故障排查

一、前言

搞过WireGuard的人都晓得,这玩意儿配起来快,出问题排查起来是真他妈的蛋疼。明明配置文件看着没问题,ping就是不通,手册看烂了还是一头雾水。这篇不废话,直接从实战出发,手把手教你把WireGuard的疑难杂症一个个揪出来。

二、操作步骤

步骤1:确认WireGuard服务状态和内核模块加载

很多问题根源在于WireGuard压根没跑起来,先把基础状态摸清楚。

# 检查内核模块是否加载(所有发行版通用) lsmod | grep wireguard # 预期输出: # wireguard 212992 0 # ip6_udp_tunnel 16384 1 wireguard # udp_tunnel 16384 1 wireguard # 检查wg0接口是否存在 ip link show wg0 # 预期输出(已配置): # 4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 # link/nopeer 10.0.0.1 peer 10.0.0.2 # 检查服务状态(systemd系统) systemctl status wg-quick@wg0 # 预期输出: # ● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0 # Loaded: loaded (/lib/systemd/system/wg-quick@.service; enabled) # Active: active (exited) since Mon 2024 01:30:00 CST; 2 days ago

如果模块没加载,手动加载一下:

# 加载内核模块 modprobe wireguard # 确认版本 wg --version # 预期输出: # wg 1.0.20210424

步骤2:核对服务端配置文件

服务端配置错一个字符都白搭,这条老哥们踩的坑最多。

# 查看当前运行配置(关键!这是实际生效的配置) wg show # 预期输出示例: # interface: wg0 # public key: XXXXXXXXXXXXXXX= # private key: (hidden) # listening port: 51820 # peer: YYYYYYYYYYYYYYY= # endpoint: 203.0.113.50:51820 # allowed ips: 10.0.0.2/32 # persistent keepalive: every 25 seconds # 查看配置文件内容 cat /etc/wireguard/wg0.conf # CentOS/RHEL路径 cat /etc/wireguard/wg0.conf # Ubuntu路径(同样适用) cat /etc/wireguard/wg0.conf # 预期输出结构: # [Interface] # Address = 10.0.0.1/24 # ListenPort = 51820 # PrivateKey = SERVER_PRIVATE_KEY_BASE64 # PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE # [Peer] # PublicKey = CLIENT_PUBLIC_KEY_BASE64 # AllowedIPs = 10.0.0.2/32

⚠️ 警告:PostUp/PostDown里的iptables命令执行后不可逆,操作前确认好规则。

步骤3:核对客户端配置和密钥配对

密钥不配对,握手都别想成功。这是80%连接失败的原因。

# 服务端生成本机密钥对(如果还没生成) wg genkey | tee privatekey | wg pubkey > publickey # 在服务端查看客户端的公钥 # 假设客户端把你的公钥发过来了,服务端配置里应该有对应的Peer wg show wg0 peers # 预期输出: # YYYYYYYYYYYYYYY= <-- 这是客户端的公钥 # 客户端配置示例(/etc/wireguard/wg0.conf) # [Interface] # PrivateKey = CLIENT_PRIVATE_KEY_BASE64 # Address = 10.0.0.2/24 # DNS = 8.8.8.8 # [Peer] # PublicKey = SERVER_PUBLIC_KEY_BASE64 # Endpoint = your-server-ip:51820 # AllowedIPs = 0.0.0.0/0 # PersistentKeepalive = 25 # 验证公钥是否匹配 # 在服务端和客户端分别执行: wg pubkey < privatekey # 两边的PublicKey必须完全一致

步骤4:测试网络连通性

配置没问题但不通,先确认网络层能不能到达。

# 客户端测试到服务端UDP端口的连通性 # 注意:WireGuard用UDP,不是TCP! nc -vzu SERVER_IP 51820 # 预期输出: # Connection to SERVER_IP 51820 port [udp/*] succeeded! # 或者用nmap(如果没有nc) nmap -sU -p 51820 SERVER_IP # 预期输出: # PORT STATE SERVICE # 51820/udp open|filtered unknown # 检查服务端是否在监听 ss -ulnp | grep 51820 # 预期输出: # UNDEFIED 0 0 *:51820 *:* users:(("wg-quick",pid=1234),("wg-crypt",pid=1235)) # 从服务端ping客户端的WireGuard IP(需要在AllowedIPs范围内) ping -c 3 10.0.0.2 # 预期输出: # PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. # 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=50.2 ms # 如果ping不通但配置都正确,检查客户端防火墙是否允许ICMP

步骤5:检查防火墙规则

防火墙是个大坑,无数人栽在这。服务端和客户端都要检查。

# ================ 服务端操作 ================ # 检查iptables FORWARD链(CentOS/RHEL和Ubuntu通用) iptables -L FORWARD -v -n # 预期输出应包含: # ACCEPT all -- wg0 * 0.0.0.0/0 0.0.0.0/0 # ACCEPT all -- * wg0 0.0.0.0/0 0.0.0.0/0 # 检查NAT/POSTROUTING规则 iptables -t nat -L POSTROUTING -v -n # 预期输出应包含: # MASQUERADE all -- * eth0 10.0.0.0/24 0.0.0.0/0 # CentOS/RHEL额外检查firewalld firewall-cmd --list-all # 预期输出: # public (active) # interfaces: eth0 # services: dhcpv6-client ssh wireguard # 如果没有wireguard服务,手动添加 firewall-cmd --permanent --add-service=wireguard firewall-cmd --reload # CentOS/RHEL检查SELinux getenforce # 预期输出:Disabled 或 Enforcing(如果Enforcing需要配置) # ================ 客户端操作 ================ # Ubuntu/Debian检查ufw ufw status # 如果开启,确保允许wg0 ufw allow from 10.0.0.0/24 ufw reload # macOS客户端检查系统偏好设置 # 确保VPN配置已启用且允许连接

⚠️ 警告:iptables -F 会清空所有规则,非必要勿用。调试时用 -C 检查而非 -A。

步骤6:检查MTU和分片问题

MTU不匹配会导致包被丢弃,表现为能ping但实际流量不通。

# 检查服务端wg0接口MTU ip link show wg0 # 预期输出: # 4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 # 检查物理接口MTU ip link show eth0 # 预期输出: # 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 # MTU计算:物理MTU - WireGuard头(60) - IP头(20) = 典型值1420 # 如果物理MTU是1500,wg0应该是1420 # 从客户端测试MTU路径 tracepath -m 5 SERVER_PUBLIC_IP # 预期输出: # 1?: [LOCALHOST] pmtu 1500 # 1: gateway 58ms # 2: SERVER_IP 55ms pmtu 1500 # 手动设置MTU(如果需要调整) # 在/etc/wireguard/wg0.conf的[Interface]段添加: # MTU = 1380 # 调试:使用ping测试分片 ping -M do -s 1300 SERVER_WG_IP # 如果不通,降低-s值重试

步骤7:查看握手和加密日志

WireGuard加密出问题会导致握手失败。

# 实时监控WireGuard状态变化(调试模式) # 重启wg0接口观察日志 wg-quick down wg0 wg-quick up wg0 # journalctl查看systemd日志 journalctl -u wg-quick@wg0 -f --since "1 minute ago" # CentOS/RHEL和Ubuntu通用 # 检查是否有握手时间戳(判断是否在通讯) wg show wg0 # 预期输出: # peer: YYYYYYYYYYYYYYY= # endpoint: 203.0.113.50:51820 # allowed ips: 10.0.0.2/32 # latest handshake: 45 seconds ago <-- 这个时间戳说明握手正常 # transfer: 10.50 MiB received, 2.30 MiB sent # 如果latest handshake显示Never,说明没有成功握手 # 启用WireGuard调试日志(临时) echo 'module wireguard +p' | sudo tee /sys/kernel/debug/dynamic_debug/control # 预期输出: # module wireguard +p # 查看调试日志 dmesg -w | grep wireguard

步骤8:验证路由和AllowedIPs

AllowedIPs配置错误是最容易被忽视的问题源头。

# 查看服务端路由表 ip route # 确保有类似这样的路由: # 10.0.0.0/24 dev wg0 proto kernel scope link src 10.0.0.1 # 查看详细路由信息 ip route show dev wg0 # 预期输出: # 10.0.0.0/24 proto kernel link src 10.0.0.1 # 在客户端检查路由(Split Tunnel vs 全流量) # Split Tunnel模式(只有特定流量走WireGuard): ip route | grep wg0 # 10.0.0.0/24 dev wg0 proto kernel scope link src 10.0.0.2 # 全流量模式(所有流量走WireGuard): ip route # default dev wg0 proto static metric 50 # 10.0.0.0/24 dev wg0 proto kernel scope link src 10.0.0.2 # 测试特定IP是否走WireGuard ip route get 8.8.8.8 # 全流量模式预期: # 8.8.8.8 dev wg0 src 10.0.0.2 mark 0xdeadbeef # Split Tunnel模式预期: # 8.8.8.8 via 实际网关 dev eth0 src 实际IP

三、常见问题FAQ

Q1: "latest handshake显示Never,配置检查八百遍了还是不通,什么鬼?"

老哥,别光看配置,先用tcpdump抓包确认包到底到没到:

# 服务端抓UDP 51820端口 tcpdump -i eth0 udp port 51820 -n # 预期输出(如果客户端发包了): # 15:30:01.234567 IP CLIENT_IP.12345 > SERVER_IP.51820: UDP, length 148 # 15:30:01.234800 IP SERVER_IP.51820 > CLIENT_IP.12345: UDP, length 148 # 如果只看到发出去没收到回来,检查: # 1. 服务端防火墙是否拦住入站UDP # 2. 云服务商安全组是否放行UDP 51820(这条坑了最多人) # 3. NAT类型问题 # 云平台安全组检查(AWS EC2为例): # 入站规则必须允许:Custom UDP 51820 0.0.0.0/0 # 阿里云安全组: # 自定义UDP 51820 0.0.0.0/0

Q2: "能ping通WireGuard IP,但访问内网服务就超时,脑子嗡嗡的"

这明显是路由或防火墙的锅,别慌:

# 第一步:确认服务端FORWARD是否开启 cat /proc/sys/net/ipv4/ip_forward # 必须输出 1,否则: echo 1 | tee /proc/sys/net/ipv4/ip_forward # 永久生效(CentOS/RHEL): echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf # 永久生效(Ubuntu): echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.d/99-wireguard.conf # 第二步:确认MASQUERADE规则存在 iptables -t nat -L POSTROUTING -n | grep MASQUERADE # 没有的话补上(CentOS/RHEL和Ubuntu通用): iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # PostUp里没配置的话要手动加 # 第三步:确认FORWARD规则 iptables -L FORWARD -n | grep wg0 # 没有的话: iptables -A FORWARD -i wg0 -j ACCEPT iptables -A FORWARD -o wg0 -j ACCEPT # 第四步:如果是访问内网特定网段,确认AllowedIPs包含那个网段 # 服务端wg0.conf的[Peer]段: # AllowedIPs = 10.0.0.2/32, 192.168.1.0/24

Q3: "手机端WireGuard经常断线,电脑端没事,什么原因?"

移动网络环境复杂,NAT超时和Keepalive是核心:

# 确保客户端配置了PersistentKeepalive(25秒是个经验值) # 在客户端/etc/wireguard/wg0.conf的[Peer]段: [Peer] PublicKey = SERVER_PUBLIC_KEY_BASE64 Endpoint = your-server-ip:51820 AllowedIPs = 0.0.0.0/0 PersistentKeepalive = 25 # 服务端也可以设置,但客户端设置更关键 # 如果移动网络特别差,可以降到15秒 # 检查服务端是否限制了连接数 # 有些云服务商会限制UDP并发连接数 # 查看握手日志判断断线频率 wg show wg0 # 如果latest handshake时间一直在跳动但频繁重置,说明网络不稳定 # 如果latest handshake一直是固定时间(几小时前),说明已经断了 # 建议在手机上开启WireGuard的"Connect on Demand"功能(iOS/Android) # 这样只在需要时建立连接,减少断线重连的频率

Q4: "服务端重启后客户端全部需要重新导入配置,烦死了"(这条是老手向)

服务端重启不会影响客户端配置,除非你换了密钥:

# 如果重启后客户端全挂,检查以下原因: # 1. 服务端IP变了(DHCP获取的情况) # 解决:给服务器绑定静态IP或使用DDNS # 2. 防火墙规则没持久化 # 检查PostUp/PostDown是否写入/etc/wg-keys.conf等配置文件 # CentOS/RHEL确保iptables服务enabled: systemctl enable iptables # Ubuntu确保iptables-persistent包已安装 # 3. 内核模块没自动加载 # 编辑 /etc/modules-load.d/wireguard.conf: echo "wireguard" > /etc/modules-load.d/wireguard.conf # 4. wg-quick服务没自动启动 systemctl enable wg-quick@wg0 # CentOS/RHEL和Ubuntu通用 # 5. 配置文件被覆盖(云服务商重置镜像的情况) # 解决:备份配置到非系统目录

四、总结

核心要点

  • 排查顺序:服务状态 → 配置文件 → 密钥配对 → 网络连通性 → 防火墙 → MTU → 路由
  • 最常见问题:云平台安全组没放行UDP、云服务商限制UDP并发、防火墙拦住包
  • 调试神器:wg show 看状态、tcpdump 抓包、journalctl 查日志
  • 密钥问题:服务端和客户端公钥必须配对,用 wg pubkey < privatekey 验证
  • Keepalive:移动网络必开,25秒是经验值
  • MTU:一般设置1420,PPPoE环境要更低(1380)

延伸阅读

最后说一句:WireGuard这玩意儿配好了是真稳,出问题大概率是配置文件或者防火墙的锅。按这个排查流程走,八成能定位到问题。遇到云平台限制就换端口或者走TCP over WebSocket,别死磕UDP。

上一篇: Claude:安装配置

下一篇: Nmap:安全审计