9104 字
46 分钟

WireGuard VPN 自建完全指南:协议原理、服务端部署到全平台客户端配置 | 2026 最新实践

你有没有遇到过这些场景:

  • 公司有内网系统,在家办公连不上,想搞个 VPN 回去
  • 几台分散在不同地方的 VPS,想组成一个内网互相访问
  • 手机在外面想访问家里的 NAS,但不想暴露端口到公网
  • 试过 OpenVPN,配置证书搞了一下午还没通
  • 听说 WireGuard 很快很安全,但不知道怎么搭

WireGuard 就是解决这些问题的现代 VPN 方案——代码量仅 4000 行,性能比 OpenVPN 快 2-5 倍,配置一个文件就能跑通。

与 Hysteria2、VLESS Reality 这类抗审查代理协议不同,WireGuard 的核心定位是组建私有网络——异地组网、远程办公、内网穿透、站点到站点互联,这些才是它的主场。

WireGuard VPN 自建完全指南

阅读提示

本文与站内其他文章互补:《Hysteria2 协议完全指南》 聚焦翻墙抗审查,《VLESS Reality 协议完全指南》 聚焦流量伪装,本文聚焦 WireGuard 组建私有网络。如果目标是翻墙,建议优先阅读前两篇;如果目标是组网/远程访问,本文是正确起点。

相关阅读:《Linux 防火墙完全指南》(WireGuard 需要防火墙配合)、《systemd 服务管理完全指南》(wg-quick 本质是 systemd 服务)、《SSH 完全指南》(远程端口转发替代方案)。


一、WireGuard 是什么#

1.1 一句话定义#

WireGuard 是一种现代的、快速的、安全的 VPN 隧道协议,代码量约 4000 行,使用现代加密算法,已集成到 Linux 内核(5.6+)。

1.2 与其他 VPN 协议对比#

特性WireGuardOpenVPNIPSec/IKEv2Hysteria2VLESS Reality
代码量~4000 行~100,000 行~600,000 行~15,000 行~30,000 行
传输协议UDPTCP/UDPUDPUDP (QUIC)TCP
加密ChaCha20-Poly1305AES (OpenSSL)AES/CamelliaChaCha20-Poly1305AES/XTS
密钥交换Curve25519RSA/DHDHX25519X25519
性能极快(内核级)慢(用户态)快(内核级)中等
配置复杂度低(一个 conf)高(证书体系)高(策略配置)
抗审查极强
NAT 穿透原生支持需额外配置支持原生支持不适用
IP 漫游原生支持不支持部分不适用不适用
内核集成是(5.6+)
适用场景组网/VPN传统 VPN企业 VPN翻墙翻墙

1.3 核心设计哲学#

WireGuard 的设计遵循三个原则:

1. 简单性(Simplicity)

# 一个完整的 WireGuard 服务端配置,就这么几行
[Interface]
PrivateKey = <server-private-key>
Address = 10.0.0.1/24
ListenPort = 51820
[Peer]
PublicKey = <client-public-key>
AllowedIPs = 10.0.0.2/32

没有证书链、没有 CA、没有协商参数。一对密钥、一个端口、一个配置文件。

2. 加密保守主义(Cryptographic Victimhood)

WireGuard 不允许用户选择加密算法——它固定使用一组经过验证的现代加密套件:

组件算法说明
对称加密ChaCha20-Poly1305AEAD,比 AES 在移动端更快
密钥交换Curve25519 (X25519)ECDH,比 RSA 更短更快
哈希BLAKE2s比 SHA-2 更快
MACBLAKE2s用于握手认证
HKDFHMAC-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 │ │
│ └────────────────────────────────────────┘ │
└─────────────────────────────────────────────┘

工作流程:

  1. 发送方向:当内核要发送一个 IP 包到 10.0.0.2,查找路由表发现 10.0.0.2/32 属于 Peer A,用 Peer A 的公钥加密后发送到 Peer A 的端点
  2. 接收方向:收到一个加密包,解密后得到源 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 位的对称密钥,在握手时混入密钥派生过程:

