Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion docs/projects/core/protocols/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,35 @@ Mixed 同时接受 SOCKS5 TCP、SOCKS5 UDP ASSOCIATE 和 HTTP CONNECT。
}
```

### VLESS REALITY + Vision

```json
{
"tag": "vless-reality-vision-out",
"protocol": {
"type": "vless",
"server": "edge.example.com",
"port": 443,
"id": "11111111-2222-3333-4444-555555555555",
"flow": "xtls-rprx-vision",
"reality": {
"public_key": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"short_id": "0123456789abcdef",
"server_name": "www.cloudflare.com",
"client_fingerprint": "chrome"
}
}
}
```

`xtls-rprx-vision` 使用 Xray 兼容的 VLESS Addons 和 Vision 数据阶段语义。当前已验证边界是 **REALITY 上的 TCP 出站**:

- 不能与 `mux_concurrency` 组合;
- UDP 会被配置校验或运行时明确拒绝;
- `reality.client_fingerprint` 支持 `chrome`、`firefox`、`safari` 和 `edge`,默认 `chrome`;
- 历史 Zero 私有请求头加密格式只以 `flow: zero-aead-v1` 保留,它不与 Xray Vision 互通;
- 旧别名 `xtls-rprx-vision-udp443` 已拒绝,必须显式迁移到标准 Vision 或 `zero-aead-v1`。

### VMess

```json
Expand Down Expand Up @@ -334,7 +363,7 @@ Mixed 同时接受 SOCKS5 TCP、SOCKS5 UDP ASSOCIATE 和 HTTP CONNECT。

## 传输和高级字段

VLESS、VMess 等协议还支持 TLS、REALITY、WebSocket、gRPC、H2、HTTP Upgrade、XHTTP、MUX 和 UDP 相关组合。不要仅凭字段存在就任意叠加;组合限制见[完整配置字段](/projects/core/configuration/)和[协议能力矩阵](/projects/core/reference/protocol-capabilities)。
VLESS、VMess 等协议还支持 TLS、REALITY、WebSocket、gRPC、H2、QUIC、HTTP Upgrade、XHTTP、MUX 和 UDP 相关组合。不要仅凭字段存在就任意叠加;组合限制见[完整配置字段](/projects/core/configuration/)和[协议能力矩阵](/projects/core/reference/protocol-capabilities)。

完成配置后:

Expand Down
19 changes: 19 additions & 0 deletions docs/projects/core/reference/protocol-capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,25 @@ IPC:
| `vmess` | `partial` | 部分 | 部分 | 部分 | 部分 | 部分 |
| `mieru` | `supported` | 支持 | 支持 | 支持 | 支持 | 不支持 |

## VLESS 组合边界

VLESS 顶层保持 `partial`,因为不同 flow、传输、MUX 和 UDP 路径的成熟度不同。当前开发线中需要特别区分:

| 组合 | 当前结论 |
|------|----------|
| 普通 VLESS TCP + TLS/REALITY | 可用;仍需检查所选传输和发行物 capability |
| REALITY + `xtls-rprx-vision` + TCP 出站 | 已按 Xray Vision 线协议实现并完成真实进程互操作验证 |
| `xtls-rprx-vision` + `mux_concurrency` | 不支持,配置必须拆分 |
| `xtls-rprx-vision` + UDP | 不支持,会明确拒绝 |
| `zero-aead-v1` | Zero 私有兼容 flow,不是 Xray Vision |
| `xtls-rprx-vision-udp443` | 已废弃并拒绝,不再作为别名猜测 |
| Mux.Cool TCP / XUDP | 分别由 `mux_concurrency` / `xudp_concurrency` 启用,不依赖 Vision flow |
| XHTTP `stream-one` | 支持单条 H2/H2C 双向流;部署前仍需验证对端版本和链路组合 |

REALITY 客户端的 `client_fingerprint` 支持 `chrome`、`firefox`、`safari`、`edge`,默认 `chrome`。它只改变 REALITY 客户端 ClientHello;普通 TLS 和 REALITY 入站不读取该字段。

