96e8402cf93fbff83c34e7e33fe8a5275aee3adc
sub-provider
一个可部署的订阅聚合后端模板,目标是同时支持两种输出方式:
- 薄壳模式:客户端拉取
/clients/*.yaml,配置内继续引用远程proxy-providers/rule-providers - 打包模式:客户端拉取
/bundle/*.yaml,服务端把节点、策略组、规则全部铺开成单文件 YAML
这一版已经补上:
- 多机场源选择:
?sources=airport-a,airport-b - 单机场或多机场时,始终取第一个源的
Subscription-Userinfo返回给客户端 GET和HEAD都支持- provider 单源输出、merged provider 输出、thin client 输出、bundle 输出
- 服务端内部继续解耦:抓取、配额头解析、provider 构建、规则加载、profile 组装分层处理
当前版本会自动识别上游输入格式,支持:
- 已经能返回 Clash/Mihomo YAML
proxies:文件的地址- base64 编码的 URI 订阅
- 明文 URI 订阅
当前已兼容常见的
anytls://、vless://、trojan://、ss://、vmess://。
目录结构
sub-provider/
app/
config.py
main.py
models.py
services/
cache.py
headers.py
loader.py
profiles.py
rules.py
subscriptions.py
config/
sources.yaml
rules/
reject.yaml
direct.yaml
proxy.yaml
cn-ip.yaml
data/
cache/
.env.example
Dockerfile
docker-compose.yaml
requirements.txt
快速开始
- 复制环境变量文件:
cp .env.example .env
- 编辑
.env:
PUBLIC_PATH改成足够长的随机字符串PUBLIC_BASE_URL建议填写你反代后的最终访问地址,例如https://sub.example.comAIRPORT_A_URL/AIRPORT_B_URL都可以直接填订阅地址,项目会自动判断是 YAML 还是 URI 订阅- 允许把其中一个留空;留空时这个机场会自动跳过
- 启动:
docker compose up -d --build
- 访问检查:
- 健康检查:
http://YOUR_HOST:18080/healthz - 单 provider:
https://YOUR_DOMAIN/<PUBLIC_PATH>/providers/airport-a.yaml - merged provider:
https://YOUR_DOMAIN/<PUBLIC_PATH>/providers/merged.yaml?sources=airport-a,airport-b - Mihomo/OpenClash 薄壳入口:
https://YOUR_DOMAIN/<PUBLIC_PATH>/clients/mihomo.yaml?sources=airport-a,airport-b - Stash 薄壳入口:
https://YOUR_DOMAIN/<PUBLIC_PATH>/clients/stash.yaml?sources=airport-a,airport-b - Mihomo/OpenClash bundle:
https://YOUR_DOMAIN/<PUBLIC_PATH>/bundle/mihomo.yaml?sources=airport-a,airport-b - Stash bundle:
https://YOUR_DOMAIN/<PUBLIC_PATH>/bundle/stash.yaml?sources=airport-a,airport-b
接口说明
1. 单 provider
GET /<PUBLIC_PATH>/providers/{name}.yaml
HEAD /<PUBLIC_PATH>/providers/{name}.yaml
返回指定机场源的 provider 文件,并携带这个源的 Subscription-Userinfo(如果上游有)。
2. merged provider
GET /<PUBLIC_PATH>/providers/merged.yaml?sources=airport-a,airport-b
HEAD /<PUBLIC_PATH>/providers/merged.yaml?sources=airport-a,airport-b
把多个 provider 合并成一个 proxies: 文件返回。响应头只取 sources 参数里第一个源的配额信息。
3. 薄壳客户端配置
GET /<PUBLIC_PATH>/clients/mihomo.yaml?sources=airport-a,airport-b
GET /<PUBLIC_PATH>/clients/stash.yaml?sources=airport-a,airport-b
HEAD /<PUBLIC_PATH>/clients/mihomo.yaml?sources=airport-a,airport-b
HEAD /<PUBLIC_PATH>/clients/stash.yaml?sources=airport-a,airport-b
特点:
- 客户端收到的是轻量入口配置
- 节点更新依赖远程
proxy-providers - 规则更新依赖远程
rule-providers - 响应头同样只取第一个源的
Subscription-Userinfo
4. bundle 单文件配置
GET /<PUBLIC_PATH>/bundle/mihomo.yaml?sources=airport-a,airport-b
GET /<PUBLIC_PATH>/bundle/stash.yaml?sources=airport-a,airport-b
HEAD /<PUBLIC_PATH>/bundle/mihomo.yaml?sources=airport-a,airport-b
HEAD /<PUBLIC_PATH>/bundle/stash.yaml?sources=airport-a,airport-b
特点:
- 服务端把节点、策略组、规则全部展开到一个 YAML 里
- 适合想直接给 Mihomo Party / Clash Party / Stash 一个最终链接的场景
- 响应头同样只取第一个源的
Subscription-Userinfo - 生成后的完整 YAML 会缓存到
output/bundle-cache/,默认 600 秒内直接返回缓存 - 可用
force_refresh=true强制跳过缓存并覆盖旧缓存文件
默认策略结构
当前默认生成的策略组是一个基础版:
☁️ 机场选择♻️ 自动选择🚀 手动切换🇭🇰 香港自动🇸🇬 新加坡自动🇯🇵 日本自动🇺🇸 美国自动节点选择
其中:
☁️ 机场选择允许在“混合自动”和各机场单独自动组之间切换节点选择是最终主策略组- bundle 模式会把节点名全部展开
- thin 模式会保留 provider 引用关系
你后面要继续进阶的话,最值得加的是:
policies.yaml:把 Telegram / AI / YouTube / Netflix 这类业务组模板化regions.yaml:把更多地区从sources.yaml独立出去- URI/base64 原始订阅解析
- 鉴权层(例如前置 Caddy/Nginx Basic Auth 或仅 Tailscale 可访问)
配额头策略
为了避免聚合多个机场后“总流量怎么显示”语义混乱,这个版本统一采用:
sources只填一个机场源:返回这个机场源的配额信息sources填多个机场源:只取第一个机场源的Subscription-Userinfo
这样 Stash、Clash Party 这类客户端读取配置订阅头时,行为是稳定可预期的。
Description
Languages
Python
99.2%
Dockerfile
0.8%