虽然我在切换到 Linux 做主力机后用到很顺利,但是工作上不可避免要用到 macOS 。咱还是得有个凑合够用的代理方案。我买了 5 设备版本的 surge 但我更想尝试用(相对)开源软件进行替代。
这篇文章以 clash premium 闭源软件为例,不过 https://github.com/MetaCubeX/Clash.Meta/tree/Alpha 这里有一份 fork 开源 tun 实现。
使用 clash 并不会和 wireguard 等服务冲突。
很抱歉我对网络相关的知识还处于一窍不通的状态,之前也只是看了 iptables 的手册。如果有啥错误的地方还请直接指出来。
为了将流量转发到特定服务上,我们可以使用 route 这个工具。
使用下面的命令可以目标为 198.18.0.0/16 流量发到 198.18.0.1 这个网关 /tun/interface:
route add -net 198.18.0.0/16 198.18.0.1
198.18.0.0/15 是个特殊网段,正常不会有网站使用这个 ip ,刚好 clash 可以用来做 fake-ip 。
clash/surge 都是通过这个基本操作完成的流量转发。 如果要代理全部的流量就要添加更完整的路由规则,不过这里我的使用方法和 clash/surge 不同,我没有配置所有 ip 都转发到 clash tun 中。 一个原因是我不知道该咋处理回环流量,如果这里接管所有流量,clash 本身发出的流量可能还会走这个路由形成个环,另外一个重要原因我可以自己配置路由规则来更好地支持 wireguard 和 openconnect 。
从 Clash.Meta 上的代码看,似乎是 clash 会直接把从 tun 来的流量直接发到 en0 ?
由于上述的配置,只有 198.18.0.0/16 会走到 clash ,其他网段还是走系统默认规则,这刚好不会干扰其他流量转发服务,免得一个数据包走好几次路由。
此时使用 wg-quick 会启动 wireguard 同时配置类似上面的路由规则,最后启动 openconnect 也会有类似的路由规则。
路由表大概是这个样子:
198.18.0.0/16 -> 198.18.0.1 (clash tun3)
192.168.1.1/24 -> 192.168.2.1 (wireguard tun4)
10.0.0.0/8 -> 10.0.0.1 (openconnect tun5)
other -> en0
分别完成各自的代理。
只配置路由规则不够,我们还需要启动 clash 的 DNS 服务,并设置系统的 DNS 为 clash 提供的 ip 。 这里直接让 clash 监听 0.0.0.0:53 ,系统就可以设置代理为 127.0.0.1 或者 198.18.0.1 (最好选择 198.18.0.1 )。
此时使用 nslookup 就能得到一个类似下面的 ip:
$ nslookup v2ex.com
Server: 198.18.0.1
Address: 198.18.0.1#53
Name: v2ex.com
Address: 198.18.1.104
此时所有域名流量应该都会转发到 clash 同时完成代理浏览的功能。
如果所有域名都在 198.18.0.0/16 内,那 wireguard 等无法接管对应的流量。 clash 的 dns 服务提供了例外配置,我们把使用 wireguard 和 openconnect 代理的域名添加进去。 此时这些域名的会指向原本的 ip ,这样一来就完成以下内容:
如果所有网站都使用域名提供服务,那可太开心了,上面这波配置就结束了,可是像 Telegram 客户端会直接使用 ip 访问,这个我们直接补一份 Telegram 的 ip 段路由到 clash tun 即可。
到这一步基本上就完成了!接下来我们让这一套流程开机自动执行。
比较遗憾的是 clash 还没有提供像 openconnect 的 --vpnc-script 参数,可以调用一个脚本配置路由。
在这里我创建了两个 plist ,参见: https://gist.github.com/DianQK/752412a5b79d4117bb95127a096ffdc1 。
最后补充,这还有个优势,如果你挂了 qt 等服务,这可以在 ip 路由上避免 qt 走代理。