真实场景:我被OpenVPN折磨了三天
上个月,公司要给三个机房搭内网互通。我按老习惯用OpenVPN,结果被证书体系折腾够呛。CA签发、服务端证书、客户端证书、CRL吊销列表,每个环节都可能出错。最崩溃的是,一个客户端配置写错,排查到凌晨两点,最后发现只是少了个remote-cert-tls参数。
后来CTO说:试试WireGuard。我花了一个下午读完官方文档和几个issue,晚上就把三机房连通了。延迟比OpenVPN低40%,吞吐量翻倍,配置量只有OpenVPN的五分之一。
这篇文章不是WireGuard官方文档的翻译。是我从零搭建、踩坑、调优的完整记录。你照着做,不用像我一样浪费那三天。
为什么选WireGuard:三种方案横向对比
先说结论:不是所有场景都适合WireGuard。做方案对比,是为了让你别选错。
| 维度 | WireGuard 1.0.20210914 | OpenVPN 2.6.6 | IPsec StrongSwan 5.9.13 |
|---|---|---|---|
| 代码量 | 约4000行 | 约10万行 | 约15万行 |
| 首次握手耗时 | 0.1s~0.3s | 1s~3s(需TLS握手+证书校验) | 2s~5s(IKE_SA+CHILD_SA协商) |
| 加密套件 | 仅ChaCha20-Poly1305,无协商 | TLS 1.2/1.3,多种可选 | ESP/AH,算法可配 |
| 配置复杂度 | 1个配置文件/端 | CA+证书+server.conf+client.ovpn | ipsec.conf+ipsec.secrets+证书 |
| Linux内核集成 | 5.6+内置模块 | 用户态TUN设备 | 内核态xfrm |
| 移动端支持 | iOS/Android官方App | 需要第三方客户端 | 需要额外配置 |
| NAT穿透 | 客户端 roaming 自动重连 | 需keepalive+端口固定 | 需NAT-T+端口固定 |
| UDP 4500bps小包吞吐 | 812 Mbps | 156 Mbps | 238 Mbps |
| CPU占用(iperf3 1Gbps) | 单核28% | 单核67% | 单核81% |
测试环境:两台 Ubuntu 22.04.3 LTS 云服务器,同一可用区,内核 6.2.0-26-generic,CPU 2核 Intel Xeon Platinum 8374C,万兆内网。WireGuard 走 UDP 51820 端口,MTU 1420。
我的选择逻辑:内网互通、客户端漫游、弱网环境,这三个需求OpenVPN和IPsec也能做,但WireGuard用最少配置达到最好效果,尤其是在高丢包链路(10%丢包)下,WireGuard的TCP吞吐比OpenVPN高3.2倍。原因是WireGuard在用户态处理包太少,内核态直接转发。
完整搭建过程:三机房组网
网络拓扑
北京机房 (wg0: 10.0.0.1/24)
上海机房 (wg0: 10.0.0.2/24)
广州机房 (wg0: 10.0.0.3/24)
每个机房内网分别是 192.168.1.0/24、192.168.2.0/24、192.168.3.0/24
目标:三机房内网互通,并能通过VPN访问各机房的内部服务
三台服务器都有一个公网IP,不需要NAT穿透,但我会在客户端配置里加上PersistentKeepalive,确保后续加新机房时不需要改配置。
1. 安装 WireGuard
Ubuntu 22.04 内核 5.15+ 自带 wireguard 内核模块,只需要装工具链。这里有个坑:不要用 apt install wireguard 默认源,Ubuntu 22.04 官方源里的 wireguard-tools 版本是 1.0.20210914,但内核模块可能不是最新的。建议先确认内核模块。
# 在三台服务器上分别执行
sudo apt update
sudo apt install -y wireguard wireguard-tools
# 确认内核模块已加载
sudo modprobe wireguard
lsmod | grep wireguard
# wireguard 28672 0
# 确认版本
wg --version
# wireguard-tools v1.0.20210914 - https://git.zx2c4.com/wireguard-tools/
# 确认内核支持(5.6+内置)
uname -r
# 6.2.0-26-generic
如果你用的是 CentOS 9 Stream 或 Rocky Linux 9,需要额外启用 EPEL 源:dnf install epel-release,然后 dnf install wireguard-tools。内核模块在 el9 的内核中默认编译为模块,不需要额外安装。
2. 生成密钥对
WireGuard 使用 Curve25519 密钥对,一个私钥一个公钥。每台机器都需要独立的密钥对。
# 在三台服务器上分别执行(生成各自独立的密钥)
cd /etc/wireguard
umask 077
# 生成私钥
wg genkey | tee privatekey
# 从私钥推导公钥
wg pubkey < privatekey | tee publickey
# 输出结果(示例,实际每次生成都不同)
echo "--- 北京机房 ---"
cat privatekey
# 8CzF0yHzk3Kk8dR+oQvJqJQ1zXV6ZzM0xKUbPbqB1UY=
cat publickey
# +T4YxOQYzCkQeCcWjQ6BCFjO/YT7CkzN8yPzQn2J0Ew=
echo "--- 上海机房 ---" # 在上海机器上执行
echo "--- 广州机房 ---" # 在广州机器上执行
三台机器我都生成了,把公钥记录下来:
| 节点 | 私钥(示例) | 公钥(示例) |
|---|---|---|
| 北京 | 2Nk...(保密) | t5Zx...(公开) |
| 上海 | 8Yb...(保密) | wQpR...(公开) |
| 广州 | HfK...(保密) | v3mN...(公开) |
注意权限:umask 077 确保私钥文件只有root可读。WireGuard 对私钥文件权限要求严格,如果权限太宽松,wg-quick up 会直接报错。
3. 服务端配置(北京机房)
北京作为中心节点,但WireGuard是P2P的,没有真正的客户端/服务端之分。我习惯把第一个配置的当成主节点。
sudo vim /etc/wireguard/wg0.conf
# /etc/wireguard/wg0.conf - 北京机房
[Interface]
# 北京机房的私钥
PrivateKey = 2Nk...(北京私钥)
# WireGuard 隧道 IP
Address = 10.0.0.1/24
# 监听端口(UDP)
ListenPort = 51820
# 默认允许所有流量走隧道。如果要分流,改成 0.0.0.0/0 但配合路由表。
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
[Peer]
# 上海机房的公钥
PublicKey = wQpR...(上海公钥)
# 上海机房能访问的隧道IP段(上海分配了 10.0.0.2,同时允许访问北京内网)
AllowedIPs = 10.0.0.2/32, 192.168.1.0/24
# 广州机房 peer
[Peer]
PublicKey = v3mN...(广州公钥)
AllowedIPs = 10.0.0.3/32, 192.168.1.0/24
PostUp 里的 eth0 要改成你的实际网卡名。用 ip route 查看默认路由对应的网卡。北京这台机器网卡是 eth0,如果你的是 ens3 或 eno1,记得替换。
AllowedIPs 是 WireGuard 的访问控制列表。我允许上海和广州访问北京内网 192.168.1.0/24。这是通过路由实现的:WireGuard 会自动添加路由到路由表。
这里有个关键点:AllowedIPs 不止控制访问,还告诉本机怎么路由流量。如果写 0.0.0.0/0,就是全量VPN,所有流量走隧道。我们这里是点对点组网,所以写具体网段。
4. 客户端配置(上海机房)
sudo vim /etc/wireguard/wg0.conf
# /etc/wireguard/wg0.conf - 上海机房
[Interface]
PrivateKey = 8Yb...(上海私钥)
Address = 10.0.0.2/24
ListenPort = 51820
# 上海有公网IP,同样开启转发
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 = t5Zx...(北京公钥)
# 上海需要访问北京内网 + 广州内网
# 路由:去 10.0.0.0/24 的走隧道,去 192.168.0.0/16 的走隧道
AllowedIPs = 10.0.0.0/24, 192.168.1.0/24, 192.168.3.0/24
# 指定北京的公网IP和端口
Endpoint = 北京公网IP:51820
# 每25秒发一次心跳,保持NAT映射
PersistentKeepalive = 25
注意:上海访问广州内网,数据包会先发给北京,再由北京转发给广州。这就是中心节点组网。WireGuard 支持 mesh,但需要每个节点都配置与其他节点的 peer。
这里 AllowedIPs 里的 192.168.3.0/24 不是直接路由到北京,而是告诉本机去往这些目标地址的包走 wg0 隧道。至于隧道内的下一跳怎么走,由 WireGuard 内部的路由决定。
5. 广州机房配置
# /etc/wireguard/wg0.conf - 广州机房
[Interface]
PrivateKey = HfK...(广州私钥)
Address = 10.0.0.3/24
ListenPort = 51820
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 = t5Zx...(北京公钥)
AllowedIPs = 10.0.0.0/24, 192.168.1.0/24, 192.168.2.0/24
Endpoint = 北京公网IP:51820
PersistentKeepalive = 25
6. 启动并验证
# 三台机器分别执行
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0
# 查看状态(在任意一台执行)
sudo wg show
# 输出类似:
# interface: wg0
# public key: t5Zx...(北京公钥)
# private key: (hidden)
# listening port: 51820
# peer: wQpR...(上海公钥)
# endpoint: 上海公网IP:51820
# allowed ips: 10.0.0.2/32, 192.168.1.0/24
# latest handshake: 1 minute ago
# transfer: 1.2 MiB received, 3.4 MiB sent
# peer: v3mN...(广州公钥)
# endpoint: 广州公网IP:51820
# allowed ips: 10.0.0.3/32, 192.168.1.0/24
# latest handshake: 1 minute ago
# transfer: 0.8 MiB received, 2.1 MiB sent
latest handshake 表示最近一次握手时间。如果显示 - 或超过2分钟,说明握手失败,检查防火墙和 Endpoint 配置。
然后从北京 ping 上海的隧道 IP:
# 北京执行
ping -c 3 10.0.0.2
# 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=8.42 ms
# 64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=8.31 ms
# 64 bytes from 10.0.0.2: icmp_seq=3 ttyl=64 time=8.28 ms
# 验证跨机房内网访问(北京 ping 广州的内网机器)
ping -c 3 192.168.3.15
# 64 bytes from 192.168.3.15: icmp_seq=1 ttl=62 time=18.4 ms
ttl=62 说明经过了两次路由跳转(北京-广州隧道+广州内网路由),符合预期。
7. 路由转发与防火墙配置
如果内网其他机器也想通过 VPN 访问远端内网,需要做 NAT 或添加静态路由。我的方案是在服务器上做 MASQUERADE,这样内网机器不需要额外配置。
# 持久化 iptables 规则(Ubuntu 22.04)
sudo apt install -y iptables-persistent
sudo netfilter-persistent save
# 或者用 ufw 放行 WireGuard 端口
sudo ufw allow 51820/udp
sudo ufw allow from 10.0.0.0/24
# 确认 IP 转发已开启
sudo sysctl net.ipv4.ip_forward
# net.ipv4.ip_forward = 1
# 如果不是 1,执行:
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
wg-quick 脚本会自动设置 net.ipv4.ip_forward,但只对当前会话有效。持久化配置要写进 sysctl.conf。
还有一个细节:如果服务器用 UFW 防火墙,需要放行 FORWARD 链。wg-quick 的 PostUp 已经加了 ACCEPT 规则,但 UFW 默认策略可能比较激进。我建议用 iptables-persistent 管理,避免 UFW 和 iptables 规则冲突。
Production级配置:性能调优
基础配置能通,但距离生产可用还差几个关键优化。下面是压测数据和对应调优参数。
性能对比:WireGuard vs OpenVPN 实测
测试工具:iperf3 3.12,TCP 窗口默认,测试时长60秒。分别在直连、WireGuard、OpenVPN三种模式下的表现:
| 测试项 | 直连(基准) | WireGuard | OpenVPN |
|---|---|---|---|
| TCP 吞吐(iperf3 单线程) | 9.41 Gbps | 2.12 Gbps | 1.06 Gbps |
| TCP 吞吐(iperf3 8线程) | 9.87 Gbps | 2.38 Gbps | 1.12 Gbps |
| UDP 小包(64字节) | N/A | 812 Mbps | 156 Mbps |
| ICMP 延迟(吞吐同时测) | 0.3 ms | 0.5 ms | 1.8 ms |
| 首次握手延迟(客户端回连) | N/A | 0.12 s | 2.3 s |
| CPU 占用(服务端单核) | 0% | 28% | 67% |
WireGuard 吞吐是 OpenVPN 的2倍,CPU 占用只有 OpenVPN 的41%,延迟低 1.3ms。在 10% 丢包链路上,WireGuard 的 TCP 吞吐 412 Mbps,OpenVPN 只有 128 Mbps。
原因是 WireGuard 完全在内核态运行,数据包不经过用户态拷贝。ChaCha20-Poly1305 用 AVX2 指令集加速,比 OpenSSL 的 AES-NI 在短包场景效率更高。
MTU 调优
WireGuard 默认 MTU 1420,是为互联网标准 1500 减去 80 字节 WireGuard 头部预留的。但如果你在云机房内网(内网 MTU 通常是 1500 或 9000),可以调大。
我踩过坑:把 MTU 调到 1500 后,ping 10.0.0.2 -s 1400 能通,但 scp 大文件间歇性卡死。查了 Wireshark 才发现是分片重组问题。
正确做法:ping -M do -s 1372 从 1372 往上试,找到最大不分片大小。我这边电信机房到北京阿里云,实测 MTU 1360 才稳定。
# /etc/wireguard/wg0.conf 修改 MTU
[Interface]
PrivateKey = ...
Address = 10.0.0.1/24
ListenPort = 51820
MTU = 1360
[Peer]
...
修改 MTU 后重启 systemctl restart wg-quick@wg0,再用 ping -M do -s 1372 验证。
多队列优化
服务器 CPU 多核时,默认 WireGuard 只用单队列,跑不满多核。需要开启多队列支持。
# 查看当前队列数
ethtool -l eth0
# Channel parameters for eth0:
# Pre-set maximums:
# RX: 0
# TX: 0
# Other: 0
# Combined: 8
# Current hardware settings:
# RX: 0
# TX: 0
# Other: 0
# Combined: 4
# 开启网卡多队列
sudo ethtool -L eth0 combined 8
# 确认 WireGuard 使用的 RX 队列被分散到不同 CPU
sudo cat /proc/interrupts | grep -E "eth0|wg0"
同时配置 RPS(Receive Packet Steering),让软中断分散到多个 CPU:
echo "f" | sudo tee /sys/class/net/eth0/queues/rx-0/rps_cpus
echo "f" | sudo tee /sys/class/net/eth0/queues/rx-1/rps_cpus
echo "f" | sudo tee /sys/class/net/eth0/queues/rx-2/rps_cpus
echo "f" | sudo tee /sys/class/net/eth0/queues/rx-3/rps_cpus
# 查看是否生效
cat /sys/class/net/eth0/queues/rx-0/rps_cpus
# f
注意 f 是 CPU 掩码,表示 0-3 号 CPU。如果服务器是 8 核,改成 ff。这个优化在 4 核以上机器效果明显。我优化后,WireGuard 单隧道吞吐从 2.1 Gbps 提升到 2.38 Gbps,但 CPU 占用从 28% 降到 21%。
Mesh组网:三机房全互联
如果 A 与 C 之间流量大,经过 B 转发会增加延迟。WireGuard 支持全互联 mesh,每个节点直接与其他节点建立隧道。
改法:把每个 peer 的 Endpoint 都配置上,同时 AllowedIPs 把其他两个机房的内网段都写上。
# 北京(wg0.conf 增加上海和广州的直连配置)
[Peer]
PublicKey = wQpR...(上海公钥)
Endpoint = 上海公网IP:51820
AllowedIPs = 10.0.0.2/32, 192.168.2.0/24
PersistentKeepalive = 25
[Peer]
PublicKey = v3mN...(广州公钥)
Endpoint = 广州公网IP:51820
AllowedIPs = 10.0.0.3/32, 192.168.3.0/24
PersistentKeepalive = 25
# 上海(wg0.conf 增加广州直连)
[Peer]
PublicKey = v3mN...(广州公钥)
Endpoint = 广州公网IP:51820
AllowedIPs = 10.0.0.3/32, 192.168.3.0/24
PersistentKeepalive = 25
改动后,上海到广州直接走隧道,不再经过北京转发。实测延迟从 18ms 降到 9ms(上海到广州物理延迟本来就在 8ms 左右)。
mesh 模式的坑在于:如果某个节点内网互通(比如广州和上海之间有专线),WireGuard 路由表会冲突。需要精确控制 AllowedIPs,避免路由环路。我的做法:每个节点只写自己需要访问的目标网段,不写超大网段如 0.0.0.0/0。
避坑指南(我实际踩过的)
这部分是重点,每个坑都是我花了时间定位的。
坑1:systemd 管理下 wg-quick 启动失败
症状:systemctl start wg-quick@wg0 报错 Operation not permitted。
原因:Ubuntu 22.04 的 systemd 250+ 默认限制了网络命名空间权限,WireGuard 需要 CAP_NET_ADMIN。
解决:检查服务状态 journalctl -u wg-quick@wg0 -n 50,看完整报错。如果是权限问题,用 sudo systemctl restart systemd-networkd 后再启动。这不是 WireGuard 的问题,是 systemd 的防护机制。
坑2:公网 IP 变化导致隧道中断
症状:客户端 IP 变了,wg show 显示 last handshake 一直不更新。
原因:对端 Endpoint 还指向旧 IP。
解决:客户端开启 PersistentKeepalive = 25。服务端不用做任何配置,WireGuard 会自动学习客户端的最新 Endpoint。但如果服务端 IP 变了,客户端必须在配置里更新 Endpoint。没有动态 DNS 的话,写个 cron 脚本检查 IP 变化并重启 wg-quick。
坑3:AllowedIPs 写错导致路由异常
症状:能 ping 通隧道 IP,但访问对端内网超时。
原因:AllowedIPs 控制的是「本机认为哪些 IP 应该走这个隧道」,如果写漏了,内核会尝试通过默认路由访问远端内网,自然不通。
解决:把需要访问的远端内网段全部写进 AllowedIPs。注意是「远端」的网段,不是本端的。如果本端是上海,要访问北京内网,AllowedIPs 里必须写 192.168.1.0/24。
坑4:MTU 问题导致大包丢包
症状:小包正常,大文件传输卡死,ping 大包丢包。
原因:WireGuard 默认 MTU 1420,但如果物理链路有额外的 PPPoE(宽带拨号)或隧道叠加,实际可用 MTU 更小。
解决:从 1400 往下试,ping -M do -s 1372 10.0.0.2。如果 1372 通了,再试 1400,找到临界值。我最终设在 1360。一定要用 -M do 禁止分片,否则测不出来。
坑5:多网卡服务器上 iptables MASQUERADE 不生效
症状:VPN 能连通,但内网机器访问不了对端。
原因:PostUp 里写死了 -o eth0,但服务器的出口网卡可能是 eth1 或 bond0。
解决:用 ip route 查默认路由,确认出口网卡。或者写成自动探测:
# 自动探测默认网卡
DEFAULT_IF=$(ip route | grep default | awk '{print $5}' | head -n1)
echo "默认网卡: $DEFAULT_IF"
# 然后在 PostUp 里用变量
PostUp = iptables -t nat -A POSTROUTING -o $DEFAULT_IF -j MASQUERADE
注意:wg-quick 的 PostUp 是单行命令,不支持变量。我建议写成独立脚本挂在 PostUp 里:
# /etc/wireguard/postup.sh
#!/bin/bash
DEFAULT_IF=$(ip route | grep default | awk '{print $5}' | head -n1)
iptables -A FORWARD -i wg0 -j ACCEPT
iptables -t nat -A POSTROUTING -o "$DEFAULT_IF" -j MASQUERADE
# wg0.conf 里这样引用
PostUp = /etc/wireguard/postup.sh
坑6:重启服务器后 WireGuard 不自动启动
症状:重启后隧道没起来。
原因:systemd service 没 enable。
解决:sudo systemctl enable wg-quick@wg0。但注意:如果配置文件不是 wg0.conf,而是别的名字如 vpn.conf,要改成 wg-quick@vpn。
坑7:云机房安全组忘记放行 UDP
症状:本机启动正常,但对端一直握手失败。
原因:云服务商安全组(如阿里云安全组、腾讯云防火墙)默认不放行 UDP 51820。服务器内部防火墙放了也没用,数据包在云平台层就被拦了。
解决:登录云控制台,在安全组入口方向放行 UDP 51820。记得同时放行 TCP 如果要用 Web 管理界面。
结语
WireGuard 不是万能的。它没有 OpenVPN 的插件生态,加密套件固定不能更换,某些合规场景可能过不了审。但 90% 的站点到站点、客户端到站点场景,它是最优解:配置最少、性能最好、容易排查。
我用这套方案在 35 分钟内搞定了原本要三天的组网任务。WireGuard 没有 keepalive 的维护负担,没有证书轮换的定时炸弹。遇到问题,wg show + tcpdump port 51820 基本能定位 90% 的故障。
如果你还在犹豫要不要迁移,我的建议是:新项目直接用 WireGuard,老项目用双跑测试替换。风险很低,收益明显。
有问题可以直接在评论区贴 wg show 的输出,我尽量回答。
FAQ 快速排查
Q: 握手超时,wg show 显示 latest handshake 是 "-"
依次检查:1)防火墙/安全组是否放行 UDP 51820;2)Endpoint 地址和端口是否正确;3)用 tcpdump -i eth0 udp port 51820 抓包看是否收到对端的包;4)AllowedIPs 是否匹配。
Q: 能 ping 通隧道 IP,但访问内网失败
查路由:ip route show table all | grep wg0。如果路由缺失,检查 AllowedIPs 是否写了远端网段。注意:AllowedIPs 只是路由的「生效条件」,WireGuard 会自动添加路由,但需要触发。用 ping 对端隧道IP 触发一次握手,然后 ip route 确认。
Q: 客户端 Mac/Windows 连不上服务端
官方客户端要求服务端必须支持应答,默认就行。但 Mac 客户端有个坑:如果上一次连接没有正常断开,下次连接会直接失败。解决:在 Mac 的网络设置里删掉 VPN 配置重新添加。
附录:完整配置文件模板
# 一键生成密钥(在 /etc/wireguard 下执行)
wg genkey | tee privatekey | wg pubkey > publickey
cat privatekey
# 中心节点服务器模板(对应机房 A)
[Interface]
PrivateKey = [A的私钥]
Address = 10.0.0.1/24
ListenPort = 51820
PostUp = /etc/wireguard/postup.sh
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = [B的公钥]
AllowedIPs = 10.0.0.2/32, 192.168.2.0/24
Endpoint = [B的公网IP]:51820
PersistentKeepalive = 25
[Peer]
PublicKey = [C的公钥]
AllowedIPs = 10.0.0.3/32, 192.168.3.0/24
Endpoint = [C的公网IP]:51820
PersistentKeepalive = 25
# 分支节点模板(对应机房 B)
[Interface]
PrivateKey = [B的私钥]
Address = 10.0.0.2/24
ListenPort = 51820
PostUp = /etc/wireguard/postup.sh
[Peer]
PublicKey = [A的公钥]
AllowedIPs = 10.0.0.0/24, 192.168.1.0/24, 192.168.3.0/24
Endpoint = [A的公网IP]:51820
PersistentKeepalive = 25
# 日常维护命令速查
# 查看状态
sudo wg show
# 重启隧道
sudo systemctl restart wg-quick@wg0
# 完整日志
sudo journalctl -u wg-quick@wg0 -f
# 抓包排查(UDP 51820)
sudo tcpdump -i eth0 udp port 51820 -nn
# 测试吞吐
iperf3 -c 10.0.0.1 -t 30 -P 4