24. 连接故障排查
24.1 无法建立连接
24.1.1 检查步骤
步骤1:验证VPN服务是否运行
服务器端:
# 检查WireGuard接口
sudo wg show
# 检查接口状态
ip link show wg0
# 检查systemd服务
sudo systemctl status wg-quick@wg0
预期结果:
interface: wg0
public key: rUEB9pR7DO7qgkbo6Ylerrh/Fvl1XA8RJuALBdlkFkk=
listening port: 51820
如果没有输出:
# 启动WireGuard
sudo wg-quick up wg0
# 或使用systemd
sudo systemctl start wg-quick@wg0
步骤2:检查网络连通性
客户端测试服务器可达性:
# ping服务器物理IP
ping 192.168.1.66
# 测试UDP端口(需要nc)
nc -u -v 192.168.1.66 51820
如果ping不通:
- 检查网络连接
- 检查服务器IP是否正确
- 检查防火墙规则
步骤3:验证防火墙规则
服务器端:
# 检查ufw状态
sudo ufw status
# 检查iptables规则
sudo iptables -L INPUT -n -v | grep 51820
sudo iptables -L FORWARD -n -v | grep wg0
sudo iptables -t nat -L POSTROUTING -n -v
必需的规则:
# 允许WireGuard端口
sudo ufw allow 51820/udp
# 或iptables
sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT
步骤4:检查配置文件
服务器端:
# 查看配置
sudo cat /etc/wireguard/wg0.conf
# 检查语法
sudo wg-quick strip wg0
客户端检查:
- PrivateKey 是否正确
- PublicKey(服务器公钥)是否正确
- Endpoint 是否正确
- AllowedIPs 是否配置
步骤5:验证密钥匹配
服务器端验证客户端公钥:
sudo wg show wg0 peers
客户端验证服务器公钥:
# 从私钥生成公钥
echo "<服务器私钥>" | wg pubkey
# 应该匹配客户端配置中的PublicKey
步骤6:检查IP转发
服务器端:
# 检查IP转发是否启用
sysctl net.ipv4.ip_forward
如果输出为0:
# 临时启用
sudo sysctl -w net.ipv4.ip_forward=1
# 永久启用
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
24.1.2 诊断命令
完整诊断脚本:
#!/bin/bash
# wireguard-diagnostic.sh
echo "=== WireGuard 诊断工具 ==="
echo ""
# 1. 检查WireGuard是否安装
echo "[1] 检查WireGuard安装..."
if command -v wg &> /dev/null; then
echo "✓ WireGuard已安装 ($(wg --version))"
else
echo "✗ WireGuard未安装"
exit 1
fi
# 2. 检查接口状态
echo ""
echo "[2] 检查接口状态..."
if sudo wg show wg0 &> /dev/null; then
echo "✓ wg0接口运行中"
sudo wg show wg0 | head -5
else
echo "✗ wg0接口未运行"
fi
# 3. 检查监听端口
echo ""
echo "[3] 检查监听端口..."
if sudo ss -ulnp | grep :51820 &> /dev/null; then
echo "✓ 51820端口正在监听"
sudo ss -ulnp | grep :51820
else
echo "✗ 51820端口未监听"
fi
# 4. 检查IP转发
echo ""
echo "[4] 检查IP转发..."
if [ "$(sysctl -n net.ipv4.ip_forward)" = "1" ]; then
echo "✓ IP转发已启用"
else
echo "✗ IP转发未启用"
fi
# 5. 检查防火墙规则
echo ""
echo "[5] 检查防火墙规则..."
if sudo iptables -L FORWARD -n | grep wg0 &> /dev/null; then
echo "✓ FORWARD规则存在"
else
echo "✗ FORWARD规则缺失"
fi
if sudo iptables -t nat -L POSTROUTING -n | grep MASQUERADE &> /dev/null; then
echo "✓ NAT规则存在"
else
echo "✗ NAT规则缺失"
fi
# 6. 检查peer连接
echo ""
echo "[6] 检查peer连接..."
peer_count=$(sudo wg show wg0 peers 2>/dev/null | wc -l)
echo "连接的peer数量: $peer_count"
# 7. 检查最近握手
echo ""
echo "[7] 检查最近握手..."
sudo wg show wg0 latest-handshakes 2>/dev/null | while read pubkey timestamp; do
if [ "$timestamp" != "0" ]; then
age=$(($(date +%s) - timestamp))
echo "Peer ${pubkey:0:10}... 最后握手: ${age}秒前"
fi
done
echo ""
echo "=== 诊断完成 ==="
使用方法:
chmod +x wireguard-diagnostic.sh
sudo ./wireguard-diagnostic.sh
24.1.3 常见原因
原因1:配置文件错误
症状:
Error: Configuration parsing error
排查:
# 检查配置语法
sudo wg-quick strip wg0
# 常见错误:
# - PrivateKey格式错误(不是44字符Base64)
# - IP地址格式错误
# - 缺少必需字段
修复:
# 重新生成密钥
wg genkey | tee private.key | wg pubkey > public.key
# 验证配置
sudo nano /etc/wireguard/wg0.conf
原因2:端口被占用
症状:
Error: Address already in use
排查:
# 检查端口占用
sudo lsof -i :51820
sudo ss -ulnp | grep :51820
修复:
# 杀死占用进程
sudo fuser -k 51820/udp
# 或修改配置使用其他端口
ListenPort = 41194
原因3:防火墙阻止
症状:客户端显示”连接中”但始终无法成功
排查:
# 服务器端查看连接尝试
sudo tcpdump -i pnet0 udp port 51820
# 检查防火墙日志
sudo journalctl -k | grep -i ufw
sudo tail -f /var/log/kern.log | grep UFW
修复:
# 允许WireGuard端口
sudo ufw allow 51820/udp
# 或iptables
sudo iptables -I INPUT -p udp --dport 51820 -j ACCEPT
原因4:NAT问题
症状:服务器能收到握手包,但客户端无响应
排查:
# 检查NAT规则
sudo iptables -t nat -L POSTROUTING -n -v
# 抓包查看
sudo tcpdump -i wg0 -n
修复:
# 添加NAT规则
sudo iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
# 或在配置文件添加PostUp
PostUp = iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
24.1.4 解决方案
方案1:重置配置
# 停止WireGuard
sudo wg-quick down wg0
# 备份配置
sudo cp /etc/wireguard/wg0.conf /etc/wireguard/wg0.conf.bak
# 重新生成密钥
cd /etc/wireguard
sudo wg genkey | tee server_private.key | wg pubkey > server_public.key
# 重新配置
sudo nano /etc/wireguard/wg0.conf
# 启动
sudo wg-quick up wg0
方案2:使用最小配置测试
服务器最小配置:
[Interface]
PrivateKey = <服务器私钥>
Address = 10.8.0.1/24
ListenPort = 51820
[Peer]
PublicKey = <客户端公钥>
AllowedIPs = 10.8.0.2/32
客户端最小配置:
[Interface]
PrivateKey = <客户端私钥>
Address = 10.8.0.2/24
[Peer]
PublicKey = <服务器公钥>
Endpoint = 192.168.1.66:51820
AllowedIPs = 10.8.0.0/24
PersistentKeepalive = 25
测试连接:
# 客户端连接后测试
ping 10.8.0.1
方案3:逐步添加功能
- 先建立基本连接
- 测试ping通信
- 添加NAT规则
- 测试访问互联网
- 添加DNS配置
- 添加其他高级功能
24.2 连接不稳定
24.2.1 症状识别
症状1:频繁断连
- 每隔几分钟就断开
- 需要手动重新连接
- 握手时间间隔过长
症状2:间歇性丢包
- ping有丢包
- 网页加载缓慢
- 文件传输中断
症状3:延迟波动大
- 延迟时高时低
- 视频通话卡顿
- 游戏延迟不稳定
24.2.2 诊断方法
检查握手频率:
# 持续监控握手时间
watch -n 1 'sudo wg show wg0 | grep "latest handshake"'
正常情况:
- 有流量时每2分钟握手一次
- 配置PersistentKeepalive时按设定间隔握手
异常情况:
- 握手间隔远大于预期
- 长时间无握手
测试连接稳定性:
# 持续ping测试
ping -c 1000 10.8.0.1 > ping-results.txt
# 分析结果
cat ping-results.txt | grep "packet loss"
cat ping-results.txt | grep "rtt"
监控流量:
# 实时流量监控
sudo iftop -i wg0
# 或使用nethogs
sudo nethogs wg0
24.2.3 常见原因
原因1:NAT超时
症状:
- 几分钟后连接中断
- 服务器无法主动发送数据给客户端
- 客户端重启后恢复
排查:
# 检查PersistentKeepalive设置
sudo wg show wg0 persistent-keepalive
修复:
# 客户端配置添加
[Peer]
PersistentKeepalive = 25 # 每25秒发送保活包
原因2:MTU不匹配
症状:
- 小数据包正常(如ping)
- 大数据包失败(如网页、文件)
- SSH连接建立后无响应
排查:
# 测试不同MTU
ping -M do -s 1472 10.8.0.1 # 测试1500 MTU
ping -M do -s 1392 10.8.0.1 # 测试1420 MTU
ping -M do -s 1252 10.8.0.1 # 测试1280 MTU
修复:
# 降低MTU
[Interface]
MTU = 1280 # 或1380、1420
原因3:网络质量差
症状:
- 延迟波动大
- 随机丢包
- 特定时段问题明显
排查:
# 长时间ping测试
ping -c 1000 -i 0.2 10.8.0.1 | tee ping-test.log
# 分析丢包模式
grep "time=" ping-test.log | awk '{print $7}' | sed 's/time=//' | sort -n
修复方案:
- 更换网络环境
- 使用有线连接替代WiFi
- 联系ISP解决网络问题
原因4:服务器性能问题
症状:
- 高负载时连接不稳定
- CPU占用率高
- 内存不足
排查:
# 检查系统负载
uptime
top
# 检查WireGuard进程
ps aux | grep wireguard
修复:
- 优化服务器配置
- 增加硬件资源
- 限制并发连接数
24.2.4 解决方案
方案1:优化保活设置
# 客户端配置
[Peer]
# 根据网络环境调整
PersistentKeepalive = 25 # 标准环境
# PersistentKeepalive = 15 # 严格NAT环境
# PersistentKeepalive = 60 # 稳定环境(省电)
方案2:调整MTU
自动查找最优MTU:
#!/bin/bash
# find-best-mtu.sh
TARGET="10.8.0.1"
for size in 1472 1392 1352 1312 1252; do
echo "测试MTU $((size + 28))..."
if ping -M do -s $size -c 3 -W 1 $TARGET > /dev/null 2>&1; then
mtu=$((size + 28))
echo "✓ 推荐MTU: $mtu"
break
fi
done
方案3:添加TCP MSS钳制
服务器端:
# 添加MSS钳制规则
sudo iptables -t mangle -A FORWARD -i wg0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
# 或在配置文件
PostUp = iptables -t mangle -A FORWARD -i wg0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
方案4:启用BBR拥塞控制
服务器端:
# 启用BBR
sudo modprobe tcp_bbr
echo "tcp_bbr" | sudo tee -a /etc/modules
# 配置sysctl
cat <<EOF | sudo tee -a /etc/sysctl.conf
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
EOF
# 应用配置
sudo sysctl -p
验证:
sysctl net.ipv4.tcp_congestion_control
# 输出:net.ipv4.tcp_congestion_control = bbr
24.3 频繁断开
24.3.1 症状分析
断开模式:
- 定时断开(如每5分钟)
- 随机断开
- 特定操作后断开
- 网络切换时断开
影响范围:
- 仅VPN断开,物理网络正常
- 整个网络断开
- 特定客户端断开
24.3.2 日志分析
查看系统日志:
# WireGuard服务日志
sudo journalctl -u wg-quick@wg0 -f
# 内核日志
sudo dmesg -w | grep -i wireguard
# 网络管理日志
sudo journalctl -u NetworkManager -f
关键错误信息:
# NAT超时
"Endpoint destroyed due to timeout"
# 配置错误
"Configuration parsing error"
# 权限问题
"Operation not permitted"
# 接口错误
"Link has gone down"
24.3.3 常见原因
原因1:保活包丢失
诊断:
# 检查保活设置
sudo wg show wg0 persistent-keepalive
# 监控握手
while true; do
date
sudo wg show wg0 | grep "latest handshake"
sleep 10
done
修复:
# 减小保活间隔
[Peer]
PersistentKeepalive = 15 # 从25改为15
原因2:IP地址冲突
诊断:
# 检查IP配置
ip addr show wg0
# 检查路由
ip route | grep wg0
# ping测试
ping -c 1 10.8.0.1
ping -c 1 10.8.0.2
修复:
# 修改为唯一IP
[Interface]
Address = 10.8.0.3/24 # 确保不与其他客户端冲突
原因3:电源管理
症状:
- 笔记本电脑休眠后断开
- 移动设备锁屏后断开
诊断:
# 检查电源管理设置
sudo systemctl status systemd-suspend.service
修复(Linux):
# 创建唤醒脚本
sudo nano /etc/systemd/system/wg-resume.service
内容:
[Unit]
Description=Restart WireGuard after resume
After=suspend.target
[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl restart wg-quick@wg0
[Install]
WantedBy=suspend.target
启用:
sudo systemctl enable wg-resume.service
原因4:防火墙规则问题
诊断:
# 查看被阻止的包
sudo iptables -L -n -v | grep DROP
sudo ufw status verbose
修复:
# 确保允许已建立的连接
sudo iptables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
24.3.4 解决方案
方案1:增强保活机制
客户端脚本:
#!/bin/bash
# wireguard-keepalive.sh
while true; do
# 检查连接
if ! ping -c 1 -W 2 10.8.0.1 > /dev/null 2>&1; then
echo "$(date): 连接断开,尝试重连..."
# 重启接口
sudo wg-quick down wg0
sleep 2
sudo wg-quick up wg0
fi
sleep 30
done
方案2:自动重连脚本
#!/bin/bash
# auto-reconnect-wg.sh
LOG_FILE="/var/log/wireguard-reconnect.log"
check_connection() {
ping -c 3 -W 2 10.8.0.1 > /dev/null 2>&1
return $?
}
reconnect() {
echo "$(date): 检测到连接断开,开始重连..." >> $LOG_FILE
sudo wg-quick down wg0
sleep 5
sudo wg-quick up wg0
sleep 5
if check_connection; then
echo "$(date): 重连成功" >> $LOG_FILE
else
echo "$(date): 重连失败" >> $LOG_FILE
fi
}
# 主循环
while true; do
if ! check_connection; then
reconnect
fi
sleep 60
done
配置systemd服务:
sudo nano /etc/systemd/system/wg-auto-reconnect.service
内容:
[Unit]
Description=WireGuard Auto Reconnect
After[email protected]
Requires[email protected]
[Service]
Type=simple
ExecStart=/usr/local/bin/auto-reconnect-wg.sh
Restart=always
[Install]
WantedBy=multi-user.target
启用:
sudo systemctl enable wg-auto-reconnect
sudo systemctl start wg-auto-reconnect
方案3:网络切换处理
移动设备(NetworkManager脚本):
sudo nano /etc/NetworkManager/dispatcher.d/99-wireguard
内容:
#!/bin/bash
interface=$1
status=$2
if [ "$status" = "up" ]; then
# 网络恢复,重启WireGuard
sleep 5
systemctl restart wg-quick@wg0
fi
权限:
sudo chmod +x /etc/NetworkManager/dispatcher.d/99-wireguard
24.4 握手失败
24.4.1 握手过程
WireGuard握手流程:
1. 客户端发送Initiation消息
└─ 包含:客户端临时公钥、时间戳(加密)
2. 服务器响应Response消息
└─ 包含:服务器临时公钥、确认
3. 双方建立会话密钥
└─ 使用Curve25519密钥交换
4. 开始数据传输
└─ 使用ChaCha20-Poly1305加密
24.4.2 诊断握手问题
检查握手状态:
# 查看最近握手时间
sudo wg show wg0 latest-handshakes
# 实时监控
watch -n 1 'sudo wg show wg0 | grep "latest handshake"'
正常输出:
latest handshake: 23 seconds ago
异常输出:
latest handshake: 5 minutes ago # 太久没握手
latest handshake: (none) # 从未握手成功
抓包分析握手:
# 服务器端抓包
sudo tcpdump -i pnet0 -n udp port 51820 -v
# 观察握手包
# Type 1: Initiation (客户端发起)
# Type 2: Response (服务器响应)
# Type 4: Data (数据传输)
24.4.3 常见原因
原因1:密钥错误
症状:
- 从未成功握手
- 服务器无响应
诊断:
# 验证服务器公钥
echo "<服务器私钥>" | wg pubkey
# 与客户端配置的PublicKey对比
# 验证客户端公钥
echo "<客户端私钥>" | wg pubkey
# 与服务器配置的PublicKey对比
修复:
# 重新生成密钥对
wg genkey | tee private.key | wg pubkey > public.key
# 更新配置文件
sudo nano /etc/wireguard/wg0.conf
原因2:时间不同步
WireGuard对时间敏感,时间差>5分钟会导致握手失败。
诊断:
# 检查系统时间
date
# 检查时区
timedatectl
修复:
# 安装NTP
sudo apt install systemd-timesyncd
# 同步时间
sudo timedatectl set-ntp true
# 手动同步
sudo ntpdate pool.ntp.org
# 验证时间
date
原因3:replay攻击保护
症状:
- 客户端重启后无法连接
- 服务器拒绝旧的握手包
解决:
# 客户端重新生成握手
sudo wg-quick down wg0
sudo wg-quick up wg0
原因4:防火墙拦截握手包
诊断:
# 服务器端抓包
sudo tcpdump -i pnet0 udp port 51820 -c 10
# 查看是否收到Initiation包
如果没有收到包:
# 检查防火墙
sudo iptables -L INPUT -n -v | grep 51820
# 添加规则
sudo iptables -I INPUT -p udp --dport 51820 -j ACCEPT
24.4.4 解决方案
方案1:重置握手
服务器端:
# 删除peer并重新添加
sudo wg set wg0 peer <客户端公钥> remove
sudo wg set wg0 peer <客户端公钥> allowed-ips 10.8.0.2/32
客户端:
# 重启接口
sudo wg-quick down wg0
sudo wg-quick up wg0
方案2:强制握手
客户端发送数据触发握手:
# ping触发握手
ping -c 5 10.8.0.1
# 或发送任意数据
echo "test" | nc -u 10.8.0.1 12345
方案3:调试模式
启用内核调试:
# 启用WireGuard调试日志
echo "module wireguard +p" | sudo tee /sys/kernel/debug/dynamic_debug/control
# 查看调试日志
sudo dmesg -w | grep wireguard
关闭调试:
echo "module wireguard -p" | sudo tee /sys/kernel/debug/dynamic_debug/control
25. 性能故障排查
25.1 延迟过高
25.1.1 基准测试
测量基准延迟:
# 物理网络延迟(不通过VPN)
ping -c 100 192.168.1.66
# VPN隧道延迟
ping -c 100 10.8.0.1
# 通过VPN到互联网
ping -c 100 8.8.8.8
正常延迟范围:
| 场景 | 预期延迟 |
|---|---|
| 局域网VPN | <1ms |
| 同城VPN | 1-10ms |
| 跨省VPN | 10-50ms |
| 跨国VPN | 50-200ms |
VPN增加的开销:通常0.5-2ms
25.1.2 延迟分析
分段测试:
# 1. 客户端到服务器物理IP
ping 192.168.1.66
# 2. 客户端到VPN服务器虚拟IP
ping 10.8.0.1
# 3. 服务器到目标
# 在服务器执行
ping 8.8.8.8
路由跟踪:
# 跟踪VPN路由
traceroute 10.8.0.1
# 跟踪通过VPN的互联网路由
traceroute 8.8.8.8
使用mtr详细分析:
# 实时路由监控
mtr 10.8.0.1
# 报告模式
mtr -r -c 100 8.8.8.8
25.1.3 常见原因
原因1:CPU性能不足
诊断:
# 检查CPU使用率
top
# 查看WireGuard CPU占用
ps aux | grep wireguard
# 检查加密性能
openssl speed chacha20-poly1305
修复:
- 升级CPU
- 关闭不必要的服务
- 使用硬件加速(如AES-NI)
原因2:网络拥塞
诊断:
# 检查网络流量
sudo iftop -i wg0
# 查看队列深度
ip -s link show wg0
修复:
# 增加接口队列长度
sudo ip link set wg0 txqueuelen 10000
# 启用BBR拥塞控制
sudo sysctl -w net.ipv4.tcp_congestion_control=bbr
原因3:MTU分片
诊断:
# 测试不同包大小
ping -s 1400 -M do 10.8.0.1 # 成功
ping -s 1500 -M do 10.8.0.1 # 失败 = MTU过大
修复:
# 降低MTU
[Interface]
MTU = 1420
原因4:DNS解析慢
诊断:
# 测试DNS解析时间
time nslookup www.google.com
time dig www.baidu.com
修复:
# 使用更快的DNS
[Interface]
DNS = 223.5.5.5, 8.8.8.8
或使用本地DNS缓存:
# 安装dnsmasq
sudo apt install dnsmasq
# 配置为本地DNS
DNS = 127.0.0.1
25.1.4 优化方案
方案1:内核参数优化
# 编辑sysctl配置
sudo nano /etc/sysctl.d/99-wireguard-performance.conf
内容:
# 网络缓冲区
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
# TCP优化
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
net.ipv4.tcp_fastopen = 3
# 拥塞控制
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# 其他优化
net.ipv4.tcp_low_latency = 1
net.ipv4.tcp_no_metrics_save = 1
应用:
sudo sysctl -p /etc/sysctl.d/99-wireguard-performance.conf
方案2:CPU亲和性
# 查找WireGuard进程
ps aux | grep wg
# 设置CPU亲和性(绑定到CPU 0)
sudo taskset -cp 0 <PID>
方案3:中断均衡
# 安装irqbalance
sudo apt install irqbalance
# 启动服务
sudo systemctl enable --now irqbalance
25.2 速度慢
25.2.1 速度测试
基准测试:
# 安装iperf3
sudo apt install iperf3
# 服务器端(在VPN服务器上)
iperf3 -s
# 客户端测试
iperf3 -c 10.8.0.1
# 双向测试
iperf3 -c 10.8.0.1 --bidir
# UDP测试
iperf3 -c 10.8.0.1 -u -b 100M
预期速度:
| 网络 | 预期吞吐量 |
|---|---|
| 千兆以太网 | 700-900 Mbps |
| 百兆以太网 | 80-95 Mbps |
| WiFi 5GHz | 200-500 Mbps |
| WiFi 2.4GHz | 50-150 Mbps |
25.2.2 瓶颈分析
检查CPU瓶颈:
# 监控CPU使用
top
# 查看单核负载
mpstat -P ALL 1
# WireGuard CPU占用
ps -p $(pgrep wireguard) -o %cpu,%mem,cmd
如果单核CPU >80%,说明CPU是瓶颈。
检查网络瓶颈:
# 查看网卡速度
ethtool pnet0 | grep Speed
# 查看网络错误
ip -s link show pnet0
# 查看丢包
netstat -s | grep -i drop
检查磁盘I/O:
# I/O监控
sudo iotop
# 磁盘使用
df -h
# 查看I/O wait
vmstat 1
25.2.3 优化方案
方案1:启用多队列
# 检查网卡队列数
ethtool -l pnet0
# 设置多队列
sudo ethtool -L pnet0 combined 4
方案2:关闭offload
某些网卡的offload功能可能与WireGuard冲突:
# 关闭TCP分段卸载
sudo ethtool -K pnet0 tso off gso off
# 或全部关闭
sudo ethtool -K pnet0 rx off tx off sg off tso off gso off gro off lro off
方案3:增大缓冲区
# 接口缓冲区
sudo ip link set wg0 txqueuelen 10000
# 系统缓冲区(sysctl)
net.core.netdev_max_backlog = 5000
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
25.3 丢包严重
25.3.1 丢包检测
基本丢包测试:
# 短期测试
ping -c 1000 10.8.0.1
# 长期测试
ping -c 10000 10.8.0.1 > ping-long.txt
# 分析结果
grep "packet loss" ping-long.txt
丢包分布分析:
# 提取延迟数据
grep "time=" ping-long.txt | awk '{print $7}' | sed 's/time=//' > latency.dat
# 统计分析(需要Python)
python3 << EOF
import statistics
with open('latency.dat') as f:
data = [float(x) for x in f.readlines()]
print(f"平均: {statistics.mean(data):.2f}ms")
print(f"中位数: {statistics.median(data):.2f}ms")
print(f"标准差: {statistics.stdev(data):.2f}ms")
print(f"最小: {min(data):.2f}ms")
print(f"最大: {max(data):.2f}ms")
EOF
25.3.2 丢包原因
原因1:缓冲区溢出
诊断:
# 查看丢包统计
ip -s link show wg0
# 查看网卡丢包
ethtool -S pnet0 | grep drop
修复:
# 增大缓冲区
sudo sysctl -w net.core.netdev_max_backlog=5000
sudo ip link set wg0 txqueuelen 10000
原因2:防火墙限制
诊断:
# 查看防火墙计数器
sudo iptables -L -n -v | grep DROP
# 查看被拒绝的包
sudo ufw status verbose
修复:
# 调整防火墙规则
sudo iptables -D INPUT <规则编号>
原因3:物理链路问题
诊断:
# 查看网卡错误
ip -s -s link show pnet0
# 查看硬件错误
sudo ethtool -S pnet0 | grep -E 'err|drop|fail'
可能的问题:
- 网线质量差
- 网卡驱动问题
- 端口故障
25.3.3 解决方案
方案1:启用FEC(前向纠错)
对于UDP协议,可以在应用层添加FEC:
# 安装UDPspeeder(示例工具)
# 注:这需要额外的第三方工具
方案2:调整重传策略
# TCP快速重传
sudo sysctl -w net.ipv4.tcp_frto=2
sudo sysctl -w net.ipv4.tcp_early_retrans=3
方案3:QoS优化
# 为WireGuard流量设置高优先级
sudo tc qdisc add dev pnet0 root handle 1: htb default 12
sudo tc class add dev pnet0 parent 1: classid 1:1 htb rate 100mbit
sudo tc class add dev pnet0 parent 1:1 classid 1:10 htb rate 80mbit prio 0
sudo tc filter add dev pnet0 protocol ip parent 1:0 prio 1 u32 match ip dport 51820 0xffff flowid 1:10
26. 配置错误排查
26.1 密钥错误
26.1.1 密钥格式验证
有效密钥特征:
- 长度:44个字符(Base64编码)
- 字符集:A-Z, a-z, 0-9, +, /
- 结尾:通常以=或==结束
- 示例:
QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
验证密钥格式:
#!/bin/bash
# validate-wireguard-key.sh
validate_key() {
local key="$1"
# 检查长度
if [ ${#key} -ne 44 ]; then
echo "✗ 密钥长度错误: ${#key} (应为44)"
return 1
fi
# 检查Base64格式
if ! echo "$key" | base64 -d > /dev/null 2>&1; then
echo "✗ 不是有效的Base64编码"
return 1
fi
# 检查解码后长度(应为32字节)
decoded_len=$(echo "$key" | base64 -d | wc -c)
if [ $decoded_len -ne 32 ]; then
echo "✗ 解码后长度错误: $decoded_len (应为32字节)"
return 1
fi
echo "✓ 密钥格式有效"
return 0
}
# 使用示例
validate_key "QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4="
26.1.2 密钥匹配验证
验证公私钥对:
# 从私钥生成公钥
PRIVATE_KEY="eKX7A+ZxHanItaMVdEIwB3ENUZpQhX0VdPCL1CCWCmE="
GENERATED_PUBLIC=$(echo "$PRIVATE_KEY" | wg pubkey)
echo "私钥: $PRIVATE_KEY"
echo "生成的公钥: $GENERATED_PUBLIC"
echo "配置中的公钥: QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4="
# 比较
if [ "$GENERATED_PUBLIC" = "QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=" ]; then
echo "✓ 密钥对匹配"
else
echo "✗ 密钥对不匹配"
fi
验证服务器和客户端密钥配置:
#!/bin/bash
# verify-key-config.sh
echo "=== 验证WireGuard密钥配置 ==="
# 服务器端
echo ""
echo "[服务器端]"
SERVER_PRIVATE=$(sudo grep PrivateKey /etc/wireguard/wg0.conf | awk '{print $3}')
SERVER_PUBLIC_FROM_PRIVATE=$(echo "$SERVER_PRIVATE" | wg pubkey)
SERVER_PUBLIC_RUNTIME=$(sudo wg show wg0 public-key)
echo "配置文件私钥: ${SERVER_PRIVATE:0:10}..."
echo "从私钥生成的公钥: ${SERVER_PUBLIC_FROM_PRIVATE:0:10}..."
echo "运行时公钥: ${SERVER_PUBLIC_RUNTIME:0:10}..."
if [ "$SERVER_PUBLIC_FROM_PRIVATE" = "$SERVER_PUBLIC_RUNTIME" ]; then
echo "✓ 服务器密钥一致"
else
echo "✗ 服务器密钥不一致"
fi
# 客户端(需要从服务器配置中提取)
echo ""
echo "[客户端配置验证]"
CLIENT_PUBLIC=$(sudo grep -A 5 "\[Peer\]" /etc/wireguard/wg0.conf | grep PublicKey | awk '{print $3}')
echo "配置中的客户端公钥: ${CLIENT_PUBLIC:0:10}..."
# 检查是否在运行时peer列表中
if sudo wg show wg0 peers | grep -q "$CLIENT_PUBLIC"; then
echo "✓ 客户端公钥已加载"
else
echo "✗ 客户端公钥未加载"
fi
26.1.3 常见密钥错误
错误1:复制粘贴错误
症状:
Invalid key format
Configuration parsing error
排查:
# 检查隐藏字符
cat -A /etc/wireguard/wg0.conf | grep PrivateKey
# 正常输出(仅末尾有$):
# PrivateKey = eKX7A+ZxHanItaMVdEIwB3ENUZpQhX0VdPCL1CCWCmE=$
# 错误输出(有多余空格或特殊字符):
# PrivateKey = eKX7A+ZxHanItaMVdEIwB3ENUZpQhX0VdPCL1CCWCmE= $
修复:
# 重新生成密钥
wg genkey | sudo tee /etc/wireguard/server_private.key
cat /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
# 更新配置
sudo nano /etc/wireguard/wg0.conf
错误2:密钥文件权限错误
症状:
Permission denied: /etc/wireguard/wg0.conf
Key file has too open permissions
修复:
# 设置正确权限
sudo chmod 600 /etc/wireguard/wg0.conf
sudo chmod 600 /etc/wireguard/*_private.key
sudo chown root:root /etc/wireguard/*
# 验证
ls -la /etc/wireguard/
错误3:使用了错误的密钥
症状:握手永远不成功,无任何错误消息
排查:
# 在服务器端查看peer列表
sudo wg show wg0 peers
# 确认客户端公钥是否在列表中
# 如果不在,说明服务器配置的是错误的公钥
修复:
# 获取客户端正确的公钥(在客户端执行)
cat client_private.key | wg pubkey
# 在服务器端更新
sudo nano /etc/wireguard/wg0.conf
# 更新[Peer]段的PublicKey
# 重新加载
sudo wg syncconf wg0 <(wg-quick strip wg0)
26.1.4 密钥安全检查
检查密钥泄露风险:
#!/bin/bash
# check-key-security.sh
echo "=== WireGuard密钥安全检查 ==="
# 1. 检查权限
echo ""
echo "[1] 检查文件权限"
for file in /etc/wireguard/*.key /etc/wireguard/*.conf; do
if [ -f "$file" ]; then
perms=$(stat -c %a "$file")
owner=$(stat -c %U "$file")
if [ "$perms" != "600" ]; then
echo "✗ $file 权限错误: $perms (应为600)"
else
echo "✓ $file 权限正确"
fi
if [ "$owner" != "root" ]; then
echo "✗ $file 所有者错误: $owner (应为root)"
fi
fi
done
# 2. 检查密钥是否在Git仓库
echo ""
echo "[2] 检查Git仓库"
if [ -d /etc/wireguard/.git ]; then
echo "✗ 警告: /etc/wireguard是Git仓库,可能泄露密钥"
# 检查是否有密钥被跟踪
cd /etc/wireguard
if git ls-files | grep -E '\.key$|\.conf$'; then
echo "✗ 发现密钥文件被Git跟踪"
fi
else
echo "✓ 不是Git仓库"
fi
# 3. 检查备份文件
echo ""
echo "[3] 检查备份文件"
if find /etc/wireguard -name "*.bak" -o -name "*~" | grep -q .; then
echo "✗ 发现备份文件,可能包含密钥"
find /etc/wireguard -name "*.bak" -o -name "*~"
else
echo "✓ 未发现备份文件"
fi
# 4. 检查日志泄露
echo ""
echo "[4] 检查日志文件"
if sudo journalctl -u wg-quick@wg0 | grep -i "private"; then
echo "✗ 警告: 日志中可能包含私钥信息"
else
echo "✓ 日志中未发现私钥"
fi
26.2 IP地址冲突
26.2.1 检测IP冲突
检查配置的IP:
# 服务器端查看所有peer的IP
sudo wg show wg0 allowed-ips
# 检查重复
sudo wg show wg0 allowed-ips | awk '{print $2}' | sort | uniq -d
如果有输出,说明存在IP冲突。
检查运行时IP:
# 查看wg0接口IP
ip addr show wg0
# 查看所有VPN网段IP
ip addr | grep "10.8.0"
# ping测试
for ip in 10.8.0.{1..10}; do
if ping -c 1 -W 1 $ip > /dev/null 2>&1; then
echo "$ip is alive"
fi
done
ARP扫描(检测同网段设备):
# 安装arp-scan
sudo apt install arp-scan
# 扫描VPN网段
sudo arp-scan --interface=wg0 10.8.0.0/24
26.2.2 常见冲突场景
场景1:多个客户端使用相同IP
配置错误示例:
# 服务器配置
[Peer]
PublicKey = Client1_PublicKey
AllowedIPs = 10.8.0.2/32
[Peer]
PublicKey = Client2_PublicKey
AllowedIPs = 10.8.0.2/32 # 错误:与Client1冲突
症状:
- 两个客户端都能连接
- 但网络行为异常
- 数据包可能发送到错误的客户端
修复:
[Peer]
PublicKey = Client2_PublicKey
AllowedIPs = 10.8.0.3/32 # 修改为唯一IP
场景2:VPN网段与物理网段冲突
错误配置:
# VPN使用192.168.1.0/24
[Interface]
Address = 192.168.1.100/24
# 但物理网络也是192.168.1.0/24
症状:
- 无法访问物理网络的192.168.1.x设备
- 路由混乱
修复:
# 使用不同的网段
[Interface]
Address = 10.8.0.1/24
场景3:客户端配置错误的IP
服务器配置:
[Peer]
PublicKey = ClientA_PublicKey
AllowedIPs = 10.8.0.2/32 # 仅允许10.8.0.2
客户端配置:
[Interface]
Address = 10.8.0.5/24 # 错误:使用了10.8.0.5
症状:
- 客户端可以连接
- 但服务器会拒绝来自10.8.0.5的数据包
修复:
[Interface]
Address = 10.8.0.2/24 # 与服务器AllowedIPs匹配
26.2.3 IP分配管理
创建IP分配表:
# 创建管理表
sudo nano /etc/wireguard/ip-allocation.txt
内容:
# WireGuard IP地址分配表
# 日期: 2025-03-23
# 管理员: admin
# 格式: IP地址 | 用户名 | 设备 | 公钥 | 分配日期 | 状态
10.8.0.1 | server | Ubuntu | rUEB9pR7... | 2025-03-01 | 活跃
10.8.0.2 | user1 | Windows | QcDIGh0M... | 2025-03-10 | 活跃
10.8.0.3 | user2 | MacBook | AbC12345... | 2025-03-15 | 活跃
10.8.0.4 | user3 | iPhone | DefGhi78... | 2025-03-20 | 禁用
10.8.0.5 | - | - | - | - | 可用
IP分配脚本:
#!/bin/bash
# allocate-ip.sh
IP_TABLE="/etc/wireguard/ip-allocation.txt"
CONFIG_FILE="/etc/wireguard/wg0.conf"
# 查找下一个可用IP
find_next_ip() {
local used_ips=$(grep -oP '10\.8\.0\.\d+' $IP_TABLE | sort -t. -k4 -n | tail -1)
local last_octet=$(echo $used_ips | cut -d. -f4)
local next_octet=$((last_octet + 1))
if [ $next_octet -gt 254 ]; then
echo "错误: IP地址池已满"
return 1
fi
echo "10.8.0.$next_octet"
}
# 分配IP
allocate_ip() {
local username=$1
local device=$2
local pubkey=$3
local new_ip=$(find_next_ip)
local date=$(date +%Y-%m-%d)
# 添加到分配表
echo "$new_ip | $username | $device | ${pubkey:0:10}... | $date | 活跃" >> $IP_TABLE
# 添加到WireGuard配置
cat >> $CONFIG_FILE << EOF
[Peer]
PublicKey = $pubkey
AllowedIPs = $new_ip/32
EOF
echo "✓ 已分配IP: $new_ip 给 $username ($device)"
echo "客户端配置:"
echo "Address = $new_ip/24"
}
# 使用示例
# allocate_ip "user4" "Android" "XyZ9876543210..."
26.2.4 解决IP冲突
步骤1:识别冲突
# 列出所有分配的IP
sudo wg show wg0 allowed-ips | awk '{print $2}' | sort
# 查找重复
sudo wg show wg0 allowed-ips | awk '{print $2}' | sort | uniq -d
步骤2:确定冲突的peer
# 查看使用冲突IP的peer
CONFLICT_IP="10.8.0.2/32"
sudo wg show wg0 allowed-ips | grep "$CONFLICT_IP"
步骤3:解决冲突
# 方案1:修改配置文件
sudo nano /etc/wireguard/wg0.conf
# 将其中一个peer的AllowedIPs改为可用IP
# AllowedIPs = 10.8.0.5/32
# 重新加载
sudo wg syncconf wg0 <(wg-quick strip wg0)
# 方案2:动态修改
sudo wg set wg0 peer <冲突Peer的公钥> allowed-ips 10.8.0.5/32
步骤4:通知客户端
# 通知受影响的客户端更新配置
# 客户端需要修改Address为新IP
26.3 路由配置错误
26.3.1 检查路由表
查看当前路由:
# 显示所有路由
ip route show
# 仅显示VPN相关路由
ip route show | grep wg0
# 显示特定目标的路由
ip route get 10.8.0.2
ip route get 8.8.8.8
正确的路由配置示例:
服务器端:
10.8.0.0/24 dev wg0 proto kernel scope link src 10.8.0.1
192.168.1.0/24 dev pnet0 proto kernel scope link src 192.168.1.66
default via 192.168.1.1 dev pnet0
客户端(分流模式):
10.8.0.0/24 dev wg0 proto kernel scope link src 10.8.0.2
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100
default via 192.168.1.1 dev eth0
客户端(全流量模式):
0.0.0.0/1 dev wg0 scope link
10.8.0.0/24 dev wg0 proto kernel scope link src 10.8.0.2
128.0.0.0/1 dev wg0 scope link
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100
26.3.2 常见路由错误
错误1:AllowedIPs配置错误
客户端配置:
# 错误:忘记包含VPN网段本身
[Peer]
AllowedIPs = 0.0.0.0/0 # 仅包含互联网,缺少10.8.0.0/24
症状:
- 可以访问互联网
- 无法访问VPN内其他设备
修复:
[Peer]
AllowedIPs = 0.0.0.0/0, 10.8.0.0/24
# 或简化为
AllowedIPs = 0.0.0.0/0
错误2:路由优先级问题
症状:
- 有多条到同一目标的路由
- 选择了错误的路由
诊断:
# 查看到特定目标的路由
ip route get 10.8.0.2
# 查看路由metric
ip route show table main
修复:
# 删除错误的路由
sudo ip route del 10.8.0.0/24 dev eth0
# 或调整metric
sudo ip route add 10.8.0.0/24 dev wg0 metric 100
错误3:缺少默认路由
症状:
- 可以访问VPN
- 无法访问互联网
诊断:
# 检查默认路由
ip route | grep default
修复:
# 添加默认路由
sudo ip route add default via 192.168.1.1 dev pnet0
错误4:路由表污染
症状:路由表中有大量过期或错误的路由
清理:
# 清理wg0相关的所有路由
sudo ip route flush dev wg0
# 重新启动接口
sudo wg-quick down wg0
sudo wg-quick up wg0
26.3.3 路由策略调试
启用路由调试:
# 启用内核路由调试
echo 1 | sudo tee /proc/sys/net/ipv4/conf/all/log_martians
# 查看日志
sudo dmesg -w | grep -i route
使用tcpdump追踪路由:
# 追踪ICMP包的路由
sudo tcpdump -i any -n icmp
# 同时在多个接口抓包
sudo tcpdump -i wg0 -w wg0.pcap &
sudo tcpdump -i pnet0 -w pnet0.pcap &
# 发送测试包
ping -c 5 10.8.0.2
# 停止抓包并分析
sudo killall tcpdump
tcpdump -r wg0.pcap
tcpdump -r pnet0.pcap
策略路由(高级):
# 创建自定义路由表
echo "100 vpn" | sudo tee -a /etc/iproute2/rt_tables
# 添加规则
sudo ip rule add from 10.8.0.0/24 table vpn
sudo ip route add default via 10.8.0.1 dev wg0 table vpn
# 查看规则
ip rule show
# 查看路由表
ip route show table vpn
26.4 防火墙拦截
26.4.1 诊断防火墙问题
检查是否被防火墙阻止:
# 查看被拒绝的包
sudo iptables -L -n -v | grep DROP
sudo iptables -L -n -v | grep REJECT
# 查看防火墙日志
sudo journalctl -k | grep -i "UFW BLOCK"
sudo tail -f /var/log/kern.log | grep UFW
# 使用ufw
sudo ufw status verbose
临时禁用防火墙测试:
# 临时关闭ufw
sudo ufw disable
# 测试连接
ping 10.8.0.1
# 重新启用
sudo ufw enable
⚠️ 警告:禁用防火墙会暴露安全风险,仅用于诊断!
抓包分析:
# 在服务器端抓包
sudo tcpdump -i pnet0 udp port 51820 -vv
# 观察是否收到客户端的包
# 如果收到但没有响应,可能是防火墙问题
26.4.2 常见防火墙问题
问题1:INPUT链阻止WireGuard端口
诊断:
sudo iptables -L INPUT -n -v --line-numbers | grep 51820
如果没有ACCEPT规则或有DROP规则在ACCEPT之前:
# 添加允许规则
sudo iptables -I INPUT 1 -p udp --dport 51820 -j ACCEPT
# 或使用ufw
sudo ufw allow 51820/udp
问题2:FORWARD链阻止转发
诊断:
sudo iptables -L FORWARD -n -v --line-numbers
修复:
# 允许wg0转发
sudo iptables -I FORWARD 1 -i wg0 -j ACCEPT
sudo iptables -I FORWARD 1 -o wg0 -j ACCEPT
问题3:NAT表规则缺失
诊断:
sudo iptables -t nat -L POSTROUTING -n -v
如果没有MASQUERADE或SNAT规则:
sudo iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
问题4:连接跟踪问题
症状:
- 新连接可以建立
- 已建立的连接突然中断
诊断:
# 查看连接跟踪表
sudo cat /proc/net/nf_conntrack | grep wireguard
# 查看连接跟踪统计
sudo sysctl net.netfilter.nf_conntrack_count
sudo sysctl net.netfilter.nf_conntrack_max
修复:
# 增大连接跟踪表
sudo sysctl -w net.netfilter.nf_conntrack_max=131072
# 永久配置
echo "net.netfilter.nf_conntrack_max = 131072" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
26.4.3 防火墙规则验证
验证脚本:
#!/bin/bash
# verify-firewall-rules.sh
echo "=== 防火墙规则验证 ==="
# 1. 检查INPUT链
echo ""
echo "[1] INPUT链 - WireGuard端口"
if sudo iptables -L INPUT -n | grep -q "udp dpt:51820.*ACCEPT"; then
echo "✓ 51820/udp 已允许"
else
echo "✗ 51820/udp 未允许"
fi
# 2. 检查FORWARD链
echo ""
echo "[2] FORWARD链 - VPN转发"
if sudo iptables -L FORWARD -n | grep -q "wg0.*ACCEPT"; then
echo "✓ wg0转发已允许"
else
echo "✗ wg0转发未允许"
fi
# 3. 检查NAT
echo ""
echo "[3] NAT表 - MASQUERADE"
if sudo iptables -t nat -L POSTROUTING -n | grep -q "MASQUERADE"; then
echo "✓ NAT规则存在"
else
echo "✗ NAT规则缺失"
fi
# 4. 检查IP转发
echo ""
echo "[4] IP转发"
if [ "$(sysctl -n net.ipv4.ip_forward)" = "1" ]; then
echo "✓ IP转发已启用"
else
echo "✗ IP转发未启用"
fi
# 5. 检查默认策略
echo ""
echo "[5] 默认策略"
sudo iptables -L | grep "Chain.*policy" | while read line; do
echo " $line"
done
echo ""
echo "=== 验证完成 ==="
26.4.4 安全的防火墙配置
推荐配置脚本:
#!/bin/bash
# setup-secure-firewall.sh
echo "配置WireGuard防火墙规则..."
# 1. 设置默认策略
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
# 2. 允许已建立的连接
sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
# 3. 允许本地回环
sudo iptables -A INPUT -i lo -j ACCEPT
# 4. 允许SSH(修改为你的SSH端口)
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 5. 允许WireGuard
sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT
# 6. 允许VPN转发
sudo iptables -A FORWARD -i wg0 -j ACCEPT
sudo iptables -A FORWARD -o wg0 -j ACCEPT
# 7. 配置NAT
sudo iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
# 8. 保存规则
sudo netfilter-persistent save
echo "✓ 防火墙配置完成"
27. 服务故障排查
27.1 服务无法启动
27.1.1 检查服务状态
查看详细错误:
# 查看服务状态
sudo systemctl status wg-quick@wg0
# 查看失败原因
sudo systemctl status wg-quick@wg0 -l
# 查看完整日志
sudo journalctl -u wg-quick@wg0 -n 50 --no-pager
27.1.2 常见启动错误
错误1:配置文件语法错误
错误信息:
Configuration parsing error: /etc/wireguard/wg0.conf
诊断:
# 检查配置语法
sudo wg-quick strip wg0
# 查看具体错误
sudo wg setconf wg0 /etc/wireguard/wg0.conf
常见语法错误:
# 错误:参数名拼写错误
[Interface]
PrivateKye = xxx # 应为PrivateKey
# 错误:缺少等号
[Interface]
PrivateKey xxx # 应为PrivateKey = xxx
# 错误:IP格式错误
Address = 10.8.0.1 # 应为10.8.0.1/24
# 错误:多余的空格或特殊字符
PrivateKey = xxx # 末尾有空格
修复:
# 备份配置
sudo cp /etc/wireguard/wg0.conf /etc/wireguard/wg0.conf.bak
# 重新编辑
sudo nano /etc/wireguard/wg0.conf
# 验证
sudo wg-quick strip wg0
错误2:接口已存在
错误信息:
RTNETLINK answers: File exists
诊断:
# 检查接口是否已存在
ip link show wg0
# 查看WireGuard进程
ps aux | grep wireguard
修复:
# 删除现有接口
sudo ip link delete wg0
# 或强制停止
sudo wg-quick down wg0
# 重新启动
sudo wg-quick up wg0
错误3:权限不足
错误信息:
Operation not permitted
Permission denied
诊断:
# 检查当前用户
whoami
# 检查文件权限
ls -l /etc/wireguard/wg0.conf
# 检查capabilities
sudo getcap /usr/bin/wg
sudo getcap /usr/bin/wg-quick
修复:
# 使用sudo
sudo systemctl start wg-quick@wg0
# 或以root登录
sudo su -
systemctl start wg-quick@wg0
错误4:端口已占用
错误信息:
Address already in use
诊断:
# 检查端口占用
sudo lsof -i :51820
sudo ss -ulnp | grep :51820
修复:
# 杀死占用进程
sudo fuser -k 51820/udp
# 或修改配置使用其他端口
sudo nano /etc/wireguard/wg0.conf
# ListenPort = 41194
# 重新启动
sudo wg-quick up wg0
错误5:依赖服务未启动
错误信息:
Failed to start [email protected]: Unit network.target not found
诊断:
# 检查网络服务
sudo systemctl status network.target
sudo systemctl status NetworkManager
修复:
# 启动网络服务
sudo systemctl start NetworkManager
# 设置依赖
sudo systemctl edit wg-quick@wg0
添加:
[Unit]
After=network-online.target
Wants=network-online.target
27.1.3 启动流程调试
手动启动调试:
# 逐步执行启动命令
echo "1. 创建接口"
sudo ip link add wg0 type wireguard
echo "2. 配置WireGuard"
sudo wg setconf wg0 /etc/wireguard/wg0.conf
echo "3. 配置IP地址"
sudo ip addr add 10.8.0.1/24 dev wg0
echo "4. 启用接口"
sudo ip link set wg0 up
echo "5. 执行PostUp脚本"
# (手动执行PostUp命令)
echo "6. 验证"
sudo wg show wg0
27.2 端口被占用
27.2.1 识别占用进程
检查方法:
# 方法1:lsof
sudo lsof -i :51820
# 方法2:netstat
sudo netstat -tulnp | grep :51820
# 方法3:ss
sudo ss -ulnp | grep :51820
# 方法4:fuser
sudo fuser 51820/udp
详细信息:
# 获取进程详情
PID=$(sudo lsof -t -i :51820)
ps -p $PID -o pid,ppid,cmd,%mem,%cpu
# 查看进程树
pstree -p $PID
27.2.2 处理占用
方案1:停止占用进程
# 优雅停止
sudo kill $(sudo lsof -t -i :51820)
# 强制停止
sudo kill -9 $(sudo lsof -t -i :51820)
# 使用fuser
sudo fuser -k 51820/udp
方案2:修改WireGuard端口
# 编辑配置
sudo nano /etc/wireguard/wg0.conf
# 修改端口
[Interface]
ListenPort = 41194 # 使用其他端口
# 重启WireGuard
sudo systemctl restart wg-quick@wg0
# 更新防火墙
sudo ufw delete allow 51820/udp
sudo ufw allow 41194/udp
⚠️ 注意:修改端口后,所有客户端的Endpoint也需要更新!
方案3:端口冲突预防
# 启动前检查脚本
#!/bin/bash
# pre-start-check.sh
PORT=51820
if sudo lsof -i :$PORT > /dev/null 2>&1; then
echo "错误: 端口$PORT已被占用"
echo "占用详情:"
sudo lsof -i :$PORT
exit 1
else
echo "端口$PORT可用"
sudo systemctl start wg-quick@wg0
fi
27.3 权限不足
27.3.1 权限问题诊断
检查用户权限:
# 当前用户
whoami
id
# sudo权限
sudo -l
# 组成员
groups
检查文件权限:
# WireGuard配置目录
ls -la /etc/wireguard/
# 关键文件
ls -l /etc/wireguard/wg0.conf
ls -l /etc/wireguard/*.key
27.3.2 常见权限错误
错误1:配置文件权限过于开放
错误信息:
Warning: config file is world accessible
Configuration file permissions are too open
修复:
# 设置正确权限
sudo chmod 600 /etc/wireguard/wg0.conf
sudo chmod 600 /etc/wireguard/*.key
# 验证
ls -l /etc/wireguard/
错误2:无sudo权限
错误信息:
user is not in the sudoers file
修复:
# 方法1:添加到sudo组(需要root)
su -
usermod -aG sudo username
# 方法2:编辑sudoers
visudo
# 添加行
username ALL=(ALL:ALL) ALL
错误3:SELinux/AppArmor阻止
诊断:
# 检查SELinux状态(CentOS/RHEL)
getenforce
# 检查AppArmor状态(Ubuntu)
sudo aa-status
# 查看拒绝日志
sudo ausearch -m avc -ts recent # SELinux
sudo dmesg | grep -i apparmor # AppArmor
修复(临时):
# SELinux
sudo setenforce 0
# AppArmor
sudo systemctl stop apparmor
修复(永久):
# 创建SELinux策略
# 或
# 创建AppArmor profile
27.4 配置文件语法错误
27.4.1 语法验证工具
使用wg-quick strip:
# 验证语法
sudo wg-quick strip wg0
# 如果有错误,会显示具体行号
使用wg setconf:
# 尝试加载配置
sudo wg setconf wg0 /etc/wireguard/wg0.conf
27.4.2 常见语法错误
错误列表:
# 1. 拼写错误
[Interface]
PrivateKye = xxx # 应为PrivateKey
# 2. 缺少等号
ListenPort 51820 # 应为ListenPort = 51820
# 3. 重复的键
[Interface]
Address = 10.8.0.1/24
Address = 10.8.0.2/24 # 错误:重复
# 4. 无效的IP格式
Address = 10.8.0.1 # 缺少掩码,应为10.8.0.1/24
# 5. 无效的Base64
PrivateKey = invalid-key-format
# 6. 段名拼写错误
[Interfce] # 应为[Interface]
# 7. 多余的空格或制表符
PrivateKey = xxx # 末尾有空格
# 8. 使用了注释符号后的内容
PrivateKey = xxx # comment # 可能导致问题
# 9. 缺少必需字段
[Interface]
# 缺少PrivateKey
# 10. 顺序错误
[Peer]
[Interface] # Interface应该在前面
27.4.3 配置验证脚本
#!/bin/bash
# validate-wg-config.sh
CONFIG_FILE="/etc/wireguard/wg0.conf"
echo "=== WireGuard配置验证 ==="
# 1. 检查文件是否存在
if [ ! -f "$CONFIG_FILE" ]; then
echo "✗ 配置文件不存在: $CONFIG_FILE"
exit 1
fi
echo "✓ 配置文件存在"
# 2. 检查文件权限
perms=$(stat -c %a "$CONFIG_FILE")
if [ "$perms" != "600" ]; then
echo "⚠ 警告: 权限为$perms,建议600"
else
echo "✓ 文件权限正确"
fi
# 3. 检查必需字段
echo ""
echo "检查必需字段:"
if grep -q "^\[Interface\]" "$CONFIG_FILE"; then
echo "✓ [Interface]段存在"
else
echo "✗ 缺少[Interface]段"
fi
if grep -q "^PrivateKey" "$CONFIG_FILE"; then
echo "✓ PrivateKey存在"
else
echo "✗ 缺少PrivateKey"
fi
if grep -q "^Address" "$CONFIG_FILE"; then
echo "✓ Address存在"
else
echo "✗ 缺少Address"
fi
# 4. 验证密钥格式
echo ""
echo "验证密钥格式:"
private_key=$(grep "^PrivateKey" "$CONFIG_FILE" | awk '{print $3}')
if [ ${#private_key} -eq 44 ]; then
echo "✓ PrivateKey长度正确"
else
echo "✗ PrivateKey长度错误: ${#private_key} (应为44)"
fi
# 5. 检查IP格式
echo ""
echo "验证IP格式:"
address=$(grep "^Address" "$CONFIG_FILE" | awk '{print $3}')
if [[ $address =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+$ ]]; then
echo "✓ Address格式正确: $address"
else
echo "✗ Address格式错误: $address"
fi
# 6. 尝试strip
echo ""
echo "语法检查:"
if sudo wg-quick strip wg0 > /dev/null 2>&1; then
echo "✓ 配置语法正确"
else
echo "✗ 配置语法错误"
echo "详细错误:"
sudo wg-quick strip wg0
fi
echo ""
echo "=== 验证完成 ==="
28. 日志分析方法
28.1 系统日志位置
28.1.1 主要日志文件
systemd日志:
# WireGuard服务日志
sudo journalctl -u wg-quick@wg0
# 内核日志
sudo journalctl -k
# 系统日志
sudo journalctl
传统日志文件:
/var/log/syslog # 系统日志(Debian/Ubuntu)
/var/log/messages # 系统日志(CentOS/RHEL)
/var/log/kern.log # 内核日志
/var/log/auth.log # 认证日志
/var/log/ufw.log # UFW防火墙日志
WireGuard特定日志:
# 内核消息(WireGuard在内核空间)
sudo dmesg | grep -i wireguard
# syslog中的WireGuard消息
sudo grep -i wireguard /var/log/syslog
# journalctl过滤
sudo journalctl | grep -i wireguard
28.1.2 日志级别
syslog级别:
0 - emerg 系统不可用
1 - alert 必须立即采取行动
2 - crit 严重情况
3 - err 错误情况
4 - warning 警告情况
5 - notice 正常但重要的情况
6 - info 信息性消息
7 - debug 调试级别消息
过滤特定级别:
# 仅错误
sudo journalctl -u wg-quick@wg0 -p err
# 警告及以上
sudo journalctl -u wg-quick@wg0 -p warning
# 所有级别
sudo journalctl -u wg-quick@wg0 -p debug
28.2 日志查看命令
28.2.1 journalctl使用
基本用法:
# 查看WireGuard服务日志
sudo journalctl -u wg-quick@wg0
# 实时跟踪
sudo journalctl -u wg-quick@wg0 -f
# 查看最近N条
sudo journalctl -u wg-quick@wg0 -n 100
# 倒序查看(最新的在前)
sudo journalctl -u wg-quick@wg0 -r
时间过滤:
# 今天的日志
sudo journalctl -u wg-quick@wg0 --since today
# 最近1小时
sudo journalctl -u wg-quick@wg0 --since "1 hour ago"
# 指定时间范围
sudo journalctl -u wg-quick@wg0 --since "2025-03-23 10:00" --until "2025-03-23 12:00"
# 昨天的日志
sudo journalctl -u wg-quick@wg0 --since yesterday --until today
输出格式:
# 简短格式
sudo journalctl -u wg-quick@wg0 -o short
# 详细格式
sudo journalctl -u wg-quick@wg0 -o verbose
# JSON格式
sudo journalctl -u wg-quick@wg0 -o json
# 仅消息内容
sudo journalctl -u wg-quick@wg0 -o cat
28.2.2 dmesg使用
基本用法:
# 查看所有内核消息
dmesg
# 过滤WireGuard
sudo dmesg | grep -i wireguard
# 实时监控
sudo dmesg -w
# 带时间戳
sudo dmesg -T
# 彩色输出
sudo dmesg --color=always
级别过滤:
# 仅错误和警告
sudo dmesg -l err,warn
# 仅错误
sudo dmesg -l err
28.2.3 传统日志文件
实时监控:
# tail实时跟踪
sudo tail -f /var/log/syslog
# 过滤WireGuard
sudo tail -f /var/log/syslog | grep -i wireguard
# 多文件监控
sudo tail -f /var/log/syslog /var/log/kern.log
搜索和过滤:
# 搜索错误
sudo grep -i error /var/log/syslog | grep -i wireguard
# 统计错误数量
sudo grep -i error /var/log/syslog | grep -i wireguard | wc -l
# 查看上下文
sudo grep -B 5 -A 5 "error" /var/log/syslog | grep -i wireguard
28.3 常见错误信息
28.3.1 配置错误
错误1:密钥格式错误
Failed to parse private key
Invalid key format
原因:密钥不是有效的Base64或长度错误
解决:
# 重新生成密钥
wg genkey | tee private.key | wg pubkey > public.key
错误2:配置解析错误
Configuration parsing error
Unable to parse config
原因:配置文件语法错误
解决:
sudo wg-quick strip wg0 # 查看具体错误
28.3.2 网络错误
错误1:地址冲突
RTNETLINK answers: File exists
Address already in use
原因:IP地址或接口已存在
解决:
sudo ip link delete wg0
sudo ip addr del 10.8.0.1/24 dev wg0
错误2:路由错误
RTNETLINK answers: Network is unreachable
原因:路由配置错误或网络不可达
解决:
ip route show
sudo ip route add default via 192.168.1.1
28.3.3 权限错误
错误:操作不允许
Operation not permitted
Permission denied
原因:权限不足
解决:
# 使用sudo
sudo wg-quick up wg0
# 或以root运行
sudo su -
28.4 日志分析脚本
28.4.1 错误统计
#!/bin/bash
# analyze-wg-logs.sh
echo "=== WireGuard日志分析 ==="
# 1. 统计错误数量
echo ""
echo "[1] 错误统计"
error_count=$(sudo journalctl -u wg-quick@wg0 -p err --since today | wc -l)
warning_count=$(sudo journalctl -u wg-quick@wg0 -p warning --since today | wc -l)
echo "今天的错误: $error_count"
echo "今天的警告: $warning_count"
# 2. 最近的错误
echo ""
echo "[2] 最近5个错误"
sudo journalctl -u wg-quick@wg0 -p err -n 5 --no-pager
# 3. 错误类型分类
echo ""
echo "[3] 错误类型分布"
sudo journalctl -u wg-quick@wg0 -p err --since today -o cat | \
sort | uniq -c | sort -rn
# 4. 启动/停止次数
echo ""
echo "[4] 服务重启统计"
start_count=$(sudo journalctl -u wg-quick@wg0 --since today | grep -c "Starting")
stop_count=$(sudo journalctl -u wg-quick@wg0 --since today | grep -c "Stopping")
echo "启动次数: $start_count"
echo "停止次数: $stop_count"
# 5. 生成报告
echo ""
echo "[5] 生成详细报告"
report_file="/tmp/wireguard-report-$(date +%Y%m%d).txt"
cat > $report_file << EOF
WireGuard日志报告
生成时间: $(date)
================
错误统计:
- 错误: $error_count
- 警告: $warning_count
服务状态:
- 启动次数: $start_count
- 停止次数: $stop_count
最近错误:
$(sudo journalctl -u wg-quick@wg0 -p err -n 10 --no-pager)
服务状态:
$(sudo systemctl status wg-quick@wg0)
当前配置:
$(sudo wg show wg0)
EOF
echo "报告已生成: $report_file"
28.4.2 性能分析
#!/bin/bash
# performance-analysis.sh
echo "=== WireGuard性能分析 ==="
# 1. 握手频率
echo ""
echo "[1] 握手频率分析"
sudo journalctl -u wg-quick@wg0 --since "1 hour ago" | \
grep -i handshake | wc -l
echo "最近1小时握手次数: $(上面的结果)"
# 2. 连接稳定性
echo ""
echo "[2] 连接中断统计"
disconnect_count=$(sudo journalctl -u wg-quick@wg0 --since today | \
grep -ci "disconnect\|down\|fail")
echo "今天的连接中断: $disconnect_count"
# 3. 流量统计
echo ""
echo "[3] 流量统计"
sudo wg show wg0 transfer
# 4. CPU使用
echo ""
echo "[4] CPU使用率"
ps aux | grep -E "wireguard|wg" | grep -v grep