前言
有的时候下载 BitTorrent 会发现被拦截,查看了 Clash 的日志会发现,流量按照分流规则走了机场代理,但是机场是禁止 BT 下载 的,所以需要在 Clash 配置文件中加入一条使 BitTorrent 不走代理(即直连)的规则,但是目前 Clash 的配置文件中节点和规则以及配置是严重耦合在一起的,那么就需要一个工具来帮助我们实现这个需求,研究了一下发现 Surgio 可以胜任。
需求
现有多个机场订阅以及节点信息:
- Clash(V2Ray)
- Clash(SSR)
- Vmess
想将其合并成一个 Clash 配置文件,并且自定义一些分流规则。
Surgio
Surgio 就是一个可以实现(包括但不仅限于)上述需求的好帮手。
关于 Surgio 的详细介绍,还请看 Surgio官方文档 ,文档写的较为全面,对于我这样的小白来说,初次上手确实有些摸不着头脑,网上相关的教程也较少(可能大佬看一看就明白了吧,觉得没啥可以分享的)。
就这样,反反复复研究了小两天,整理出了以下内容,来解决上述需求。
Surgio 环境配置
- 以 ’$’ 开头的内容是需要输入至终端的,本教程基于 macOS Catalina 环境,其他平台请参照 Surgio 快速上手
安装 Node.js
$ brew install node若提示 Command not found 'brew',请安装 Homebrew后再次执行该命令安装 Node.js。
# 安装 Homebrew
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"下载 ssr-local 二进制文件
Surgio 导出 SSR 配置时需要 ssr-local 的支持,否则后面执行命令时会报错。
(后期可以通过配置 binPath 或者删除冗余的 SSR 导出配置等内容来优化)
# 该命令的作用是下载 ssr-local 到指定位置,并为其添加执行权限。
$ curl -L https://github.com/tindy2013/shadowsocks-static-binaries/raw/master/shadowsocksr-libev/macos/ssr-local -o /usr/local/bin/ssr-local && chmod +x /usr/local/bin/ssr-local安装 Surgio
# 安装
$ npm init surgio-store my-rule-store
# 或使用国内镜像安装
$ npm init surgio-store my-rule-store --use-cnpm
# 切换到仓库目录
$ cd my-rule-storemy-rule-store 目录如下:
.
├── node_modules
├── package-lock.json
├── package.json
├── provider
├── surgio.conf.js
└── template当前你只需要关注三个东西,他们的作用大致如下:
provider- 里面包含你的机场订阅和节点信息template- 里面包含输出文件的格式与配置surgio.conf.js- 里面是你所需要的规则和机场订阅的组合方式等等配置
添加机场订阅和节点信息
第一步,先将多个机场订阅和一些单独的节点添加到 Surgio 中。
添加机场订阅
进入 provider 文件夹
$ cd provider你能看到以下内容:
.
├── README.md
├── demo.js
├── ssr_subscribe_demo.js
├── subscribe_demo.js
└── v2ray_subscribe_demo.js首先对 subscribe_demo.js 进行修改,将 url 中的内容替换成你的机场订阅。
module.exports = {
- url: 'https://gist.githubusercontent.com/geekdada/34353d6ae23abd48f6e200b00747a87e/raw',
+ url: 'https://example.com/clash_v2.yaml',
type: 'clash',
// 定义所有的节点都支持 udpRelay
udpRelay: true,
// 添加国旗 emoji
addFlag: true,
};如果你有多个机场订阅的话,则根据 subscribe_demo.js 格式在当前目录下多创建几个文件,以我上面(两个 Clash 订阅链接)的需求为例:
# 拷贝出一份新的文件
$ cp subscribe_demo.js subscribe_demo_1.js对 subscribe_demo_1.js 的内容进行修改:
module.exports = {
- url: 'https://example.com/clash_v2.yaml',
+ url: 'https://example.com/clash_ssr.yaml',
type: 'clash',
// 定义所有的节点都支持 udpRelay
udpRelay: true,
// 添加国旗 emoji
addFlag: true,
};这样 subscribe_demo.js 和 subscribe_demo_1.js 中就分别保存了 Clash(V2Ray)和 Clash(SSR) 的订阅地址。
添加节点信息
接下来我们在 demo.js 中可以看到一些节点信息填写的模板:
'use strict';
module.exports = {
type: 'custom',
nodeList: [
{
nodeName: '🇺🇸US',
type: 'shadowsocks',
hostname: 'us.example.com',
port: '10000',
method: 'chacha20-ietf-poly1305',
password: 'password',
obfs: 'tls',
'obfs-host': 'gateway-carry.icloud.com',
'udp-relay': true,
},
{
nodeName: '🇭🇰HK(Netflix)',
type: 'shadowsocks',
hostname: 'hk.example.com',
port: '10000',
method: 'chacha20-ietf-poly1305',
password: 'password',
'udp-relay': true,
},
],
};只需稍作修改即可,结构可参考 官方文档:Provider - custom 。
到此为止,我们已经将多个机场的订阅信息和一些节点的信息就添加到了 Surgio 的配置中。
接下来添加一些我们所需要的分流规则。
配置分流规则
在 官方文档 中,我们可以了解到 Surgio 支持符合 Surge Ruleset 标准,我们就以添加 surge-rules 中的 RULE-SET: 广告域名列表 reject.txt 规则为例,在生成的 Clash 文件中拦截该规则下的域名。
添加规则
对 my-rule-store 文件夹下的 surgio.conf.js 进行修改:
module.exports = {
remoteSnippets: [
{
name: 'apple', // 模板中对应 remoteSnippets.apple
url: 'https://raw.githubusercontent.com/geekdada/surge-list/master/surgio-snippet/apple.tpl',
surgioSnippet: true
},
// 省略一些规则
{
name: 'paypal', // 模板中对应 remoteSnippets.paypal
url: 'https://github.com/DivineEngine/Profiles/raw/master/Surge/Ruleset/Extra/PayPal.list'
},
+ // 添加广告域名列表规则
+ {
+ name: 'ad-reject',
+ url: 'https://raw.githubusercontent.com/Loyalsoldier/surge-rules/release/ruleset/reject.txt'
+ },
]
}好,到此 Surgio 已经知道了该去哪里获取规则,接下来我们需要让 Surgio 知道这些规则该应用在哪里。
模板中应用规则
进入 template 文件夹,对其中的 clash.tpl 文件进行编辑:
rules:
+ {{ remoteSnippets.ad-reject.main('REJECT') | clash }}
{{ remoteSnippets.apple.main('🚀 Proxy', '🍎 Apple', '🍎 Apple CDN', 'DIRECT', 'US') | clash }}
{{ remoteSnippets.netflix.main('🎬 Netflix') | clash }}
{{ remoteSnippets.hbo.main('🚀 Proxy') | clash }}
{{ remoteSnippets.hulu.main('🚀 Proxy') | clash }}
{{ youtube_rules.main('🚀 Proxy') | clash }}
{{ us_rules.main('US') | clash }}
{{ remoteSnippets.telegram.main('🚀 Proxy') | clash }}
{{ blocked_rules.main('🚀 Proxy') | clash }}
{{ direct_rules.main('DIRECT') | clash }}在该文件中,我们添加的内容代表,从 surgio.conf.js 文件中的 remoteSnippets 中找到名字为 ad-reject 的规则,将该规则设置为 拒绝(REJECT) 状态,这样符合该规则的请求就会被拦截,从而达到去除广告的效果。
最开始的需求基本配置完毕,接下来我们需要将多个机场订阅和一些单独的节点合并生成一个 Clash 配置文件,并且其中需要包含刚刚配置的规则。
导出配置
这一部分需要回到 surgio.conf.js 中进行修改:
artifacts: [
// 省略一些内容
/**
* Clash
*/
{
+ // 该导出文件包含 Clash(V2Ray)
- name: 'Clash.yaml',
+ name: 'clash_v2.yaml',
template: 'clash',
provider: 'subscribe_demo', // 对应 provider 中的 subscribe_demo.js
},
{
+ // 该导出文件包含 Clash(SSR)
- name: 'Clash_custom_dns.yaml',
+ name: 'clash_ssr.yaml',
template: 'clash',
provider: 'subscribe_demo_1', // 对应 provider 中的 subscribe_demo_1.js
customParams: {
dns: true,
}
},
+ // 合并节点
+ {
+ // 该导出文件包含 Vmess + Clash(V2Ray) + Clash(SSR)
+ name: 'clash_combine.yaml',
+ template: 'clash',
+ provider: 'demo', // 对应 provider 中的 demo.js
+ combineProviders: ['subscribe_demo', 'subscribe_demo_1'],
+ },
// 省略一些内容
],输出代理配置文件
# 切换到项目根目录
$ cd my-rule-store
# 生成配置文件
$ npx surgio generate执行成功后,会生成一个 dist 文件夹,其中应该包含:
- clash_v2.yaml
- clash_ssr.yaml
- clash_combine.yaml
将 clash_combine.yaml 这个合并之后的 Clash 配置文件拷贝至 ClashX 的配置目录内,然后在 ClashX 中切换配置即可。
按照上面的配置,可以实现本文一开始的需求。
但是还是有以下可以优化的地方:
- 每次修改规则配置后,需要重新拷贝配置文件至 ClashX 配置目录下。
- 机场更新节点订阅后,需要重新生成配置文件。
- 配置新机器的代理时,需要先在本地配置 Node 和 Surgio 环境。
参考了官方文档,发现可以将 Surgio 部署到 SaaS 平台上,例如 Vercel 和 Heroku。
那么就开始吧~
部署 Surgio API
本地直接部署至 Vercel 的方法请参考 官方文档:快速搭建托管 API 。
以下介绍的方法是我常用的流程,将本地项目提交至 GitHub,然后在 Vercel 引如 GitHub 项目并进行部署的方法,不过会略过一些常用操作。
该流程方便后期随时随地在 GitHub 上编辑配置文件,并且 Vercel 自动化部署,无需本地再次配置环境。
# 在项目根目录 `my-rule-store` 下安装 `Surgio Gateway`。
$ cd my-rule-store
$ npm i @surgio/gateway --save
# 创建 Vercel 配置文件
$ touch vercel.json
# 创建 Surgio Gateway 配置文件
$ touch gateway.js在 vercel.json 文件中添加如下内容:
{
"version": 2,
"public": false,
"builds": [
{
"src": "/gateway.js",
"use": "@vercel/node",
"config": {
"includeFiles": [
"provider/**",
"template/**",
"*.js",
"*.json"
]
}
}
],
"routes": [
{
"src": "/(.*)",
"dest": "/gateway.js"
}
]
}在 gateway.js 文件中添加如下内容:
'use strict';
const gateway = require('@surgio/gateway');
module.exports = gateway.createHttpServer();配置接口鉴权(安全考虑,务必配置)
在 surgio.conf.js 添加如下内容
module.exports = {
gateway: {
auth: true,
accessToken: 'YOUR_PASSWORD',
},
}并将 YOUR_PASSWORD 进行随意替换。
提交至 GitHub
略
Vercel 部署
略
略略略:p