WireGuard 是什么?现代 VPN 协议的设计与代价
Yalgorup 编辑部 · 更新于 2026年8月1日
核心要点
- 加密套件是写死的:ChaCha20-Poly1305、Curve25519、BLAKE2s、HKDF,不支持协商,也就没有降级攻击面。
- 代码约 4000 行,与 OpenVPN 加依赖数十万行相比,安全审计的可行性完全不同。
- Cryptokey Routing 把「公钥」和「允许的 IP 段」直接绑定,路由和鉴权是同一件事。
- 原生实现会给每个 peer 分配固定内网 IP,这在商用多租户场景下是隐私隐患,需要厂商额外处理。
它解决了什么问题
上一代协议有个共同毛病:为了兼容一切,它们支持大量可协商的算法组合。结果是配置复杂、实现庞大、历史包袱重,而每一个被保留的弱算法都是潜在的降级攻击点。
WireGuard 的思路相反 —— 不给选择。加密套件固定为:
| 用途 | 算法 |
|---|---|
| 对称加密与认证 | ChaCha20-Poly1305(RFC 8439) |
| 密钥交换 | Curve25519(RFC 7748) |
| 哈希 | BLAKE2s(RFC 7693) |
| 密钥派生 | HKDF |
如果某个算法将来被攻破,做法是发布新版本协议,而不是在旧版本里协商替换。
握手:一个往返
WireGuard 的握手基于 Noise 协议框架的 Noise_IK 模式。客户端发起、服务端响应,一个往返完成,之后立即可以传数据。
对比 OpenVPN 的 TLS 握手需要多次往返,这个差别在高延迟线路上非常直观 —— 连接建立时间从几百毫秒降到一个 RTT。
会话密钥会定期更换。发送方在密钥使用约 120 秒后主动发起新的握手,超过约 180 秒未更新的密钥会被拒绝,从而保证前向保密。
Cryptokey Routing
这是 WireGuard 最有特点的设计:配置文件里每个 peer 只有两样东西 —— 一个公钥,一组 AllowedIPs。
[Peer]
PublicKey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
AllowedIPs = 10.0.0.2/32
Endpoint = 203.0.113.10:51820
含义是双向的:
- 出方向 —— 目的地属于
10.0.0.2/32的包,用这个公钥加密后发给它。 - 入方向 —— 用这个公钥解密出来的包,源地址必须落在
10.0.0.2/32里,否则丢弃。
路由决策和身份验证被合并成了一件事,逻辑上非常干净。
漫游与「安静」特性
WireGuard 不维护传统意义上的连接状态。当服务端收到一个用已知密钥正确加密的包,且源地址与记录的不同,它就更新对端地址。所以手机从 Wi-Fi 切到 4G,隧道不会断,也不需要重新握手。
另一个设计是默认沉默:对于无法通过认证的数据包,服务端不回任何响应。从外部扫描的角度看,这个端口像是没开。
需要注意的代价
没有内置的动态地址分配。 原生协议里,每个 peer 的内网 IP 是配置文件写死的。自建时这没问题,但商用服务给成千上万用户分配固定内网 IP,就等于给每个账号发了一个长期标识。主流服务商的做法是在服务端再加一层 NAT,或者让内网 IP 动态化 —— 这属于厂商实现,不是协议自带。
特征明显。 报文头部有固定的类型字段和长度模式,DPI 设备识别 WireGuard 流量并不困难。在会主动阻断 VPN 协议的网络里,裸 WireGuard 往往连不上。
只有 UDP。 遇到只放行 TCP 的网络就没有办法,除非借助外部封装工具。
什么时候选它
日常使用、看视频、下载、移动设备省电 —— WireGuard 基本是最优解。
需要伪装、需要走 TCP、或者所在网络会阻断 UDP 时,OpenVPN 仍然更合适。
常见问题
WireGuard 支持 TCP 吗?+
原生只支持 UDP。需要 TCP 时要靠外层工具封装(例如 udp2raw、wstunnel),这不属于协议本身的能力。
WireGuard 的固定 IP 问题严重吗?+
自建场景无所谓。商用场景下,如果服务商直接把内网 IP 与账号绑定并长期不变,等于留下了可关联的标识。主流服务商通过双重 NAT 或动态分配来规避,选服务时可以留意这点是否被说明。
为什么 WireGuard 连上后没有「已连接」状态?+
它被设计成无状态的:没有持续的会话管理,只在有数据时才发包。判断是否通了要看是否有握手记录和实际流量。
它能防止流量被识别吗?+
不能。WireGuard 报文有明确的格式特征,很容易被识别为 WireGuard。需要隐蔽性必须叠加混淆层,见 混淆与伪装协议。