不要把“某一条真实互操作路径通过”扩大解释为所有传输、UDP、MUX 和中继组合都已具备相同成熟度。配置示例见[协议配置示例](/projects/core/protocols/configuration)。

## 部署时如何判断

对于每个节点配置:
Expand Down
116 changes: 79 additions & 37 deletions docs/projects/zboard/guides/subscriptions-and-traffic.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,65 @@
# 订阅交付与流量展示

Zboard 从节点组、协议服务和订阅模板生成面向不同客户端的配置,并根据 Zero 上报的已归属流量更新订阅使用量
Zboard 从协议服务、节点组、订阅模板和用户订阅生成客户端配置。公开订阅链接的授权边界始终是**单个订阅**,筛选参数和输出模板只能缩小该订阅已经授权的内容,不能聚合或扩展到同一账号下的其他订阅

## 订阅生成链路

```text
协议服务 → 节点组 → 订阅模板 → 用户订阅 → 客户端输出
协议服务 → 节点组 → 订阅模板 → 用户订阅 → 单订阅访问令牌 → 客户端输出
```

协议服务决定节点和凭据,节点组决定可选范围,订阅模板决定策略组、规则集、本地入口和客户端格式。修改任一层后,应通过管理端预览确认最终输出。
协议服务决定节点、凭据、启用状态和交付顺序,节点组决定可选范围,订阅模板决定策略组、规则集、本地入口和客户端格式。修改任一层后,应通过管理端预览确认最终输出。

禁用协议服务后,该服务会同时从公开订阅输出和节点运行时发布中移除;重新启用后通过现有发布流程恢复。

## 单订阅访问边界

每个公开订阅 URL 只绑定一个 `subscription_id`。Zboard 会依次验证令牌、用户归属、订阅状态、有效期和剩余流量,然后只从该订阅解析节点、协议端点和凭据。

筛选是只读投影,不是授权机制:

- `plan`、`sku`、`node_group`、`protocol`、`region`、`tag`、`exclude_tag` 和 `q` 只能继续减少结果;
- 筛选不能选择同一账号下的另一份订阅,也不能增加未授权节点或凭据;
- 合法筛选没有匹配项时返回有效的空订阅,而不是越过边界回退到其他订阅;
- `Subscription-Userinfo` 和配额元数据只描述令牌绑定的订阅,不跨订阅累计。

登录用户按目标订阅管理访问凭据:

| 方法 | 路径 | 作用 |
|------|------|------|
| `GET` | `/api/v1/account/subscriptions/{id}/access` | 读取或按需创建该订阅的访问链接 |
| `POST` | `/api/v1/account/subscriptions/{id}/access/rotate` | 只轮换该订阅的令牌 |
| `DELETE` | `/api/v1/account/subscriptions/{id}/access` | 只撤销该订阅的令牌 |

旧的账号级聚合访问接口已经移除。没有 `subscription_id` 的历史聚合令牌会在数据协调时失效,并为每份可用订阅分别创建访问令牌。

## 客户端识别与输出格式

公开交付只接受明确的订阅客户端 User-Agent。当前内置识别包括:

- 严格的 `ZNet-Sink/<版本>`,例如 `ZNet-Sink/0.0.16-rc.7`;
- Clash / Mihomo;
- sing-box。

浏览器、`curl`、空 User-Agent 或仅包含 `ZNet-Sink` 子串的伪造值会在令牌解析前进入订阅伪装跳转,避免公开接口泄露令牌是否存在。

输出格式使用规范名称:

| 名称 | 表示 |
|------|------|
| `zero` | Base64 编码的 Zero JSON |
| `clash` | Clash / Mihomo 原生表示 |
| `sing-box` | sing-box 原生表示 |

`zero-json`、`zero-base64-json`、`znet-sink` 等历史别名会归一化到 `zero`,不能借助旧名称请求明文 Zero JSON。管理端预览可以保持可读,但公开 Zero 交付只输出编码文本。

Base64 不是加密。真正的安全边界仍然是随机令牌、HTTPS、令牌轮换与撤销,以及避免在日志、截图和工单中公开完整 URL。

## 无效订阅链接

