feat: 国内流量直连分流(geoip-cn / geosite-cn)— #5
国内 IP/域名直连(不走隧道)→ 省流量 + 国内访问快;非国内走代理。
- clientconfig.go: BuildClientConfig 加 ClientConfigOpts{SplitCN,RulesBaseURL};
开启时 route 加 {rule_set:[geoip-cn,geosite-cn]→direct} + 定义 rule_set
(remote .srs,download_detour:direct 直连下载)
- rules.go: 控制面静态服务 /v1/rules/{name}.srs(白名单防穿越)——自托管避免
GitHub 在国内被墙的鸡生蛋;客户端反正连控制面,可达性有保证
- nodes.go ConnectNode: 读 ?split_cn → opts;NodeAPI 加 rulesBaseURL
(PANGOLIN_PUBLIC_URL);main.go 挂 /v1/rules 路由 + RulesHandler
- 客户端: connect_api splitCN→?split_cn=1;connection_provider 传 smartRoute 偏好
- deploy/single-node: 拉 geoip-cn/geosite-cn.srs 到 $DATA_DIR/rules +
设 PANGOLIN_PUBLIC_URL/PANGOLIN_RULES_DIR
验证:go test(splitCN 开/关渲染 + RulesHandler 白名单/404)+ flutter analyze +
shellcheck;不需要节点。订阅链接暂用默认 opts、DNS 分流为后续增强。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -296,9 +296,13 @@ func mountV1(r chi.Router, sqlDB *sql.DB, rdb *redis.Client, nodeSvc *nodes.Serv
|
||||
var nodeStore nodes.NodeStore
|
||||
if nodeSvc != nil {
|
||||
nodeStore = nodeSvc.Store()
|
||||
nodeAPI = httpapi.NewNodeAPI(nodeStore, nodeSvc.Hub(), os.Getenv("NODE_DERIVE_KEY"))
|
||||
nodeAPI = httpapi.NewNodeAPI(nodeStore, nodeSvc.Hub(), os.Getenv("NODE_DERIVE_KEY"), os.Getenv("PANGOLIN_PUBLIC_URL"))
|
||||
}
|
||||
|
||||
// 国内分流(#5)的 rule-set 静态服务:GET /v1/rules/{name}.srs(自托管,
|
||||
// sing-box 直连下载;PANGOLIN_RULES_DIR 默认 /var/lib/pangolin/rules)。
|
||||
rulesHandler := httpapi.NewRulesHandler(os.Getenv("PANGOLIN_RULES_DIR"))
|
||||
|
||||
// ── Subscription URL (web user-center 订阅导入) ───────────────────────────
|
||||
subAPI := httpapi.NewSubscriptionAPI(sqlDB, nodeStore, os.Getenv("NODE_DERIVE_KEY"), os.Getenv("SUB_BASE"))
|
||||
|
||||
@@ -310,6 +314,9 @@ func mountV1(r chi.Router, sqlDB *sql.DB, rdb *redis.Client, nodeSvc *nodes.Serv
|
||||
|
||||
// ─── Mount under /v1 ─────────────────────────────────────────────────────
|
||||
r.Route("/v1", func(v1 chi.Router) {
|
||||
// Public (no auth): 国内分流 rule-set 下载(sing-box 不带 token)。
|
||||
v1.Get("/rules/{name}", rulesHandler.Serve)
|
||||
|
||||
// Public (no auth): auth endpoints.
|
||||
if authHandler != nil {
|
||||
v1.Post("/auth/code", authHandler.SendCode)
|
||||
|
||||
Reference in New Issue
Block a user