WireGuard,想说爱你不容易

warning: 这篇文章距离上次修改已过296天,其中的内容可能已经有所变动。

WireGuard,被誉为下一代VPN,而且也在很多地方被采用了,经常提到的例子就是这玩意进了Linux Kernel里面,性能得到大大提升,以及各大VPN厂商开始提供VPN服务,等等。

不过正所谓日久见人心,一个东西用久了,你自然会发现他问题到底何在。这篇博文所讨论的,便是笔者不推荐在部分生产场景下部署WireGuard的主要原因。

1. 前言

VPN技术有很多种,比如我们今天的主角WireGuard,还有OpenVPN,PPTP,L2TP等等,这一点其实笔者先前也写过文章,可以点击此处阅读,里面详细对比了『企业员工连接到公司网络』这个场景下的用例对比。其中,快速又安全,配置还简单的WireGuard,本应该受到很多人推崇,但是我在那篇文章里面给出的结论是『建议作为后备方案选用』,当时限于篇幅,只是简单提了一下做出这个决定的一些原因,所以今天单开一篇文章,从技术角度和直观角度,来分析一下WireGuard的痛点。

当然,本文的一个重要观点是:世事无绝对。如果你评估后发现下面提到的缺点并不影响你去使用WireGuard,那么自然无妨——实际上笔者对于私人场合(比如前段时间在学校机房连接回宿舍电脑远程打游戏)也会优先考虑WireGuard。此外显然,如果你用的是成品的VPN服务(例如大厂的VPN,部分SD-WAN接入提供商),在人家帮你配置好了,你只需要一键连接的情况下,就可以优先考虑WireGuard,毕竟速度快,耗电省。

info:一些约定

考虑到对于本文内容而言,OpenConnect,以及其他国内外厂商制作的SSL-VPN,比如思科的AnyConnect,深信服EasyConnect,Ivanti的Pulse Secure,等等等等(但不包括OpenVPN),他们在操作步骤上是类似的,都是只需要输入VPN服务器地址(或者厂家私有的识别码),以及给出认证信息,就可以使用了,无需额外下载配置文件。所以为了方便叙述起见,下文统一称呼此类VPN为SSL-VPN

2. 缺乏配套措施

笔者认为这是WireGuard的最大痛点,也是不推荐的主要原因。

WireGuard官方实现只给了协议范围内的东西,对于范围之外的,比如如何分发密钥,如何鉴权用户,如何传递路由信息,如何分配IP(下面简称为外围配套措施),就完全没有考虑在内,也没有统一的标准和事实上的标准,这就导致了本节所提到的问题。

2.1 用户体验

上一段引用博文里,提到了这么一个场景:你作为一个企业网管,需要开VPN给没有网络知识的员工使用——会计,写手,剪辑,美工,都一样。这就引出了一个很显然的问题:一般人是不知道如何去配置VPN的,他们对于『访问某种私密内容』这件事最直观的认知可能就是输入用户名密码,或者是短信验证码登录,不论你登录QQ,微信,钉钉,还是B站,抖音,快手,基本上都脱离不了类似的方法。

所以相对应的,VPN最好也有类似的机制。比如以认证为例,纵观目前的常用VPN,支持多种认证机制,尤其是用户名密码认证的,可以说是多如繁星,SSL-VPN,OpenVPN,甚至是祖师爷级别的PPTP,都支持这个特点,其所带来的好处是非常显然的:

  • 对于员工:SSL-VPN自不必说,地址+用户名密码就连上了;即使是OpenVPN,他也只需要下载一份公用的配置文件,导入到设备上的软件里,后面的步骤就和其他SSL-VPN是一致的——甚至如果企业搭建的服务器是OpenVPN Access,或者提供了URL下载配置文件的方法,那么操作起来就更为简便。
  • 对于网管:不需要针对不同用户制作差别化的配置文件,只要一份公用的就行。而且用户名密码认证也就意味着可以直接对接原来企业内部的认证环境,比如LDAP,域控,Radius之类的,不需要再费心倒腾额外的认证项。