无效、已撤销或非客户端请求会返回不可缓存的 HTTP 302,并跳转到系统配置中的“订阅伪装跳转地址”。该值留空时使用站点公开访问地址。

伪装跳转不能替代令牌安全,也不应被客户端当作有效订阅响应。排查同步失败时应同时检查响应状态、最终 URL、User-Agent 和订阅令牌状态。

## 本地 Mixed 端口

Expand All @@ -24,30 +75,25 @@ Zboard 会为不同客户端生成可直接运行的本地入口:

因此订阅内容不依赖客户端在导入后临时补建入口。端口已被占用时,应在订阅模板中修改 `mixed_port`,而不是手工编辑每个用户的生成结果。

## 格式识别与表示
## 托管规则与 ZRS

当请求未指定模板或使用 `auto` 时,Zboard可以根据 User-Agent 选择内置的 ZNet Sink、Clash/Mihomo 或 sing-box 模板。显式指定模板始终优先。
Zboard 托管的规则集由平台维护,而不是由节点内核临时生成:

公开交付中的 ZNet Sink 和 canonical native JSON 使用 Base64 文本表示;管理端预览保持可读。Clash 和 sing-box 继续使用各自原生格式。
1. 管理端写入或导入规则源;
2. Zboard 归一化并校验为 canonical Zero Rule IR;
3. 内置的固定版本 `zero-rule` 编译器生成 ZRS;
4. 只有验证通过的 ZRS 才会成为 Zero 客户端可引用的发布产物;
5. Clash 和 sing-box 输出继续使用各自的规则表示。

Base64 只用于降低内容直接暴露,不是加密或访问控制。真正的安全边界仍然是:
Zero 客户端拿到的是 ZRS 产物,不是公开的 IR 文本。规则元数据保存在数据库,源文件和编译产物保存在 `ZBOARD_MANAGED_RULE_HOST_DIR`,容器内挂载到 `/var/lib/zboard/artifacts/rules`。

- 足够随机的订阅令牌;
- HTTPS;
- 令牌撤销与轮换;
- 避免在日志、截图和工单中公开完整 URL。

## 无效订阅链接

无效或已撤销的公开订阅令牌会返回不可缓存的 HTTP 302,并跳转到系统配置中的“订阅伪装跳转地址”。该值留空时使用站点公开访问地址。

伪装跳转不能替代令牌安全,也不应被客户端当作有效订阅响应。排查同步失败时应同时检查响应状态、最终 URL 和订阅令牌状态。
数据库与托管规则目录必须作为一个备份、恢复和回滚单元;蓝绿实例也必须共享同一可写规则目录。只恢复数据库而不恢复匹配的规则快照,会造成元数据与发布产物不一致。

## 策略组输出

手动 selector 会保留 `DIRECT` 和 `REJECT` 作为固定选择。URLTest 和 fallback 组不会包含它们,因为它们不是可探测节点。

订阅中的节点名称默认沿用协议服务名称,不再附加内部端点或订阅 ID。名称为空时才使用协议名作为回退。
订阅中的节点名称默认沿用协议服务名称,不再附加内部端点或订阅 ID。名称为空时才使用协议名作为回退。协议服务的交付顺序是所有渲染器共享的权威顺序,端点 ID 只作为稳定的最终排序条件。

默认延迟测试地址为:

Expand All @@ -57,38 +103,34 @@ http://www.gstatic.com/generate_204

系统只会迁移旧的内置默认值,不会覆盖运营人员自定义的测速 URL。

## 流量计费语义
## 流量计费与趋势语义

Zboard 以 Zero 上报并成功归属到订阅用户的流量事件为事实来源
Zboard 以 Zero 上报并成功归属到订阅用户的完成流量事实为来源

1. Zero 建立并记录真实连接;
2. 完成事件包含该连接的上下行字节增量和用户归属
2. 完成事实包含连接的上下行字节和用户归属
3. Zboard 幂等写入流量记录;
4. 应用协议服务或套餐配置的计费倍率;
5. 累加订阅已用流量
5. 累加该订阅的已用流量
6. 剩余流量由套餐额度减去已用流量得到。

