一个通过 HTTP 按需生成代理订阅内容的小工具。
它会读取本地配置文件,按顺序执行其中的指令,然后把结果输出成目标格式。目前内置了两类能力:
- 指令:抓取、过滤、改名、改请求头、解析 DNS、检查订阅流量等
- 格式化器:输出为
clash、surge、loon或sing-box配置内容
本项目使用 GPL-3.0 许可证发布。
每个配置文件都是一个按行执行的流水线。
- 一行一个指令
- 按出现顺序执行
- 空行会忽略
- 以
#开头的行会被当作注释 - 参数支持双引号,适合包含空格的内容
例如:
# 从远端获取原始订阅
fetch https://example.com/proxies.yaml
# 设置请求头
header User-Agent "Clash.Meta"
# 只保留日本节点
include /日本/
# 给节点名前面加一个标签
prefix Tokyo
# 输出为 Clash 格式
clash
fetch https://example.com/proxies.yaml
include /香港|日本|新加坡/
exclude /剩余流量|即将到期/
emoji
replace IEPL IPLC
suffix Premium
clash
proxy http://127.0.0.1:7890
fetch https://example.com/proxies.yaml
proxy
clash
proxy 不带参数时会清空当前抓取代理设置。
fetch https://example.com/proxies.yaml
check-traffic
clash
如果响应头中的 Subscription-Userinfo 表示订阅已经过期,或者总流量已经用尽,程序会清空原有节点,并注入一个提示原因的占位节点,避免部分客户端因为空列表而报错。
下面的指令都会按照配置中的顺序执行。
从指定 URL 获取订阅内容,并在本地缓存响应。
说明:
- 支持 YAML 订阅
- 如果 YAML 解析失败,会回退尝试解析为 Base64 订阅
- 当缓存需要刷新时,会重新拉取远端内容
- 如果之前设置过
proxy或header,抓取时会带上这些配置
示例:
fetch https://example.com/proxies.yaml
执行本机上的第三方命令抓取订阅内容,并读取它的标准输出。
说明:
- 默认禁用,只有启动时显式传入
-allow-external-script才可用 - 输出内容会先按 YAML 解析,失败后回退尝试解析为 Base64 订阅
- 适合对接已有脚本、私有 CLI 或需要特殊认证流程的外部工具
- 这是一个高风险能力,因为规则文件会直接触发本机命令执行
- 如果同时启用在线编辑,用户提交的恶意规则可能借此执行本机命令,因此不推荐与
-editor一起使用
示例:
fetch-external "/usr/local/bin/subfetch" "--format=yaml"
与 fetch 类似,但只在本地没有缓存时拉取远端内容;一旦缓存存在,即使缓存可刷新,也优先使用缓存。
这个模式适合你希望手动控制刷新时机的场景。
只保留命中模式的节点名。
移除命中模式的节点名。
模式规则:
- 普通字符串:按包含关系匹配
/.../:按正则表达式匹配
示例:
include 日本
exclude /过期|失效|测试/
移除节点名称中的国旗 emoji。
示例:
emoji
把节点名称中的所有 <from> 替换成 <to>。
模式规则:
- 普通字符串:按字面量全文替换
/.../:按正则表达式替换,支持捕获组引用
示例:
replace IEPL IPLC
replace "/^(HK|JP) /" "$1 Premium "
给节点名称前面添加前缀。实现上这是一个“切换”操作:
- 如果节点名还没有这个前缀,就加上
- 如果已经有这个前缀,就移除
程序会自动在前缀末尾补一个空格。
示例:
prefix HK
给节点名称后面添加后缀,同样是“切换”操作:
- 如果节点名还没有这个后缀,就加上
- 如果已经有这个后缀,就移除
程序会自动在后缀前面补一个空格。
示例:
suffix Premium
把当前所有节点标记为冻结。
冻结节点不会再被后续过滤指令移除,但仍然会出现在最终输出中。
这个指令主要适合在同一个配置文件里串联多个订阅源使用:
- 先
fetch第一个网址 - 对这一批节点做过滤、改名等处理
- 执行一次
freeze - 再
fetch下一个网址,并继续处理后面这批节点
这样前一批已经整理好的节点可以被“锁住”,不会被后续针对新订阅的过滤条件误伤。
示例:
fetch https://example.com/a.yaml
include /香港|日本/
prefix A
freeze
fetch https://example.com/b.yaml
include /新加坡|美国/
prefix B
clash
设置抓取订阅时使用的请求头。
规则:
header <key> <value>:设置请求头header <key>:删除该请求头
示例:
header User-Agent "Clash.Meta"
header Authorization "Bearer token"
header Authorization
设置抓取远程订阅时使用的 HTTP 代理。
规则:
proxy http://127.0.0.1:7890:设置代理proxy:清空代理
把节点服务器地址解析成 IP,并写回配置。
默认 DNS 参数为 119.29.29.29。
行为说明:
- 会优先返回 IPv4
- 对部分 TLS / Reality / WebSocket 相关协议,会在解析前保留原始域名到
SNI或ServerName - 解析结果会缓存
示例:
resolve
resolve 1.1.1.1
检查远程响应头里的 Subscription-Userinfo。
当满足以下任一条件时:
- 订阅已过期
- 上传流量 + 下载流量大于等于总流量
程序会清空当前节点列表,并注入一个本地假的占位节点,节点名会显示为原因,例如“订阅已过期”或“流量已用尽”。
把当前节点输出为 Clash / Mihomo 风格的 YAML:
proxies:
- name: Example
type: ss
server: 1.2.3.4
port: 443响应头会设置为:
Content-Type: text/yaml; charset=utf-8
把当前节点输出为 Surge [Proxy] 段格式。
当前实现只支持部分代理类型;如果遇到未实现的类型,会直接返回错误。
响应头会设置为:
Content-Type: text/plain; charset=utf-8
把当前节点输出为 Loon 节点行格式。
当前实现只支持以下代理类型:
ShadowsocksTrojanVLESSVMess
其中:
Shadowsocks支持基础格式,以及simple-obfsTrojan支持普通 TLS 与wsVLESS支持tcp、ws、http,以及reality所需的public-key/short-idVMess支持tcp、ws
如果遇到其它代理类型或未覆盖的传输方式,会直接返回错误。
响应头会设置为:
Content-Type: text/plain; charset=utf-8
把当前节点输出为 sing-box 风格的 JSON 配置。
- 不带参数时,会输出一个只包含当前代理节点的最小配置
- 带上
base-config-url时,会先拉取基础配置,再把当前生成的节点合并进原有outbounds - 如果基础配置里已经存在同名
tag,会用当前生成的节点覆盖它 - 如果基础配置里有
selector/urltest,它们的outbounds可以写关键词,例如HK、SG、JP - 程序会把这些关键词展开成真实节点名,例如节点名里包含
HK的节点会自动加入对应分组
当前实现是一个精简支持集,主要覆盖常见场景:
Shadowsocks:基础格式、simple-obfsTrojan:tcp、wsVLESS:tcp、ws、http
查看 sing-box 合并示例
基础配置:
{
"outbounds": [
{
"type": "selector",
"tag": "Proxy",
"outbounds": ["HK", "SG", "DIRECT"]
},
{
"type": "urltest",
"tag": "Auto",
"outbounds": ["HK", "JP"]
}
]
}规则文件:
fetch https://example.com/proxies.yaml
include /香港|新加坡|日本/
emoji
sing-box https://example.com/base-sing-box.json
如果当前生成出的节点名称里有:
HK IPLC 01HK IPLC 02SG PremiumJP Tokyo
那么合并后:
Proxy会展开成HK IPLC 01、HK IPLC 02、SG Premium,同时保留DIRECTAuto会展开成HK IPLC 01、HK IPLC 02、JP Tokyo
响应头会设置为:
Content-Type: application/json; charset=utf-8
Warning
sing-box 当前实现是一个精简支持集,部分相对少用的协议细节和传输方式已经被收敛。如果你确实需要当前未覆盖的功能,欢迎提交 PR,或提 issue / 直接反馈。
go build -trimpath -o proxy-formatter .假设你在配置目录下放了一个 config.txt:
fetch https://example.com/proxies.yaml
check-traffic
exclude /过期|失效/
include /香港|日本|新加坡/
emoji
prefix IPLC
clash
Loon 输出示例:
fetch https://example.com/proxies.yaml
include /香港|日本/
loon
./proxy-formatter -dir /path/to/config -cache-dir /path/to/cache -port 15725参数说明:
-dir:配置文件所在目录,默认是当前工作目录-cache-dir:HTTP 抓取缓存目录,默认是系统临时目录下的cache-allow-external-script:允许fetch-external执行第三方命令,默认关闭-editor:启用在线编辑器,注意需要配合-password使用-password:保存配置时需要提供的密码-port:HTTP 服务端口,默认是15725
如果配置文件名是 config.txt,启动后可直接访问:
http://localhost:15725/config.txt
程序会读取对应文件,逐行执行配置,并返回最终生成的订阅内容。
如果启用了 -editor,也可以直接在首页新建规则:
http://localhost:15725/
如果需要重新编辑由编辑器创建的配置,可以访问:
http://localhost:15725/?edit=<配置文件名>
保存时需要提供 -password 对应的密码。
- 配置文件是按顺序执行的,指令顺序会直接影响结果
- 如果你需要处理带空格的参数,请使用双引号
fetch-once不会主动刷新已有缓存- 启用
-allow-external-script后,规则文件将具备执行本机命令的能力;如果再同时启用-editor,用户提交的恶意规则可能被服务端直接执行,因此不推荐启用在线编辑功能 surge当前不是全协议覆盖,复杂订阅建议优先用clash
仓库中附带了 proxy-formatter.service,可用于 systemd 部署。
本项目基于 GNU General Public License v3.0 发布,详见 LICENSE。