相关指南
深入了解 WireGuard:原理与发展
更新于
WireGuard 是一个开源的 VPN 协议,由 Jason A. Donenfeld 设计,2015 年前后公开,2020 年正式进入 Linux 内核。它的特点可以归结为一个词:少。代码少——核心实现只有几千行,而 OpenVPN 和 IPsec 是几十万行;选项少——加密算法只有固定的一套,不让你挑;状态少——没有「连接中」「已断开」这些概念,有数据就发,没数据就安静。少带来的是快、省电、容易审计,也带来了它的局限:只走 UDP、没有伪装、不管密钥怎么分发。下面先讲它是怎么工作的,再讲它是怎么一步步成为新一代 VPN 的基础的。
设计思路:把 VPN 做得像一块网卡
在 WireGuard 之前,主流的选择是 IPsec 和 OpenVPN。IPsec 是一大族标准,配置项极多,不同厂商之间对接是出了名的麻烦;OpenVPN 跑在用户态、依赖庞大的 TLS 库,灵活但慢。两者的代码量都大到很难有人完整审计一遍。
WireGuard 的想法是反过来:只做一件事,把它做对。它在系统里表现为一块虚拟网卡(比如 wg0),你给这块网卡配上自己的私钥和几个对端的公钥,往它发数据包就会被加密送出去,收到的包解密后从它出来。其余的事——路由、防火墙、地址分配——全部交给系统里已有的工具。
它故意不做的事也很明确:不协商算法、不管账号密码、不分配地址、不伪装流量。这些要么被认为是漏洞的来源,要么留给上层的工具去做。
密钥路由:公钥就是身份
WireGuard 里每个设备有一对密钥,公钥就是它的身份,类似 SSH 的用法:两边互相把对方的公钥写进自己的配置,就建立了信任,没有证书、没有用户名密码。
配置里给每个对端写一条「允许的地址」(AllowedIPs)。它同时管两个方向:发包时,目的地址落在谁的允许范围里,就用谁的公钥加密发给谁;收包时,解密后看源地址是不是在这个对端的允许范围里,不是就丢掉。这套做法叫密钥路由(cryptokey routing)——路由表和访问控制合成了一张表。
所以把某个对端的允许地址写成 0.0.0.0/0,就是「所有流量都交给它」,也就是通常说的全局 VPN;只写一个内网网段,就是只有访问那个网段时才走隧道。
握手和加密:固定的一套算法
两台设备第一次通信前要握手:发起方发一个包,响应方回一个包,一来一回就完成了,双方得到一组只用于这段时间的会话密钥。握手基于 Noise 协议框架,用双方的长期密钥互相认证,同时用临时密钥保证前向保密——即使以后长期私钥泄露,过去录下来的流量也解不开。
会话密钥每隔几分钟自动更换一次,整个过程对用户不可见,也没有「重连」这回事。
加密算法是固定的:密钥交换用 Curve25519,数据加密用 ChaCha20-Poly1305,哈希用 BLAKE2s。没有协商,也就没有降级攻击——攻击者没法诱使两边改用更弱的算法。如果将来其中某个算法被攻破,办法是出一个新版本的协议整体替换,而不是加一个选项。
另外可以再加一把预共享密钥,和公钥机制叠加使用,为的是防备将来量子计算机对公钥算法的威胁。
只走 UDP、不回应陌生人、换网络不掉线
- 只走 UDP:WireGuard 把每个数据包单独加密后放进一个 UDP 包里发出去。不用 TCP 是有意的——在 TCP 里再跑 TCP,两层都在重传,丢包时会互相拖累。
- 不回应陌生人:没有通过认证的包一律不回复。对扫描端口的人来说,这个端口看起来就像没有开,无从知道上面跑着 WireGuard。
- 漫游:WireGuard 不认「连接」,只认公钥。对端换了地址——手机从 Wi‑Fi 切到流量——它发来的下一个包只要认证通过,这边就自动把回包发往新地址。所以切换网络时隧道不会断。
- 安静:没有数据要发的时候,隧道不产生任何流量,手机上因此很省电。只有当设备躲在路由器后面、又需要一直能被对方找到时,才要打开定时保活(PersistentKeepalive),每隔几十秒发一个小包维持路由器上的映射。
为什么快
- 在内核里跑:Linux 上的 WireGuard 是内核模块,数据包不用在内核和用户程序之间来回拷贝;OpenVPN 传统上跑在用户态,每个包都要多绕一圈。
- 算法适合所有 CPU:ChaCha20 不依赖专门的硬件加速指令,在手机、路由器这类没有 AES 指令的芯片上尤其占便宜。
- 握手短:一来一回就能发数据,建立连接几乎没有等待。
- 代码少:路径短,能做的优化都做在了关键的那几步上。
- 要注意的是,这些说的是协议和实现本身的开销。跨境线路上的实际速度,更多取决于线路的丢包和运营商对 UDP 的态度。
发展:从一个人的项目到进入内核
- 2015 年前后:Jason A. Donenfeld 开始开发并公开 WireGuard,最初是 Linux 上一个独立的内核模块。
- 2017 年:描述其设计的论文在网络安全会议 NDSS 上发表,协议随后经过了多项独立的形式化验证。同一年前后,Mullvad 等 VPN 服务商开始提供 WireGuard 接入。
- 2018 年:Linux 的创始人 Linus Torvalds 在邮件列表里称赞它的代码,并说和 OpenVPN、IPsec 相比它简直是一件艺术品,这句话让它在开发者圈子里广为人知。
- 2019 年:Cloudflare 发布用 Rust 写的用户态实现 BoringTun,并把 WireGuard 用在它的 WARP 上;NordVPN 推出基于 WireGuard 的 NordLynx;Tailscale 也在这一时期以 WireGuard 为数据面起步。
- 2020 年 3 月:WireGuard 随 Linux 5.6 正式合入内核主线,同时发布 1.0 版本。从此主流 Linux 发行版自带 WireGuard,不用另装模块。同年 OpenBSD 也在内核里加入了它。
- 2021 年:Windows 上推出内核态实现 WireGuardNT,性能比之前的用户态实现高出一截;FreeBSD 随后也有了内核实现。
- 现在:Windows、macOS、Linux、iOS、安卓都有官方客户端,OpenWrt、群晖等路由器和 NAS 系统普遍内置支持,绝大多数商业 VPN 把它列为默认或可选协议。
它不做什么,以及由此带来的局限
- 不管密钥分发:每加一台设备,都要把它的公钥写进其他设备的配置。设备一多就管不过来,这正是 Tailscale 这类工具存在的理由。
- 不动态分配地址:每个对端的内网地址是写死在配置里的,没有 OpenVPN 那种「连上后发一个地址」的机制。商业 VPN 用它时都要在外面自己再做一层。
- 隐私上的顾虑:服务器需要记住每个对端最近一次的公网地址才能回包。对「不留日志」有要求的 VPN 服务商,通常要额外做处理(比如定期清除、双重地址转换)。
- 只有 UDP:在封锁或限速 UDP 的网络里不通或很慢。想让它走 TCP 或 443 端口,只能在外面再套一层别的工具。
- 没有伪装:握手包和数据包的格式、长度都有固定特征,很容易被识别出来。它的设计目标是安全和简单,不是抗审查。
- 没有账号体系:协议里没有用户名、密码、到期时间这些概念,认的只是公钥。
和 OpenVPN、IPsec 的对比
- 代码量:WireGuard 核心几千行;OpenVPN 加上它依赖的 TLS 库、IPsec 的各种实现都在几十万行的量级。
- 传输:WireGuard 只有 UDP;OpenVPN 两种都行,能走 TCP 443 混在 HTTPS 流量的端口上;IPsec 用自己的协议号和 UDP 500 / 4500。
- 配置:WireGuard 一个对端几行;OpenVPN 的配置文件选项很多但很灵活;IPsec 最复杂。
- 性能:干净的网络上 WireGuard 通常最快、最省电;OpenVPN 在新版本里也有了内核加速(DCO),差距在缩小。
- 功能:账号密码认证、动态下发地址和路由、走 TCP,这些 OpenVPN 自带,WireGuard 都要靠外面的系统来补。
- 设备支持:OpenVPN 历史长,老路由器、NAS、各种嵌入式设备几乎都认;WireGuard 在近几年的系统上已经普及,老设备上不一定有。
在 WireGuard 上面长出来的东西
- Tailscale:在 WireGuard 上加了登录、密钥分发、NAT 穿透和中继,做成自动组网,见《深入了解 Tailscale》。Headscale 是它的开源控制服务器实现。
- Netmaker、NetBird、Firezone 等:同样是「WireGuard 做数据面、自己做管理面」的组网或零信任产品。
- Cloudflare WARP:面向普通用户的 WireGuard 客户端,把流量送进 Cloudflare 的网络。
- 商业 VPN 的自家包装:NordLynx 等,在 WireGuard 外加一层地址分配和隐私处理。
- AmneziaWG 等变种:修改包头和填充来隐藏 WireGuard 的固定特征,用于检查严格的网络;它们和标准的 WireGuard 客户端互不兼容。
在国内的网络上
- 能不能用,首先看 UDP:不少宽带和移动网络对大流量 UDP 做限速,表现为刚连上很快、跑一会儿变慢,或者晚高峰明显卡。
- 跨境直连容易被识别:WireGuard 的握手包特征固定,在跨境链路上可能被识别并干扰,表现为握手不上或用一段时间后断流。这是协议没有伪装的直接后果。
- 国内设备之间组网(公司和家里、手机和 NAS)不经过跨境链路,一般没有这个问题,只受 UDP 限速和打洞成功率影响。
- 所以它更适合做组网和远程访问;要长期稳定地跨境,需要有伪装或能走 TCP / TLS 的方式配合,各协议的对比见《VPN 协议对比》。
雷腾 哪里用到了 WireGuard
雷腾 的「私网」栏目用的是 Tailscale,数据面就是 WireGuard:设备之间的隧道、到各地区出口节点的隧道,都是它在加密和传输。你不需要自己生成密钥或写配置,登录本站账号后由客户端自动完成。怎么用见《私网(Tailscale)是什么》,入口在私网页面。
私网之外,同一个账号还有不依赖 UDP 的方式:思科(AnyConnect)走 TLS,专网(OpenVPN)可以走 TCP,流量伪装(Hysteria2)专门对付丢包。所在网络里私网又慢又不稳时,换一种方式即可,见《各种连接方式适用的场景》。
常见问题
WireGuard 和 OpenVPN 哪个好?
干净、不限制 UDP 的网络上,WireGuard 更快、更省电、切换网络不掉线;需要走 TCP、需要账号密码登录、或者设备比较老的时候,OpenVPN 更合适。两者都是开源且经过长期检验的协议,安全性上都可靠。
WireGuard 安全吗?
它用的是一套现代而保守的算法,协议经过形式化验证,代码量小、便于审计,目前没有已知的实际攻破方法。要注意的是它不负责密钥的保管和分发:私钥泄露、或者把公钥配错了对象,协议本身帮不了你。
WireGuard 为什么只支持 UDP?
设计上的取舍。在 TCP 连接里再跑 TCP,丢包时两层同时重传,性能会急剧下降;而且 UDP 让「不回应陌生人」和漫游都容易实现。代价是在封 UDP 的网络里用不了。
WireGuard 在中国能用吗?
国内设备之间组网一般可以。跨境直连不稳定:它的流量没有伪装,容易被识别和干扰,加上部分线路对 UDP 限速。需要稳定跨境时,要配合有伪装或走 TLS 的方式。
WireGuard 是谁开发的,什么时候进的 Linux 内核?
由 Jason A. Donenfeld 设计开发,2015 年前后公开;2020 年 3 月随 Linux 5.6 合入内核主线,同时发布 1.0 版本。
Tailscale 是不是就是 WireGuard?
不是同一个东西。WireGuard 是加密隧道的协议;Tailscale 是用 WireGuard 做数据传输的一套组网系统,另外解决了登录、密钥分发、NAT 穿透和中继。详见《深入了解 Tailscale》。
用 WireGuard 需要自己配置密钥吗?
直接用 WireGuard 需要:每台设备生成密钥,再把公钥、地址、对端地址写进配置。通过 Tailscale 或商业 VPN 的客户端使用时,这些由软件代劳。在 雷腾 的私网里,登录账号即可。