客户端本地显示一次测速成功,不代表服务端一定建立了可归属连接。Zboard 不会根据客户端报告凭空生成流量费用。

## 流量单位展示

后台存储和计费使用精确字节。管理端根据数值自动显示 B、KB、MB 或 GB:

- 小流量不会因为固定换算为 MiB 而显示成 `0 MiB`;
- 对账差额保留正负号;
- 单位变化只影响显示,不改变数据库、API 或计费结果。
管理端和个人中心的趋势图从后端按时间范围聚合的结果读取,并使用订阅、用户、节点等业务标签展示关联实体;前端不应拉取全量原始明细后自行聚合。

排查额度时,应比较原始字节、计费倍率、订阅累计值和套餐额度,不要根据界面中经过缩放的字符串反推计算
后台存储和计费使用精确字节。界面根据数值自动显示 B、KB、MB 或 GB;单位变化只影响显示,不改变数据库、API 或计费结果

## 排查订阅与流量

订阅无法导入时,依次确认:

1. 令牌未撤销且用户、订阅处于有效状态;
2. HTTP 响应不是伪装跳转;
3. 客户端选择了正确模板或 User-Agent;
4. Base64 文本能够完整解码;
5. 生成配置包含 loopback Mixed 入口;
6. 节点组至少包含可发布的协议服务。
1. 请求使用受支持的订阅客户端 User-Agent;
2. 令牌未撤销且令牌绑定的用户、订阅处于有效状态;
3. HTTP 响应不是伪装跳转;
4. 客户端选择了正确模板或自动检测;
5. `zero` 响应能够完整 Base64 解码,且不是明文 JSON;
6. 生成配置包含 loopback Mixed 入口;
7. 节点组至少包含已启用、可发布的协议服务;
8. 引用的托管规则 ZRS URL 可读取且与当前数据库快照匹配。

流量未增加时,确认节点侧是否存在归属到该订阅用户的 `flow.completed` 事件。只有客户端本地探测记录、但节点没有会话和字节事件时,应排查客户端到节点的实际连接路径,而不是修改计费逻辑。
流量未增加时,确认节点侧是否存在归属到该订阅用户的完成事件。只有客户端本地探测记录、但节点没有会话和字节事实时,应排查客户端到节点的实际连接路径,而不是修改计费逻辑。
45 changes: 39 additions & 6 deletions docs/projects/znet-sink/guides/data-and-diagnostics.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,50 @@
# 数据与诊断

ZNet Sink 将应用设置、代理配置、订阅、规则和运行记录保存在本地数据目录。
ZNet Sink 将应用设置、代理配置、订阅、规则和运行记录保存在本地数据目录。连接页面以实时 IPC 事件为主要数据源,并在客户端维护有界历史,不把内核查询结果当作长期数据库。

## 查看实际路径

不同系统和安装方式的目录不同,不应依赖文档中的固定路径。打开“设置 → 通用”或“设置 → 关于”,使用界面提供的打开、定位操作查看当前实例实际使用的目录。

## 实时连接

专业模式的连接页面会先用内核快照建立活动连接基线,再合并后续生命周期事件。实时列表支持暂停刷新、筛选、查看详情和终止连接等操作。

连接记录会保留内核返回的结构化字段与原始 wire 元数据。后台协调只用于修复遗漏状态,不应持续制造可见日志,也不会用轮询结果覆盖更新的事件状态。

## 历史连接

连接完成后,客户端把完成事实写入独立的本地历史存储:

- 历史与活动连接分开保存,内核重启后仍可查看已落盘记录;
- 页面使用无限滚动按需读取,而不是一次加载全部记录;
- 筛选条件在历史存储查询前生效,切换筛选时会重置游标;
- 存储具有数量和时间边界,会按墙上时间清理过旧记录;
- 同一 flow 标识被复用时,仍按完成事件和生命周期顺序保留正确记录。

本地历史用于诊断和界面展示,不是服务端计费或审计事实来源。

## 详情与原始帧

点击连接可打开统一的详情对话框,查看:

- 连接时间、生命周期、路由、出站和流量字段;
- 内核原始记录中提供的查询 ID、revision、来源等元数据;
- 与该连接关联的 IPC 请求、响应和事件帧;
- 可直接复制的结构化详情和原始诊断报文。