但是WireGuard呢?很抱歉,WireGuard只支持一种认证方式,那就是预先交换公钥对(以及可选的PSK),换句话说,如果你有200个用户,你就要制作200份不同的配置文件。此外别忘了,WireGuard内部依靠公钥路由流量,换句话说,一个公钥同时在线的设备只能有一台(即使设备在NAT之后,也依然要分开算),否则就会引起流量乱跳,考虑到用户可能不止一个设备(比如对于画师而言,他们可能会在手机上看需求,电脑上绘图),你需要制作的配置文件数量可以达到400-600份。在这样的情况下,我建议你去一趟枫丹科学院,里面的人们对于抄写东西这种事非常擅长。

抛开制作文件麻烦这一点不谈,用户用起来也不见得简单。他需要根据自己的身份(比如,工号),找对地方,在浩如烟海的配置文件列表中,瞪大眼睛仔细核对,去下载属于自己的寥寥几份配置文件,然后分别导入到不同设备里,还要注意不要导入错了,否则开起来之后就连不上了。而且,假如一个不小心,员工下错了配置文件,那么他就可以用别人的身份登录上VPN,问题就更大了——当然你可以开发一个合适的系统来分发配置文件,不过依然无法解决用户侧的麻烦事。

即使你想办法搞定了制作和分发配置文件的麻烦,别急,后头还有更大的在等你。比如你原来制作的配置文件里面,AllowedIPs是10.0.0.0/24,也就是说只有这一部分流量需要被送入VPN处理。一段时间之后,公司内部开了新的网段,比如说10.0.1.0/24,用来放置别的服务。很显然,如果不修改配置,员工就无法访问这个新网段,那么此时你应该如何通知这几百个用户去更新他们的配置文件呢?『请大家重新进行一次显得麻烦的配置文件下载-导入操作』,还是说『请大家打开配置文件,在某某地方输入一个英文逗号,再输入10.0.1.0/24,注意是英文斜杠。收到请回复。』?

2.2 错误的类比

出现这样的情况,笔者反倒不好认为这到底是不是完全归纳于WireGuard的错,因为在我看来,WireGuard是一种被归类错误的VPN。长期以来,WireGuard都被拿来和OpenVPN之类的技术做对比,但在分析过设计理念之后,笔者更倾向于把它和IPSec对标,即,他实现的并非完整的一套软件,而只是一个协议,一个加密隧道协议。

为什么上面提到的SSL-VPN和OpenVPN会相对较为好用,除了他们在协议层面上支持这些认证方式之外,很重要的一点就在于他们提供了足够好用的(甚至是唯一的)实现,比如OpenVPN有OpenVPN Connect,SSL-VPN更是有各种厂家制作的私有客户端,过了这村就没这店,你只能用这个客户端连接。相对应的,WireGuard和IPSec更为类似,只提供协议标准,客户端和服务器的具体实现就交给其他人来办,所以你可以做到WireGuard内核版做服务器+TunSafe连接,也可以做到strongSwan做服务器+安卓手机连接,只要能正确实现这个协议,就没有什么不互通的地方。

问题偏偏就出现在这个实现上。WireGuard官方有没有面向最终用户的参考实现?有,当然有,但即使这个参考实现完美地实现了协议中的任何一个细节,也只能说是能用,远远谈不上好用,就好像你可以在各种终端上直接进入系统设置里面配置IPSec,但是我相信你应该不会让员工去这么做的吧?更多的可能还是由技术人员预先配置好,面向最终用户时,只暴露一个开关。

2.3 在补丁上打补丁

这就引出一件非常可怕的事情:『下层交给上层实现,上层选择不实现』。具体落在WireGuard身上,就导致了原版软件不原生支持高级一些的外围配套措施,你要是基于原版搭建,要么只能忍受这种不便利的分发方式,要么你基于API自己写配套措施(比如自己写带鉴权功能的公钥提交接口)并开发对应的客户端软件;或者你要是使用其他厂家的二开版本,比如Tailscale,就得面临客户端不兼容和难以下车的问题:虽然这些软件底层协议都是标准WireGuard,但是因为外围配套措施是厂家专有实现,导致了事实上的无法互通,也就是所谓的『互操作性问题』。

