WireGuard
WireGuard 是一种现代 VPN 协议,于 2015 年由 Jason A. Donenfeld 设计并开源,2020 年正式合并进 Linux 内核主线(5.6 版本)。它以极简的代码实现、优秀的性能和强健的加密设计著称,被普遍认为是目前最优秀的 VPN 协议之一。在代理软件生态中,WireGuard 通常以"出站隧道"的形式使用,或作为内网穿透和多跳代理的底层传输。
背景与地位
在 WireGuard 出现之前,主流的 VPN 协议是 OpenVPN 和 IPsec/IKEv2。这两种协议虽然功能完善,但都存在明显的缺陷:
- OpenVPN:基于 OpenSSL,代码量庞大(数十万行),配置复杂,性能受限于用户态实现
- IPsec:内核级实现,性能好,但协议本身极为复杂,配置和调试难度极高
WireGuard 的设计目标是"更简单、更快、更安全":
- 核心代码不到 4000 行,可以被单人在合理时间内完整审计
- 内核级实现,性能接近裸网卡转发速率
- 加密原语现代化,使用 Curve25519、ChaCha20-Poly1305、BLAKE2s 等当代密码学标准
- 无需繁琐的证书体系,使用简洁的密钥对认证
核心设计
密钥对认证
WireGuard 使用 Curve25519 椭圆曲线密钥对进行身份认证,类似 SSH 的公钥认证方式:
- 每一个 WireGuard 端点(Peer)拥有一对密钥:私钥(PrivateKey)和公钥(PublicKey)
- 公钥可以公开分享,私钥必须严格保密
- 两个端点要建立连接,只需要互相知道对方的公钥,以及对方的 IP 和端口
不需要 CA、不需要证书、不需要 PKI 体系。配置极为简洁。
静默连接建立
WireGuard 的握手过程极为简短(只有 2 条消息),且不会在握手阶段暴露任何可识别的身份信息。在连接建立之前,外界无法通过监听流量判断通信双方的身份。
此外,WireGuard 实现了"静默丢弃"机制:对于无法验证身份的入站数据包,直接静默丢弃,不返回任何响应。这使得端口扫描和主动探测无法确认 WireGuard 服务是否在运行。
基于 UDP 的传输
WireGuard 运行在 UDP 之上,这带来了以下特性:
- 没有 TCP 的连接状态,内核处理效率更高
- 天然支持连接迁移(IP 地址或端口变化时会话不中断)
- 在 UDP 可用的环境下,性能优于基于 TCP 的 VPN
缺点是在 UDP 被封锁或限速的网络中(如某些企业网络),WireGuard 无法正常工作。
固定加密算法
WireGuard 不像 TLS 那样支持协议协商,而是固定使用一套经过精心选择的现代密码学算法:
| 用途 | 算法 |
|---|---|
| 密钥交换 | Curve25519(ECDH) |
| 对称加密 | ChaCha20-Poly1305 |
| 哈希与 MAC | BLAKE2s |
| 密钥派生 | HKDF |
| 时间戳防护 | TAI64N |
固定算法消除了协议降级攻击的可能性,同时简化了实现复杂度。
路由即配置(Route-based)
WireGuard 使用 AllowedIPs 字段同时承担路由配置和访问控制两个功能:
- 入站:只有来自 AllowedIPs 范围内 IP 的数据包才会被接受
- 出站:发往 AllowedIPs 范围内 IP 的数据包会被自动路由到对应的 Peer
这种设计让 WireGuard 的路由配置非常直观:你只需要告诉它"哪些流量应该走这个隧道",而无需手动维护复杂的路由表。
WireGuard 在代理生态中的角色
在代理软件生态中,WireGuard 通常以以下几种方式出现:
出站隧道(常见)
Mihomo、sing-box 等代理软件支持将 WireGuard 作为一种"出站"类型,将部分或全部流量通过 WireGuard 隧道转发。这在以下场景中很有用:
- 将代理流量先走 WireGuard 隧道到达一台中间服务器,再由该服务器代理访问目标——实现双跳代理
- 访问某些仅允许从特定 IP 范围连接的服务
- 使用 Cloudflare WARP(其内部基于 WireGuard)作为出站,获得 Cloudflare 的 IP 优化
Cloudflare WARP
Cloudflare WARP 是基于 WireGuard 的消费级服务,提供免费的"零信任"流量加密。部分用户将 WARP 作为代理链的一环:
本地代理客户端(Mihomo/sing-box)
|
| 分流规则
|
v
WireGuard 出站(连接到 Cloudflare WARP)
|
v
目标服务器(通过 Cloudflare 网络访问)
这种方式可以让目标服务器看到 Cloudflare 的 IP,有时有助于访问某些对特定 IP 有优化的服务(如 ChatGPT、Netflix 等 Cloudflare 优化的服务)。
内网穿透
WireGuard 是目前内网穿透场景中最流行的 VPN 方案之一。通过在公网服务器上搭建 WireGuard 服务,可以将内网的多台设备组成一个虚拟局域网,实现跨网络的安全访问。
Tailscale / Headscale
Tailscale 是基于 WireGuard 构建的商业内网穿透服务,提供了自动 NAT 穿透、网状组网(Mesh Network)等高级功能。Headscale 是 Tailscale 控制平面的开源替代实现,可以自建控制节点。
优缺点
| 优点 | 缺点 |
|---|---|
| 代码极简(<4000 行),可被完整审计 | 基于 UDP,在 UDP 受限的网络中不可用 |
| 内核级实现,性能接近裸线速 | 不具备专门的流量混淆能力,WireGuard 流量特征明显 |
| 现代加密原语,安全性强 | 静态密钥对,轮换密钥需要人工操作 |
| 配置简单,无需证书体系 | 没有用户名/密码认证,只有密钥对 |
| 连接迁移支持,网络切换不断线 | 所有 Peer 的公钥必须预先配置,不适合大规模动态用户场景 |
| 已进入 Linux 内核主线,长期维护有保障 | 原生不支持 TCP,对需要穿越 HTTP 代理的场景不友好 |
| 低延迟,握手极快 | 流量特征明显(固定的 UDP 握手模式),容易被识别和封锁 |
与其他协议的对比
| 对比维度 | WireGuard | Hysteria 2 | VLESS + Reality | OpenVPN |
|---|---|---|---|---|
| 传输层 | UDP | UDP(QUIC) | TCP | TCP / UDP |
| 代码量 | 极少(<4000 行) | 较少 | 较少 | 庞大(数十万行) |
| 加密设计 | 固定现代算法 | TLS 1.3(QUIC) | TLS 1.3 | OpenSSL(可配置) |
| 流量混淆 | 无 | HTTP/3 伪装 | Reality 伪装 | 无(原生) |
| 抗封锁能力 | 弱(特征明显) | 较强 | 极强 | 弱 |
| 性能 | 极高(内核级) | 高 | 高 | 中 |
| 配置复杂度 | 低 | 低 | 中 | 高 |
| 适用场景 | VPN 组网、内网穿透 | 高丢包代理 | 高抗检测代理 | 企业 VPN |
适用场景
推荐使用 WireGuard 的场景:
- 组建私有 VPN 网络,连接多台服务器或设备
- 内网穿透,让外网设备访问内网服务
- 作为代理链的隧道层(如双跳代理)
- 使用 Tailscale / Headscale 组建去中心化的设备网格
- 在 UDP 畅通的网络环境中追求最高 VPN 性能
- 搭配 Mihomo、sing-box 使用 Cloudflare WARP 作为出站
不推荐在以下场景中依赖 WireGuard:
- 需要对抗 UDP 封锁或 WireGuard 协议特征检测(此时应使用专门的代理协议)
- 企业/校园网络中,UDP 出站被严格限制
- 需要隐藏流量特征,使其看起来像普通 HTTPS 浏览
关于 WireGuard 的抗检测能力
WireGuard 没有任何流量混淆机制,其握手数据包具有固定的特征,可以被 DPI 设备精准识别。在需要规避流量检测的场景下,WireGuard 不是合适的选择。此时应使用 VLESS + Reality、AnyTLS、Hysteria 2 等专门设计了流量伪装的代理协议。
WireGuard 的价值在于其作为 VPN 协议的性能和简洁性,而不在于抗检测能力。
服务端部署参考
前置条件
- 一台 Linux VPS(内核 5.6 或更高版本原生支持,旧版内核需要安装内核模块)
- 已开放目标 UDP 端口的防火墙规则
检查内核支持
modprobe wireguard && echo "WireGuard supported"
如果提示模块未找到,需要先安装 WireGuard 内核模块:
# Debian / Ubuntu
apt update && apt install wireguard
# CentOS / RHEL 8+
dnf install wireguard-tools
安装 WireGuard 工具
# Debian / Ubuntu
apt install wireguard-tools
# CentOS
dnf install wireguard-tools
生成密钥对
# 生成服务端私钥
wg genkey | tee /etc/wireguard/server_private.key
# 从私钥派生公钥
cat /etc/wireguard/server_private.key | wg pubkey | tee /etc/wireguard/server_public.key
# 生成客户端密钥对
wg genkey | tee /etc/wireguard/client_private.key
cat /etc/wireguard/client_private.key | wg pubkey | tee /etc/wireguard/client_public.key
# 保护私钥文件权限
chmod 600 /etc/wireguard/server_private.key /etc/wireguard/client_private.key
服务端配置文件(/etc/wireguard/wg0.conf)
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <server_private_key>
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]
# 客户端 1
PublicKey = <client1_public_key>
AllowedIPs = 10.0.0.2/32
配置字段说明:
| 字段 | 说明 |
|---|---|
Address | WireGuard 虚拟网卡的 IP 地址和子网 |
ListenPort | 服务端监听的 UDP 端口 |
PrivateKey | 服务端私钥,从文件中读取 |
PostUp | 接口启动后执行的命令(此处配置 NAT 转发) |
PostDown | 接口关闭后执行的命令(清理 NAT 规则) |
[Peer] | 每个客户端对应一个 Peer 块 |
PublicKey | 客户端公钥 |
AllowedIPs | 允许该 Peer 使用的 IP 范围(通常是其虚拟 IP) |
启用 IP 转发
WireGuard 作为 VPN 服务器时,需要开启 Linux 的 IP 转发功能:
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.conf
sysctl -p
启动 WireGuard
# 启动 wg0 接口
wg-quick up wg0
# 设置开机自启
systemctl enable wg-quick@wg0
# 查看状态
wg show
# 停止接口
wg-quick down wg0
开放防火墙
ufw allow 51820/udp
动态添加/删除 Peer
无需重启服务,即可动态添加或删除 Peer:
# 添加新 Peer
wg set wg0 peer <new_client_public_key> allowed-ips 10.0.0.3/32
# 删除 Peer
wg set wg0 peer <client_public_key> remove
# 保存当前配置到文件
wg-quick save wg0
客户端配置参考
Linux 客户端
客户端配置文件(/etc/wireguard/wg0.conf):
[Interface]
Address = 10.0.0.2/24
PrivateKey = <client_private_key>
DNS = 1.1.1.1
[Peer]
PublicKey = <server_public_key>
Endpoint = your.server.ip:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
AllowedIPs = 0.0.0.0/0 表示将所有流量路由到 VPN,即全局代理模式。如果只想代理特定流量,可以指定具体的 IP 段,例如 AllowedIPs = 10.0.0.0/24。
PersistentKeepalive = 25 表示每 25 秒发送一个保活数据包,用于维持 NAT 映射,适合位于 NAT 之后的客户端。
启动:
wg-quick up wg0
Windows 客户端
从 WireGuard 官网(https://www.wireguard.com/install/)下载 Windows 安装包,安装后在 GUI 中添加配置文件,配置内容与 Linux 客户端格式相同。
macOS 客户端
可以从 App Store 安装 WireGuard 应用,或通过 Homebrew 安装命令行工具:
brew install wireguard-tools
App Store 版本:在应用中导入配置文件,格式与 Linux 客户端相同。
iOS / Android 客户端
从 App Store 或 Google Play 下载官方 WireGuard 应用,支持扫描二维码导入配置或手动输入配置信息。
官方应用下载页面:https://www.wireguard.com/install/
在 Mihomo 中配置 WireGuard 出站
Mihomo(Clash Meta)原生支持 WireGuard 出站,可以将 WireGuard 作为代理链的一环:
proxies:
- name: "wg-tunnel"
type: wireguard
server: your.server.ip
port: 51820
ip: 10.0.0.2
private-key: "<client_private_key>"
public-key: "<server_public_key>"
dns: [1.1.1.1, 8.8.8.8]
mtu: 1420
allowed-ips:
- 0.0.0.0/0
在 sing-box 中配置 WireGuard 出站
{
"type": "wireguard",
"tag": "wg-tunnel",
"server": "your.server.ip",
"server_port": 51820,
"local_address": [
"10.0.0.2/24"
],
"private_key": "<client_private_key>",
"peer_public_key": "<server_public_key>",
"mtu": 1420
}
配置 Cloudflare WARP 出站(Mihomo)
Cloudflare WARP 使用 WireGuard 协议,可以通过第三方工具获取 WARP 账号的密钥信息后,在 Mihomo 中直接配置:
proxies:
- name: "warp"
type: wireguard
server: engage.cloudflareclient.com
port: 2408
ip: 172.16.0.2
ipv6: "2606:4700:110:xxxx:xxxx:xxxx:xxxx:xxxx"
private-key: "<warp_private_key>"
public-key: "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo="
reserved: [xx, xx, xx]
mtu: 1280
dialer-proxy: "your-proxy-node"
关于 WARP 密钥获取
Cloudflare WARP 的密钥需要通过 WARP 客户端注册账号后获取,或使用社区工具(如 warp-reg)自动完成注册并提取密钥。请参考社区的最新教程,此处不做详细展开。
高级配置
多跳(Multi-hop)设置
WireGuard 可以配置多跳,即流量先经过一个中间节点,再到达最终目标:
[Interface]
Address = 10.0.0.2/24
PrivateKey = <client_private_key>
# 第一跳:公网中间节点
[Peer]
PublicKey = <relay_server_public_key>
Endpoint = relay.server.ip:51820
AllowedIPs = 10.0.1.0/24 # 只将去往内网的流量路由到中间节点
PersistentKeepalive = 25
站点间隧道(Site-to-Site)
WireGuard 可以将两个不同网络的子网连接起来,实现透明的跨网络通信:
服务器 A(10.100.0.1/24):
[Interface]
Address = 10.0.0.1/30
PrivateKey = <server_a_private_key>
ListenPort = 51820
[Peer]
PublicKey = <server_b_public_key>
Endpoint = server_b.ip:51820
AllowedIPs = 10.0.0.2/32, 10.200.0.0/24 # 路由服务器 B 所在的子网
PersistentKeepalive = 25
服务器 B(10.200.0.1/24):
[Interface]
Address = 10.0.0.2/30
PrivateKey = <server_b_private_key>
ListenPort = 51820
[Peer]
PublicKey = <server_a_public_key>
Endpoint = server_a.ip:51820
AllowedIPs = 10.0.0.1/32, 10.100.0.0/24 # 路由服务器 A 所在的子网
PersistentKeepalive = 25
MTU 调优
WireGuard 会在原始数据包上增加约 60 字节的封装开销(IPv4)或 80 字节(IPv6)。如果外层链路的 MTU 是标准的 1500 字节,则 WireGuard 的 MTU 应设置为 1420(1500 - 60 - 20 的余量)。
如果外层链路本身是另一个隧道(如 PPPoE),MTU 可能更低,需要相应调整:
# 在 [Interface] 中设置
MTU = 1420
设置不当的 MTU 会导致大数据包被分片,严重影响性能。如果发现大文件传输速度异常,或某些页面无法加载,可以先尝试调低 MTU 排查。
客户端支持
| 平台 | 支持方式 |
|---|---|
| Linux | wg-quick(内核原生支持)、Mihomo、sing-box |
| Windows | 官方 GUI 客户端、v2rayN(通过 sing-box 内核) |
| macOS | 官方 App Store 应用、Homebrew 命令行工具、Mihomo、sing-box |
| iOS | 官方 App Store 应用、Shadowrocket、Loon、Surge(内置 WireGuard 支持) |
| Android | 官方 Google Play 应用、NekoBox、Husi、Exclave |
| 路由器 | OpenWrt(wireguard-tools 包)、padavan、Asuswrt-Merlin |
常见问题
Q:WireGuard 握手成功但没有流量,是什么原因?
常见原因:
- 服务端的 IP 转发未开启(
net.ipv4.ip_forward = 1) - iptables 的 NAT 规则未正确配置(PostUp 的 MASQUERADE 规则)
- 客户端的 AllowedIPs 配置与实际想路由的流量范围不匹配
- 服务端防火墙的 FORWARD 链默认拒绝,导致转发数据包被丢弃
Q:wg show 显示握手时间很久,甚至显示"(none)",说明握手未成功?
排查顺序:
- 确认服务端 UDP 端口已开放防火墙规则(
ufw allow 51820/udp) - 确认客户端的
Endpoint地址和端口正确 - 确认双端的公钥填写正确(服务端 Peer 中的公钥应为客户端公钥,反之亦然)
- 在服务端运行
tcpdump -i any udp port 51820确认是否有数据包到达
Q:PersistentKeepalive 应该设置多少?
通常设置为 25 秒。这个值的作用是维持 NAT 映射,防止 NAT 设备因超时而关闭映射。对于有固定公网 IP 的服务端,不需要设置。仅在位于 NAT 之后的客户端上设置即可。
Q:WireGuard 的公钥是否可以安全地公开?
是的。WireGuard 的公钥基于 Curve25519,是设计上可以公开分享的。它不会泄露你的私钥或连接凭证。但你仍然应该谨慎公开,避免让无关方知道你的 WireGuard 节点信息。
Q:WireGuard 能穿越 HTTP 代理(如企业代理)吗?
WireGuard 基于 UDP,无法直接穿越只支持 TCP 的 HTTP 代理。在必须通过 HTTP 代理出站的环境中,可以考虑:
- 使用基于 TCP 的代理协议(如 VLESS + WebSocket + TLS)
- 使用 WireGuard over TCP 的第三方工具(如
udp2raw将 WireGuard UDP 包装成 TCP)
Q:WireGuard 和 Tailscale 有什么关系?
WireGuard 是底层 VPN 协议,Tailscale 是基于 WireGuard 构建的上层服务,提供了:
- 自动密钥分发和轮换(通过 Tailscale 控制平面)
- 自动 NAT 穿透(无需手动配置端口转发)
- 网状组网(Mesh)——每对设备之间建立直接的 WireGuard 隧道,而不是星型拓扑
Headscale 是开源的 Tailscale 控制平面替代,可以自托管控制节点,同时保留 Tailscale 客户端的便利性。
延伸阅读
- 传统协议 — 了解 HTTP、SOCKS、SSH 等传统代理协议
- VLESS 协议 — 在需要抗检测能力的场景中,VLESS + Reality 是更合适的选择
- Hysteria 2 — 同样基于 UDP,但专为抗检测代理场景设计
- 代理协议总览 — 回到协议总览页面