使用 Surge 旁路由接管全家网络
为什么这么做?
在施工家庭网关之前,我一直都是通过在各个设备的端上各自跑一个工具来实现科学上网,对于游戏场景,则使用成熟的商业加速器,对于一些去广告的诉求,也是在各个端部署相关的工具和规则。
但是这样总还是有一些问题让我感到麻烦:
- 每个设备都需要配置一次相关的东西,设备数量多,初始化的过程比较麻烦,从工具到订阅,整个流程都要跑一遍。
- 其他家庭成员并不一定能保持良好的使用习惯,例如设定好模式、自启动,被反馈每次使用都需要开关,比较麻烦。
- 并不能很方便地在一些十分麻烦的设备上跑起来,例如 Meta Quest。
虽然上面这些问题都不是什么很大的问题,但在长时间维度上,小的问题也会被逐渐放大,我认为是时候一劳永逸地解决这些问题了。
所以我决定去做一个家庭网关,满足下面两个关键场景:
- 不论什么设备,只要接入家庭网络,就能无感科学上网,同时共享去广告规则。
- 实现必要的流量审计,一方面用于优化科学上网规则,兼容游戏场景,另一方面用于审查潜在的异常流量。
为什么用 Surge?
家庭网关的实现方式有很多种,比如直接接入一个软路由 / OpenWRT 路由直出公网,亦或是在子网下架设一个旁路由作为网关接管所有流量。
基于我现有的网络情况,我的网络是扁平且简单的。我手头上有 NAS,也有一个 XDR6088,但是我还是希望设备的功能能单一一点。对于软路由,自己建一个低功耗 x86 系统还是比较费事的,对我这种租住鸽子笼的人来说,噪音也是一个问题。另外在科学上网方案上,由于我的都是自建线路,我倾向于风险更低的方案。
在综合了各种情况之后,我还是选择用一个二手的 Mac Mini M1 配合 Surge 来做旁路由。Surge 相对来说是配置比较简便,同时 M1 相对来说性能和功耗也是比较平衡的。
在科学上网方案上,Snell 因为小众、私有,算是一个兼顾轻量、性能、延迟、安全的选择,我在 iOS 上的体验是不错的,所以在家庭方案上也就直接用了。
同时,Surge Mac 也提供了一个 Surge Dashboard,可以非常好地观测流量,覆盖了各种流量类型,基本上能够满足掌控实时流量的诉求了。
这个方案并不怎么极客,也不便宜,但是胜在稳定、易用。
方案施工
网关模式
Surge Mac 提供了一个接管家庭网络的功能,它有两种工作模式:
- 直接让 Surge 在子网启动 DHCP,Surge 通过 DHCP 实现接管。
- 其他设备直接指定网关到 Surge 的 IP,由 Surge 接管流量。
需要注意的是,Surge 不仅会接管网络流量,也会接管所有设备的 DNS。它可以选择用 VIF 完全接管 DNS,所有的 DNS 都返回 Fake-IP,也可以选择只使用 Surge 路由解析请求,返回真实 IP。
通常情况下你只需要启用 Surge 的 DHCP、停用其他路由上的 DHCP 即可,但是我的设备比较特殊,TPLink 官版固件是不支持关闭 DHCP 的,但是我需要官版固件保障稳定性,所以我选择在 XDR6088 的 DHCP 上做指向来解决问题。
搭建好之后,整个网络架构还是很简单的,家庭内的所有设备和 Surge 所在的 Mac Mini 在同一层,向上路由到 XDR6088,再通过 WAN 走到光猫出站。
IPv6
到这一步我还不能实现完全的无感科学上网,IPv6 是一个比较棘手的问题,核心在于 IPv6 的 DNS 会经过 SLAAC 分配,而 Surge 并不能处理这种情况。
假如上层有设备经由 SLAAC 分配 IPv6 DNS,会造成部分域名仍然无法访问的情况。
解决这个问题有三个方案:
- 禁用 Surge 以下设备到 Surge 的 IPv6,由 Surge 抹平差异
- 上游屏蔽 SLAAC,使用 DHCPv6 为下游分配地址,需要注意的是 Surge 自带的 DHCP 并不能这么做,同时大多数其他路由器的 DHCP 也不能精细化到 v4/v6,通常只有 OpenWRT 之类才行,你需要根据自己的设备考虑是否要用这种方案。
- 设备自己屏蔽 v6 DNS。iOS / Windows 等系统都能通过设置 v6 DNS 为 ::1,或者不设置 v6 DNS 来强制所有的 DNS 通过 IPv4 发出,这是一种权衡之计,因为所有新入网的设备都需要单独设置一次。
目前我个人使用的最后一个方案,由于它只需要设置一次,所以不至于那么麻烦,家里的设备数量也是有限的。
我目前没有体验到什么网络质量上的问题,但是考虑到在 Windows 上,微软并不允许我们不设置 v6 DNS,所以我们只能设置到 ::1,利用系统自己的 Fallback 策略来走通网络,这对网络质量还是会有一定负面影响的。
从技术角度上来说,使用 DHCPv6 是最佳方案,其他两个方案或多或少都会对连接或网络质量产生一些影响,主路由没办法支持的话,你需要根据自己的网络需求来评估使用哪个。
DNS
如上文所说,你可以通过 Surge VIF 劫持掉所有的 DNS 请求,也可以做部分劫持,也可以自行在设备端另做方案。
为了尽可能简单化,我选择用 Surge 劫持所有的 DNS 请求,同时为了避免泄漏,我也在 DHCP 端直接下发 DNS 指向到 198.18.0.2,并且每个客户端都清理掉自定义配置。
Surge 接管有一个好处,所有的下游设备都可以访问干净的 DNS,且 DNS 链路在公网上可以保证是加密的,不会因为本身设置不当等发生泄漏(前提是 Surge 本身访问的 DNS 是干净的,而且需要启用 ECH,访问 TLS / H3)。
需要注意的是这个拦截拦不住一些特定的客户端自行去做 HTTP 等模式的 DNS Query,所以如果你希望得到一个全面的拦截效果,可能还需要自行做一些重写规则(对于加密的查询可能劫持效果不佳,毕竟涉及到 MITM,很多应用本身也会结合 SSL Pinning 来验证证书是否合法,再查询 DNS)
上网方案
我个人是推荐 Snell + Hysteria 两个方案混用,Snell 适合优质线路,如果你有专线的话,通过 Snell 打游戏也不是什么大问题。Hysteria 主要用于处理一些一般的、廉价的、比较容易拥挤的线路,说人话就是斗法,获得相对好一些的延迟(当然,即使不暴力发包,使用 UDP 也能获得一定的延迟优势)。
Snell 作为 Surge 专用的小众闭源方案,主要胜在轻量和稳定,我个人目前没有遇到过什么被封禁的情况,而且确实是要比目前其他的 TCP 方案更安全、更快。
但是它也有一个前提,这个前提是设备必须要使用苹果全家桶,全套都需要使用 Surge,如果你的移动设备里有 Android,在脱离家庭网关的场景下就会比较蛋疼,如果有这种场景的话可以考虑一个服务器上跑两种服务端。
分流
到这一步,我们的整个科学上网流程就走通了,但是考虑到接入的设备多样,分流的规则还需要进一步细化。
我个人是在 https://github.com/blackmatrix7/ios_rule_script 的基础上,取了部分规则,并综合对等 IP 的 Geo-Location 进行分流。
这里的分流规则根据自己的使用习惯来做就好,线路比较多的可以做一些线路上的优选,比如 GPT 等有锁区性质的可以路由到日本,游戏可以根据目标服务器的 ASN 直接走最优线(比如专线)。
在分组方面,我个人认为除了特定线路、机器的分流,2-3 个分组就够用。我自己的习惯是优质线路配一组 Smart、其他普通线路配一组 Smart,再配一个 Fallback 组用于处理上面两种分组挂了的时候走的救急备线。这样我们可以基本保证线路故障的时候整个网络还能比较好地运转。(但是经过我实测,这里的 Fallback 其实还是不能很好兜住例如机房被 DDoS 之类被打到波动很大的情况,这种情况下还是需要手动操作)
无人值守
说到手动连接到机器上操作,就不得不说一说无人值守。Surge 本身提供了很多样化的方案进行连接,Surge 可以提供一个 HTTP API 端口,经由 HTTP 进行控制,当然我们也可以通过 VNC 或者其他远程桌面的方案来进行操作。
这里 Surge 本身提供的 Ponte 我个人认为穿透能力和稳定性十分一般,出门在外连不上是常有的事,一般来说在 Surge 上另外跑一个 Snell Server 跳回内网会比自带的 Ponte 做穿透更稳定。
远程桌面方面,我个人推荐做两条通路,一个是系统自带的 VNC,另一个可以考虑 NoMachine。做两条通路主要是双保险,因为其中某一个可能会因为奇怪的原因挂掉,或者可能因为 macOS 奇怪的锁屏机制和无人值守的冲突导致不可用,这里不建议只用一条。
SSH 连接我个人认为在 macOS 这种场景下没有什么显著的意义,Surge 本身是主打图形化界面的工具,最多只能用作兜底的救急。
体验
目前使用 Surge 的接管模式基本上可以解决 95% 的国际互联需求,而且运行期间也是很稳定的,Surge 本身没有出现过什么会导致网络不可用的异常,反而还是底层的 macOS 更不稳定…
这里 5% 解决不了的问题主要还是部分设备 IPv6 下需要手动配置,以及 Ponte 穿透实在是不尽如人意。其他方面,并没有什么太大的问题,曾经有一些比较蛋疼的局域网冲突等等问题现在也都有相对圆滑的解决方案,官方的维护也比较积极,总体上我个人对这个项目还是持乐观态度的。
Surge 我个人认为已经算是一个相当稳定且易用的方案,有一些美中不足至少在我看来都可以接受。
如果你对整个方案有更高的稳定性和功能定制需求,我个人还是不那么推荐 Surge,因为它只在其提供的功能范畴内有稳定性保障,而且不支持额外的定制,比如 VLESS,如果你需要接入这一套还是需要另外做独立的出站、转发,就很麻烦了,底层的 macOS 稳定性上也肯定不如 Linux。