From 45158c8b994d097f98e34c9e5a474cf8dfb13830 Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Mon, 27 Jul 2026 00:19:34 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=AE=A2=E6=88=B7=E7=AB=AF=E5=8F=AF?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=88=86=E6=B5=81(=E7=B1=BB=20Shadowrocket)?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=20+=20=E4=BA=A4=E4=BA=92=E5=8E=9F=E5=9E=8B(T?= =?UTF-8?q?ask=203,=E5=BE=85=E7=A1=AE=E8=AE=A4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 让用户自定义路由规则(域名/域名后缀/关键字/IP-CIDR/GeoIP/GeoSite × 直连/走隧道/ 拒绝),有序首命中。架构铁律(client 不拼配置)下走服务端 per-user 路由档案: App 编规则 → PUT /v1/routing-profile 存档案 → connect 时 BuildClientConfig 翻译进 sing-box route.rules,原样下发。 产物: - docs/configurable-proxy-prototype.html — 移动端三屏 mockup(规则表/加规则/文本导入) - docs/configurable-proxy-spec.html — 规则模型 + 优先级层级 + 直连真生效 (route_exclude/reverse_mapping)+ API + 校验兜底 + 与现有机制关系 + 分期 + 4 个待确认取舍 - docs/index.html 登记 设计-first,待用户确认后出实现计划开发。 Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01A79VtQA1BwTuQN1ThpvYpo --- docs/configurable-proxy-prototype.html | 225 +++++++++++++++++++++++++ docs/configurable-proxy-spec.html | 156 +++++++++++++++++ docs/index.html | 5 + 3 files changed, 386 insertions(+) create mode 100644 docs/configurable-proxy-prototype.html create mode 100644 docs/configurable-proxy-spec.html diff --git a/docs/configurable-proxy-prototype.html b/docs/configurable-proxy-prototype.html new file mode 100644 index 0000000..a8b24e7 --- /dev/null +++ b/docs/configurable-proxy-prototype.html @@ -0,0 +1,225 @@ + + + + + +Pangolin 可配置分流 · 原型 + + + +
+

Pangolin 可配置分流 · 交互原型

+

Task 3 设计稿 · 让用户像 Shadowrocket 那样自定义"哪些流量直连 / 走隧道 / 拒绝"。以下是移动端三块核心界面的视觉原型(mockup,非真实数据)。配套规则模型与实现见 配置说明文档 →

+ +
+ +
+
9:415G ▮▮▮
+ +
+
代理模式
+
+
全局代理
智能分流
全部直连
+
+
智能分流:按下面规则表逐条匹配;命中「直连」不走隧道,「走隧道」经节点出网。
+ +
内置规则(系统)
+
+
国内直连(GeoIP/GeoSite CN)
+
局域网直连(LAN/私网)🔒 强制
+
私有服务走隧道🔒 服务端
+
+ +
我的规则 · 按顺序匹配(首命中生效)
+
+
git.51yanmei.com
域名后缀 · DOMAIN-SUFFIX
直连
+
*.aliyun.com
域名后缀 · DOMAIN-SUFFIX
直连
+
github.com
域名后缀 · DOMAIN-SUFFIX
走隧道
+
广告 / 追踪(GeoSite: category-ads)
规则集 · GEOSITE
拒绝
+
35.190.0.0/16
IP 段 · IP-CIDR
走隧道
+
+
+ 添加规则
+ +
最终(未命中任何规则)
+
FINAL · 兜底动作走隧道
+
从文本导入(Shadowrocket / Clash 规则)· 重置为默认
+
+
+ + +
+
9:415G ▮▮▮
+ +
+
+
取消添加规则保存
+
类型
+
+ 域名域名后缀关键字 + IP-CIDRGeoIP 国家GeoSite 类别 +
+
+
+ +
+
动作
+
+ 直连 DIRECT + 走隧道 PROXY + 拒绝 REJECT +
+
+
说明(选填)
+ +
+
+
GeoIP/GeoSite 由服务端自托管规则集(.srs)支持,墙内可直连下载,无需梯子。IP-CIDR 支持 v4/v6。
+
预览:将翻译为 sing-box 路由规则
+
{ "domain_suffix": ["git.51yanmei.com"],
+  "outbound": "direct" }
+
+
+ + +
+
9:415G ▮▮▮
+ +
+
粘贴规则(Shadowrocket / Clash 风格)
+
# 一行一条:类型,值,动作
+DOMAIN-SUFFIX,git.51yanmei.com,DIRECT
+DOMAIN-SUFFIX,aliyun.com,DIRECT
+DOMAIN-SUFFIX,tencent.com,DIRECT
+DOMAIN-SUFFIX,flutter-io.cn,DIRECT
+DOMAIN-SUFFIX,github.com,PROXY
+GEOSITE,category-ads,REJECT
+GEOIP,CN,DIRECT
+FINAL,PROXY
+
解析后逐条加入「我的规则」,可再拖动排序。非法行(错误 CIDR / 未知类型)高亮跳过并提示。
+
解析结果预览
+
+
✓ 7 条有效
4 直连 · 1 走隧道 · 1 拒绝 · FINAL
OK
+
⚠ 0 条跳过
无非法行
+
+
+
+
+ +

三块界面在讲什么

+
+
+

① 分流规则主屏

+

代理模式三选一(全局代理 / 智能分流 / 全部直连),对应 Shadowrocket 的 Global/Rule/Direct。

+

内置规则是系统/服务端强制层:LAN 直连恒开(🔒),私有服务走隧道由服务端下发(🔒),国内直连可开关。

+

我的规则是用户自定义、可拖动排序的有序表,首命中生效FINAL 是兜底动作。

+
+
+

② 添加 / 编辑规则

+

类型(域名/后缀/关键字/IP-CIDR/GeoIP/GeoSite)→ 填 → 选动作(直连/走隧道/拒绝)。

+

实时预览该规则会被翻译成的 sing-box 路由片段,让高级用户看得懂、放心。

+
+
+

③ 从文本导入

+

粘贴 类型,值,动作 一行一条,兼容 Shadowrocket/Clash 直觉。批量建规则、迁移旧配置。

+

解析给出有效/跳过统计,非法行不静默吞。

+
+
+ +

动作与类型对照(给你确认)

+ + + + + +
动作含义sing-box outbound
直连不走隧道,本机物理网卡直接出网(国内站、CI 源、私网)direct
走隧道经 pangolin 节点出网(需科学上网的站)auto(REALITY/Hy2 择优)
拒绝直接阻断(广告/追踪/恶意域)block
+ + + + + + + + +
类型值示例匹配
域名example.com精确
域名后缀aliyun.com含子域(*.aliyun.com)
关键字google域名含该串
IP-CIDR35.190.0.0/16IP 段(v4/v6)
GeoIP 国家CN该国 IP 段(自托管规则集)
GeoSite 类别category-ads / netflix预置域名集
+ +

需要你确认:①这套 UI/模型对不对路?②要不要「从文本导入」这一块(可后置)?③规则粒度够不够(要不要 per-app 分应用代理,shadowrocket 有,较重、建议后置)?确认后我出实现计划开发。设计取舍与实现细节见 配置说明文档 →

+
+ + diff --git a/docs/configurable-proxy-spec.html b/docs/configurable-proxy-spec.html new file mode 100644 index 0000000..768518a --- /dev/null +++ b/docs/configurable-proxy-spec.html @@ -0,0 +1,156 @@ + + + + + +Pangolin 可配置分流 · 配置说明 + + + +
+

Pangolin 可配置分流 · 配置说明文档

+

Task 3 设计 · 让用户像 Shadowrocket 那样自定义路由规则(哪些直连 / 走隧道 / 拒绝)。

+

配套视觉原型:交互原型 → · 状态:设计待确认(未开发)

+ +

1. 目标与背景

+

当前 pangolin 客户端的分流是服务端固定渲染的:LAN 直连、DNS 劫持、可选国内分流(geoip/geosite-cn)、私有域名走隧道,用户无法自定义。实际需求(如 CI 编译源、公司内网、某些国内站要直连;某些站要强制走隧道;广告要拒绝)无处配置——这次暴露的「CI 流量被灌进隧道拖垮小节点」就是典型。

+

本设计给用户一套可配置路由规则,心智模型对齐 Shadowrocket 的 [Rule] 段:有序规则表,首命中生效,动作三选一(直连 / 走隧道 / 拒绝)。

+ +

2. 架构铁律:客户端不拼配置

+
ARCHITECTURE.md §3.1:Dart/Flutter 客户端不得自行拼装或修改 sing-box 配置——配置一律服务端渲染、原样下发。所以"客户端可配置"不能变成"客户端本地改 config"。
+

解法:用户在 App 编规则 → 存为服务端 per-user「路由档案(routing profile)」→ connect 时服务端把档案翻译进渲染的配置。客户端只负责编辑 UI + 存/取档案,永不碰 sing-box JSON。

+
App 规则编辑器  ──PUT /v1/routing-profile──▶  服务端存 per-user 档案(DB)
+                                                      │
+App 点连接  ──POST /v1/nodes/{id}/connect──▶  BuildClientConfig(读档案→翻译成 route.rules)
+                                                      │
+App  ◀────────── 完整 sing-box 配置(含用户规则)─────┘  原样喂内核
+ +

3. 规则模型

+

一条规则 = { type, value, action, note?, enabled }。整个档案:

+
{
+  "mode": "rule",            // global | rule | direct(对齐 shadowrocket 三模式)
+  "builtin": {
+    "china_direct": true,    // 国内分流(geoip-cn/geosite-cn → 直连)开关
+    "lan_direct": true,      // LAN/私网直连(强制,不可关)
+    "private_via_tunnel": true // 私有服务域名走隧道(服务端下发,不可关)
+  },
+  "rules": [                 // 用户自定义,有序,首命中生效
+    { "type": "domain_suffix", "value": "git.51yanmei.com", "action": "direct", "note": "CI 源", "enabled": true },
+    { "type": "geosite",       "value": "category-ads",     "action": "reject" },
+    { "type": "ip_cidr",       "value": "35.190.0.0/16",    "action": "proxy" }
+  ],
+  "final": "proxy"           // 兜底:未命中任何规则的动作
+}
+ +

类型 type

+ + + + + + + + +
type值示例sing-box 字段
domainexample.comdomain(精确)
domain_suffixaliyun.comdomain_suffix(含子域)
domain_keywordgoogledomain_keyword
ip_cidr35.190.0.0/16 · ::/0ip_cidr(v4/v6)
geoipCN · USrule_set(自托管 geoip-*.srs)
geositecn · netflix · category-adsrule_set(自托管 geosite-*.srs)
+

动作 action → sing-box outbound

+ + + + + +
actionoutbound说明
directdirect物理网卡直连(配合 route_exclude/reverse_mapping 真直连)
proxyauto经节点(REALITY/Hy2 urltest 择优)
rejectblock阻断
+ +

4. 优先级(渲染顺序)

+

服务端把规则按固定层级拼进 route.rules,自上而下首命中:

+
+
1DNS 劫持(port 53 → hijack-dns)· 系统强制
+
2LAN / 私网直连(10/8·192.168/16·127/8)· 系统强制
+
3私有服务域名 → 走隧道(PANGOLIN_PRIVATE_SPLIT_DOMAINS服务端
+
4用户规则(档案 rules[] 顺序展开)← 新增
+
5国内分流 geoip-cn/geosite-cn → 直连(china_direct 开时)
+
6FINAL 兜底(final:proxy / direct)
+
+
用户规则排在国内分流之前——这样"我要 github 走隧道""我要某国内站走隧道"能压过 geoip-cn 的直连默认。系统层(1-3)永远在用户规则之上,防止用户误配把 DNS/LAN/私有服务弄坏。
+ +

5. 直连是否真"不走 VPN"

+

direct outbound 让 sing-box 从物理网卡直接出连接。但 TUN strict_route 会把包重新捕回隧道——已有两个机制解决,用户规则复用:

+ +
这是关键实现难点:域名类直连规则要真生效,必须开 reverse_mapping 且用 local DNS 解析该域名;IP 类直连规则要真生效,值必须同时进 route_exclude_address。这两点在实现计划里逐条落。
+ +

6. 存储与传输(API)

+ + + + + +
端点作用
GET /v1/routing-profile拉当前用户档案(App 编辑器初始化;无则返回内置默认)
PUT /v1/routing-profile保存档案(服务端校验:CIDR 合法、type 合法、条数上限、去重)
POST …/connect(现有)渲染时读该用户档案,翻译进 route.rules
+

档案存 DB(routing_profiles 表:user_id · profile_json · updated_at),不走 connect body(与现有 split_cn 走 query 的约束一致——大规则集不塞 query/body)。客户端本地也缓存一份(离线可看/编,连接时以服务端为准)。

+ +

7. 校验与兜底(fail-safe)

+ + +

8. 与现有机制的关系

+ + + + + + +
现有本设计如何吸收
SplitCN(geoip/geosite-cn 直连,#5)降为档案里的 builtin.china_direct 开关(层级 5)
PrivateSplitDomains(走隧道)保留为系统层 3(服务端 env,用户不可动)
route_exclude_address(LAN)保留 + 扩展:用户 ip_cidr→direct 规则动态并入
reverse_mapping / local DNS复用:域名直连规则靠它命中
+

换句话说,本设计是把三个散落的分流机制统一收进一个用户可见、可配的规则模型,底层复用已验证的 sing-box 手法。

+ +

9. 待你确认的取舍

+
Q1 规则粒度:先做"域名/IP/GeoIP/GeoSite + 三动作"的规则表(本设计)?还是要更细(URL 正则、UA、进程名)?建议先前者,后者 shadowrocket 也少人用。
+
Q2 分应用代理(per-app):按 App 分流(仅 Android/桌面可行,iOS 系统扩展做不到)。较重,建议后置为独立任务。
+
Q3「从文本导入」:粘贴 Shadowrocket/Clash 规则批量建(原型第三屏)。锦上添花,可 Phase 2
+
Q4 档案作用域:per-user(跨设备同步,推荐)还是 per-device(每台独立)?推荐 per-user + 单档案起步。
+ +

10. 分期建议

+ +

确认这份设计后,我用 writing-plans 出 Phase 1 的实现计划(TDD、多端、服务端翻译逐条测),再开发。

+
+ + diff --git a/docs/index.html b/docs/index.html index 1387ef4..9e11b63 100644 --- a/docs/index.html +++ b/docs/index.html @@ -84,6 +84,11 @@
iOS 隧道从 PoC 桩推到真机连通 + TestFlight;五条工作线 + NE 50MB 内存闸门;iPad 横屏侧栏布局适配。
docs/ios-ipad-support-design.html
+ +
客户端可配置分流(类 Shadowrocket)设计 HTML
+
让用户自定义路由规则(域名/IP/GeoIP/GeoSite × 直连/走隧道/拒绝),有序首命中。架构铁律下走「服务端 per-user 路由档案」:App 编规则→存档案→connect 时 server 翻译进 sing-box route.rules。含规则模型、优先级层级、直连真生效(route_exclude/reverse_mapping)、API、校验兜底、分期。配套交互原型。Task 3,待确认。
+
docs/configurable-proxy-spec.html
+
Windows 客户端设计 MD
Windows 端 sing-box 子进程 + wintun 隧道客户端设计。