V2EX-最热主题 ( ) • 2024-04-26 10:22
lanthora:

TL;DR

一个可靠,低延迟,反审查的组网工具

背景

我在国外有一台性能非常弱但是有公网 IP 的 VPS. 国内有一台 7*24 小时开机的 mini 主机.让 mini 主机作为 VPS 的后端,不在 VPS 上存放任何数据,解决了 VPS 性能弱的问题,也解决了替换 VPS 供应商时迁移数据的问题(当然也包括对 VPS 供应商的信任问题).

最初选择的组网方案是 WireGuard, 它平静的陪伴了我几个年头,直到 2023 年某此会议的召开.原因为会议开完我的 WireGuard 就能继续用,一个月后证明我想多了.

于是决定解决这个问题.调研了一系列项目后,没有找到天生隐藏协议特征的组网工具(可能设计者设计之初也没有考虑这种问题把).把 VPN 套到 Proxy 里的这种诡异方案也称试过,虽然能用,但是很不喜欢

整体设计思路

设计的宗旨是简洁.在不牺牲性能和核心功能的情况下,用最少的代码量和最简单的概念完成设计.

降低配置复杂度

WireGuard 在 VPN 里配置已经相对较简单了,但对我来说依旧过于复杂.回忆一下你用多长时间完成的第一次 WireGuard 组网. WireGuard 需要强制指定虚拟地址,不适用于想要灵活接入多个客户端并动态分配地址的场景.

用 WSS(Web Socket Secure) 处理通信,在保证链路数据安全的情况下,免去了配置公私钥的过程. 用口令校验客户端,可以轻松的让新客户端加入网络,这样就能由服务端实现地址动态分配.

高效的断线重连

在某些情况下 WireGuard 会断线,只有重启客户端才能解决.此时对于一个无人值守的设备,就意味着彻底失联. 曾经为了解决这个问题,给设备配置每天重启一次,这显然是一种很丑陋的解决方案.

使用 WSS 通信,就可以用 Ping/Pong 完成 TCP 保活,即使 TCP 连接异常断开,应用也可以及时发现,迅速处理.

支持内网穿透的对等连接

虽然 WireGuard 支持对等连接,但要求设备之间能够直接访问,对于双方都在 NAT 后面的情况无能为力. 增加内网穿透功能,可以节约服务端转发的流量,同时还能降低通信延迟.

内网穿透通过 STUN 服务器获取本地 UDP Socket 被映射后的公网地址和端口,通过服务端与其他客户端交换地址和端口信息,并尝试建立连接.

高速的中继路由

有时候两个客户端之间无法直连,但它们都能与另一个客户端直连.此时可以以这个客户端作为中继相互访问.

这实际上是路由的问题.本项目实现的是距离向量算法.

局域网对等连接

通过 STUN 查到的用于对等连接的地址是公网地址,对于局域网内能够直连的设备来说,绕到最外层的路由器再回来是浪费了时间的,并且还会受到公网带宽的限制.

通过用户配置或主动探测本机的局域网地址,可以优先尝试本地直连.

总结

其实最初的版本只有 WSS 中继功能,后来在用户的反馈中加上了 P2P 和利用网络中的其他客户端做中继的功能.新增的功能我自己也能用得上,体验上也有巨大的提升.

有一些其他的组网工具有着极其丰富的功能,而我的设计初衷是让两台装了客户端的机器能够简单快速稳定的通信,因此舍弃了很多功能,甚至用"口令"这种在现代视角看上去不够零信任的方式鉴权.