WireGuard VPN 自建完全指南:协议原理、服务端部署到全平台客户端配置 | 2026 最新实践
你有没有遇到过这些场景:
- 公司有内网系统,在家办公连不上,想搞个 VPN 回去
- 几台分散在不同地方的 VPS,想组成一个内网互相访问
- 手机在外面想访问家里的 NAS,但不想暴露端口到公网
- 试过 OpenVPN,配置证书搞了一下午还没通
- 听说 WireGuard 很快很安全,但不知道怎么搭
WireGuard 就是解决这些问题的现代 VPN 方案——代码量仅 4000 行,性能比 OpenVPN 快 2-5 倍,配置一个文件就能跑通。
与 Hysteria2、VLESS Reality 这类抗审查代理协议不同,WireGuard 的核心定位是组建私有网络——异地组网、远程办公、内网穿透、站点到站点互联,这些才是它的主场。

阅读提示本文与站内其他文章互补:《Hysteria2 协议完全指南》 聚焦翻墙抗审查,《VLESS Reality 协议完全指南》 聚焦流量伪装,本文聚焦 WireGuard 组建私有网络。如果目标是翻墙,建议优先阅读前两篇;如果目标是组网/远程访问,本文是正确起点。
相关阅读:《Linux 防火墙完全指南》(WireGuard 需要防火墙配合)、《systemd 服务管理完全指南》(wg-quick 本质是 systemd 服务)、《SSH 完全指南》(远程端口转发替代方案)。
一、WireGuard 是什么
1.1 一句话定义
WireGuard 是一种现代的、快速的、安全的 VPN 隧道协议,代码量约 4000 行,使用现代加密算法,已集成到 Linux 内核(5.6+)。
1.2 与其他 VPN 协议对比
| 特性 | WireGuard | OpenVPN | IPSec/IKEv2 | Hysteria2 | VLESS Reality |
|---|---|---|---|---|---|
| 代码量 | ~4000 行 | ~100,000 行 | ~600,000 行 | ~15,000 行 | ~30,000 行 |
| 传输协议 | UDP | TCP/UDP | UDP | UDP (QUIC) | TCP |
| 加密 | ChaCha20-Poly1305 | AES (OpenSSL) | AES/Camellia | ChaCha20-Poly1305 | AES/XTS |
| 密钥交换 | Curve25519 | RSA/DH | DH | X25519 | X25519 |
| 性能 | 极快(内核级) | 慢(用户态) | 快(内核级) | 快 | 中等 |
| 配置复杂度 | 低(一个 conf) | 高(证书体系) | 高(策略配置) | 低 | 中 |
| 抗审查 | 弱 | 弱 | 弱 | 强 | 极强 |
| NAT 穿透 | 原生支持 | 需额外配置 | 支持 | 原生支持 | 不适用 |
| IP 漫游 | 原生支持 | 不支持 | 部分 | 不适用 | 不适用 |
| 内核集成 | 是(5.6+) | 否 | 是 | 否 | 否 |
| 适用场景 | 组网/VPN | 传统 VPN | 企业 VPN | 翻墙 | 翻墙 |
1.3 核心设计哲学
WireGuard 的设计遵循三个原则:
1. 简单性(Simplicity)
# 一个完整的 WireGuard 服务端配置,就这么几行[Interface]PrivateKey = <server-private-key>Address = 10.0.0.1/24ListenPort = 51820
[Peer]PublicKey = <client-public-key>AllowedIPs = 10.0.0.2/32没有证书链、没有 CA、没有协商参数。一对密钥、一个端口、一个配置文件。
2. 加密保守主义(Cryptographic Victimhood)
WireGuard 不允许用户选择加密算法——它固定使用一组经过验证的现代加密套件:
| 组件 | 算法 | 说明 |
|---|---|---|
| 对称加密 | ChaCha20-Poly1305 | AEAD,比 AES 在移动端更快 |
| 密钥交换 | Curve25519 (X25519) | ECDH,比 RSA 更短更快 |
| 哈希 | BLAKE2s | 比 SHA-2 更快 |
| MAC | BLAKE2s | 用于握手认证 |
| HKDF | HMAC-BLAKE2s | 密钥派生 |
不支持协商意味着:没有降级攻击、没有弱密码套件、没有配置错误。
3. 无连接状态(Stateless)
WireGuard 没有连接的概念——它像一个无状态的 UDP 服务器。收到合法的数据包就处理,不维护连接状态。这意味着:
- 没有「连接」「断开」的概念
- IP 漫游:手机从 WiFi 切到 4G,VPN 不断
- 不回复未认证的数据包(对外表现为端口无响应)
1.4 什么时候用 WireGuard
| 场景 | 是否推荐 | 原因 |
|---|---|---|
| 异地组网(多台 VPS 互联) | ✅ 强烈推荐 | 原生支持,配置简单 |
| 远程办公(连公司内网) | ✅ 强烈推荐 | 性能好,全平台支持 |
| 手机访问家里 NAS | ✅ 推荐 | IP 漫游,移动端体验好 |
| 翻墙科学上网 | ⚠️ 不推荐 | 流量特征明显,容易被封 |
| 站点到站点企业 VPN | ✅ 推荐 | 比 IPSec 简单得多 |
| 绕过 Netflix 地区限制 | ⚠️ 一般 | 可以用,但不如代理灵活 |
二、协议原理
2.1 Cryptokey Routing(加密密钥路由)
WireGuard 的核心机制叫 Cryptokey Routing——每个网络接口维护一张「公钥 → AllowedIPs」路由表。
┌─────────────────────────────────────────────┐│ WireGuard 接口 wg0 ││ PrivateKey: <server-private-key> ││ Address: 10.0.0.1/24 ││ ListenPort: 51820 ││ ││ ┌────────────────────────────────────────┐ ││ │ Peer 路由表 │ ││ │ │ ││ │ PublicKey A → AllowedIPs 10.0.0.2/32 │ ││ │ PublicKey B → AllowedIPs 10.0.0.3/32 │ ││ │ PublicKey C → AllowedIPs 10.0.0.4/32 │ ││ └────────────────────────────────────────┘ │└─────────────────────────────────────────────┘工作流程:
- 发送方向:当内核要发送一个 IP 包到
10.0.0.2,查找路由表发现10.0.0.2/32属于 Peer A,用 Peer A 的公钥加密后发送到 Peer A 的端点 - 接收方向:收到一个加密包,解密后得到源 IP
10.0.0.2,查找路由表确认10.0.0.2/32确实属于 Peer A 的 AllowedIPs → 放行
这就是为什么 AllowedIPs 既是 ACL 又是路由表——一石二鸟。
2.2 握手流程
WireGuard 使用 Noise 协议框架(Noise_IKpsk2 模式),1-RTT 完成握手:
客户端 (Initiator) 服务端 (Responder) | | | ---- Handshake Initiation ----> | | (临时公钥 + 静态公钥加密) | | | | <--- Handshake Response ------ | | (临时公钥 + MAC确认) | | | | ===== 数据传输 (已加密) =======> | | <==== 数据传输 (已加密) ======= |关键点:
- 握手约 120 秒后自动重新协商(Rekey After Time)
- 握手包只有 92 字节(Initiation)和 88 字节(Response)
- 握手成功后生成 ChaCha20-Poly1305 对称密钥,后续数据传输使用对称加密
- 每个方向有独立的发送/接收计数器,防止重放攻击
2.3 双密钥体系
每个 WireGuard 节点有两对密钥:
| 密钥 | 用途 | 保密级别 |
|---|---|---|
| Static Private Key | 身份标识,长期使用 | 绝对保密 |
| Static Public Key | 分发给其他 Peer | 可公开 |
| Ephemeral Private Key | 每次握手临时生成 | 用完即弃 |
| Ephemeral Public Key | 随握手包发送 | 用完即弃 |
静态密钥用于身份认证,临时密钥用于前向保密(Forward Secrecy)——即使静态私钥泄露,历史流量也无法解密。
2.4 PreShared Key (PSK)
除了双密钥体系,WireGuard 还支持可选的 PreShared Key——一个 256 位的对称密钥,在握手时混入密钥派生过程:
# 生成 PSKwg genpsk# 输出示例:cGFzc3dvcmQxMjM0NTY3ODkwYWJjZGVmZ2hpamtsbW5vcA==PSK 的作用:
- 提供后量子安全(Post-Quantum Security)——即使未来量子计算机破解了 Curve25519,PSK 仍能保护通信
- 多一层安全保险——即使静态私钥泄露,没有 PSK 仍无法建立连接
- 适合极高安全要求的场景
使用建议: 个人使用一般不需要 PSK,企业/高安全场景建议启用。
2.5 IP 漫游机制
WireGuard 最独特的特性之一——无状态设计使得 IP 漫游成为可能:
时刻 T1: 手机在 WiFi (192.168.1.100) → 服务端记录 Peer 端点为 192.168.1.100:51820时刻 T2: 手机切到 4G (10.0.0.50) → 发出一个数据包 服务端收到包,源 IP 是 10.0.0.50 → 自动更新 Peer 端点为 10.0.0.50:51820 → 后续回包发往新地址不需要重新握手、不需要重连、用户无感知。 这对移动设备来说是巨大优势。
三、服务端部署
3.1 环境要求
| 要求 | 说明 |
|---|---|
| 操作系统 | Linux 内核 5.6+(Ubuntu 20.04+、Debian 11+、CentOS 9+ 原生支持) |
| 内核模块 | wireguard 模块(5.6+ 已内置) |
| 用户工具 | wireguard-tools(提供 wg 和 wg-quick 命令) |
| 网络 | 公网 IP + UDP 端口(默认 51820) |
| 权限 | root(需要创建网络接口) |
3.2 安装
Ubuntu / Debian(内核 5.6+):
apt updateapt install -y wireguard wireguard-toolsCentOS / RHEL / Fedora:
dnf install -y epel-releasednf install -y wireguard-tools低版本内核(< 5.6)安装 wireguard-dkms:
# Ubuntu 18.04 等旧系统apt install -y wireguard-dkms wireguard-tools# 需要 DKMS 和内核头文件apt install -y dkms linux-headers-$(uname -r)验证安装:
# 检查内核模块modprobe wireguard && echo "OK" || echo "FAIL"
# 检查工具wg --version# 输出示例: wireguard-tools v1.0.20210914 - amneziawg-tools v1.0.20240227
# 检查 wg-quickwhich wg-quick# /usr/bin/wg-quick3.3 生成密钥对
# 创建配置目录mkdir -p /etc/wireguardcd /etc/wireguard
# 生成服务端密钥对wg genkey | tee server-private.key | wg pubkey > server-public.key
# 查看密钥cat server-private.key# 输出示例: yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=
cat server-public.key# 输出示例: GtL7fZc/bLnqZldpVofMCD6hDjrK9Ky0D24ZGFHdPzQ=
# 设置密钥文件权限chmod 600 server-private.keychmod 644 server-public.key3.4 编写服务端配置
cat > /etc/wireguard/wg0.conf << EOF[Interface]# 服务端私钥PrivateKey = $(cat server-private.key)# VPN 内网地址Address = 10.0.0.1/24# 监听端口ListenPort = 51820# DNS(可选,给客户端用的 DNS)# DNS = 1.1.1.1, 8.8.8.8
# 启动后执行的 iptables 规则(NAT 转发,让客户端能上网)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 = <client-public-key># 该客户端的 VPN 内网 IPAllowedIPs = 10.0.0.2/32EOF
chmod 600 /etc/wireguard/wg0.conf配置项详解:
| 字段 | 说明 | 示例 |
|---|---|---|
PrivateKey | 本机私钥 | yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk= |
Address | 本机 VPN 内网 IP | 10.0.0.1/24 |
ListenPort | UDP 监听端口 | 51820 |
PostUp | 接口启动后执行的命令 | iptables NAT 规则 |
PostDown | 接口停止后执行的命令 | 清理 iptables 规则 |
PublicKey | 对端公钥 | GtL7fZc/bLnqZldpVofMCD6hDjrK9Ky0D24ZGFHdPzQ= |
AllowedIPs | 对端可用的 IP 范围 | 10.0.0.2/32 |
3.5 开启 IP 转发
如果要让客户端通过 VPN 上网,必须开启 IP 转发:
# 临时开启sysctl -w net.ipv4.ip_forward=1sysctl -w net.ipv6.conf.all.forwarding=1
# 永久开启cat >> /etc/sysctl.conf << EOFnet.ipv4.ip_forward=1net.ipv6.conf.all.forwarding=1EOF
# 应用sysctl -p3.6 防火墙配置
开放 UDP 端口:
# UFWufw allow 51820/udpufw reload
# firewalldfirewall-cmd --permanent --add-port=51820/udpfirewall-cmd --reload
# iptablesiptables -A INPUT -p udp --dport 51820 -j ACCEPT⚠️ 注意:WireGuard 使用 UDP 协议,开放端口时必须指定
/udp,否则防火墙不会放行。
允许 WireGuard 接口转发:
# 允许 wg0 接口的转发流量iptables -A FORWARD -i wg0 -j ACCEPTiptables -A FORWARD -o wg0 -j ACCEPT详细防火墙配置参见 《Linux 防火墙完全指南》。
3.7 启动服务
# 手动启动wg-quick up wg0
# 验证wg show# 输出:# interface: wg0# public key: GtL7fZc/bLnqZldpVofMCD6hDjrK9Ky0D24ZGFHdPzQ=# private key: (hidden)# listening port: 51820
# 设置开机自启systemctl enable wg-quick@wg0
# 使用 systemd 管理systemctl start wg-quick@wg0systemctl status wg-quick@wg0wg-quick@.service 说明:
wg-quick@wg0.service 是一个 systemd 模板服务,@ 后面的 wg0 对应 /etc/wireguard/wg0.conf。如果要创建第二个接口 wg1,配置文件为 /etc/wireguard/wg1.conf,服务名为 wg-quick@wg1.service。
3.8 验证服务端运行
# 检查接口状态ip addr show wg0# 应看到:# 4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 ...# inet 10.0.0.1/24 scope global wg0
# 检查路由ip route | grep wg0# 应看到: 10.0.0.0/24 dev wg0 proto kernel scope link
# 检查 UDP 端口监听ss -ulnp | grep 51820# 应看到: udp UNCONN 0 0 0.0.0.0:51820 0.0.0.0:* users:(("wireguard",...))
# 检查 WireGuard 状态wg show四、客户端配置
4.1 生成客户端密钥
在任意一台机器上生成客户端密钥(也可以在服务端生成):
# 生成客户端密钥对wg genkey | tee client-private.key | wg pubkey > client-public.key
# 查看客户端公钥(需要填入服务端配置)cat client-public.key# 输出示例: xT5tA9p7K3mF2qR8sN4vL6wY1cB0hJ3gD5eU7iO2pA=将客户端公钥填入服务端配置:
# 编辑服务端配置nano /etc/wireguard/wg0.conf
# 将 <client-public-key> 替换为实际公钥# PublicKey = xT5tA9p7K3mF2qR8sN4vL6wY1cB0hJ3gD5eU7iO2pA=
# 重启服务端使配置生效wg-quick down wg0 && wg-quick up wg04.2 Linux 客户端
# 安装工具apt install -y wireguard-tools
# 创建客户端配置cat > /etc/wireguard/wg0.conf << EOF[Interface]# 客户端私钥PrivateKey = $(cat client-private.key)# 客户端 VPN 内网 IPAddress = 10.0.0.2/24# DNS(可选)DNS = 1.1.1.1, 8.8.8.8
[Peer]# 服务端公钥PublicKey = $(cat server-public.key)# 服务端地址和端口Endpoint = <server-public-ip>:51820# 允许通过 VPN 的目标 IP 范围# 0.0.0.0/0 = 全局代理(所有流量走 VPN)# 10.0.0.0/24 = 只走内网流量(Split Tunneling)AllowedIPs = 0.0.0.0/0# 保持连接(NAT 后面的客户端需要,每 25 秒发一个心跳包)PersistentKeepalive = 25EOF
# 启动wg-quick up wg0
# 验证wg showping 10.0.0.1 # ping 服务端 VPN IP4.3 Windows 客户端
方式一:官方客户端
- 从 wireguard.com/install 下载 Windows 安装包
- 安装后打开 WireGuard 应用
- 点击「导入 tunnel(s) from file」→ 选择
.conf配置文件 - 或点击「Add Tunnel」→ 「Add empty tunnel」→ 手动粘贴配置
客户端配置文件:
[Interface]PrivateKey = <client-private-key>Address = 10.0.0.2/24DNS = 1.1.1.1, 8.8.8.8
[Peer]PublicKey = <server-public-key>Endpoint = <server-public-ip>:51820AllowedIPs = 0.0.0.0/0PersistentKeepalive = 25方式二:生成二维码(方便手机扫描)
在 Linux 服务端上:
apt install -y qrencodeqrencode -t ansiutf8 /etc/wireguard/client-wg0.conf# 会在终端打印二维码,手机扫码即可导入4.4 macOS 客户端
方式一:App Store
从 Mac App Store 搜索安装 WireGuard。
方式二:Homebrew
brew install wireguard-tools
# 配置文件放在 /usr/local/etc/wireguard/wg0.conf(Intel)# 或 /opt/homebrew/etc/wireguard/wg0.conf(Apple Silicon)mkdir -p /opt/homebrew/etc/wireguardcat > /opt/homebrew/etc/wireguard/wg0.conf << EOF[Interface]PrivateKey = <client-private-key>Address = 10.0.0.2/24DNS = 1.1.1.1
[Peer]PublicKey = <server-public-key>Endpoint = <server-public-ip>:51820AllowedIPs = 0.0.0.0/0PersistentKeepalive = 25EOF
# 启动wg-quick up wg04.5 iOS 客户端
- App Store 搜索安装 WireGuard
- 打开 App → 右上角「+」→ 「Scan QR code」
- 扫描在服务端生成的二维码
- 或手动输入配置
4.6 Android 客户端
- Google Play 或 F-Droid 搜索安装 WireGuard
- 打开 App → 右上角「+」→ 「Scan QR code」或 「Import from file」
- 连接即可
4.7 配置模板速查
┌──────────────────────────────────────────────────────────────────┐│ 完整配置模板 │├──────────────────────────────────────────────────────────────────┤│ ││ 服务端 /etc/wireguard/wg0.conf: ││ ┌────────────────────────────────────────────────────────────┐ ││ │ [Interface] │ ││ │ PrivateKey = <SERVER_PRIVATE_KEY> │ ││ │ Address = 10.0.0.1/24 │ ││ │ ListenPort = 51820 │ ││ │ PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; \ │ ││ │ iptables -t nat -A POSTROUTING -o eth0 -j MASQ │ ││ │ PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; \ │ ││ │ iptables -t nat -D POSTROUTING -o eth0 -j MASQ │ ││ │ │ ││ │ [Peer] │ ││ │ PublicKey = <CLIENT_PUBLIC_KEY> │ ││ │ AllowedIPs = 10.0.0.2/32 │ ││ └────────────────────────────────────────────────────────────┘ ││ ││ 客户端 wg0.conf: ││ ┌────────────────────────────────────────────────────────────┐ ││ │ [Interface] │ ││ │ PrivateKey = <CLIENT_PRIVATE_KEY> │ ││ │ Address = 10.0.0.2/24 │ ││ │ DNS = 1.1.1.1, 8.8.8.8 │ ││ │ │ ││ │ [Peer] │ ││ │ PublicKey = <SERVER_PUBLIC_KEY> │ ││ │ Endpoint = <SERVER_PUBLIC_IP>:51820 │ ││ │ AllowedIPs = 0.0.0.0/0 │ ││ │ PersistentKeepalive = 25 │ ││ └────────────────────────────────────────────────────────────┘ ││ ││ 网络拓扑: ││ 客户端 10.0.0.2 ←──WireGuard──→ 服务端 10.0.0.1 → 互联网 ││ ││ AllowedIPs 说明: ││ 服务端: 10.0.0.2/32 → 该 Peer 只能用这个内网 IP ││ 客户端: 0.0.0.0/0 → 全局代理(所有流量走 VPN) ││ 客户端: 10.0.0.0/24 → 只走内网(Split Tunneling) │└──────────────────────────────────────────────────────────────────┘五、多用户管理
5.1 手动添加多用户
每个用户就是一个 Peer,在服务端配置中添加 [Peer] 段即可:
# 为每个用户生成密钥对cd /etc/wireguard
# 用户 Alicewg genkey | tee alice-private.key | wg pubkey > alice-public.key
# 用户 Bobwg genkey | tee bob-private.key | wg pubkey > bob-public.key
# 用户 Charliewg genkey | tee charlie-private.key | wg pubkey > charlie-public.key服务端配置(多用户):
[Interface]PrivateKey = <server-private-key>Address = 10.0.0.1/24ListenPort = 51820PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADEPostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# Alice[Peer]PublicKey = <alice-public-key>AllowedIPs = 10.0.0.2/32
# Bob[Peer]PublicKey = <bob-public-key>AllowedIPs = 10.0.0.3/32
# Charlie[Peer]PublicKey = <charlie-public-key>AllowedIPs = 10.0.0.4/32⚠️ 关键规则:每个 Peer 的
AllowedIPs必须是/32(单个 IP),且不能重叠。如果两个 Peer 的 AllowedIPs 重叠,WireGuard 无法正确路由。
应用配置变更(不需要重启):
# 使用 wg syncconf 热加载配置(不断开现有连接)wg syncconf wg0 <(wg-quick strip wg0)
# 或使用 wg set 命令动态添加 Peerwg set wg0 peer <alice-public-key> allowed-ips 10.0.0.2/325.2 客户端配置生成脚本
为每个用户生成独立的客户端配置文件:
#!/bin/bash# 用法: ./generate-client.sh <username> <vpn-ip>
USERNAME=$1VPN_IP=$2SERVER_PUBKEY=$(cat /etc/wireguard/server-public.key)SERVER_PUBLIC_IP="203.0.113.100" # 替换为你的服务器公网 IPPORT=51820
# 生成密钥cd /etc/wireguardwg genkey | tee ${USERNAME}-private.key | wg pubkey > ${USERNAME}-public.keyPRIVKEY=$(cat ${USERNAME}-private.key)
# 生成客户端配置cat > ${USERNAME}-client.conf << EOF[Interface]PrivateKey = ${PRIVKEY}Address = ${VPN_IP}/24DNS = 1.1.1.1, 8.8.8.8
[Peer]PublicKey = ${SERVER_PUBKEY}Endpoint = ${SERVER_PUBLIC_IP}:${PORT}AllowedIPs = 0.0.0.0/0PersistentKeepalive = 25EOF
# 生成二维码qrencode -t ansiutf8 ${USERNAME}-client.conf
echo "客户端配置已生成: ${USERNAME}-client.conf"echo "请将以下公钥添加到服务端配置:"cat ${USERNAME}-public.keyecho ""echo "在服务端 [Peer] 段中添加:"echo "[Peer]"echo "PublicKey = $(cat ${USERNAME}-public.key)"echo "AllowedIPs = ${VPN_IP}/32"5.3 使用 wg-easy Web 管理面板
对于多用户场景,手动管理密钥很繁琐。wg-easy 是最流行的 WireGuard Web 管理面板:
# 使用 Docker 部署 wg-easydocker run -d \ --name=wg-easy \ -e WG_HOST=203.0.113.100 \ -e PASSWORD_HASH='$2a$12$B5mP...' \ -v ~/.wg-easy:/etc/wireguard \ -p 51820:51820/udp \ -p 51821:51821/tcp \ --cap-add=NET_ADMIN \ --cap-add=SYS_MODULE \ --sysctl="net.ipv4.conf.all.src_valid_mark=1" \ --sysctl="net.ipv4.ip_forward=1" \ --restart unless-stopped \ ghcr.io/wg-easy/wg-easy:latestwg-easy 功能:
- Web 界面添加/删除客户端
- 自动生成配置和二维码
- 实时查看客户端连接状态
- 一键启停客户端
- 流量统计
访问 http://<server-ip>:51821 即可使用。
5.4 其他管理工具
| 工具 | 特点 | 适合场景 |
|---|---|---|
| wg-easy | 轻量 Web UI,Docker 部署 | 个人/小团队 |
| wg-access-server | 功能更全,支持 LDAP/OIDC 认证 | 企业 |
| Firezone | 开源,支持 SSO,多组织 | 中大型企业 |
| Netmaker | 自动组网,无需手动配置 | 大规模 Mesh 网络 |
| Tailscale | 基于 WireGuard 的 SaaS,零配置 | 快速部署,不想自建 |
六、高级配置
6.1 Split Tunneling(分流隧道)
Split Tunneling 指只让特定流量走 VPN,其余走本地网络。通过 AllowedIPs 控制:
[Interface]PrivateKey = <client-private-key>Address = 10.0.0.2/24
[Peer]PublicKey = <server-public-key>Endpoint = 203.0.113.100:51820
# 只让 10.0.0.0/24 的内网流量走 VPN# 其他流量(上网、看视频)走本地网络AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 25多网段分流:
# 同时走多个内网段AllowedIPs = 10.0.0.0/24, 172.16.0.0/16, 192.168.50.0/24排除特定 IP(需要 wg-quick 的 Table 功能):
[Interface]PrivateKey = <client-private-key>Address = 10.0.0.2/24# 不自动添加路由表,手动控制Table = off
# 手动添加路由(只让特定 IP 走 VPN)PostUp = ip route add 10.10.0.0/16 dev wg0PostDown = ip route del 10.10.0.0/16 dev wg0
[Peer]PublicKey = <server-public-key>Endpoint = 203.0.113.100:51820AllowedIPs = 10.0.0.0/24PersistentKeepalive = 256.2 Kill Switch(断线保护)
Kill Switch 确保当 VPN 断开时,不会泄露真实 IP。通过 iptables 实现:
[Interface]PrivateKey = <client-private-key>Address = 10.0.0.2/24
# Kill Switch - 只允许通过 wg0 接口出去# 阻止所有不经过 VPN 的流量PostUp = iptables -A OUTPUT ! -o wg0 -m mark ! --mark $(wg show wg0 fwmark) -m addrtype ! --dst-type LOCAL -j DROPPostDown = iptables -D OUTPUT ! -o wg0 -m mark ! --mark $(wg show wg0 fwmark) -m addrtype ! --dst-type LOCAL -j DROP
[Peer]PublicKey = <server-public-key>Endpoint = 203.0.113.100:51820AllowedIPs = 0.0.0.0/0PersistentKeepalive = 256.3 PersistentKeepalive 详解
PersistentKeepalive = 25| 值 | 含义 | 适用场景 |
|---|---|---|
0(默认) | 不发心跳 | 服务端(有公网 IP,不需要) |
1-65535 | 每隔 N 秒发一个心跳包 | NAT 后面的客户端 |
为什么需要 PersistentKeepalive?
NAT 设备会维护一个映射表(内部 IP:端口 → 外部 IP:端口),如果一段时间没有流量,映射就会被清除。当服务端要回包时,NAT 映射已失效,包被丢弃。
无 PersistentKeepalive: T0: 客户端发包 → NAT 建立映射 → 服务端收到 T5min: NAT 映射超时被清除 T5min: 服务端回包 → NAT 无映射 → 包被丢弃 ❌
有 PersistentKeepalive=25: T0: 客户端发包 → NAT 建立映射 T25s: 心跳包 → NAT 映射刷新 T50s: 心跳包 → NAT 映射刷新 ...NAT 映射永远不会超时 ✅建议值:
- 客户端在 NAT 后面 →
PersistentKeepalive = 25 - 客户端有公网 IP → 不需要设置
- 服务端 → 不需要设置
6.4 IPv6 支持
# 服务端配置[Interface]PrivateKey = <server-private-key>Address = 10.0.0.1/24, fd00::1/64ListenPort = 51820PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADEPostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]PublicKey = <client-public-key>AllowedIPs = 10.0.0.2/32, fd00::2/128# 客户端配置[Interface]PrivateKey = <client-private-key>Address = 10.0.0.2/24, fd00::2/64
[Peer]PublicKey = <server-public-key>Endpoint = [2001:db8::1]:51820AllowedIPs = 0.0.0.0/0, ::/0PersistentKeepalive = 256.5 MTU 优化
WireGuard 默认 MTU 为 1420(减去了 WireGuard 头部开销)。在某些网络环境下可能需要调整:
[Interface]PrivateKey = <private-key>Address = 10.0.0.1/24# 降低 MTU 解决某些网络的包丢失问题MTU = 1280| MTU 值 | 适用场景 |
|---|---|
| 1420 | 默认值,大多数情况适用 |
| 1280 | PPPoE / 嵌套隧道 |
| 1380 | 某些云厂商内网 |
测试最佳 MTU:
# 在客户端 ping 服务端,逐步降低包大小找到不分片的阈值ping -M do -s 1392 10.0.0.1# 如果能通,MTU = 1392 + 28 = 1420# 如果不通,降低 -s 值继续测试ping -M do -s 1372 10.0.0.1# 1372 + 28 = 1400七、站点到站点 VPN
站点到站点 VPN(Site-to-Site)连接两个网络,让两个局域网互相访问。
7.1 拓扑
站点 A (192.168.1.0/24) 站点 B (192.168.2.0/24)┌───────────────────┐ ┌───────────────────┐│ 局域网设备 │ │ 局域网设备 ││ 192.168.1.10 │ │ 192.168.2.10 ││ 192.168.1.11 │ │ 192.168.2.11 ││ │ │ │ │ ││ ┌────┴────────┐ │ │ ┌────┴────────┐ ││ │ 网关 A │ │ │ │ 网关 B │ ││ │ 192.168.1.1 │ │ │ │ 192.168.2.1 │ ││ │ wg0:10.0.0.1│◄─┼── WireGuard ──┼─►│ wg0:10.0.0.2│ ││ │ 公网IP: A │ │ 隧道 │ │ 公网IP: B │ ││ └─────────────┘ │ │ └─────────────┘ │└───────────────────┘ └───────────────────┘7.2 网关 A 配置
[Interface]PrivateKey = <gateway-a-private-key>Address = 10.0.0.1/30ListenPort = 51820
# 允许从 wg0 到 eth0 的转发PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPTPostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT
[Peer]PublicKey = <gateway-b-public-key>Endpoint = <gateway-b-public-ip>:51820# 允许访问站点 B 的内网段AllowedIPs = 10.0.0.2/32, 192.168.2.0/24PersistentKeepalive = 257.3 网关 B 配置
[Interface]PrivateKey = <gateway-b-private-key>Address = 10.0.0.2/30ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPTPostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT
[Peer]PublicKey = <gateway-a-public-key>Endpoint = <gateway-a-public-ip>:51820# 允许访问站点 A 的内网段AllowedIPs = 10.0.0.1/32, 192.168.1.0/24PersistentKeepalive = 257.4 局域网设备路由
方案一:静态路由(简单)
在站点 A 的局域网设备上添加到站点 B 的路由:
# Linuxip route add 192.168.2.0/24 via 192.168.1.1
# macOSsudo route -nv add 192.168.2.0/24 192.168.1.1方案二:在网关上自动配置(推荐)
在网关 A 上添加 NAT 规则,让对端内网设备不需要额外配置:
# 网关 A 的 PostUp 中添加 SNATPostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -j MASQUERADEPostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -j MASQUERADE方案三:在 DHCP 中下发路由(企业级)
在 DHCP 服务器中配置 option 121(无类静态路由):
# dnsmasq 配置dhcp-option=option:router,192.168.1.1dhcp-option=121,192.168.2.0/24,192.168.1.17.5 多站点 Mesh 组网
WireGuard 支持 Full Mesh 拓扑——每个节点都与其他所有节点直连:
节点 A / \ 节点 B —— 节点 C \ / 节点 D每个节点配置中添加所有其他节点为 Peer:
# 节点 A 的配置[Interface]PrivateKey = <node-a-private-key>Address = 10.0.0.1/24ListenPort = 51820
[Peer]# 节点 BPublicKey = <node-b-public-key>Endpoint = <node-b-ip>:51820AllowedIPs = 10.0.0.2/32PersistentKeepalive = 25
[Peer]# 节点 CPublicKey = <node-c-public-key>Endpoint = <node-c-ip>:51820AllowedIPs = 10.0.0.3/32PersistentKeepalive = 25
[Peer]# 节点 DPublicKey = <node-d-public-key>Endpoint = <node-d-ip>:51820AllowedIPs = 10.0.0.4/32PersistentKeepalive = 25💡 Full Mesh vs Hub-Spoke:4 个节点 Full Mesh 需要 6 条隧道(n*(n-1)/2),Hub-Spoke 只需 3 条但所有流量经过 Hub。节点少时用 Full Mesh(性能好),节点多时用 Hub-Spoke(管理简单)。
八、安全加固
8.1 使用 PreShared Key
# 生成 PSKwg genpsk# 输出: cGFzc3dvcmQxMjM0NTY3ODkwYWJjZGVmZ2hpamtsbW5vcA==在服务端和客户端的 [Peer] 段中添加:
[Peer]PublicKey = <peer-public-key>PresharedKey = cGFzc3dvcmQxMjM0NTY3ODkwYWJjZGVmZ2hpamtsbW5vcA==AllowedIPs = 10.0.0.2/328.2 更换默认端口
[Interface]ListenPort = 53982 # 不用默认 518208.3 限制源 IP 访问
如果服务端有公网 IP 且客户端 IP 固定,可以限制只接受特定 IP 的连接:
# iptables 限制只有特定 IP 能连接 WireGuard 端口iptables -A INPUT -p udp --dport 51820 -s 203.0.113.50 -j ACCEPTiptables -A INPUT -p udp --dport 51820 -j DROP⚠️ 注意:如果客户端在 NAT 后面或 IP 会变(如手机 4G),不要限制源 IP。
8.4 禁用 root 通过 VPN 登录
# SSH 只允许从特定网卡(非 wg0)登录# 编辑 /etc/ssh/sshd_configMatch Address 10.0.0.* PermitRootLogin no PasswordAuthentication no8.5 审计与监控
# 查看所有 Peer 的握手时间(判断谁在用)wg show all dump | awk '{print $1, $2, $3, $5}' | column -t
# 监控 WireGuard 流量watch -n 1 'wg show'
# 记录握手日志(使用 systemd journal)journalctl -u wg-quick@wg0 -f
# 使用 Prometheus 监控(wgc-exporter)# https://github.com/mdlayher/wgexporter8.6 安全清单
| 项目 | 说明 | 状态 |
|---|---|---|
| 私钥权限 600 | chmod 600 /etc/wireguard/*.key | ☐ |
| 配置文件权限 600 | chmod 600 /etc/wireguard/wg0.conf | ☐ |
| 启用 PSK | 每个 Peer 添加 PresharedKey | ☐ |
| 更换默认端口 | 不使用 51820 | ☐ |
| 开启 IP 转发 | net.ipv4.ip_forward=1 | ☐ |
| 防火墙放行 UDP | ufw allow <port>/udp | ☐ |
| 定期更换密钥 | 每 6-12 个月更换密钥对 | ☐ |
| 禁用不用的 Peer | 删除离职人员的 Peer | ☐ |
| 审计日志 | 定期检查 wg show | ☐ |
| 系统更新 | 保持内核和 wireguard-tools 最新 | ☐ |
九、与 Hysteria2 / VLESS Reality 对比
9.1 定位差异
| 维度 | WireGuard | Hysteria2 | VLESS Reality |
|---|---|---|---|
| 核心定位 | 私有网络组网 | 翻墙抗审查 | 翻墙抗审查 |
| 协议类型 | VPN 隧道 | 代理协议 | 代理协议 |
| 流量伪装 | 无 | HTTP/3 伪装 | TLS 1.3 伪装 |
| 抗封锁能力 | 弱 | 强 | 极强 |
| UDP 支持 | 原生 | 原生(基于 QUIC) | 不支持 |
| 多路复用 | 不支持 | 原生(QUIC Stream) | 支持 |
| 分流规则 | 不支持(靠路由表) | 支持(客户端配置) | 支持(客户端配置) |
| 典型用途 | 组网/远程办公 | 翻墙/科学上网 | 翻墙/科学上网 |
9.2 性能对比
| 指标 | WireGuard | Hysteria2 | VLESS Reality |
|---|---|---|---|
| 延迟(直连) | 最低 | 低 | 中 |
| 延迟(高丢包) | 差(UDP 无纠错) | 最好(QUIC 纠错) | 差(TCP) |
| 吞吐量 | 最高(内核级) | 高 | 中 |
| CPU 占用 | 最低(内核级) | 中 | 中 |
| 内存占用 | 最低 | 中 | 中 |
9.3 选型建议
你的需求是什么?│├─ 翻墙/科学上网│ ├─ 网络环境差(高丢包/移动网络)→ Hysteria2│ ├─ 网络环境好/高对抗 → VLESS Reality│ └─ 两者都有 → 搭配使用,客户端按规则切换│├─ 组建私有网络│ ├─ 异地组网/多 VPS 互联 → WireGuard│ ├─ 远程办公连公司内网 → WireGuard│ └─ 手机访问家里 NAS → WireGuard│└─ 两者都需要 ├─ 翻墙用 Hysteria2/VLESS(代理协议) └─ 组网用 WireGuard(VPN 隧道) └─ 可以同时运行,互不干扰十、一键部署脚本
以下脚本在全新 Ubuntu 22.04/24.04 服务器上一键部署 WireGuard 服务端:
#!/bin/bash# WireGuard VPN 一键安装脚本# 用法: sudo bash wireguard-install.sh
set -e
# 检查 root 权限if [ "$EUID" -ne 0 ]; then echo "请使用 root 权限运行: sudo bash $0" exit 1fi
# 获取服务器公网 IPSERVER_PUB_IP=$(curl -s -4 ifconfig.me)echo "服务器公网 IP: $SERVER_PUB_IP"
# 获取端口read -p "WireGuard 端口 [51820]: " SERVER_PORTSERVER_PORT=${SERVER_PORT:-51820}
# 获取 VPN 网段read -p "VPN 内网网段 [10.0.0.0/24]: " VPN_SUBNETVPN_SUBNET=${VPN_SUBNET:-10.0.0.0/24}VPN_SERVER_IP=$(echo $VPN_SUBNET | sed 's/0\/24/1\/24/')
# 获取第一个客户端 IPVPN_CLIENT_IP=$(echo $VPN_SUBNET | sed 's/0\/24/2\/32/')
# 获取 DNSread -p "客户端 DNS [1.1.1.1,8.8.8.8]: " CLIENT_DNSCLIENT_DNS=${CLIENT_DNS:-1.1.1.1,8.8.8.8}
echo ""echo "========== 开始安装 =========="
# 安装 WireGuardapt updateapt install -y wireguard wireguard-tools qrencode
# 生成服务端密钥cd /etc/wireguardwg genkey | tee server-private.key | wg pubkey > server-public.keychmod 600 server-private.key
# 生成客户端密钥wg genkey | tee client-private.key | wg pubkey > client-public.keychmod 600 client-private.key
SERVER_PRIVKEY=$(cat server-private.key)SERVER_PUBKEY=$(cat server-public.key)CLIENT_PRIVKEY=$(cat client-private.key)CLIENT_PUBKEY=$(cat client-public.key)
# 获取主网卡名称SERVER_NIC=$(ip route show default | awk '{print $5}' | head -1)echo "主网卡: $SERVER_NIC"
# 生成服务端配置cat > /etc/wireguard/wg0.conf << EOF[Interface]PrivateKey = $SERVER_PRIVKEYAddress = $VPN_SERVER_IPListenPort = $SERVER_PORTPostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o $SERVER_NIC -j MASQUERADEPostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o $SERVER_NIC -j MASQUERADE
[Peer]PublicKey = $CLIENT_PUBKEYAllowedIPs = $VPN_CLIENT_IPEOF
chmod 600 /etc/wireguard/wg0.conf
# 开启 IP 转发sed -i '/net.ipv4.ip_forward/d' /etc/sysctl.confecho "net.ipv4.ip_forward=1" >> /etc/sysctl.confsysctl -p
# 生成客户端配置cat > /etc/wireguard/client-wg0.conf << EOF[Interface]PrivateKey = $CLIENT_PRIVKEYAddress = $VPN_CLIENT_IPDNS = $CLIENT_DNS
[Peer]PublicKey = $SERVER_PUBKEYEndpoint = $SERVER_PUB_IP:$SERVER_PORTAllowedIPs = 0.0.0.0/0PersistentKeepalive = 25EOF
# 启动 WireGuardwg-quick up wg0systemctl enable wg-quick@wg0
# 防火墙if command -v ufw &> /dev/null; then ufw allow $SERVER_PORT/udp echo "UFW 已放行 $SERVER_PORT/udp"fi
echo ""echo "========== 安装完成 =========="echo ""echo "服务端配置: /etc/wireguard/wg0.conf"echo "客户端配置: /etc/wireguard/client-wg0.conf"echo ""echo "客户端二维码(手机扫码导入):"qrencode -t ansiutf8 /etc/wireguard/client-wg0.confecho ""echo "管理命令:"echo " 启动: wg-quick up wg0"echo " 停止: wg-quick down wg0"echo " 状态: wg show"echo " 重启: systemctl restart wg-quick@wg0"使用方法:
# 下载并运行wget -O wireguard-install.sh https://raw.githubusercontent.com/your-repo/wireguard-install.shsudo bash wireguard-install.sh十一、常见问题排查
问题 1:客户端无法连接
症状: wg show 显示 latest handshake 为 (none) 或超过 3 分钟
排查步骤:
# 1. 检查服务端是否在监听ss -ulnp | grep 51820# 如果没有输出,说明服务端未启动wg-quick up wg0
# 2. 检查防火墙是否放行 UDP 端口ufw status | grep 51820# 或iptables -L INPUT -n | grep 51820
# 3. 检查公钥是否匹配# 服务端的 [Peer] PublicKey 应该是客户端的公钥# 客户端的 [Peer] PublicKey 应该是服务端的公钥wg show # 查看服务端# 在客户端也运行 wg show
# 4. 检查 Endpoint 地址是否正确# 客户端配置中的 Endpoint 应该是服务端的公网 IP
# 5. 使用 tcpdump 抓包确认tcpdump -i any udp port 51820 -nn# 在客户端发起连接,看服务端是否收到包问题 2:能连接但无法上网
症状: ping 10.0.0.1 通,但 ping 8.8.8.8 不通
原因: IP 转发未开启或 NAT 规则有问题
# 1. 检查 IP 转发sysctl net.ipv4.ip_forward# 应输出: net.ipv4.ip_forward = 1
# 2. 检查 NAT 规则iptables -t nat -L POSTROUTING -n# 应看到 MASQUERADE 规则
# 3. 检查 FORWARD 链iptables -L FORWARD -n# 应看到 ACCEPT 规则
# 4. 检查网卡名称# PostUp 中的 -o eth0 需要匹配实际网卡名ip route show default# 输出: default via X.X.X.X dev eth0 ← 这里的 eth0问题 3:连接不稳定,频繁断开
症状: 每隔几分钟断一次
解决方案:
# 1. 添加 PersistentKeepalive# 在客户端 [Peer] 段添加PersistentKeepalive = 25
# 2. 检查 MTU# 降低 MTU 试试# 在 [Interface] 段添加MTU = 1280
# 3. 检查是否多个客户端用了相同的 VPN IP# 每个 Peer 的 AllowedIPs 必须唯一问题 4:AllowedIPs 冲突
症状: 添加新 Peer 后,其他 Peer 断连
原因: 两个 Peer 的 AllowedIPs 重叠
# 查看所有 Peer 的 AllowedIPswg show wg0 | grep -A2 "peer"
# 确保每个 Peer 的 AllowedIPs 是不同的 /32 IP# 错误: Peer A = 10.0.0.2/32, Peer B = 10.0.0.2/32# 正确: Peer A = 10.0.0.2/32, Peer B = 10.0.0.3/32问题 5:客户端配置 AllowedIPs = 0.0.0.0/0 后 SSH 断开
原因: 全局代理后,SSH 回包也走 VPN 隧道,但 VPN 还没建立
解决方案:
# 方案 1: Split Tunneling - 排除服务端公网 IP# 不要用 0.0.0.0/0,而是排除服务端 IP# 在 [Interface] 段添加Table = off# 然后手动添加路由PostUp = ip route add 0.0.0.0/0 dev wg0PostDown = ip route del 0.0.0.0/0 dev wg0
# 方案 2: 使用 Kill Switch 但允许 SSH 端口# 见第六章 Kill Switch 配置
# 方案 3: 先 SSH 到 VPN 内网 IP 再开启全局代理问题 6:Docker 与 WireGuard 冲突
症状: 启动 WireGuard 后 Docker 容器网络异常
原因: WireGuard 的 PostUp iptables 规则与 Docker 的 iptables 规则冲突
解决方案:
# 1. 将 WireGuard 规则插入 DOCKER-USER 链(而不是默认的 FORWARD)# 修改 PostUp:PostUp = iptables -I DOCKER-USER -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADEPostDown = iptables -D DOCKER-USER -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# 2. 或者使用 Docker 网络与 WireGuard 分离# WireGuard 监听 wg0 接口,Docker 使用默认 bridge# 通过路由让 Docker 容器走 wg0问题 7:wg-quick 启动报错 RTNETLINK answers: Operation not permitted
原因: 在容器或 LXC 中运行,缺少 NET_ADMIN 权限
# Docker 中运行需要:docker run --cap-add=NET_ADMIN --cap-add=SYS_MODULE ...
# LXC 中需要在宿主机配置:# /etc/pve/lxc/<CTID>.conflxc.cgroup2.devices.allow: c 10:200 rwmlxc.mount.entry: /dev/net dev/net none bind,create=dirlxc.cap.drop:常见错误速查表
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
Cannot find device "wg0" | 内核不支持 WireGuard | 安装 wireguard-dkms 或升级内核 |
RTNETLINK answers: Permission denied | 缺少权限 | 使用 root 或 sudo |
RTNETLINK answers: Operation not permitted | 容器缺少 NET_ADMIN | 添加 --cap-add=NET_ADMIN |
Key is not the correct length | 密钥格式错误 | 重新生成密钥 wg genkey |
No such file or directory | 配置文件不存在 | 检查 /etc/wireguard/wg0.conf |
Address already in use | 端口被占用 | 更换 ListenPort |
Invalid argument | AllowedIPs 格式错误 | 确保用逗号分隔,如 10.0.0.0/24, 172.16.0.0/16 |
Endpoint resolution failed | 域名无法解析 | 使用 IP 地址或检查 DNS |
十二、wg 命令速查
12.1 接口管理
# 查看所有接口wg show all
# 查看指定接口wg show wg0
# 简洁输出wg show wg0 brief
# JSON 输出wg show wg0 json
# dump 格式(适合脚本处理)wg show wg0 dump12.2 Peer 管理
# 添加 Peerwg set wg0 peer <public-key> allowed-ips 10.0.0.2/32
# 添加 Peer 并指定端点wg set wg0 peer <public-key> allowed-ips 10.0.0.2/32 endpoint 203.0.113.50:51820
# 添加 PSKwg set wg0 peer <public-key> preshared-key /etc/wireguard/psk.txt allowed-ips 10.0.0.2/32
# 删除 Peerwg set wg0 peer <public-key> remove
# 修改 AllowedIPswg set wg0 peer <public-key> allowed-ips 10.0.0.2/32,10.0.0.3/32
# 设置 PersistentKeepalivewg set wg0 peer <public-key> persistent-keepalive 2512.3 统计与监控
# 查看流量统计wg show wg0 transfer# 输出: <peer-pubkey> <rx-bytes> <tx-bytes>
# 查看握手时间wg show wg0 latest-handshakes# 输出: <peer-pubkey> <unix-timestamp>
# 查看端点wg show wg0 endpoints# 输出: <peer-pubkey> <ip:port>12.4 配置同步
# 从配置文件同步(不重启接口)wg syncconf wg0 <(wg-quick strip wg0)
# 导出当前运行配置wg showconf wg0 > /etc/wireguard/wg0.conf.bak
# 从备份恢复wg setconf wg0 /etc/wireguard/wg0.conf.bak十三、生产级完整配置模板
13.1 服务端模板
# WireGuard 服务端生产级配置
[Interface]PrivateKey = <SERVER_PRIVATE_KEY>Address = 10.0.0.1/24ListenPort = 51820
# MTU(默认 1420,网络差时调低)MTU = 1420
# NAT 转发 - 让客户端能上网# 注意: eth0 替换为实际网卡名(用 ip route show default 查看)PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADEPostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# === 客户端 Peers ===
# 客户端 1 - Alice[Peer]PublicKey = <ALICE_PUBLIC_KEY>PresharedKey = <PSK_FOR_ALICE>AllowedIPs = 10.0.0.2/32
# 客户端 2 - Bob[Peer]PublicKey = <BOB_PUBLIC_KEY>PresharedKey = <PSK_FOR_BOB>AllowedIPs = 10.0.0.3/32
# 客户端 3 - 手机[Peer]PublicKey = <PHONE_PUBLIC_KEY>AllowedIPs = 10.0.0.4/3213.2 客户端模板(全局代理)
# client-wg0.conf# WireGuard 客户端 - 全局代理模式
[Interface]PrivateKey = <CLIENT_PRIVATE_KEY>Address = 10.0.0.2/24DNS = 1.1.1.1, 8.8.8.8MTU = 1420
[Peer]PublicKey = <SERVER_PUBLIC_KEY>PresharedKey = <PSK>Endpoint = <SERVER_PUBLIC_IP>:51820AllowedIPs = 0.0.0.0/0PersistentKeepalive = 2513.3 客户端模板(Split Tunneling)
# client-wg0.conf# WireGuard 客户端 - 分流模式(只走内网流量)
[Interface]PrivateKey = <CLIENT_PRIVATE_KEY>Address = 10.0.0.2/24DNS = 1.1.1.1
[Peer]PublicKey = <SERVER_PUBLIC_KEY>Endpoint = <SERVER_PUBLIC_IP>:51820# 只走 VPN 内网和远程局域网AllowedIPs = 10.0.0.0/24, 192.168.1.0/24PersistentKeepalive = 2513.4 站点到站点模板
# 站点 A 网关配置[Interface]PrivateKey = <SITE_A_PRIVATE_KEY>Address = 10.10.0.1/30ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPTPostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT
[Peer]PublicKey = <SITE_B_PUBLIC_KEY>Endpoint = <SITE_B_PUBLIC_IP>:51820AllowedIPs = 10.10.0.2/32, 192.168.2.0/24PersistentKeepalive = 25十四、最佳实践
14.1 核心原则
- 密钥安全:私钥文件权限 600,不要提交到 Git,不要通过不安全渠道传输
- 每用户独立密钥:不要多人共用一个密钥对,方便管理和撤销
- AllowedIPs 不重叠:服务端每个 Peer 的 AllowedIPs 必须唯一
- 客户端加 PersistentKeepalive:NAT 后面的客户端必须设置,否则断连
- 开启 IP 转发:服务端必须
net.ipv4.ip_forward=1 - 防火墙只开 UDP:WireGuard 不使用 TCP,不要开 TCP 端口
- 定期审计:
wg show检查谁在用,删除不用的 Peer - 备份配置:定期备份
/etc/wireguard/目录 - 监控告警:关键节点用 Prometheus + wgc-exporter 监控
- 保持更新:WireGuard 在内核中,保持系统更新即可
14.2 场景推荐
| 场景 | 推荐方案 | 配置要点 |
|---|---|---|
| 个人远程办公 | 1 服务端 + 1 客户端 | AllowedIPs=0.0.0.0/0, Kill Switch |
| 团队 VPN | 1 服务端 + N 客户端 | wg-easy 管理面板, 每人独立密钥 |
| 异地组网 | Full Mesh | 每节点 ListenPort + 互为 Peer |
| 站点到站点 | Hub-Spoke 或 Full Mesh | PostUp 添加 FORWARD 规则 |
| 手机访问 NAS | 1 服务端 + 手机客户端 | PersistentKeepalive=25, Split Tunneling |
| 多云互联 | Full Mesh | 每台 VPS 互为 Peer |
| 临时访问 | Tailscale(零配置) | 不需要自建,扫码即用 |
14.3 学习路径
| 阶段 | 目标 | 操作 |
|---|---|---|
| 第 1 天 | 跑通基本连接 | 一键脚本部署,客户端连接成功 |
| 第 2 天 | 理解配置 | 手动编写 wg0.conf,理解每个字段 |
| 第 3 天 | 多用户管理 | 手动添加 3 个 Peer,使用 wg set 命令 |
| 第 4 天 | 分流与安全 | Split Tunneling + Kill Switch + PSK |
| 第 5 天 | 站点到站点 | 连接两个局域网,内网互通 |
| 第 6 天 | 自动化运维 | wg-easy 面板 + 监控告警 |
| 第 7 天 | 高级场景 | Full Mesh 组网 + IPv6 + 性能调优 |
十五、总结
WireGuard 的核心价值可以归纳为三点:
| 价值 | 说明 |
|---|---|
| 简单 | 一个配置文件,一对密钥,一条命令启动 |
| 快速 | 内核级运行,吞吐量比 OpenVPN 高 2-5 倍 |
| 安全 | 现代加密套件,前向保密,代码量小易审计 |
记住三个核心概念:
- Cryptokey Routing — AllowedIPs 既是路由表又是 ACL,一石二鸟
- 无状态设计 — 没有「连接」概念,IP 漫游无感知
- 固定加密套件 — 不支持协商,没有降级攻击
选择决策树:
需要 VPN 吗?├─ 翻墙 → Hysteria2(弱网)/ VLESS Reality(高对抗)└─ 组网 → WireGuard ├─ 2-3 个节点 → Full Mesh ├─ 5+ 个节点 → Hub-Spoke + wg-easy └─ 不想自建 → Tailscale推荐阅读
- WireGuard 官方文档
- WireGuard 白皮书
- 《Linux 防火墙完全指南》 — WireGuard 离不开的防火墙配置
- 《systemd 服务管理完全指南》 — wg-quick 的底层管理
- 《SSH 完全指南》 — 远程端口转发是 WireGuard 的替代方案
- 《Hysteria2 协议完全指南》 — 翻墙场景的协议选择
- 《VLESS Reality 协议完全指南》 — 抗审查场景的协议选择