Clash 扩展脚本使用
最近在使用 Clash Verge 作为本地工具实现一些网络访问。
在订阅一些代理源时,遇到了一些访问内网网站使用的问题。
首先说一下我的环境,使用的 Windows11 + Clash Verge v2.4.2。
1. 自己搭建搭建的经验-小水管/不稳定问题
最开始我使用的是自己搭建的服务器作为中转,规则全是自己写的,所以流量都自己定义,同时访问内部网站和外部网站都可以。
2. 服务商提供-有内网访问问题
但是自己搭建的终究还是很不稳定,并且带宽也小,所以就想使用一些提供成熟服务的代理服务提供商(说白了就是氪金了)。
氪金是爽,访问也很稳定,并且带宽也可以。
但凡事总有但是,此时就会出现开了代理之后,内部网站就无法访问的问题。
3. 内网访问失败原因
原因也很简单,就是公司内部有一些 自己建的DNS和内部才能解析的域名,
而开启代理后这些 流量全走代理先一步解析 ,导致了无法访问这些服务。
解决方案也很简单,就是在Clash的配置文件中添加一些规则,让这些内网域名不走代理,直接走本地网络即可。
4. 一般解决方案
我们服务商一般都会提供一个订阅链接,我们只需要订阅就行,他自己会帮我们更新配置文件.
但是这就是问题所在,每次我们自己修改好配置文件,并且可以愉快的访问内外网后,你一个更新订阅——好了,你的修改被覆盖掉了 :)
这就导致了你每次更新配置后,都需要再去修改一次..
实在是太麻烦,太不优雅了(不适合懒人)。
5. 更方便优雅的解决方案
还好Clash Verge 提供了一些机制给我们使用, 有两种 配置覆盖 和 脚本动态修改(推荐)。
当你同时使用两种方式的时候,他会先应用 配置覆盖 后再应用 脚本动态修改。
5.1 配置覆盖
先说配置覆盖,这个一般在订阅中不太常用,因为通过我的实验,他只能一条配置完全覆盖,不能做添加/删除/修改的操作,
而订阅所获得的配置文件一般有自己的规则,我们直接覆盖掉那外网代理规则就没了 :)
但是,我也在这里简单提一下,功能界面入口如下:

再右键并且选择编辑文件后是这样:

我们可以在这里添加一些规则,覆盖掉订阅的配置文件中的规则。
需要看生成的结果,可以在下图这里点开开,这里会显示出当前应用后的最终配置文件:

他的格式是 yaml 格式的,我们可以添加一些规则进去,比如一个公司的域名mycompany.com:
rules:
- DOMAIN-SUFFIX,mycompany.com,DIRECT
然后让我们假设订阅得到的配置如下(简略版):
mixed-port: 7897
# other..
rules:
- DOMAIN-SUFFIX,internal.company.com,DIRECT
- DOMAIN-SUFFIX,another.internal,DIRECT
# more
本来你可能想的是我把我公司的域名也加进去不就好了,可能期待的如下。
mixed-port: 7897
# other..
rules:
- DOMAIN-SUFFIX,mycompany.com,DIRECT
- DOMAIN-SUFFIX,internal.company.com,DIRECT
- DOMAIN-SUFFIX,another.internal,DIRECT
# more
但是最后生成的结果可能就不是你期待的了,最后的结果可能如下:
mixed-port: 7897
# other..
rules:
- DOMAIN-SUFFIX,mycompany.com,DIRECT
# more
此时,你可以访问你的公司内网域名了,但是订阅的其他规则都没了 :)
还有,一般订阅的规则会使用 fake-ip + 自定义的 DNS 来确定流量走向,
一般查到的国内ip都会直接走直连,外网才走代理,或者在你明确写了的时候才走代理。
对于域名的访问他会默认先给你解析成IP, 所以一般公司内网还需要配置规则中加 no-resolve,
更多规则相关的知识需要你上网查询了, 我这边只给出了我自己成功的一些例子
5.2 脚本动态修改
脚本动态修改就方便多了,我们可以写一个脚本,在每次配置更新后,动态的把我们想要添加的规则添加进去。
入口就在上面覆盖配置的旁边,不然图图太多了,操作也是一样的操作,但是基础的内容变成了下面的东西:
// Define main function (script entry)
function main(config, profileName) {
return config;
}
这是一个 js 的钩子函数。
有两个参数,第一个就是我们的配置: config,以及配置文件的文件名:profileName。
我们要做的就是根据这两个参数对 config 做修改, 然后再把新的配置文件返回回去。
其中, config 的结构和我们的 yaml 配置文件是一一对应的,我们可以直接通过 js 的方式对他进行操作。
在这里我只做简单的示例,你们要是有什么更复杂的骚气的操作,就需要自己去看看 js 教程了(大佬当然不在此列:)。
5.2.1 第一个就是日志打印以及可以对不同的配置做差异化修改了.
差异化修改可以帮你在不同配置上应用不同的规则。
日志就是帮你调试用的,否则不知道错在哪里是很痛苦的事。
例如,我自己搭建的配置代理和配置就不想对他做修改(名称是: clash_rules.yaml), 我就像下面这些在函数开头写:
function main(config, profileName) {
// 如果是clash_rules.yaml, 直接原样返回
if (profileName === "clash_rules.yaml") {
return config;
}
// 打日志
console.log(profileName);
return config;
}
你在保存脚本后他就会立马应用一次,在更新订阅时也会自动执行。
日志的查看点击如图的按钮:
你还可以从 config 中取不同的参数来判断,他就是个 js 函数而已 :)
5.2.2 第二个就是实际的修改了
我这里只做了一些添加的工作,把公司内部的 DNS服务器地址 和一些 内网域名 加到了规则的最前面,
这样让代理遇到这些就先走内部的解析,如下所示:
function main(config, profileName) {
if (profileName === "clash_rules.yaml") {
return config;
}
console.log(profileName);
// 添加 DNS nameserver
const orig = config.dns["nameserver"] || [];
orig.push("172.16.xx.xx");
orig.push("10.200.xxx.xx");
// ...
// 使用修改过的值覆盖掉原来的
config.dns.nameserver = orig;
const origFilter = config.dns["fake-ip-filter"] || [];
config.dns["fake-ip-filter"] = ["*.open-xxx.com", "*.inner-xxx.com", ...origFilter];
// rules 插入前面
const origRules = config.rules || [];
// 使用修改过的值覆盖掉原来的
config.rules = [
"DOMAIN-SUFFIX,open-xxx.com,DIRECT,no-resolve",
"DOMAIN-SUFFIX,inner-xxx.com,DIRECT,no-resolve",
"IP-CIDR,60.xxx.xxx.xxx/32,DIRECT,no-resolve",
...origRules
];
return config;
}
好了现在就可以愉快的订阅和更新了,再也不用担心被覆盖以及每次都去搞一次了 ^_^
clash 规则和配置文件的话需要大家自己去网上看看了,或者直接 ChatGPT 问问,我就是这样 ^_^ 只能说比 X 度方便
再次提醒一下, 需要看生成的结果,可以在下图这里点开开,这里会显示出当前应用后的最终配置文件:
