Clash 中 GeoSite 分流的正确使用方式
文章目录
因为觉得写 ruleset 太麻烦,研究了一下 GeoSite,发现其实在「正确的配置」下,只靠 GeoSite 就能满足绝大部分的分流需求。这方面的文章好像很少,写一篇分享一下折腾经验。
GeoSite 是啥
GeoSite 也是一组规则列表,很多配置文件中都有用到它,只不过用的不多。
随便找了个例子,下面的 geosite:cn,private
和 GEOSITE,cn
都是在引用 GeoSite 规则。
|
|
和普通的规则集相比,GeoSite 有哪些不同呢?
使用简单
绝大多数工具都内置了对 GeoX 系列的支持,有些工具甚至不用特地引入,默认就给你带上了,直接写就行,就像上面的配置一样。
树形规则
GeoSite 底层是一系列小规则,这些小规则又组成更大的规则,最终汇总到几个大分组上,因此可以通过指定不同的分组来实现灵活的分流。
graph LR cn --> category-games; cn --> category-bank; category-games --> mihoyo; category-games --> tencent-games; mihoyo --> mihoyo.com mihoyo --> mihoyogift.com
而 ruleset 只有一个层级,只能把它当成一个整体使用。
属性过过滤
GeoSite 支持 @attr 来进一步筛选分组中的规则,灵活程度更上一层楼。
比如 steam@cn
可以过滤出国内直连的 steam 域名。
又比如 jd@!cn
可以过滤出 jd 的国际域名。
GeoSite 规则现状及问题
v2fly/domain-list-community
这是目前 GeoSite 最上游项目,由 v2fly 进行维护。
它的问题在于分组规则很迷惑,很多域名会同时归属两个截然相反的规则(我也说不好算是 bug 还是 feature)。
像 geolocation-cn
和 geolocation-!cn
,从字面意思上看,应该分别是国内和国外域名,但实际上里面有大量重叠域名。
大部分人更常用的是 cn 规则,它由 geolocation-cn 和 tld-cn 组成。我喜欢拆开写,这样看起来整齐一点(
如 steampowered.com.8686c.com
这个应该直连的域名,同时归属 geolocation-cn
和 geolocation-!cn
,一旦你这么写规则,就会因为匹配到 geolocation-!cn
而走代理浪费流量。
|
|
那是不是把 geolocation-cn
规则放到前面就行了呢?也不行,tiktok.com
也归属这两个分组,但是它应该走代理,如果先匹配到 geolocation-cn
就会变成直连。
这个看起来无解(其实并不)的问题导致很多人,甚至官方维护者,都建议使用下游规则1。
Loyalsoldier/v2ray-rules-dat
这应该是目前使用最广泛的 GeoSite 分支了,其他分支基本上都是在这上面小修小补,它有两大特点:
- 修复了原始项目的分组问题,从
geolocation-cn
和geolocation-!cn
剔除了@!cn
和@cn
域名,防止冲突。 - 引入了大量其他规则作为补充。
相比默认配置的 GeoSite,这个版本绝大多数情况下确实工作得更好,但是,仍然存在一定的问题,而且恰恰也是这两点导致的。
域名分组缺失
首先,剔除掉 @cn
和 @!cn
后,确实不会「误分流」了,但是变成「漏分流」了。因为它们既不在 geolocation-cn
中也不在 geolocation-!cn
中,如果你不用 cn 分组就匹配不到它们,很难说究竟和原版相比哪个更符合直觉。
比如域名 gstore.val.manlaxy.com
,既不在 geolocation-cn
也不在 geolocation-!cn
,只能用 steam@cn
来引用它 。但问题就在于——我不知道究竟哪些域名是漏网之鱼,总不能把所有 category-x@cn
分类都写一次吧……
过于宽泛的 CN 规则
可能是为了弥补第一点造成的问题,项目额外引入了 dnsmasq-china-list/accelerated-domains.china.conf 补充到了 CN 规则中。
吐槽一下,这个做法导致了 geolocation-cn + tld-cn != cn,也很反直觉,会坑到一些用户
乍一看很好,但实际上 accelerated-domains.china.conf 并不代表能国内直连的域名 ,它的收录标准(之一)是是否有中国 NS 服务器,而不是域名解析结果是否在中国,导致了一些错误的分流结果2。
甚至在 dnsmasq-china-list 2023 年的一个 issue 3中,有人使用脚本进行筛选,发现这个列表中有 43% 的域名解析结果都不在中国。虽然不在中国并不意味着不能直连,但肯定是起不到到加速效果的。
仍然存在的冲突分组
继上面的问题,由于 cn 分组中添加了其他规则,又再次导致了某些域名同时出现了两个冲突的分组中。
比如 vscode.download.prss.microsoft.com
,既在 geolocation-!cn
分组,也在 cn
分组中,如果没用 microsft@cn
指定它直连,就会走代理浪费流量。
正确用法
流量分流
经过一番研究之后,我认为最好还是使用原版 GeoSite 作为基础,再此基础上再搭配其他规则进行分流。
至于原版规则存在的问题,其实规避起来非常简单。使用 @cn
和 @!cn
属性搭配如下写法,就能避免原版规则中存在的问题,实现正确的分流:
|
|
—— geolocation-!cn 整体是国外网站,只是存在一些国内加速域名,那就先使用 @cn 筛选出这些域名进行直连,剩下的再走代理。如 alibaba.cdn.steampipe.steamcontent.com 之于 steam 分组。
—— geolocation-cn 整体是国内网站,只是存在一些只能在国外访问的域名,那就先使用 @!cn 筛选出这些域名进行代理,剩下的走直连如 jd.hk 之于 jd 分组。
由于 geolocation-!cn@cn
已经包含了诸如 steam@cn
这样的子分组规则,不需要额外设置就可以实现绝大部分域名的正确分流,劣势瞬间变成了优势。但在 Loyalsoldier 分支就无法这么写,因为它不存在 geolocation-cn@!cn
和 geolocation-!cn@cn
分组,必须手动写 steam@cn
这样的子分组名称。
steam 直连其实还需要额外设置 steamserver.net 为直连,否则 steam 进行测速后还是会从国外 CDN 下载游戏,此时还是会走代理。4
fake-ip-filter
众所周知,fake-ip 模式有个问题,就是域名 ping 不通,这会导致一些程序错误地认为自己没有联网(比如 Windows)。
常见的解法是把 msftconnecttest.com 和 msftncsi.com 加入 fake-ip-filter,但这只解决了 Windows 的问题。
更好的方法是使用 geosite:connectivity-check
分组,这里面包含了安卓、苹果、Windows、华为、KDE、Arch Linux ……的连通性检查域名,一劳永逸。
|
|
DNS 分流
完美了吗?还没有。除了流量分流以外,DNS 分流也很重要。像 fonts.googleapis.com 这样的域名,虽然没有被墙,但是如果使用国外 DNS 解析,也会造成访问非常缓慢。
如果发现「明明设置了直连,但是反而更慢了?」,大概率就是没有配置 DNS 分流,导致直连的其实是国外 IP。
Clash 中的 DNS 配置策略有挺多的,这里采用最简单的一种:
|
|
解释一下这一堆 nameserver 的作用:
default-nameserver
用来解析「DNS 服务器域名」的 DNS,需要直接使用 IP
proxy-server-nameserver
用来解析「代理服务器域名」,防止 nameserver 无法访问导致连不上代理。 比如上个月国外 DoH 大规模被墙,很多 nameserver 设置为国外 DoH,又没有设置 proxy-server-nameserver 的人就连不上代理了(我自己就是)。
direct-nameserver
「直连」域名的解析,这里用了 DoH 来防止劫持。直接用运营商的 DNS 也行,愿意自建 smartdns / adgurad home 等服务效果更好。
nameserver
用来解析没有匹配到任何「域名规则」的域名,通常是国外域名,建议使用国外 DoH 防止污染。但这个解析结果并不会用来发起连接,所以为了追求速度不使用 DoH 或直接使用国内 DNS 也行。
这里我配置得比较复杂:
- PROXY - 查询时使用的代理接口,如果使用能直连的国外 DoH 也可以省略。
ecs=120.76.0.0/14&ecs-override=true
- 使用 ECS 来查询,这样可以尽量避免能直连的网站解析出国外 IP。但是需要注意不是所有 DNS 都支持 ECS。
nameserver + direct-nameserver 的解析流程非常清晰,没有弯弯绕——
flowchart TD Rule[匹配规则] Domain[匹配到域名规则] IP[匹配到目标 IP 规则] NameServer[使用 nameserver 查询] DirectNS[使用 direct-nameserver 重新解析] Proxy[发送域名给代理] Direct[使用 IP 直接连接] Rule --> Domain Rule --> IP Domain -- 域名匹配到直连 --> DirectNS IP --> NameServer NameServer -- IP 匹配到直连 --> DirectNS DirectNS --> Direct NameServer -- IP 匹配到代理 --> Proxy[发送域名给代理] Domain -- 域名匹配到代理 --> Proxy
另一个常用方案 nameserver-policy 也可以达到同样的效果,但 nameserver-policy 的配置比较复杂,没配置好反而会适得其反。
举例来说,很多人在更新 rules 时并不会更新 nameserver-policy。比如发现 download.org 有国内节点,可以直连,于是就写下了:
|
|
这个写法问题在于一旦 geosite:cn
没有匹配到 download.org
,clash 就会使用 nameserver 来解析,结果通常是一个国外 IP,效果适得其反。
相比之下 direct-nameserver 就简单多了,只要是直连规则,一定会使用它来解析,免去手动配置的麻烦。
引入其他规则
Loyalsoldier/v2ray-rules-dat 引入的很多规则确实很强大,比如去广告就比原版分支强多了。幸运的是 Loyalsoldier 提供了 txt 格式的域名集合,可以直接在 Clash 中导入。
例子:
|
|
尽量避免使用 classical 规则
引入第三方规则时,注意尽量不要使用 behavior 为 classical 的规则,理由如下:
1. 性能
ruleset 的 behavior 支持 domain、ipcidr 和 classical 三种。
前两种只能进行域名/IPCIDR的匹配,优化更好;后者则是支持完整语法的 clash 规则,但资源消耗更大。对于大型规则,最好是选用 domain/ipcidr 格式来降低资源占用。
2. 优化 DNS 查询
正常情况下,一个匹配到域名规则的网站应该直接走直连/代理。
但如果在域名规则之前存在不带 no-resolve 的 IP 规则,clash 会立即进行 DNS 查询。这不仅浪费时间,根据不同的配置也可能出现 DNS 泄漏风险甚至分流错误。
这里最大的坑点在于某些 classical 规则里也会有 IP 规则,没注意就可能掉坑里。
杂七杂八
GitHub - snowie2000/geoview: A handy tool to extract information from geosite/geoip
每个人都有不同的需求,因此没有什么规则是完美的。
在研究过程中,我发现 geoview 这个工具非常好用,它在查询域名时可以把属性也列出来,可以有效帮助你制定更细化的分流规则。
比如在 BT 下载时发现 tracker 竟然在走代理,但我希望它直连,于是就可以查询 tracker 域名属于哪个分组
|
|
通过查询结果可以发现 tracker 原来不在 cn
或 !cn
分组中,而是单独的「顶级分组」 category-public-tracker。
我顺便用脚本查询了 GeoSite 中的所有「顶级分组」,可以按需取用确保规则覆盖完全。
|
|
-
tiktok.com为什么归到cn? · Issue #1585 · v2fly/domain-list-community · GitHub ↩︎
-
accelerated-domains.china.conf 不应作为 geosite:cn 的上游 · Issue #399 · Loyalsoldier/v2ray-rules-dat · GitHub ↩︎
-
存在多条冗余域名,筛除脚本可能有 bug · Issue #483 · felixonmars/dnsmasq-china-list · GitHub ↩︎
-
是否可以添加steam@cn对下载时的支持 · Issue #254 · Loyalsoldier/v2ray-rules-dat · GitHub ↩︎