VPN怎么又双叒叕掉了,我直接换方案 - WireGuard 部署实录

Shi Yi2026/7/19fixvpnwireguardlinux

背景

上次费了好大劲修的 VPN,效果还是不太行 😮‍💨

每次都是 rekey,重协商失败,没招了。

你这样不如写个后台脚本,定时重连吧,你这怎么只有第一次连接的时候才会成功呀,重协商就失败了呀,很难绷啊

估计是这玩意本身的 bug,我反正修不好。但是我总得交差呀,公司的人用这个,没法用啊。

WARNING

既然修不好,那就。在不影响之前功能的前提下,新搞一个东西。


方案选型:WireGuard

我搞的东西叫 WireGuard

不是,这玩意 yum 能下载 kmod-wireguard 吗?我曹威

很显然:

  • CentOS 7 内核 3.10 不原生支持 WireGuard
  • ELRepo 已不再提供可直接安装的 kmod-wireguard

因此使用 wireguard-linux-compat 编译当前内核的外置模块。


1. 安装依赖

确认当前内核版本,并安装 WireGuard 工具与编译依赖:

uname -r

yum install -y wireguard-tools gcc make perl elfutils-libelf-devel \
    kernel-devel-$(uname -r)

2. 编译并加载内核模块

运行外置模块安装脚本:

chmod 700 /root/install-wireguard-external-module.sh
bash /root/install-wireguard-external-module.sh

验证内核模块已加载:

lsmod | grep wireguard
modinfo wireguard | head -n 5

成功示例:

wireguard           193586  0
ip6_udp_tunnel       12755  1 wireguard
udp_tunnel           14423  1 wireguard

3. 服务端配置

DANGER

文件位置:/etc/wireguard/wg0.conf私钥必须由服务器本地生成,权限为 600;不得在聊天、工单或文档中公开。

生成密钥:

umask 077
wg genkey | tee /etc/wireguard/server.key | wg pubkey > /etc/wireguard/server.pub
chmod 600 /etc/wireguard/server.key /etc/wireguard/wg0.conf

单用户示例(公钥替换为实际值):

[Interface]
Address        = <隧道服务器地址>
ListenPort     = 51820
PrivateKey     = <服务器私钥>
SaveConfig     = false

PostUp   = iptables -I INPUT 1 -p udp --dport 51820 -j ACCEPT
PostUp   = iptables -I INPUT 1 -i %i -s 10.66.0.0/24 -j ACCEPT
PostUp   = iptables -I FORWARD 1 -i %i -o eth0 -s 10.66.0.0/24 -d <目标内网IP>/32 -j ACCEPT
PostUp   = iptables -I FORWARD 1 -i eth0 -o %i -d 10.66.0.0/24 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
PostUp   = iptables -t nat -I POSTROUTING 1 -s 10.66.0.0/24 -d <目标内网IP>/32 -o eth0 -j MASQUERADE

PostDown = iptables -D INPUT -p udp --dport 51820 -j ACCEPT
PostDown = iptables -D INPUT -i %i -s 10.66.0.0/24 -j ACCEPT
PostDown = iptables -D FORWARD -i %i -o eth0 -s 10.66.0.0/24 -d <目标内网IP>/32 -j ACCEPT
PostDown = iptables -D FORWARD -i eth0 -o %i -d 10.66.0.0/24 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -s 10.66.0.0/24 -d <目标内网IP>/32 -o eth0 -j MASQUERADE

[Peer]
PublicKey    = <Windows 用户 1 公钥>
AllowedIPs   = <用户1 隧道地址>

WARNING

规则必须使用 -I 插入链首。若使用 -A 追加到 firewalld 已有 REJECT/DROP 规则之后,UDP 51820 虽可被 tcpdump 捕获,但可能无法进入 WireGuard socket,表现为没有 latest handshake


4. Windows 客户端配置

安装官方 WireGuard 客户端,创建空隧道。Windows 私钥仅保存在本机。

[Interface]
PrivateKey  = <Windows 自动生成的私钥>
Address     = <用户隧道地址>

[Peer]
PublicKey            = <服务器 /etc/wireguard/server.pub 内容>
Endpoint             = <服务器公网IP>:51820
AllowedIPs           = <目标内网IP>/32, <其他目标网段>
PersistentKeepalive  = 25
参数说明
PersistentKeepalive = 25用于维持客户端位于 NAT 后的 UDP 映射
AllowedIPs仅下发目标的主机路由,网页、外网应用和 DNS 继续走本地网络

TIP

每增加一位用户,分配新的隧道地址与新的独立公钥。

这是一个很简单的配置,具体内容就是为远程主机分配相应的 IP,私钥服务器存储,很基础的内容,不再展开了。


5. 多用户管理

每位用户一个 [Peer] 块。服务端的 AllowedIPs 只填写该用户的隧道地址;不要将多个用户分配为同一地址。

[Peer]
# 用户 2
PublicKey    = <用户 2 Windows 公钥>
AllowedIPs   = 10.66.0.3/32

[Peer]
# 用户 3
PublicKey    = <用户 3 Windows 公钥>
AllowedIPs   = 10.66.0.4/32

日常新增或撤销用户无需重启服务。编辑完 /etc/wireguard/wg0.conf 后,使用以下命令将 peer 实时同步到运行中的 wg0

wg syncconf wg0 <(wg-quick strip wg0)
wg show

TIP

wg syncconf 不会断开现有 WireGuard 用户;新增 peer 后应在 wg show 中看到其 public key,连接后出现 latest handshake

WARNING

撤销用户时,先删除对应 [Peer] 块,再执行相同的 wg syncconf 命令;同时从用户设备移除该隧道配置。

systemctl restart wg-quick@wg0 也能应用配置,但会短暂中断所有用户,只用于接口修复或维护窗口。

提示一下,当使用 WireGuard 客户端新建隧道的时候就可以看见客户端私钥。


总结

已经严肃使用一天,未发生掉线情况

我曹威终于好了 🎉

TIP

回头看,WireGuard 相比之前的方案:配置简洁、内核态运行、基于 UDP 抗 NAT 抖动,关键是没有 rekey 死循环

Last Updated 7/19/2026, 1:40:50 PM