3. 仅限 UDP

虽然严格来说,在VPN这种需要传递IP数据包的环境下,外层不使用可靠传输层(例如TCP)是一个很正确的决定,因为可以避免『外层重传内层的重传包』导致的TCP Meltdown的问题,虽然这个问题可以被解决,但毕竟是位于难以调整的地方,因此可以放心假定绝大多数用户并没有缓解TCP Meltdown的办法。

不过考虑另一个场景,国内运营商对于UDP的脸色一向不太好看,TCP可以畅行无阻的时候,UDP能给你丢到妈都不认识,甚至部分神奇的场合只允许TCP流量(还贴心地做了内网DNS转发),这就导致仅限于UDP的协议无法正常连接。对于OpenVPN和SSL-VPN而言,他们要么可以提供TCP连接选项,要么具有自动回落措施,在UDP不可用时候自动回落到TCP。但对于WireGuard,官方在已知限制中提到,WireGuard 明确不支持TCP隧道,所有相关工作都应该交给上层实现——此时又回到了上一节的问题,也就是上层实现不统一甚至不实现,带来了互操作性问题。

即使你不需要连接到其他地方,单纯只是公司内部专用,问题也不会缓解。作为网络管理员,你要么自己写一个程序(别忘了还得给移动端准备)并实现所有你想实现的东西,要么跟目前网上的教程一样,用一堆普通用户看起来觉得发毛且不能随意关闭的『黑框框』来实现类似功能,你怎么选?

4. 缺乏好用的UI

上面这截图在本博客里面引用多次了,图中的软件是TunSafe,并非官方版WireGuard的Windows客户端。笔者使用TunSafe的一个主要原因,就是他的UI更加...直观。(而且笔者用TunSafe也经常只是连接原版协议,不是用他魔改的TCP和HTTP混淆协议,所以即使TunSafe不支持这些玩意,笔者也会坚持使用)

除了上面已经讨论过的问题之外,别的我不多提,就提一点:官方原版WireGuard客户端的指示器,你点击Connect之后状态会变为Actived,但这仅仅表示『接口起来了』,至于能不能连上对端,数据通不通,甚至对端是否在线,不结合流量计数器根本不知道,反正你就说接口起来没起来吧。另一方面,TunSafe指示的就是连接状态,如果对端没有正确回包,就会一直显示黄灯的Connecting,直到正确回包了,才会变绿灯显示Connected。虽然受限于协议,连不上的时候无法确定是服务没起来还是密钥不对,但至少能分开是否正确连接,就好了一大步。

Connecting示例Connecting示例

当然严格来说这一点有利有弊,原版指示器可能更接近于WireGuard设想中的『对等点』概念,也就是说,我可以在机器上Active一个端点,放一个没有指定Endpoint(也就是动态确定地址)的Peer让别人来连接,或者说可以加入多个Peer字段去连接不同的机器;TunSafe更接近我们讨论的C/S架构使用模式,客户端更需要一个明确的状态,但是也部分牺牲了上面提到的这个小功能(多Peer字段情况笔者未测试过,但是没有端点地址的情况,其他机器没连进来之前,TunSafe只会显示Connecting,也不清楚会不会在一定时间之后把接口关掉)。

5. 写在最后

上述问题就是WireGuard目前的一些大痛点,而且看来短期内很难改善。

留给我们的唯有一条路,那就是 希巴拉克的道路 使用第三方给封装好的WireGuard实现,比如Tailscale(毕竟这个是真的直接面对最终用户的),或者干脆换协议吧,OpenConnect就不错,其他SSL-VPN也不是不行。

(完)


木头箱子脆脆,但是这样正好

如无特殊声明,本站内容遵循 CC BY-NC-SA 4.0 协议

转载请注明出处并保留作者信息,谢谢!

本站由 搬瓦工VPS 强力驱动

none
最后修改于:2025年09月18日 22:30

添加新评论

提醒:『评论回复邮件提醒』功能正在测试中
评论后,如果站长有回复,会有邮件通知