Files
Private-Proxy/server_config/rrpp-subscription/API.md
T

153 lines
7.4 KiB
Markdown
Raw 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.
# RRPP 订阅服务 · SSO 认证接入文档
架构:`客户端 → nginx(api.rrrosmontis.icu) → RRPP 后端(127.0.0.1:5010) → SSO(127.0.0.1:4550) → nodes.json(国家分层)`
## 1. 客户端公开端点
### 统一订阅端点
```
GET https://api.rrrosmontis.icu/v1/rrpp/subscription?method=<类型>&user=<b64url邮箱>&password=<b64url密码>[&prefer=<协议>][&rules=<模式>]
```
| 参数 | 必填 | 说明 |
|---|---|---|
| `method` | 是 | `clash` / `v2ray` / `shadowrocket` / `rrpp_client` |
| `user` | 是 | URL-safe base64 编码的邮箱 |
| `password` | 是 | URL-safe base64 编码的密码 |
| `prefer` | 否 | `vless` / `ss` / `http`,指定优先协议;缺省 `vless`,无则回退 vless→ss→http |
| `rules` | 否 | 仅 `method=clash`:`provider`(默认) / `inline` / `global`,见 §7 |
| `token` | 否 | SSO 会话 token(免密,代登录态);与 `user`/`password` 二选一 |
### 旧端点(兼容)
```
GET /v1/rrpp/nodes_update?user=<b64>&password=<b64>
```
等价于 `method=rrpp_client`。
## 2. method 说明
| method | Content-Type | 内容 | 适用客户端 |
|---|---|---|---|
| `clash` | `text/yaml` | Clash YAML:`proxies` + `proxy-groups(RRPP)` + `rule-providers` + `rules`(备注 `R.R.P.P. - 国家代码`) | mihomo / Clash Verge / ClashX Meta |
| `v2ray` | `text/plain` | base64 节点串(`vless://` / `ss://` / `http://`) | v2rayN / Shadowrocket / Quantumult |
| `shadowrocket` | `text/plain` | Shadowrocket `.conf`:`[General]` + 远程 `RULE-SET` + `FINAL`(**不含节点**) | Shadowrocket |
| `rrpp_client` | `application/json` | 旧格式节点 JSON(仅 http,remark = `服务商 流量`) | RRPP 自建客户端 |
## 3. 返回码
| 码 | 场景 |
|---|---|
| 200 | 成功 |
| 401 | 凭据缺失/SSO 认证失败 |
| 403 | tier=0(RRPP 未开通) |
| 404 | method 未知,或 `rules` 取值非法 |
| 502 | SSO 不可达 |
| 503 | nodes.json 缺失/损坏,或该 tier 无可用节点 |
## 4. nodes.json 格式(国家分层)
`C:/BtSoft/nginx/others/backEnd/api-rrrosmontis-icu/RRPP/nodes.json`,顶层为国家数组:
```jsonc
[
{
"country": "JP", // 国家代码
"available_level": [1, 2, 3], // 可见等级
"provider": "Azure", // 服务商
"traffic": "15G", // 流量限额
"domain": "iam.aeolianchi.me", // 域名
"ipv6_only": false, // 可选,true 时备注加 (IPv6)
"methods": { // 可用协议
"http": { "port": ..., "username": ..., "password": ... },
"vless": { "port": ..., "uuid": ..., "flow": ..., "sni": ..., "public_key": ..., "short_id": ... },
"ss": { "port": ..., "method": ..., "password": ... }
}
},
...
]
```
## 5. 协议选择逻辑
- `prefer` 指定则优先用该协议
- 缺省默认 `vless`(最好用)
- 该国家无 `prefer` 协议时按 `vless → ss → http` 回退
- `rrpp_client` 固定只用 `http`(兼容性),备注 = `provider + traffic`(IPv6 加 `(IPv6)`)
## 6. SSO 认证
- 后端调 SSO `POST http://127.0.0.1:4550/v1/sso/service/rrpp/nodes`(带 `X-SSO-Service-Token` + `X-Real-IP`)
- SSO 返回 `{tier: 0|1|2|3}`,0=未开通
- 服务密钥读 `sso-rrrosmontis-icu/secrets.json` 的 `service_tokens.rrpp`
## 7. 分流规则(PAC → 规则集,随订阅下发)
### 7.1 为什么不是直接下发 PAC
PAC 是给浏览器/操作系统用的 JS 自动配置;**mihomo/Clash 与 Shadowrocket 都不能读 PAC**。
两者唯一共同能吃的格式是「每行自带规则类型的规则行文本」(Clash 术语 `behavior: classical`):
- mihomo:`rule-providers`(`behavior: classical` + `format: text`)
- Shadowrocket:`RULE-SET,<url>,<策略>`(官方手册要求「规则集的内容需包含规则类型」)
因此把 PAC 数据**在后端一次性转换成三个规则集文件**,两种客户端共用同一份文件。
### 7.2 规则集文件(CDN 公开)
生成目录即 CDN 根下的 `RRPP/PAC/`,公开可访问、无鉴权(规则集本身不含节点信息):
| 规则集 | 文件 | 规则数 | 组成 | 策略 |
|---|---|---|---|---|
| `rrpp-proxy` | `rrpp-proxy.list` | 3943 | 539 `DOMAIN` + 3404 `DOMAIN-SUFFIX`(强制代理域名) | `RRPP` / `PROXY` |
| `rrpp-direct` | `rrpp-direct.list` | 16 | 16 `DOMAIN-SUFFIX`(保守直连种子) | `DIRECT` |
| `rrpp-cn-ip` | `rrpp-cn-ip.list` | 7456 | 7456 `IP-CIDR`(中国 IP 段) | `DIRECT` |
URL:`https://cdn.rrrosmontis.icu/RRPP/PAC/<文件名>`
体积:120366 / 386 / 177443 字节,合计 11415 条规则。
### 7.3 规则顺序(与 PAC 语义一致)
```
RULE-SET,rrpp-proxy → RRPP # 强制代理优先(PAC 中强制代理规则优先级更高)
RULE-SET,rrpp-direct → DIRECT # 直连种子
RULE-SET,rrpp-cn-ip → DIRECT # 中国 IP 直连
MATCH → RRPP # 其余全走代理
```
### 7.4 维护流程(PAC 更新后)
转换脚本 `gen_rulesets.py`(与本文件同目录,另在仓库 `server_config/rrpp-subscription/` 存有副本):
```bash
python gen_rulesets.py # 读 PAC 目录 → 原子覆写三个 .list(幂等,内容不变则不写)
python gen_rulesets.py --check # 只检查将有哪些变化,不写盘
python gen_rulesets.py --pac-dir <目录> --out-dir <目录> --quiet
```
- 输入:`pac_domains.json` / `pac_direct_domains.json` / `pac_ip_cn.json`
- 转换规则:`full:x`→`DOMAIN,x`;`keyword:x`→`DOMAIN-KEYWORD,x`;`regexp:`/`include:`→跳过并计数;行内 `#` 注释剥离;`*.x`/普通域名→`DOMAIN-SUFFIX,x`
- 输出排序去重、LF 换行、无注释,写盘用临时文件 + `os.replace` 原子替换
- **订阅端无需任何改动**:文件名与 URL 固定,客户端按 `interval` 自动拉新规则
### 7.5 客户端接入
| 场景 | 用法 |
|---|---|
| mihomo / Clash Verge(推荐) | `&method=clash` → 规则走 `rule-providers`,YAML 约 2.4KB,规则每 24h 自动更新 |
| 客户端不认 `rule-providers`,或想「导入一次到位」 | `&method=clash&rules=inline` → 规则内联进 YAML(约 440KB),导入即含节点+全部规则 |
| Shadowrocket(只想要规则,节点另行导入) | `&method=shadowrocket` → `.conf`,规则走远程 `RULE-SET`(在「配置 → 规则集URL」中可见并自动更新) |
| Shadowrocket(想一次导入节点+规则) | 用 `&method=clash&rules=inline`(小火箭兼容 Clash YAML,含节点信息的标准 Clash 链接可同时导入配置与节点) |
| 兜底 / 排障 | `&rules=global` → 只有 `MATCH,RRPP`,全流量走代理(等价旧行为) |
> `method=shadowrocket` 的 `.conf` **不写 `[Proxy]` 段**:Shadowrocket 的 REALITY 参数写法官方未文档化,不猜测;
> 该配置的策略 `PROXY` 指向首页当前选中的节点,节点请用 `clash`/`v2ray` 订阅导入。
### 7.6 验证记录(2026-09-19)
- 生成:11415 条规则;`regexp:` 跳过 7 条、非法 1 条
- CDN:三个 URL 均 HTTP 200,`md5` 与本地生成一致(`806808b8` / `8f89397e` / `3e75093d`)
- **mihomo v1.19.31 真实内核运行验证**:`-t` 校验通过;运行时 `GET /providers/rules` 显示
`rrpp-proxy=3943`、`rrpp-direct=16`、`rrpp-cn-ip=7456`(`behavior=Classical`),落地文件字节数与生成完全一致;
`&rules=inline` 配置亦通过 `-t` 校验
- Shadowrocket 为 iOS 应用,**未做实机验证**,仅依据官方手册的 `RULE-SET` / Clash YAML 兼容说明实现