Terminal window
# 生成 PSK
wg 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(提供 wgwg-quick 命令)
网络公网 IP + UDP 端口(默认 51820)
权限root(需要创建网络接口)

3.2 安装#

Ubuntu / Debian(内核 5.6+):

Terminal window
apt update
apt install -y wireguard wireguard-tools

CentOS / RHEL / Fedora:

Terminal window
dnf install -y epel-release
dnf install -y wireguard-tools

低版本内核(< 5.6)安装 wireguard-dkms:

Terminal window
# Ubuntu 18.04 等旧系统
apt install -y wireguard-dkms wireguard-tools
# 需要 DKMS 和内核头文件
apt install -y dkms linux-headers-$(uname -r)

验证安装:

Terminal window
# 检查内核模块
modprobe wireguard && echo "OK" || echo "FAIL"
# 检查工具
wg --version
# 输出示例: wireguard-tools v1.0.20210914 - amneziawg-tools v1.0.20240227
# 检查 wg-quick
which wg-quick
# /usr/bin/wg-quick

3.3 生成密钥对#

Terminal window
# 创建配置目录
mkdir -p /etc/wireguard
cd /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.key
chmod 644 server-public.key

3.4 编写服务端配置#

Terminal window
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 内网 IP
AllowedIPs = 10.0.0.2/32
EOF
chmod 600 /etc/wireguard/wg0.conf

配置项详解:

字段说明示例
PrivateKey本机私钥yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=
Address本机 VPN 内网 IP10.0.0.1/24
ListenPortUDP 监听端口51820
PostUp接口启动后执行的命令iptables NAT 规则
PostDown接口停止后执行的命令清理 iptables 规则
PublicKey对端公钥GtL7fZc/bLnqZldpVofMCD6hDjrK9Ky0D24ZGFHdPzQ=
AllowedIPs对端可用的 IP 范围10.0.0.2/32

3.5 开启 IP 转发#

如果要让客户端通过 VPN 上网,必须开启 IP 转发:

Terminal window
# 临时开启
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv6.conf.all.forwarding=1
# 永久开启
cat >> /etc/sysctl.conf << EOF
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
EOF
# 应用
sysctl -p

3.6 防火墙配置#

开放 UDP 端口:

Terminal window
# UFW
ufw allow 51820/udp
ufw reload
# firewalld
firewall-cmd --permanent --add-port=51820/udp
firewall-cmd --reload
# iptables
iptables -A INPUT -p udp --dport 51820 -j ACCEPT

⚠️ 注意:WireGuard 使用 UDP 协议,开放端口时必须指定 /udp,否则防火墙不会放行。

允许 WireGuard 接口转发:

Terminal window
# 允许 wg0 接口的转发流量
iptables -A FORWARD -i wg0 -j ACCEPT
iptables -A FORWARD -o wg0 -j ACCEPT

详细防火墙配置参见 《Linux 防火墙完全指南》

3.7 启动服务#

Terminal window
# 手动启动
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@wg0
systemctl status wg-quick@wg0

wg-quick@.service 说明:

wg-quick@wg0.service 是一个 systemd 模板服务,@ 后面的 wg0 对应 /etc/wireguard/wg0.conf。如果要创建第二个接口 wg1,配置文件为 /etc/wireguard/wg1.conf,服务名为 wg-quick@wg1.service

详见 《systemd 服务管理完全指南》

3.8 验证服务端运行#

Terminal window
# 检查接口状态
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 生成客户端密钥#

任意一台机器上生成客户端密钥(也可以在服务端生成):

Terminal window
# 生成客户端密钥对
wg genkey | tee client-private.key | wg pubkey > client-public.key
# 查看客户端公钥(需要填入服务端配置)
cat client-public.key
# 输出示例: xT5tA9p7K3mF2qR8sN4vL6wY1cB0hJ3gD5eU7iO2pA=

将客户端公钥填入服务端配置:

Terminal window
# 编辑服务端配置
nano /etc/wireguard/wg0.conf
# 将 <client-public-key> 替换为实际公钥
# PublicKey = xT5tA9p7K3mF2qR8sN4vL6wY1cB0hJ3gD5eU7iO2pA=
# 重启服务端使配置生效
wg-quick down wg0 && wg-quick up wg0

