说在前面
本文将介绍如何使用不优雅的方式在开启Surge for iOS时或者开启Surge for Mac的增强模式时连接Tailscale网络。
本文以介绍原理和学习,理解原理为主,在介绍如何操作之前,我都会先尽量解释原理,以及为什么要这么做。
在明白原理后再进行操作,比无脑跟着教程走更加可靠,也可以帮助到自己学习更多知识。
背景介绍
众所周知,Surge for Mac的增强模式,与基于WireGuard 的Tailscale一样都借助「虚拟网卡」来实现代理的目的,而当macOS同时运行2个虚拟网卡就会出现意料之外的错误。
我有数十台设备使用Tailscale组建虚拟局域网,而在Mac上,开启Surge的增强模式后就有几率无法访问Tailscale网络,这是无法接受的,十分的不优雅。
本人十分懒惰,不想更改规则时要改2份配置,所以iOS与Mac的Surge使用了同一份配置文件,配置文件通过iCloud进行同步,任何一端更改配置另一端都会自动重载。
需求解析
我的需求十分简单,只需要在Surge for Mac开启增强模式时以及Surge for iOS启动时依旧可以访问Tailscale网络。
macOS上无法访问Tailscale网络是因为虚拟网卡冲突,而iOS上则是因为VPN不能共存,现在就让我们来解决这个问题
需求实现 – Surge for iOS/Mac 配置文件分离
PS: 下文主要以Tailscale IP访问为主要介绍与参考,如您使用MagicDNS,将IP规则修改为域名规则即可。
macOS
如果你的Surge for Mac与iOS使用了不同的配置文件,实现前者十分的简单,可以让Surge for Mac将收到的Tailscale网络流量转发给Tailscale的虚拟网卡。
首先启动Tailscale,并打开macOS终端,并输入
ifconfig
在终端返回的结果当中找到Tailscale的虚拟网卡代号,在图中,Tailscale的代号即为utun10
在Surge GUI添加一个新的代理,并且在代理类型选择「绑定网络接口」,绑定刚刚看到的Tailscale虚拟网卡,为你的代理创建一个顾名思义的名称,如 Tailscale Direct,覆盖默认测试地址,如果启用了MagicDNS,那么将测试地址改为 http://100.100.100.100 ,如果没有启用则改为 http://{网络内任意Tailscale IP}
创建一个新的IP-CIDR规则,匹配 100.64.0.0/8
,将策略设定为你刚刚添加的Tailscale虚拟网卡代理,在这里就是“Tailscale Direct”,切记选择“如果请求使用的是域名则跳过该规则”,避免不必要的DNS查询
macOS的配置就大功告成了!现在你就可以畅通无阻的在开启Surge增强模式的情况下访问Tailscale网络
iOS
对于iOS的解决方案,由于系统限制原因,iOS不允许2个VPN同时运行,所以你需要拥有一个「可以加入Tailscale网络,并且您的iOS设备随时可以访问」的「跳板」,而在iOS设备,你只需要将Tailscale网络的请求(100.64.0.0/8)设定规则到「跳板机」上运行的代理服务器即可,「跳板机」的代理服务器收到Tailscale网络的请求后会通过Tailscale Client与网络内的对应节点建立连接,再将客户的连接代理到对应的设备,相当于将本来Surge无法直接使用的Tailscale连接转化为Surge可以使用的SSH,SS,Vmess等
这一切都是无缝且无感的,例如在完成操作后,你在iOS即可直接访问Tailscale网络的IP
这段话并不难理解,我希望你在真的完全理解这段话之后再继续看下面的教程。
作为例子,我使用我自己国内的VPS作为「跳板机」使用SSH的方式连接到国内的VPS,在Surge添加你的跳板代理,(覆盖默认测试地址,如果启用了MagicDNS,那么将测试地址改为 http://100.100.100.100 ,如果没有启用则改为 http://{网络内任意Tailscale IP}),我将跳板命名为“Tailscale Jump”,随后与macOS一样,添加一条IP-CIDR规则 100.64.0.0/8
,切记选择“如果请求使用的是域名则跳过该规则”,避免不必要的DNS查询
至此,对于iOS部分也大功告成!加入你使用MagicDNS的域名访问Tailscale网络,将IP规则改为域名规则即可。
需求实现 – Surge for iOS/Mac 同一配置
在上面就提及了,我非常懒懒懒懒,如果修改一个规则需要同时改2个配置文件,对我无意识灾难性的,而对于上方我给出的iOS/Mac配置,他们并不相融,规则会使他们冲突。
而在2024的今天,Surge依旧不支持在同一套配置文件中设定指定内容只在iOS/Mac的Surge运行时有效
接下来我将介绍如何在使用同一配置文件实现我的需求,以及我在实现的路上走的弯路。(本来打算折叠弯路模块,但是wordpress的折叠太不好用了,还是直接贴出来了好了)
弯路 1
使用「逻辑规则」来判断客户端是macOS或者iOS
结果:就算是逻辑规则也不能做到通过iOS/mac特有的特征+请求IP来判断
弯路 2
独立2份配置文件,并在配置文件中添加用于识别Only Mac的注释,借助Python脚本没分钟自动读取iCloud云盘中的Surge配置文件,注释,或者去掉给Only Mac行
结果:太麻烦了写都懒得写
弯路 3
使用Script规则,添加一个Rule的JavaScript,Surge为JavaScript提供了可以判断用户为iOS客户端或者Mac客户端的API
结果:写完了,可以用,但是导致规则匹配时间变高了整整5ms,太不优雅。附一下代码
function isInTailscaleRange(ip) {
const parts = ip.split('.');
return parts[0] === '100' && parts[1] >= 64 && parts[1] <= 127;
}
if (isInTailscaleRange($request.hostname)) {
$done({ matched: true, policy: $environment.system === 'macOS' ? 'Tailscale Direct' : 'Tailscale Home' });
} else {
$done({ matched: false });
}
正路
在经历这些弯路后我选择了最简单粗暴的办法,因为Mac的网卡策略在iOS是无法连通的,所以可以添加一个Fallback策略组,策略内包括“Tailscale Jump”与“Tailscale Direct”,Fallback策略会有优先选择排序靠前的节点,记得将Tailscale Direct位于前置。然后将IP-CIDR或者Domain规则指向这个策略组即可。