很久以前偶然看到一个 Android 上有趣的加密通讯项目,它把对称加密算法应用到了 SOCKS 代理协议上,并设计一个自定义协议来组织通讯数据,这样,这个设计了自定义协议的 SOCKS 代理客户端与服务器之间就形成了一条虚拟的加密通讯线路。
之后,我基于这个加密线路做过几个客户端应用,有 Android 系统的也有 Windows 系统的,根据不同的目的又做过分割重组,总之有些凌乱。现在用 Flutter 跨平台框架整合成一个跨平台加密通讯客户端应用:加密通道(Private Channel),这篇博文主要梳理一下这些应用,给之前发过的 XTransmit 和 Mobified 收个尾。
App 的目的很简单,就是应用加密线路来传输网络通讯数据。加密 SOCKS 代理客户端和服务器是存在的,只需要把客户端对接上网络流量整个加密通讯就可以工作起来,而各大操作系统都提供了网络流量相关的接口,这使得 App 在各大系统上实现成为了可能。
起初的计划就是开发各个系统平台下的客户端 App,当然也有商业化的想法不过一直没主意,其实这领域我也不敢有啥主意。Windows 端的 App 叫 XTransmit,它是 Windows .NET WPF 桌面应用,而 Android 端的 App 则是官方 Android 原生客户端的定制。两个 App 都穿插着并行开发吧,也都在 GitHub 开源的,不过后续明确使用 Flutter 重构后这两个 App 的源码仓库就撤销了,这个后面还会讲到。
XTransmit
XTransmit 主要包含 SOCKS 加密代理客户端的实现、HTTP 流量过滤及转发模块、以及上层的 WPF 应用程序。App 通过 Windows 代理接口拿到应用层的(HTTP)流量,然后转发到 SOCKS 加密客户端再进行传输,而第三方应用程序通过使用系统设置的代理端口就实现应用层流量的加密传输。
由于 Proxy 工作在应用层,很多协议不走 Proxy(如 Ping 工具),所以 Windows 客户端的流量加密只能对接到应用,而且需要应用支持 Proxy。有些 App 可以检测并且自动使用 Windows 操作系统(IE)代理设置,像 Chrome 浏览器,这类应用直接就可以走加密通讯了,而那些读取 http(s)_proxy
环境变量的 Linux 类应用(如 Git)则需要客户端给它们设置环境变量信息,不过,也有一些应用需要做比较复杂的手动设置才能走代理,还有一些不支持 Proxy 的应用那就没法使用代理,所以 Proxy 模式下体验并不会太好。
当然,也可以通过 VPN 的方式来解决,VPN 工作在 IP 层,它不存在 Proxy 那些体验上的问题,不过当时 XTransmit 还没进展到扩展 VPN 能力的阶段就已经打算用 Flutter 来重构了。底层能力的实现都是复用的,Flutter 通过 Plugin 来抽象加密代理能力,只是不用 WPF 以及基于 WPF 的一系列组件,App 的类型也会变成 Windows Native 应用。
我是从驱动转到应用开发的,工作前两三年就很明确了,最先接触的就是 Windows MFC 应用程序,编程语言也是 C/C++,区别在于思维不同,应用是面向对象、抽象、封装这些东西,虽然对 Windows 桌面应用有些情怀,但还是做了减法。这些 App 都是断断续续进行的,Windows 端 WPF 版本投入精力并不多,空缺了一段比较长的时间后 2020 年底就打算转向 Flutter 了,原 WPF 应用也就没再推进,下图是最后一个版本的 XTransmit 客户端应用。
可以看到标题栏写的是“PrivCh”而不是“XTransmit”,这是因为 App 的名称被人注册域名了,原计划 XTransmit 会包含移动应用,Android 端也会从定制过度到一个新开发的 XTransmit Android App,名称被注册之后就更名为 Private Channel(简写 PrivCh)但是不影响计划,也会包含 PrivCh 桌面和移动端。
更名后原代码仓库倒是很快就删除了,毕竟不想再看到那个名称,我觉得这算是更名的不好的影响吧。另外值得一提的是,Windows 系统的客户端曾经添加过 HTTP 相关的强力功能,还添加过 V2Ray 协议的支持,不过后面都拿掉了(其中 HTTP 功能独立出来放到了另外一个应用里,以后有可能会介绍一下)。断断续续,2021 年全面切换到 Flutter 框架的 Windows 客户端。
Modified
全称是 Shadowsocks-Android-Modified,名字太长我就用 Modified 简写了,前面说偶然看到的项目就是 Shadowsocks Android 客户端,加密代理协议部分是 C 语言实现的,上层应用则是 Kotlin 开发的,在项目源码里可以看到应用最初是 Java 语言开发,慢慢的用 Kotlin 进行重构,我看到的时候基本都是 Kotlin 了。
C 语言实现的加密通讯模块在 Android 或 Windows 甚至其他系统上都差不多,在 Native 层适配操作系统,算源码跨平台。流量对接方面 Android 上走的是 VPN 接口,它接管操作系统(包含应用程序)的网络通讯数据,然后交给 SOCKS 加密代理,之后就走各个平台上都通用的流程。
一个应用有了基础功能后还需要有支撑这个基础功能的设计,Android 客户端就有扫码、应用筛选、检测服务器甚至广告等额外的功能模块,不过这些模块有的依赖 Firebase 云(国内不稳定)。PrivCh Android 端初期是基于它的定制,目的是解除对 Firebase 的依赖并提升交互体验。
下图是移除了 Firebase 依赖的版本,要不然在国内会无法使用。部分能力走了本地实现,和官方的做法相反,他们的用 Kotlin 重构 Java,而我则用 Java 重构 Kotlin,想起来挺折腾的。其中左边那个询问添加服务器的设计一直保留到现在,这个状态下询问用户的目的是:把控制权交给用户,改善用户体验也是我定制的重要目标。
定制版本投入精力也不多,当时官方版本很稳定,定制版也很久不会出现问题,以至于没了升级的驱动力。直到 2020 年接触到 Flutter,这个框架可以把 App 各个平台的版本很好的组织起来,2020 年定制版本的开发维护基本就处于停滞的状态,当时已经在了解 Flutter 跨平台框架并且评估应用这个框架进行重构的可行性。
受项目更名的影响,定制版的源码仓库也很快就删除了,转向 Flutter 方案。Flutter 率先支援了移动平台系统,PrivCh 就先在 Android 上重构再扩展到 Windows。Flutter 跨平台框架其实做了很多工作,以至于能够从 C/C++ Native 实现直接贯穿到“前端”,应对垂直方向比较厚的应用也能够轻松驾驭。
PrivCh
2021 年,加密通道客户端应用 PrivCh 在 Android 及 Windows 平台上都可以很好的工作(那些零散的版本也早都不存在了)。当然,Bug 肯定也会有,我觉得持续改进就好,从 0 到 1 是个过程,从 1 到 100 又是个过程。