4.2 Linux 客户端#

Terminal window
# 安装工具
apt install -y wireguard-tools
# 创建客户端配置
cat > /etc/wireguard/wg0.conf << EOF
[Interface]
# 客户端私钥
PrivateKey = $(cat client-private.key)
# 客户端 VPN 内网 IP
Address = 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 = 25
EOF
# 启动
wg-quick up wg0
# 验证
wg show
ping 10.0.0.1 # ping 服务端 VPN IP

4.3 Windows 客户端#

方式一:官方客户端

  1. wireguard.com/install 下载 Windows 安装包
  2. 安装后打开 WireGuard 应用
  3. 点击「导入 tunnel(s) from file」→ 选择 .conf 配置文件
  4. 或点击「Add Tunnel」→ 「Add empty tunnel」→ 手动粘贴配置

客户端配置文件:

[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

方式二:生成二维码(方便手机扫描)

在 Linux 服务端上:

Terminal window
apt install -y qrencode
qrencode -t ansiutf8 /etc/wireguard/client-wg0.conf
# 会在终端打印二维码,手机扫码即可导入

4.4 macOS 客户端#

方式一:App Store

从 Mac App Store 搜索安装 WireGuard。

方式二:Homebrew

Terminal window
brew install wireguard-tools
# 配置文件放在 /usr/local/etc/wireguard/wg0.conf(Intel)
# 或 /opt/homebrew/etc/wireguard/wg0.conf(Apple Silicon)
mkdir -p /opt/homebrew/etc/wireguard
cat > /opt/homebrew/etc/wireguard/wg0.conf << EOF
[Interface]
PrivateKey = <client-private-key>
Address = 10.0.0.2/24
DNS = 1.1.1.1
[Peer]
PublicKey = <server-public-key>
Endpoint = <server-public-ip>:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF
# 启动
wg-quick up wg0

4.5 iOS 客户端#

  1. App Store 搜索安装 WireGuard
  2. 打开 App → 右上角「+」→ 「Scan QR code」
  3. 扫描在服务端生成的二维码
  4. 或手动输入配置

4.6 Android 客户端#

  1. Google Play 或 F-Droid 搜索安装 WireGuard
  2. 打开 App → 右上角「+」→ 「Scan QR code」或 「Import from file」
  3. 连接即可

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] 段即可:

Terminal window
# 为每个用户生成密钥对
cd /etc/wireguard
# 用户 Alice
wg genkey | tee alice-private.key | wg pubkey > alice-public.key
# 用户 Bob
wg genkey | tee bob-private.key | wg pubkey > bob-public.key
# 用户 Charlie
wg genkey | tee charlie-private.key | wg pubkey > charlie-public.key

服务端配置(多用户):

