Files
sub-provider/README.md
2026-04-01 16:19:08 +08:00

188 lines
5.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 组装分层处理
> 当前版本会自动识别上游输入格式,支持:
> 1. 已经能返回 Clash/Mihomo YAML `proxies:` 文件的地址
> 2. base64 编码的 URI 订阅
> 3. 明文 URI 订阅
>
> 当前已兼容常见的 `anytls://`、`vless://`、`trojan://`、`ss://`、`vmess://`。
---
## 目录结构
```text
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
```
---
## 快速开始
1. 复制环境变量文件:
```bash
cp .env.example .env
```
2. 编辑 `.env`
- `PUBLIC_PATH` 改成足够长的随机字符串
- `PUBLIC_BASE_URL` 建议填写你反代后的最终访问地址,例如 `https://sub.example.com`
- `AIRPORT_A_URL` / `AIRPORT_B_URL` 都可以直接填订阅地址,项目会自动判断是 YAML 还是 URI 订阅
- 允许把其中一个留空;留空时这个机场会自动跳过
3. 启动:
```bash
docker compose up -d --build
```
4. 访问检查:
- 健康检查:`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
```text
GET /<PUBLIC_PATH>/providers/{name}.yaml
HEAD /<PUBLIC_PATH>/providers/{name}.yaml
```
返回指定机场源的 provider 文件,并携带这个源的 `Subscription-Userinfo`(如果上游有)。
### 2. merged provider
```text
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. 薄壳客户端配置
```text
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 单文件配置
```text
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 这类客户端读取配置订阅头时,行为是稳定可预期的。