wangjia
bc890974c0
fix(server): 补 #5 国内分流的 DNS 面 + 链路诊断端点( #12 )
...
#5 只分了数据面(geoip/geosite-cn 路由 direct),DNS 仍 final:remote 全量经隧道
解析 → 国内域名解析到非 CN IP、漏过 geoip-cn 又走隧道(白盒实测国内 TLS
1000-1660ms;修后 ~50ms)。
- clientconfig.go: 开分流时 dns.rules 加 {rule_set:[geosite-cn]→local},国内域名
用 local(223.5.5.5)直连解析 → 拿到真 CN IP → geoip-cn 命中直连
- main.go: PANGOLIN_PUBLIC_URL 缺失时启动告警(空则分流静默跳过,是隐蔽坑)
- nodes.go: connect 渲染加可观测日志(split_cn/rules_base/split_active/bytes)
- diag.go: 新增只读端点 GET /v1/diag/egress?host=X,节点侧量出海段耗时(白名单
防 SSRF、只回耗时数字),供白盒拆「接入段 vs 出海段」
验证:go test(splitCN 开渲染 dns.rules→local、关无 dns.rules)+ go vet;cara
实测国内 TLS 1000ms+→~50ms、接入段占 TLS 握手 ~98%。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-22 14:12:31 +08:00
wangjia
43b25c8aa0
feat: 国内流量直连分流(geoip-cn / geosite-cn)— #5
...
ci-pangolin / Lint — shellcheck (push) Has been cancelled
ci-pangolin / OpenAPI Sync Check (push) Has been cancelled
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Has been cancelled
ci-pangolin / Flutter — analyze + test (push) Has been cancelled
国内 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 >
2026-06-19 20:34:00 +08:00
wangjia
da8f3a4fef
feat(server): Hy2 自签 TLS 证书(方案①)— 补全 hysteria2 入站可用
...
Hy2 跑在 QUIC 上、强制 TLS,需服务端证书(不像 REALITY 借大站证书)。此前
handler_grpc 只发 ListenPort、cert 路径为空 → hysteria2 入站起不来。改为节点自签:
- agentd/hy2cert.go: ensureSelfSignedCert 生成 ECDSA P-256 自签证书到
/etc/sing-box/hy2.{crt,key}(幂等,缺失才生成;key 0600;SAN=reality SNI)
- singbox.go: writeAndRestart 渲染前对启用 hy2 的节点 ensure 证书并把
CertPath/KeyPath 写回 hy2 配置
- httpapi/clientconfig.go: hy2 出站 TLS 加 insecure:true + server_name,收自签
(两端自有,服务端鉴权靠 per-user 派生的 hy2 密码)
验证:单元测试(证书可被 crypto/tls 加载/幂等/0600)+ sing-box check 接受自签 hy2 入站。
注:节点实际启用 hy2 还需配 Hy2Port + 放行 UDP(单独步骤)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-19 12:12:35 +08:00
wangjia
3d87bffbe9
feat(server): P2 后端补字段 — 套餐价格 + 节点 host( #6 6B)
...
- 迁移 000014_plan_pricing(mysql+sqlite 双套):plans 加 price_cents/currency/
period,seed pro=2500 team=9900(¥25/¥99);ListPlans 返回价格字段。
- /v1/nodes 暴露 host+port(取自 node.Endpoint,无 schema 变更),供客户端实测
真实 per-client 延迟(服务端无法代知)。
- 修复 account.go 的 GetMe/weeklyGB 残留 MySQL 专属 UTC_DATE()/INTERVAL
(#1 漏网):改 Go 端算日期传 ?,否则 SQLite 节点今日/周流量恒 0。
- sqlite 迁移 up/down 测试期望版本 13→14。
go build/vet 干净;sqlite 迁移 up/down + httpapi 测试通过。节点 tag 暂不加
(无真实数据,不造空字段;客户端将不显示伪造 tag)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-18 23:42:23 +08:00
wangjia
b9e5dbec9b
refactor(client): 抽统一日志函数 logLine + 去掉重复时间戳
...
ci-pangolin / Lint — shellcheck (push) Has been cancelled
ci-pangolin / OpenAPI Sync Check (push) Has been cancelled
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Has been cancelled
ci-pangolin / Flutter — analyze + test (push) Has been cancelled
- log_time.dart → log.dart:提供 logLine(tag, msg),格式 `[时:分:秒.毫秒] [tag] msg`,
DesktopKernel / DesktopVpnBridge 散落的 print+拼接全部收敛到此。
- 下发配置 log.timestamp=false:sing-box 不再自带时间戳,避免一行打印两个时间
(之前 `[22:10:35.213] [stderr] +0800 2026-06-18 22:10:35 ...` 重复)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-18 22:17:09 +08:00
wangjia
3a20a40101
fix(client-config): Hy2 未启用时不下发 hy2-out(消除 urltest 死成员探测)
...
hy2_port 为空(当前默认,Hy2 证书未接)时,旧逻辑仍把 hy2-out 默认指向
REALITY 的 TCP 443 端口塞进 urltest 探测组,导致客户端持续探测一个无 Hy2
监听的死成员 → "connection reset by peer"。改为 hy2Enabled 才下发 hy2-out
并加入探测组;否则 outbounds/urltest 只含 reality-out。已校验下发配置。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-18 22:11:00 +08:00
wangjia
52edb377e4
fix(client-config): 去掉 local DNS 的 detour:direct(sing-box 1.12 运行时 FATAL)
...
sing-box 1.12 start-service 阶段拒绝 DNS server detour 到空 direct 出站
(FATAL: detour to an empty direct outbound makes no sense)。local DNS 去掉
detour 后走默认路由,功能不变。已在节点用 `sing-box run`(空 inbound 复现
start-service)实测启动无 FATAL —— sing-box check 抓不到这类运行时错。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-18 21:51:10 +08:00
wangjia
bdf67cb56e
fix(client-config): 加 route.default_domain_resolver(sing-box 1.12+ 必需)
...
sing-box 1.13 对缺失 default_domain_resolver 直接 FATAL。加 {"server":"local"}
后,节点下发的整份客户端配置经 `sing-box check` 验证通过(无 FATAL/废弃)。
顺带 local_test.sh:免密已生效则跳过(不再反复要密码)+ --no-build 快速重跑。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-18 21:35:50 +08:00
wangjia
df72ad60f4
fix: DNS 用 sing-box 1.12+ 新格式 + 引导仅首次显示
...
ci-pangolin / Lint — shellcheck (push) Has been cancelled
ci-pangolin / OpenAPI Sync Check (push) Has been cancelled
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Has been cancelled
ci-pangolin / Flutter — analyze + test (push) Has been cancelled
- clientconfig/mockserver:客户端配置 DNS 从 legacy address 串格式改为
type+server 新格式(sing-box 1.13 对 legacy DNS 直接 FATAL,导致连不上)
- 引导页只首次:TokenStore 加 markOnboarded/isOnboarded;main.dart 登录后
若已引导过直接进主界面,不再每次都弹引导
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-18 21:20:11 +08:00
wangjia
cadd527680
feat(backend): 挂载 /v1 API + 实现 nodes/connect 端到端
...
- 新增 internal/dpcred 包,统一 DeriveHy2Password + DefaultFlow
agentd 与 HTTP connect handler 共享同一实现
- 新增迁移 000011:nodes 表拆分 reality_prk 私钥 / reality_pbk 公钥
reality_short_id;修正 handler_grpc.go 使用私钥字段
- 新增迁移 000012:connect_credentials 持久化凭证
实现 CredentialsForNode 修复 agent 重连 resync 原先返回空的桩
- 扩展 NodeStore 接口:ListUp / EntitlementForUser /
PersistCredential / DeleteCredential;同步 grpc_test.go mock
- 新增 httpapi/nodes.go:GET /nodes、POST /nodes/id/connect
Hub.Push + PersistCredential + 渲染完整 sing-box client 配置 JSON
POST /nodes/id/disconnect
- 新增 httpapi/account.go:GET /me、GET /plans、GET /notices
- 新增 httpapi/clientconfig.go:BuildClientConfig 服务端渲染
- 重写 cmd/server/main.go:手写 chi public/protected 分组
nodes.Service/Hub 在 main 构造并共享;SMTPMailer/LogMailer
go build ./... && go vet ./... && go test ./... 全部通过
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-15 23:09:56 +08:00