[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 MASQUERADE
PostDown = 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 无法正确路由。

应用配置变更(不需要重启):

Terminal window
# 使用 wg syncconf 热加载配置(不断开现有连接)
wg syncconf wg0 <(wg-quick strip wg0)
# 或使用 wg set 命令动态添加 Peer
wg set wg0 peer <alice-public-key> allowed-ips 10.0.0.2/32

5.2 客户端配置生成脚本#

为每个用户生成独立的客户端配置文件:

generate-client.sh
#!/bin/bash
# 用法: ./generate-client.sh <username> <vpn-ip>
USERNAME=$1
VPN_IP=$2
SERVER_PUBKEY=$(cat /etc/wireguard/server-public.key)
SERVER_PUBLIC_IP="203.0.113.100" # 替换为你的服务器公网 IP
PORT=51820
# 生成密钥
cd /etc/wireguard
wg genkey | tee ${USERNAME}-private.key | wg pubkey > ${USERNAME}-public.key
PRIVKEY=$(cat ${USERNAME}-private.key)
# 生成客户端配置
cat > ${USERNAME}-client.conf << EOF
[Interface]
PrivateKey = ${PRIVKEY}
Address = ${VPN_IP}/24
DNS = 1.1.1.1, 8.8.8.8
[Peer]
PublicKey = ${SERVER_PUBKEY}
Endpoint = ${SERVER_PUBLIC_IP}:${PORT}
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF
# 生成二维码
qrencode -t ansiutf8 ${USERNAME}-client.conf
echo "客户端配置已生成: ${USERNAME}-client.conf"
echo "请将以下公钥添加到服务端配置:"
cat ${USERNAME}-public.key
echo ""
echo "在服务端 [Peer] 段中添加:"
echo "[Peer]"
echo "PublicKey = $(cat ${USERNAME}-public.key)"
echo "AllowedIPs = ${VPN_IP}/32"

5.3 使用 wg-easy Web 管理面板#

对于多用户场景,手动管理密钥很繁琐。wg-easy 是最流行的 WireGuard Web 管理面板:

Terminal window
# 使用 Docker 部署 wg-easy
docker 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:latest

wg-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 wg0
PostDown = ip route del 10.10.0.0/16 dev wg0
[Peer]
PublicKey = <server-public-key>
Endpoint = 203.0.113.100:51820
AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 25

6.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 DROP
PostDown = 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:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

6.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/64
ListenPort = 51820
PostUp = 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 MASQUERADE
PostDown = 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]:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25

6.5 MTU 优化#

WireGuard 默认 MTU 为 1420(减去了 WireGuard 头部开销)。在某些网络环境下可能需要调整:

[Interface]
PrivateKey = <private-key>
Address = 10.0.0.1/24
# 降低 MTU 解决某些网络的包丢失问题
MTU = 1280
MTU 值适用场景
1420默认值,大多数情况适用
1280PPPoE / 嵌套隧道
1380某些云厂商内网

测试最佳 MTU:

Terminal window
# 在客户端 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/30
ListenPort = 51820
# 允许从 wg0 到 eth0 的转发
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT
PostDown = 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/24
PersistentKeepalive = 25

7.3 网关 B 配置#

[Interface]
PrivateKey = <gateway-b-private-key>
Address = 10.0.0.2/30
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT
PostDown = 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/24
PersistentKeepalive = 25

7.4 局域网设备路由#

方案一:静态路由(简单)

在站点 A 的局域网设备上添加到站点 B 的路由:

Terminal window
# Linux
ip route add 192.168.2.0/24 via 192.168.1.1
# macOS
sudo route -nv add 192.168.2.0/24 192.168.1.1

方案二:在网关上自动配置(推荐)

在网关 A 上添加 NAT 规则,让对端内网设备不需要额外配置:

# 网关 A 的 PostUp 中添加 SNAT
PostUp = 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 MASQUERADE
PostDown = 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.1
dhcp-option=121,192.168.2.0/24,192.168.1.1

7.5 多站点 Mesh 组网#

WireGuard 支持 Full Mesh 拓扑——每个节点都与其他所有节点直连:

节点 A
/ \
节点 B —— 节点 C
\ /
节点 D

每个节点配置中添加所有其他节点为 Peer:

# 节点 A 的配置
[Interface]
PrivateKey = <node-a-private-key>
Address = 10.0.0.1/24
ListenPort = 51820
[Peer]
# 节点 B
PublicKey = <node-b-public-key>
Endpoint = <node-b-ip>:51820
AllowedIPs = 10.0.0.2/32
PersistentKeepalive = 25
[Peer]
# 节点 C
PublicKey = <node-c-public-key>
Endpoint = <node-c-ip>:51820
AllowedIPs = 10.0.0.3/32
PersistentKeepalive = 25
[Peer]
# 节点 D
PublicKey = <node-d-public-key>
Endpoint = <node-d-ip>:51820
AllowedIPs = 10.0.0.4/32
PersistentKeepalive = 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#

Terminal window
# 生成 PSK
wg genpsk
# 输出: cGFzc3dvcmQxMjM0NTY3ODkwYWJjZGVmZ2hpamtsbW5vcA==

在服务端和客户端的 [Peer] 段中添加:

