一个可靠,低延迟,反审查的组网工具
我在国外有一台性能非常弱但是有公网 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 和利用网络中的其他客户端做中继的功能.新增的功能我自己也能用得上,体验上也有巨大的提升.
有一些其他的组网工具有着极其丰富的功能,而我的设计初衷是让两台装了客户端的机器能够简单快速稳定的通信,因此舍弃了很多功能,甚至用"口令"这种在现代视角看上去不够零信任的方式鉴权.
1
YangMame 216 天前
|
2
zephyru 216 天前
这工具看起来蛮实用的,进入 24 年我依赖 CloudFlare Tunnel 的服务经常断链,感觉是个很好的替代
|
3
GeekGao 216 天前
|
4
hanguofu 216 天前
谢谢分享,请问 CLI: https://github.com/lanthora/candy 能不能运行在 arm64 ( aarch64 ) 的 Ubuntu 22.04 中 ?
|
5
Qetesh 216 天前
现在使用 xray 配合 wireguard ,wireguard over websockets 。等有空试试楼主这个
|
6
lanthora OP @hanguofu 有 aarch64 的 docker 镜像, ubuntu22.04 只编译过 x86 的版本.我感觉在你的环境上编译后是能用的,但没试过
|
7
povsister 216 天前 via iPhone 1
感觉这轮子造的有点重复了,xray/v2ray/clash 等工具都可以结合 tun 接口/tproxy 做到以 IP 转发模式完成对等网络配置,两侧网络的连接除了 ws 外,还有非常多的代理协议/transport 可选择
|
10
povsister 216 天前 via iPhone
@lanthora 可以,上面有关键词,tun (虚拟网卡),或者使用透明代理,本质都是把运行代理软件的这台机器当作网关使用,配置 ok 的话三层基本上就是通的
|
12
lanthora OP @povsister 我很确定我知道什么是 TUN/TAP 也知道透明代理是什么,在这基础之上,还是没有通过 Google 简单的找到组网的方案,看样子他们不适合我
|
14
weijancc 216 天前
除了 wireguard 还有别的组网工具, 我目前用的 n2n, 在客户端直接指定 ip, 而不是在服务端.
|
15
Akitora 216 天前 via Android
gost 了解下
|
17
lanthora OP @Akitora 用过 gost, 这也就是 "背景" 里最后一句话的由来.和上面提到的 wstunnel 类似,它们是转发流量,而不能组网,组网还需要依赖其他工具.
|
18
Akitora 216 天前
@lanthora 基于 TCP 的 TUN/TAP 隧道 https://gost.run/tutorials/tuntap/#tcptuntap 这个也不能满足楼主的组网需求吗
|
19
chairuosen 216 天前
注意隐藏自己的信息
|
20
lanthora OP @Akitora 这个链接里面应该可能可以满足我最初的转发流量的需求,也就是这个项目的最初版本.不过现在的实现可以内网穿透 P2P, 举一个实际中已经应用了的场景:两台电脑装好客户端后就可以联机打红警.上面的这个就不满足了
|
21
lanthora OP @chairuosen 这是个只能用来组网的工具,应该还不用隐藏自己的信息吧.
|
22
wskymark 216 天前
wireguard 要重启确实麻烦
|
24
Fish1024 216 天前
好,收藏。
|
26
Damn 216 天前
在某些情况下 WireGuard 会断线,只有重启客户端才能解决。
---------- 比如? 我国内互联似乎还没遇到过,只遇到过宽带重新拨号导致 IP 变化了,需要更新 endpoint 的 ip:port 。 |
27
frencis107 216 天前
@Damn 国内某些地区,使用 wg 跨运营商连接时,会出现一段时间(一分钟内)后自动断开的问题,只能重启重连解决。ip 没变,keepalive 参数也有设置
|
28
lanthora OP |
29
deerpine 216 天前 via Android
试一试
|
30
Damn 216 天前
|
32
wuruxu 216 天前
@lanthora 是的 wireguard keepalive 是单向的,只是用来标记 Peer 是否还活着
国内七八台 openwrt 路由器组成一个 wireguard group, 这两年用下来也还正常 跨国的 wireguard 一般都是 节点丢包率太高了,一般只要没有丢包,都挺正常的 等你的包移植到 openwrt 上,我也去试试 |
33
coffeesun 216 天前 via Android
我不太懂网络,意思是可以替换掉我 zerotier 组网,并可以使组成的局域网设备通过国外的机子转发流量并翻墙么?这个能长期稳定如 v2ray 么
|
35
wuruxu 216 天前
@Damn 路由器重启 换了 ip , 这个目前有什么好的办法吗?
目前我就是通过 ddns 上报新的公网 IP ,然后在其他 Peer 上,定时去 set wireguard 的 peer 域名地址,一般需要 10 分钟才可以恢复 |
36
lanthora OP @coffeesun
> 替换掉我 zerotier 组网 理论上可以替换,但是如果你现在 zerotier 用着很爽,完全没有换的必要. > 使组成的局域网设备通过国外的机子转发流量并翻墙 不能,没有翻墙的功能. |
37
Damn 216 天前
@wuruxu 你是有机器没有 ipv6 且 v4 在 nat 后面么?
如果各 peer 都有公网 ip 并配置独立的二级域名的话,除非同时换 ip 了,不然重启或者重拨都会触发解析 ip 地址这个动作,然后可以成功连接的。 nat 后面的话原版 wg 似乎确实没什么高效的解决方法,可以选择各种修改版。 |
39
blankmiss 216 天前
用 tailscale 不就行了
|
40
KanVivii 216 天前
哈喽 方便给个联系方式嘛!
有个 SD-WAN 类似的项目想一起合作一下 |
42
lanthora OP |
43
s82kd92l 216 天前
最近一直在找有没有利用 stun/ice 完成 udp duplex 传输的工具,就是只负责包转发,不负责上层的加密/tun/路由。找到好多项目都是基于 webrtc 的 datachannel, 其基于 sctp over udp ,很重且不稳定。
看到楼主的实现也是基于 stun 的,要不考虑加上这个功能? |
44
amrice 216 天前 via Android
怎么都在说 wireguard ,没人用 tailscale 吗?我感觉很好用
|
45
Archeb 216 天前
同时支持对等连接和 C/S 架构来组网的 SDWAN ,使用常用的互联网协议进行通信,足够简洁的配置和够用的安全系数。
非常棒的思路,这正是我一直在寻找的东西。在此之前 tailscale 的 DERP 勉强可以符合我的需求(毕竟 DERP 协议也是走的 HTTP ,在大部分网络环境下可以正常使用),但 derper 的实现并不是太稳定。 目前有点懒癌发作,等未来这个项目更完善了的时候顺便一波换了。 |
46
uncat 216 天前
@wuruxu 路由器重启导致:
1. 导致重新拨号,所以换了 IP 2. 路由器上的 WireGuard 也被重启,导致动态的 Endpoint 信息丢失 解决思路: 将 WireGuard 运行到非路由器的设备上,然后开启 WireGuard 所有 Peer 的 Keepalive ,路由器重启但 WireGuard 不重启即可。WireGuard 会根据最后一次成功收包时 Peer 的来源信息,作为发包的目的地址( Endpoint 地址,首次连接可以指定,后续会被动态更新),这个信息就是 NAT 后设备对应的 NAT 记录(即 NAT 的公网 IP 和端口),本地的 WireGuard 将通过动态 Endpoint 地址,主动连接 NAT 后的设备,NAT 后的设备收到数据包,也会主动更新 Endpoint 地址的。 |
47
uncat 216 天前
WireGuard 会动态更新 Endpoint 的地址为该 Peer 最后一次收到的有效的数据包的来源地址。
假设你有公网 IP 且通过 DDNS 将公网 IP 通过域名进行实时更新,域名更新有延迟,所以这里面就可以利用 WireGuard 的这个特性了。 当有公网 IP 的 WireGuard 节点地址变化时,由于这个公网节点会主动的发送保活的空数据包( Keepalive )给所有对端节点,对端节点收到包后会根据数据包的来源 IP 更新 Endpoint 地址(这个地址将作为回包的目的地址),所以即使 IP 变化,通信也不会中断。 |
48
lanthora OP @s82kd92l 不考虑,除非真的有利于组网(更低的延迟或者更好的稳定性),否则就不加功能,代码越少越不容易出 BUG 。那些能配合其他工具实现的功能都不考虑
|
52
maybeonly 216 天前 2
@lanthora @Damn
> 在某些情况下 WireGuard 会断线,只有重启客户端才能解决 这是因为防火墙或者 nat 造成的。因为 wireguard 不会改变 udp 的源端口。 同时目的 ip 和端口也不会变,这就会导致,对应的失效 nat 表项一直不会超时。 对于自家路由器 ip 变化的情况,可以在路由器更换 ip 的时候清理出口的 conntrack 表得到解决。 但是这也是权衡利弊的结果。只有依赖这样的固定端口 udp ,才能组成“网状网络”而非“一个一个的连接” 其实跨国的话试试看 wireguard over ipv6 吧,感觉根本没人管啊。 作为后备方案,可以考虑 openvpn tcp over xray/hysteria ,不要嫌弃 openvpn 重,人家原生支持 tcp ,而且组网功能完善。 |
56
lanthora OP @maybeonly
> 其实跨国的话试试看 wireguard over ipv6 吧,感觉根本没人管啊 并非所有 VPS 都有 IPv6 地址.不太清楚有没有人管,不过现在确实有一些人即使用 IPv4 也能正常用. > VPN over Proxy 的方案是能用的,但是不喜欢那么复杂,单单因为重这一条就被我抛弃了.还得是自己用的爽才行 |
57
uncat 216 天前
@lanthora
> 并非所有 VPS 都有 IPv6 地址.不太清楚有没有人管,不过现在确实有一些人即使用 IPv4 也能正常用. 我就是长期 IPv4 WireGuard 用户。跟你场景很像,一台公网服务器作为中转,实际的所有流量和负载都在个人局域网的物理服务器上。 > 局域网对等连接 如果两个端都在 Symmetric NAT 后呢?也可以对等连接么? |
58
lanthora OP @uncat
> 如果两个端都在 Symmetric NAT 后呢?也可以对等连接么? 如果两个机器能通过某个局域网 IP 通的话就可以(至少能单向访问).这个功能跟 NAT 类型没有关系,也不会用到公网的任何信息.如果是两个不同 NAT 下的就不可以了 |
59
uncat 216 天前
@lanthora
> 如果两个机器能通过某个局域网 IP 通的话就可以(至少能单向访问).这个功能跟 NAT 类型没有关系,也不会用到公网的任何信息.如果是两个不同 NAT 下的就不可以了 明白了你的意思了,如果两个端都在同一个局域网内,基于局域网而不是绕行公网进行通信的意思。 |
60
wacke 216 天前
个人目前使用混淆版 wireguard ,也从 compat 版 port 到了 mainline ,3 年了吧,除了链路本身的波动外,基本没有不稳定的情况。。。。用户态的程序,效能还是弱了些。。。
https://github.com/el3xyz/wireguard-linux-compat |
61
isSamle 216 天前
已 Start ,能不能出个带图的操作说明文档
|
62
juzisang 215 天前
这个 P2P 是走的 UDP 吗?国内 UDP 带宽一大就会触发 QoS ,目前市面上 P2P 组网工具貌似都是走的 UDP 。
|
63
hxse 215 天前
为什么服务端不能支持 wss 协议? 抗审查效果怎么样? 小白不懂求教
|
65
wangsijie 215 天前
有对抗 GFW 吗
|
66
lanthora OP @hxse 加密交给外层的 web 服务就可以了,服务端没必要实现这个功能.从原理上用了比较广泛使用的 https,并且 p2p 的 udp 流量应该没有任何特征,这个项目从我做出来到现在用着还可以,效果需要用的人多了才能看出来.
也希望有大佬来尝试识别出这东西的流量 |
67
lanthora OP @isSamle 我没有提供带图操作的计划,在不同环境需要不同的操作,这个工作量太大了,我没有能力穷举出所有可能的用法.
根据提得 issue, 我会尽可能的让文字版的文档清晰,我自己是意识不到哪些地方需要做提醒的. |
68
hikarikongou 215 天前
TCP over TCP 在拥塞网络上的性能会比较难看。
|
69
lanthora OP @hikarikongou UDP 在 Qos 的时候也会很难看,所以除了 TCP 和 UDP 您还有什么好的建议吗
|
70
RangerWolf 215 天前
歪个楼,从“联机打红警” 我猜楼主应该 80 后
|
71
lanthora OP @RangerWolf 你猜错了,我三年级玩红警的(虽然现在依旧很菜),不是 80 后
|
72
cnbatch 215 天前
|
73
lhtdeg 215 天前
已 star ,等我的 tailscale 不能用的时候我就换
|
74
sunnysab 214 天前
“有时候两个客户端之间无法直连,但它们都能与另一个客户端直连.此时可以以这个客户端作为中继相互访问.” 这是我最想要的一个功能!
|
76
lanthora OP @cnbatch 这个人也去我项目下面开 issue 了,一开始还以为只是一个不太了解的用户,后面感觉不太对劲,虽然你的帖子没有暴露这个人的 id, 但是我发现这个人再各个项目里提得 issue 数量是能对上的,离谱
|
77
RangerWolf 213 天前
@lanthora 厉害了!三年级我们还在玩泥巴
|
78
cnbatch 213 天前
@lanthora 没错,就是他。越是帮他,他接下来越会继续提更多 issue
要是没帮他的情况下继续提更多 issue ,那得看着办了 我那帖子里面 Ipsum 的评论:直接摆烂 个人认为这是最佳应对措施 |
79
hikarikongou 212 天前
@lanthora UDP 虽然丢包的时候难看,但丢包并不影响整个隧道的运行。TCP 遇到丢包保证可靠传输的时候会引入慢启动和流量控制,引发巨大的延迟。参见
https://www.inventio.co.uk/Ideas/Why%20TCP%20Over%20TCP%20Is%20A%20Bad%20Idea.pdf UDP 加 FEC 其实是一个比较便利的方案。 |
80
lanthora OP @hikarikongou 选 wss 是为了过防火墙, p2p 用普通的 udp. 为这种弱网络环境引入对于正常网络环境来说冗余的代码没有价值.而且如果真的出现了和服务器之间丢包的情况,用正常的 tcp 做拥塞控制减少流量是合理的.如果真的那么在意延迟就不要把服务器部署到容易丢包的地方.
|
81
hikarikongou 202 天前
@lanthora 问题是 TCP 强制性的保序会干扰隧道中实时流量(比如 UDP 承载的 RTP )的正常传输,况且中国互联网出口是有普遍性的拥塞的,QoS 等级和丢包比率是没办法控制的。伪装过墙不如考虑假 WSS 握手后 faketcp 的方案。
|
82
lanthora OP @hikarikongou 最终都是各种取舍的结果罢了.去实现 "假 WSS 握手后 faketcp" 的方案是需要时间代价的,同时对我来说没有可以感知到的收益,这种代价不能接受,更不用说按照你说的这个方案做了以后就没法把服务端当成一个普通 Web 服务导致的各种问题.比如没法套一层 cloudflare 了.当它还是个普通 Web 应用的时候,可以很低代价的增强服务端的功能.
|
83
rebecca554owen 171 天前
|
84
zagfai 166 天前
@rebecca554owen 你怎搞呢?文档都没有...
|
85
rebecca554owen 165 天前
|
86
rebecca554owen 116 天前
@zagfai 我写了文档。
|