第八部分:故障排查

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不通:

步骤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

客户端检查:

步骤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:逐步添加功能

  1. 先建立基本连接
  2. 测试ping通信
  3. 添加NAT规则
  4. 测试访问互联网
  5. 添加DNS配置
  6. 添加其他高级功能

24.2 连接不稳定

24.2.1 症状识别

症状1:频繁断连

症状2:间歇性丢包

症状3:延迟波动大

24.2.2 诊断方法

检查握手频率:

# 持续监控握手时间
watch -n 1 'sudo wg show wg0 | grep "latest handshake"'

正常情况:

异常情况:

测试连接稳定性:

# 持续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不匹配

症状:

排查:

# 测试不同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

修复方案:

原因4:服务器性能问题

症状:

排查:

# 检查系统负载
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 症状分析

断开模式:

影响范围:

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
同城VPN1-10ms
跨省VPN10-50ms
跨国VPN50-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

修复:

原因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 5GHz200-500 Mbps
WiFi 2.4GHz50-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 密钥格式验证

有效密钥特征:

验证密钥格式:

#!/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

症状:

修复:

# 使用不同的网段
[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

症状:

修复:

[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

症状:

修复:

[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:缺少默认路由

症状:

诊断:

# 检查默认路由
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

XBR

© 2026 XBR

bilibili bluesky discord