[Peer]
PublicKey = <peer-public-key>
PresharedKey = cGFzc3dvcmQxMjM0NTY3ODkwYWJjZGVmZ2hpamtsbW5vcA==
AllowedIPs = 10.0.0.2/32

8.2 更换默认端口#

[Interface]
ListenPort = 53982 # 不用默认 51820

8.3 限制源 IP 访问#

如果服务端有公网 IP 且客户端 IP 固定,可以限制只接受特定 IP 的连接:

Terminal window
# iptables 限制只有特定 IP 能连接 WireGuard 端口
iptables -A INPUT -p udp --dport 51820 -s 203.0.113.50 -j ACCEPT
iptables -A INPUT -p udp --dport 51820 -j DROP

⚠️ 注意:如果客户端在 NAT 后面或 IP 会变(如手机 4G),不要限制源 IP。

8.4 禁用 root 通过 VPN 登录#

Terminal window
# SSH 只允许从特定网卡(非 wg0)登录
# 编辑 /etc/ssh/sshd_config
Match Address 10.0.0.*
PermitRootLogin no
PasswordAuthentication no

8.5 审计与监控#

Terminal window
# 查看所有 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/wgexporter

8.6 安全清单#

项目说明状态
私钥权限 600chmod 600 /etc/wireguard/*.key
配置文件权限 600chmod 600 /etc/wireguard/wg0.conf
启用 PSK每个 Peer 添加 PresharedKey
更换默认端口不使用 51820
开启 IP 转发net.ipv4.ip_forward=1
防火墙放行 UDPufw allow <port>/udp
定期更换密钥每 6-12 个月更换密钥对
禁用不用的 Peer删除离职人员的 Peer
审计日志定期检查 wg show
系统更新保持内核和 wireguard-tools 最新

九、与 Hysteria2 / VLESS Reality 对比#

9.1 定位差异#

维度WireGuardHysteria2VLESS Reality
核心定位私有网络组网翻墙抗审查翻墙抗审查
协议类型VPN 隧道代理协议代理协议
流量伪装HTTP/3 伪装TLS 1.3 伪装
抗封锁能力极强
UDP 支持原生原生(基于 QUIC)不支持
多路复用不支持原生(QUIC Stream)支持
分流规则不支持(靠路由表)支持(客户端配置)支持(客户端配置)
典型用途组网/远程办公翻墙/科学上网翻墙/科学上网

9.2 性能对比#

指标WireGuardHysteria2VLESS 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 服务端:

wireguard-install.sh
#!/bin/bash
# WireGuard VPN 一键安装脚本
# 用法: sudo bash wireguard-install.sh
set -e
# 检查 root 权限
if [ "$EUID" -ne 0 ]; then
echo "请使用 root 权限运行: sudo bash $0"
exit 1
fi
# 获取服务器公网 IP
SERVER_PUB_IP=$(curl -s -4 ifconfig.me)
echo "服务器公网 IP: $SERVER_PUB_IP"
# 获取端口
read -p "WireGuard 端口 [51820]: " SERVER_PORT
SERVER_PORT=${SERVER_PORT:-51820}
# 获取 VPN 网段
read -p "VPN 内网网段 [10.0.0.0/24]: " VPN_SUBNET
VPN_SUBNET=${VPN_SUBNET:-10.0.0.0/24}
VPN_SERVER_IP=$(echo $VPN_SUBNET | sed 's/0\/24/1\/24/')
# 获取第一个客户端 IP
VPN_CLIENT_IP=$(echo $VPN_SUBNET | sed 's/0\/24/2\/32/')
# 获取 DNS
read -p "客户端 DNS [1.1.1.1,8.8.8.8]: " CLIENT_DNS
CLIENT_DNS=${CLIENT_DNS:-1.1.1.1,8.8.8.8}
echo ""
echo "========== 开始安装 =========="
# 安装 WireGuard
apt update
apt install -y wireguard wireguard-tools qrencode
# 生成服务端密钥
cd /etc/wireguard
wg genkey | tee server-private.key | wg pubkey > server-public.key
chmod 600 server-private.key
# 生成客户端密钥
wg genkey | tee client-private.key | wg pubkey > client-public.key
chmod 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_PRIVKEY
Address = $VPN_SERVER_IP
ListenPort = $SERVER_PORT
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o $SERVER_NIC -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o $SERVER_NIC -j MASQUERADE
[Peer]
PublicKey = $CLIENT_PUBKEY
AllowedIPs = $VPN_CLIENT_IP
EOF
chmod 600 /etc/wireguard/wg0.conf
# 开启 IP 转发
sed -i '/net.ipv4.ip_forward/d' /etc/sysctl.conf
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p
# 生成客户端配置
cat > /etc/wireguard/client-wg0.conf << EOF
[Interface]
PrivateKey = $CLIENT_PRIVKEY
Address = $VPN_CLIENT_IP
DNS = $CLIENT_DNS
[Peer]
PublicKey = $SERVER_PUBKEY
Endpoint = $SERVER_PUB_IP:$SERVER_PORT
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF
# 启动 WireGuard
wg-quick up wg0
systemctl 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.conf
echo ""
echo "管理命令:"
echo " 启动: wg-quick up wg0"
echo " 停止: wg-quick down wg0"
echo " 状态: wg show"
echo " 重启: systemctl restart wg-quick@wg0"

使用方法:

Terminal window
# 下载并运行
wget -O wireguard-install.sh https://raw.githubusercontent.com/your-repo/wireguard-install.sh
sudo bash wireguard-install.sh

十一、常见问题排查#

问题 1:客户端无法连接#

症状: wg show 显示 latest handshake(none) 或超过 3 分钟

排查步骤:

Terminal window
# 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 规则有问题

Terminal window
# 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:连接不稳定,频繁断开#

症状: 每隔几分钟断一次

解决方案:

Terminal window
# 1. 添加 PersistentKeepalive
# 在客户端 [Peer] 段添加
PersistentKeepalive = 25
# 2. 检查 MTU
# 降低 MTU 试试
# 在 [Interface] 段添加
MTU = 1280
# 3. 检查是否多个客户端用了相同的 VPN IP
# 每个 Peer 的 AllowedIPs 必须唯一

问题 4:AllowedIPs 冲突#

症状: 添加新 Peer 后,其他 Peer 断连

原因: 两个 Peer 的 AllowedIPs 重叠

Terminal window
# 查看所有 Peer 的 AllowedIPs
wg 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 还没建立

解决方案:

Terminal window
# 方案 1: Split Tunneling - 排除服务端公网 IP
# 不要用 0.0.0.0/0,而是排除服务端 IP
# 在 [Interface] 段添加
Table = off
# 然后手动添加路由
PostUp = ip route add 0.0.0.0/0 dev wg0
PostDown = 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 规则冲突

解决方案:

Terminal window
# 1. 将 WireGuard 规则插入 DOCKER-USER 链(而不是默认的 FORWARD)
# 修改 PostUp:
PostUp = iptables -I DOCKER-USER -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = 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

原因: 在容器或 LXC 中运行,缺少 NET_ADMIN 权限

Terminal window
# Docker 中运行需要:
docker run --cap-add=NET_ADMIN --cap-add=SYS_MODULE ...
# LXC 中需要在宿主机配置:
# /etc/pve/lxc/<CTID>.conf
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net dev/net none bind,create=dir
lxc.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 argumentAllowedIPs 格式错误确保用逗号分隔,如 10.0.0.0/24, 172.16.0.0/16
Endpoint resolution failed域名无法解析使用 IP 地址或检查 DNS

十二、wg 命令速查#

12.1 接口管理#

Terminal window
# 查看所有接口
wg show all
# 查看指定接口
wg show wg0
# 简洁输出
wg show wg0 brief
# JSON 输出
wg show wg0 json
# dump 格式(适合脚本处理)
wg show wg0 dump

12.2 Peer 管理#

Terminal window
# 添加 Peer
wg 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
# 添加 PSK
wg set wg0 peer <public-key> preshared-key /etc/wireguard/psk.txt allowed-ips 10.0.0.2/32
# 删除 Peer
wg set wg0 peer <public-key> remove
# 修改 AllowedIPs
wg set wg0 peer <public-key> allowed-ips 10.0.0.2/32,10.0.0.3/32
# 设置 PersistentKeepalive
wg set wg0 peer <public-key> persistent-keepalive 25

12.3 统计与监控#

Terminal window
# 查看流量统计
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 配置同步#

Terminal window
# 从配置文件同步(不重启接口)
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 服务端模板#

/etc/wireguard/wg0.conf
# WireGuard 服务端生产级配置
[Interface]
PrivateKey = <SERVER_PRIVATE_KEY>
Address = 10.0.0.1/24
ListenPort = 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 MASQUERADE
PostDown = 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/32

13.2 客户端模板(全局代理)#

# client-wg0.conf
# WireGuard 客户端 - 全局代理模式
[Interface]
PrivateKey = <CLIENT_PRIVATE_KEY>
Address = 10.0.0.2/24
DNS = 1.1.1.1, 8.8.8.8
MTU = 1420
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
PresharedKey = <PSK>
Endpoint = <SERVER_PUBLIC_IP>:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

13.3 客户端模板(Split Tunneling)#

# client-wg0.conf
# WireGuard 客户端 - 分流模式(只走内网流量)
[Interface]
PrivateKey = <CLIENT_PRIVATE_KEY>
Address = 10.0.0.2/24
DNS = 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/24
PersistentKeepalive = 25

13.4 站点到站点模板#

# 站点 A 网关配置
[Interface]
PrivateKey = <SITE_A_PRIVATE_KEY>
Address = 10.10.0.1/30
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT
PostDown = 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>:51820
AllowedIPs = 10.10.0.2/32, 192.168.2.0/24
PersistentKeepalive = 25

十四、最佳实践#

14.1 核心原则#

  1. 密钥安全:私钥文件权限 600,不要提交到 Git,不要通过不安全渠道传输
  2. 每用户独立密钥:不要多人共用一个密钥对,方便管理和撤销
  3. AllowedIPs 不重叠:服务端每个 Peer 的 AllowedIPs 必须唯一
  4. 客户端加 PersistentKeepalive:NAT 后面的客户端必须设置,否则断连
  5. 开启 IP 转发:服务端必须 net.ipv4.ip_forward=1
  6. 防火墙只开 UDP:WireGuard 不使用 TCP,不要开 TCP 端口
  7. 定期审计wg show 检查谁在用,删除不用的 Peer
  8. 备份配置:定期备份 /etc/wireguard/ 目录
  9. 监控告警:关键节点用 Prometheus + wgc-exporter 监控
  10. 保持更新:WireGuard 在内核中,保持系统更新即可

14.2 场景推荐#

场景推荐方案配置要点
个人远程办公1 服务端 + 1 客户端AllowedIPs=0.0.0.0/0, Kill Switch
团队 VPN1 服务端 + N 客户端wg-easy 管理面板, 每人独立密钥
异地组网Full Mesh每节点 ListenPort + 互为 Peer
站点到站点Hub-Spoke 或 Full MeshPostUp 添加 FORWARD 规则
手机访问 NAS1 服务端 + 手机客户端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 倍
安全现代加密套件,前向保密,代码量小易审计

记住三个核心概念:

  1. Cryptokey Routing — AllowedIPs 既是路由表又是 ACL,一石二鸟
  2. 无状态设计 — 没有「连接」概念,IP 漫游无感知
  3. 固定加密套件 — 不支持协商,没有降级攻击

选择决策树:

需要 VPN 吗?
├─ 翻墙 → Hysteria2(弱网)/ VLESS Reality(高对抗)
└─ 组网 → WireGuard
├─ 2-3 个节点 → Full Mesh
├─ 5+ 个节点 → Hub-Spoke + wg-easy
└─ 不想自建 → Tailscale

推荐阅读#

WireGuard VPN 自建完全指南:协议原理、服务端部署到全平台客户端配置 | 2026 最新实践
https://971918.xyz/posts/proxy-tools/wireguard-complete-guide/
作者
九所长
发布于
2026-07-10
许可协议
CC BY-NC-SA 4.0