详情对话框在实时更新时会保持当前标签和选中记录,内容区独立滚动,避免页面、弹窗和代码块形成多重滚动。

原始帧可能包含地址、域名、标签和错误上下文。复制或公开前必须检查敏感信息。

## 日志与调试

专业模式提供
专业模式还提供

- 应用日志和内核日志;
- 实时连接与本地连接记录
- IPC 调试帧
- 内核能力和运行状态
- 节点测速的原始 IPC 诊断
- 内核能力和运行状态
- 连接与策略事件的原始帧

日志页用于日常筛选和复制;调试页更接近原始控制面数据,不应把其中未经检查的内容直接公开。

Expand All @@ -27,6 +58,8 @@ ZNet Sink 将应用设置、代理配置、订阅、规则和运行记录保存

诊断包仍可能包含本机路径、版本、时间和网络错误上下文。发送给第三方前请再次检查。

## 清理日志
## 清理日志与历史

清理日志不会删除代理配置、订阅、规则、应用设置或内核文件。应用或内核继续运行时会按需生成新的日志。

清理连接历史只删除客户端保存的诊断记录,不会修改内核当前连接,也不会回滚 Zboard 已接收的流量事实。
15 changes: 11 additions & 4 deletions docs/projects/znet-sink/guides/proxy-and-probes.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ Windows 上会保存原始 `ProxyServer`、绕过列表和自动配置地址,
- 是否存在其他应用同时修改系统代理;
- Windows 的绕过列表或 PAC 是否来自接管前的旧设置。

系统代理主要覆盖遵循操作系统 HTTP/HTTPS 代理设置的 TCP 应用。它不等同于 TUN,也不会自动接管所有 UDP、WebRTC 或 DNS 流量。

## 打开代理终端

Windows 托盘菜单中的“打开终端”会:
Expand All @@ -52,13 +54,17 @@ Windows 托盘菜单中的“打开终端”会:
节点页会把单节点探测、策略组快照和本地历史合并为当前显示结果:

- URLTest 组使用内核返回的成员快照和当前选中项;
- 当 URLTest 作为另一个组中的节点卡片出现时,单点测速只探测它当前实际生效的出站,不递归重测全部成员;
- 手动等待期间到达的新鲜定时结果也可以完成本次等待;
- 本地先显示的超时可以被随后到达的有效结果替换;
- 嵌套 URLTest 卡片使用自身策略组的历史,不沿用父组的旧值;
- 批量测速会去重父组中已经由 URLTest 负责探测的成员;
- 进度数字按本次实际目标数量计算,不再把策略组展开数量误当作单点目标;
- 即使批量完成事件丢失,全部成员的终态或看门狗超时也会清除加载状态。

策略组等待时间会根据成员数量调整,并设置上限。大量节点不应使用固定的短超时判断失败。
策略组等待时间会根据成员数量调整,并设置上限。大量节点不应使用固定的短超时判断失败。探测失败会归一化为可读错误,同时保留原始 IPC 请求、响应和错误供复制排查。

Windows 不稳定支持区域旗帜 emoji,因此节点卡片使用旗帜图片渲染已识别国家/地区,避免显示为字母或方框。

## 历史记录的作用域

Expand All @@ -76,8 +82,9 @@ Windows 托盘菜单中的“打开终端”会:

1. 确认当前配置和内核运行状态一致;
2. 检查应用日志中的 `probe`、`policy.probe.completed` 和超时记录;
3. 确认切换配置后页面已加载新的策略快照;
4. 避免连续点击父组、子 URLTest 和全部成员;
5. 等待一次完整批次结束后再重试。
3. 在诊断详情中复制对应的 `policies.probe`、`diagnostics.probe_outbound` 或查询帧;
4. 确认切换配置后页面已加载新的策略快照;
5. 避免连续点击父组、子 URLTest 和全部成员;
6. 等待一次完整批次结束后再重试。

本地代理无法使用时,先在“设置 → 常规”确认代理端口,再检查[故障排查](./troubleshooting)。
Loading
Loading