WireGuard 跨国组网失败后,一个新工具的诞生

60 天前
 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 和利用网络中的其他客户端做中继的功能.新增的功能我自己也能用得上,体验上也有巨大的提升.

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

8513 次点击
所在节点    宽带症候群
85 条回复
YangMame
60 天前
zephyru
60 天前
这工具看起来蛮实用的,进入 24 年我依赖 CloudFlare Tunnel 的服务经常断链,感觉是个很好的替代
GeekGao
60 天前
hanguofu
60 天前
谢谢分享,请问 CLI: https://github.com/lanthora/candy 能不能运行在 arm64 ( aarch64 ) 的 Ubuntu 22.04 中 ?
Qetesh
60 天前
现在使用 xray 配合 wireguard ,wireguard over websockets 。等有空试试楼主这个
lanthora
60 天前
@hanguofu 有 aarch64 的 docker 镜像, ubuntu22.04 只编译过 x86 的版本.我感觉在你的环境上编译后是能用的,但没试过
povsister
60 天前
感觉这轮子造的有点重复了,xray/v2ray/clash 等工具都可以结合 tun 接口/tproxy 做到以 IP 转发模式完成对等网络配置,两侧网络的连接除了 ws 外,还有非常多的代理协议/transport 可选择
lanthora
60 天前
@GeekGao 不错的东西,不过貌似不是一个组网的工具,更像是代理?
lanthora
60 天前
@povsister 他们可以把一堆设备放到一个网络下通过 IP 直接相互访问吗,以前没有发现这个功能,给我文档我去看看
povsister
60 天前
@lanthora 可以,上面有关键词,tun (虚拟网卡),或者使用透明代理,本质都是把运行代理软件的这台机器当作网关使用,配置 ok 的话三层基本上就是通的
GeekGao
60 天前
@lanthora 可以 Wireguard via wstunnel
lanthora
60 天前
@povsister 我很确定我知道什么是 TUN/TAP 也知道透明代理是什么,在这基础之上,还是没有通过 Google 简单的找到组网的方案,看样子他们不适合我
lanthora
60 天前
@GeekGao 看看 "背景" 里的最后一句?
weijancc
60 天前
除了 wireguard 还有别的组网工具, 我目前用的 n2n, 在客户端直接指定 ip, 而不是在服务端.
Akitora
60 天前
gost 了解下
lanthora
60 天前
@weijancc 这个了解过,确实是个好工具,如果所有设备都在国内的话是个很不错的选择.可惜还是有报文特征明显的问题,不适合跨防火墙
lanthora
60 天前
@Akitora 用过 gost, 这也就是 "背景" 里最后一句话的由来.和上面提到的 wstunnel 类似,它们是转发流量,而不能组网,组网还需要依赖其他工具.
Akitora
60 天前
@lanthora 基于 TCP 的 TUN/TAP 隧道 https://gost.run/tutorials/tuntap/#tcptuntap 这个也不能满足楼主的组网需求吗
chairuosen
60 天前
注意隐藏自己的信息
lanthora
60 天前
@Akitora 这个链接里面应该可能可以满足我最初的转发流量的需求,也就是这个项目的最初版本.不过现在的实现可以内网穿透 P2P, 举一个实际中已经应用了的场景:两台电脑装好客户端后就可以联机打红警.上面的这个就不满足了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1035681

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX