Skip to content

Commit

Permalink
更新 README 补充项目的来龙去脉
Browse files Browse the repository at this point in the history
  • Loading branch information
lanthora committed Jan 7, 2024
1 parent c40e8ab commit bfe8e0d
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 21 deletions.
71 changes: 65 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,73 @@
# Candy

中文 | [English](README_en.md)
部署跨境虚拟专用网络的新选择.

一款易部署并支持对等连接的虚拟专用网络工具.请参考[文档](https://icandy.one)获取更多信息.
## 什么是虚拟专用网络

## 特点
互联网上存在大量命名为 VPN (虚拟专用网络)的代理工具,严格意义上来说这些工具应该被称为 Proxy (代理).
这里需要澄清一下它们的区别: VPN 可以让虚拟网络中的设备相互访问; Proxy 则是把一台设备作为跳板访问另一台设备.

- 易用: 简单配置即可完成组网
- 跨平台兼容: 支持 Linux, MacOS 和 Windows
- 高效与可靠: 主机之间将优先尝试对等连接,失败后再通过服务端转发确确保连接有效
典型的 VPN 有 OpenVPN 和 IPSec, 以及最近几年出现的 WireGuard.
典型的 Proxy 有 Socks5, ShadowSocks, V2Ray.

显然本项目是组网工具,而非翻墙工具.

## 为什么再实现一款虚拟专用网络工具

上面已经提到许多经典的 VPN, 它们能满足用户的绝大多数场景.
我曾是 WireGuard 用户,但在国内众所周知的网络环境下,它们的设计存在"协议特征"明显这个“缺陷”.
这原本不是 VPN 需要考虑的问题,但当流量通过防火墙时,存在被丢包的风险.
我就是在 WireGuard 被丢包后才决定实现一款不容易被防火墙屏蔽的 VPN.

## 还得添加一些新特性

除了解决被防火墙屏蔽的问题,还需要引入一些更方便高效实用的新特性.

### 降低配置复杂度

WireGuard 相对来说已经是 VPN 里配置比较简单的了,但依旧需要手动在服务端和客户端配置对方的公钥.能理解这是为了安全所采取的措施,但对我来说依旧过于复杂. WireGuard 需要强制指定虚拟地址,不适用于想要灵活接入多个客户端并动态分配地址的场景.用预共享密钥代替非对称加密,可以解决前面提到的问题,同时降低配置复杂度.

### 高效的断线重连

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

### 穿透 NAT 建立对等连接

虽然 WireGuard 也支持对等连接,但对于连接双方都在 NAT 后面的情况却无能为力.当能穿透 NAT 时,就可以节约服务端转发的流量,同时还能降低通信延迟.

## 如何实现这些特性

思考了很久,不知道是否有必要在这里讲实现原理,最后决定用较少的篇幅做简单的描述.

要解决被防火墙丢包这个核心问题,可以参考目前代理的实现.主流方案是把流量伪装成已知的协议,主要是 HTTPS. 因此选择用 TLS + WebSocket 与服务端通信,不仅解决了防火墙的问题,还简化了通信的设计难度.

断线重连只需要利用 WebSocket 的 Ping/Pong, 这个包通过 TCP 发送,如果没有及时收到响应,可以认为断开连接.此时客户端退出进程,服务端清理连接.由外部进程重新拉起客户端进行重连.目前的实现心跳包的间隔是 30 秒,对我来说这个频率可以接受,实际使用过程中没有出现过有感知的断连的情况.

穿透 NAT 建立对等连接的实现与互联网公开方案基本一致.通过 STUN 服务器获取本地 UDP Socket 被映射后的公网地址和端口,通过 Server 与其他客户端交换端口信息,然后尝试建立连接,如果能成功建连就通过直连处理数据,否则通过服务端转发.

## 这个软件给我带来了什么

预期之内的,替代 WireGuard 完成组网,让我国内外的设备又可以在同一个虚拟网络下工作.

更多的还是意料之外的惊喜.首先是认识到可以通过软件模拟网络设备实现 VPN.

其次,为了方便容器化部署,我终于学会了用 Github Actions, 代码提交后自动检查并生成镜像上传.

对于软件本身,由于部署过于简单,就让我可能需要的设备都参与了组网.进而轻易解决了公司的 VPN 没有 Linux 版的问题.我把 Shadowsocks 部署在 VPN 里,也解决了 Splatoon 3 掉线问题.这次回家买了个 Mac mini, 接入由树莓派制作的 AP, 由于在树莓派上也接入的虚拟网络,因此可以直接在 Mac mini 上访问所有接入了网络的设备.同时由于对等连接的功劳,这些设备之间访问的延迟非常低.这篇文章就是在 Mac mini 上远程连接到距离我 500 公里远的服务器上完成的,整个写作过程非常丝滑.现在 Mac mini 上也直接部署了客户端.

总而言之,它在解决原始需求的情况下,带给我更大的想象空间.

## 未来的发展方向

除了正常的安全更新和问题修复,短期内不计划新增任何功能,希望这个软件可以像空气一样,让用户意识不到它的存在.

## 实际体验

目前支持 Linux, Mac 和 Windows. 选择你使用的系统[安装客户端](https://icandy.one/#如何安装),这些客户端的默认配置会连到我们提供的测试网络 172.16.0.0/16, 并被随机分配一个地址.

这个网络部署了两个用于测试的客户端. 172.16.0.1 的 80 端口部署了 Web 服务. 172.16.0.2 的 1080 端口部署了的 socks5 服务.

调整启动参数部署自己的服务端,然后组建自己的网络.推荐在 Linux 系统上用容器部署.

## 联系我们

Expand Down
15 changes: 0 additions & 15 deletions README_en.md

This file was deleted.

0 comments on commit bfe8e0d

Please sign in to comment.