From b4f57245f2b316d0c0df9443cfa6684c93b8892b Mon Sep 17 00:00:00 2001 From: kovawx Date: Thu, 10 Sep 2026 14:19:06 +0800 Subject: [PATCH] docs: use Chinese consistently in ZBoard guides --- docs/.vitepress/navigation.ts | 4 - .../zboard/contributing/development.md | 119 +++++++----------- docs/projects/zboard/guides/index.md | 1 - .../projects/zboard/guides/installation-en.md | 109 ---------------- docs/projects/zboard/guides/installation.md | 1 - .../zboard/guides/storage-and-backups.md | 72 +++++------ .../zboard/guides/subscription-filtering.md | 69 +++++----- docs/projects/zboard/plugins/trust-en.md | 35 ------ docs/projects/zboard/plugins/trust.md | 1 - zboard-document-migration.json | 10 +- 10 files changed, 116 insertions(+), 305 deletions(-) delete mode 100644 docs/projects/zboard/guides/installation-en.md delete mode 100644 docs/projects/zboard/plugins/trust-en.md diff --git a/docs/.vitepress/navigation.ts b/docs/.vitepress/navigation.ts index cacb15f..838e403 100644 --- a/docs/.vitepress/navigation.ts +++ b/docs/.vitepress/navigation.ts @@ -175,10 +175,6 @@ const zboardSidebar: DefaultTheme.SidebarItem[] = [ page('节点配置交付', '/projects/zboard/reference/node-config-delivery'), page('规则兼容性', '/projects/zboard/reference/managed-rule-compatibility'), ]), - group('English', [ - page('Installation', '/projects/zboard/guides/installation-en'), - page('Plugin installation trust', '/projects/zboard/plugins/trust-en'), - ]), ] export const sidebar: DefaultTheme.Sidebar = { diff --git a/docs/projects/zboard/contributing/development.md b/docs/projects/zboard/contributing/development.md index 7658b71..db80267 100644 --- a/docs/projects/zboard/contributing/development.md +++ b/docs/projects/zboard/contributing/development.md @@ -1,19 +1,17 @@ -# Local development +# 本地开发 -This guide contains the contributor setup that does not belong in the project -overview. For product architecture and supported capabilities, start with the -repository `README.md`. +本页说明贡献者如何启动开发环境和验证改动。项目定位与功能范围见 [ZBoard 首页](../)。以下命令在产品代码仓库中执行。 -## Toolchain +## 工具链 {#toolchain} -Use the versions declared by the repository instead of choosing local defaults: +使用仓库声明的版本: -- Go and the exact toolchain are declared in `backend/go.mod`; -- Node.js is pinned by the frontend and Docker build; -- pnpm is declared by `frontend/package.json#packageManager`; -- MySQL 8 is required for the current local service. +- Go 版本及工具链见 `backend/go.mod`。 +- Node.js 版本以前端项目及 Docker 构建配置为准。 +- pnpm 版本见 `frontend/package.json` 的 `packageManager`。 +- 默认本地启动流程使用 MySQL 8。 -The environment checks can resolve the repository Go toolchain automatically: +环境检查脚本可以自动准备仓库指定的 Go 工具链: ```powershell .\scripts\verify-env.ps1 @@ -23,35 +21,29 @@ The environment checks can resolve the repository Go toolchain automatically: ./scripts/verify-env.sh ``` -## One-command startup +## 一键启动 {#one-command-startup} -The development launcher verifies dependencies, starts MySQL through Docker -Compose when necessary, creates ignored local runtime configuration, -starts the backend and optionally starts the frontend. +启动脚本会检查依赖,按需通过 Docker Compose 启动 MySQL,生成被 Git 忽略的本地运行配置,然后启动后端和可选的前端。 -PowerShell: +PowerShell: ```powershell .\scripts\start-dev.ps1 -WithFrontend ``` -Bash: +Bash: ```bash ./scripts/start-dev.sh --with-frontend ``` -Use `-SkipDependencies` or `--skip-deps` when MySQL already runs -outside the repository Compose stack. Both launchers expose additional port, -timeout and datasource options in their built-in help or parameter list. +已有独立 MySQL 服务时,使用 `-SkipDependencies` 或 `--skip-deps`。端口、超时和数据库连接选项见脚本帮助或参数说明。 -The backend is available at `http://127.0.0.1:8080`; the frontend development -server defaults to `http://127.0.0.1:5173`. +后端地址为 `http://127.0.0.1:8080`,前端开发服务默认地址为 `http://127.0.0.1:5173`。 -## Manual backend startup +## 手动启动后端 {#manual-backend-startup} -Manual startup requires a datasource, a JWT secret of at least 32 bytes and one -stable 32-byte credential-encryption key: +需要准备数据库连接、至少 32 字节的 JWT 密钥和固定的 32 字节凭据加密密钥: ```powershell Set-Location backend @@ -62,16 +54,13 @@ $env:ZBOARD_CREDENTIAL_ENCRYPTION_KEY = "<32-random-bytes-as-base64-or-hex>" go run ./cmd/zboard -f ./etc/zboard.yaml.example ``` -On an empty database the service enters installation mode. Open `/setup` to -create the first administrator and finish site initialization. +空数据库启动后进入安装模式,访问 `/setup` 创建首个管理员并完成初始化。 -The embedded SQL baseline is applied during startup. To run migrations without -starting the HTTP service, use `scripts/migrate.ps1` or `scripts/migrate.sh`. -Back up an existing database before running a newer build. Review the SQL migrations -shipped with that exact build; do not apply historical baseline-squashing procedures -to a published schema. +服务启动时会执行内嵌 SQL 迁移。只执行迁移而不启动 HTTP 服务时,可使用 `scripts/migrate.ps1` 或 `scripts/migrate.sh`。使用新构建打开已有数据库前先备份,并检查目标构建附带的迁移文件;不要修改已发布的迁移历史。 -## Manual frontend startup +## 手动启动前端 {#manual-frontend-startup} + +PowerShell: ```powershell Set-Location frontend @@ -80,17 +69,17 @@ pnpm install --frozen-lockfile pnpm dev ``` -On Bash-compatible shells: +Bash: ```bash cd frontend -VITE_API_BASE=http://127.0.0.1:8080/api/v1 pnpm install --frozen-lockfile +pnpm install --frozen-lockfile VITE_API_BASE=http://127.0.0.1:8080/api/v1 pnpm dev ``` -## Verification +## 验证改动 {#verification} -Run checks in proportion to the changed area. A complete local verification is: +根据改动范围执行检查。完整的本地检查包括: ```powershell Set-Location backend @@ -102,20 +91,17 @@ pnpm test pnpm build ``` -`pnpm build` includes Vue and TypeScript type checking. API changes must also -update `backend/api/openapi.yaml` and its contract tests. +`pnpm build` 包含 Vue 和 TypeScript 类型检查。API 改动还需要同步 `backend/api/openapi.yaml` 及接口契约测试。 -The repository also provides: +仓库还提供以下脚本: -- `scripts/smoke-test.*` for a running service; -- `scripts/build-all.*` for combined backend and frontend builds; -- `scripts/check-go-version.*` and `scripts/sync-go-baseline.*` for toolchain - maintenance. +- `scripts/smoke-test.*`:检查已运行的服务。 +- `scripts/build-all.*`:构建后端和前端。 +- `scripts/check-go-version.*`、`scripts/sync-go-baseline.*`:检查和维护 Go 工具链版本。 -## Performance and stability verification +## 性能与稳定性验证 {#performance-and-stability-verification} -Run these commands from the repository root with the pinned Go toolchain -(`GO_BIN` can select its executable): +从仓库根目录执行,`GO_BIN` 可指定 Go 程序路径: ```bash bash scripts/benchmark-accounting.sh local @@ -123,44 +109,23 @@ bash scripts/benchmark-accounting.sh container bash scripts/acceptance-mixed.sh ``` -The accounting benchmark defaults to 100 batches per scenario and three runs; -`BENCH_TIME` and `BENCH_COUNT` override these settings. Container checks require -Docker. The mixed workload defaults to 10 nodes, 1,000 subscriptions, 100,000 -historical records, four concurrent readers and 100 events/second for 300 seconds. -`DURATION_SECONDS`, `EVENT_RATE` and `READERS` select other workload profiles. -The application and database share the 1 CPU / 1 GiB budget; the load generator -runs outside it. Set latency and memory budgets for the environment under test. -Also verify exact accounting under replay and reordering, no OOM, -explained failures and a fully drained backlog. +计量基准默认每个场景使用 100 个批次、运行三次,可通过 `BENCH_TIME` 和 `BENCH_COUNT` 调整。容器检查需要 Docker。混合负载默认使用 10 个节点、1,000 份订阅、100,000 条历史记录、四个并发读取方和每秒 100 个事件,持续 300 秒;通过 `DURATION_SECONDS`、`EVENT_RATE`、`READERS` 调整负载。 -Real Zero revocation checks use isolated nodes and test credentials: +应用和数据库共同使用 1 CPU / 1 GiB 资源预算,负载生成器在预算之外运行。根据测试环境设定延迟和内存要求,并核对重复、乱序事件下的计量结果、失败原因和积压是否排空。 + +真实 Zero 撤权验证应使用隔离节点和测试凭据: ```bash ZERO_ARTIFACT_DIR=/path/to/verified-linux-zero-artifact \ NODE_SCENARIO=expiry bash scripts/acceptance-node.sh ``` -The artifact directory must contain `zero` and its matching `verification.json`. -Other scenarios are `exhaustion`, `group_change` and `recovery`. Verify data-plane -access after revocation and publication recovery, including existing connections; -control-plane status or a mock SSH server alone is insufficient. - -Keep raw logs, profiles, environment details, source/build hashes and per-run -reports under the ignored `.codex-local-artifacts/acceptance/` directory. A dirty -build needs source hashes as well as Git HEAD. Share selected evidence through -CI/release artifacts when needed, without committing workstation journals. +制品目录需要包含 `zero` 和对应的 `verification.json`。其他场景包括 `exhaustion`、`group_change` 和 `recovery`。应验证实际代理连接、已有连接和配置恢复情况,控制接口或模拟 SSH 的结果不能替代真实连接验证。 -A 500-events/second, 60-second burst and a 24-hour soak are separate acceptance -profiles. Record fault injection, restarts, queue recovery and resource trends; -restart the soak clock after changing the build or resetting the environment. -Short runs do not establish long-term stability or production capacity. +原始日志、性能记录、环境信息和源码摘要保存在被忽略的 `.codex-local-artifacts/acceptance/` 中。每秒 500 个事件的 60 秒突发与 24 小时持续运行是独立测试;更换构建或重置环境后重新计时。短时间测试不能证明长期稳定性或生产容量。 -## Restricted networks +## 受限网络环境 {#restricted-networks} -`scripts/ensure-go-env.*` can install the pinned Go toolchain when it is -missing. Set `ZBOARD_GO_DOWNLOAD_BASE` to an approved mirror when direct -downloads from `go.dev` are unavailable. A preinstalled Go directory can be -selected with `ZBOARD_GOROOT_FALLBACK`. +缺少工具链时,`scripts/ensure-go-env.*` 可以安装指定 Go 版本。无法直接访问 `go.dev` 时,可将 `ZBOARD_GO_DOWNLOAD_BASE` 指向可信镜像,或通过 `ZBOARD_GOROOT_FALLBACK` 指定已安装的 Go 目录。 -Do not weaken production secrets or commit generated runtime configuration to -work around a local environment problem. +不要为解决本地环境问题降低生产密钥要求,也不要提交生成的运行配置。 diff --git a/docs/projects/zboard/guides/index.md b/docs/projects/zboard/guides/index.md index 8e77266..b19c47f 100644 --- a/docs/projects/zboard/guides/index.md +++ b/docs/projects/zboard/guides/index.md @@ -11,7 +11,6 @@ ZBoard 的核心是基础面板。先完成安装和一条服务的配置,再 5. [开通订阅](./plans-and-orders):关联节点组、套餐与用户权益。 6. [连接客户端](./subscriptions-and-traffic):获取对应格式的订阅并查看流量。 -English installation instructions are available in [First installation](./installation-en). ## 按需配置 diff --git a/docs/projects/zboard/guides/installation-en.md b/docs/projects/zboard/guides/installation-en.md deleted file mode 100644 index c9cc8be..0000000 --- a/docs/projects/zboard/guides/installation-en.md +++ /dev/null @@ -1,109 +0,0 @@ -# First installation - -[English](/projects/zboard/guides/installation-en) | [简体中文](/projects/zboard/guides/installation) - -This guide installs the published Docker image and walks through creating your first service. The image includes the backend and web console; you do not need to build the frontend or install Go and Node.js. - -## Before you start - -Prepare: - -- A Linux amd64 host with Docker Engine, the Docker Compose plugin, Git, and OpenSSL. -- An empty MySQL 8 database and a dedicated application account with permission to create and update its tables. ZBoard refuses the MySQL root account in production. -- An existing Docker network that lets the application reach MySQL. If MySQL runs in Docker, attach its container to that network and use its container name or network alias as the database host. -- A domain with HTTPS, served by a reverse proxy on the Docker host. The example binds ZBoard to `127.0.0.1:8080`. - -The release Compose file starts **only ZBoard**. It does not provision MySQL or Redis. SQLite is an alternative; see [Docker storage](/projects/zboard/guides/storage-and-backups) for its environment settings and Compose override. - -## 1. Get the deployment files - -Choose a version from [Releases](https://github.com/zerodenet/zboard/releases). The following example uses `v0.0.1`: - -```bash -git clone --branch v0.0.1 --depth 1 https://github.com/zerodenet/zboard.git -cd zboard/deploy/docker -cp .env.release.example .env.release -chmod 600 .env.release -``` - -Use the same tag for the checkout and Docker image. For another version, replace `v0.0.1` in both places. - -## 2. Configure the application - -Edit `.env.release`. Set these values for your environment: - -```dotenv -ZBOARD_IMAGE_TAG=v0.0.1 -ZBOARD_PULL_POLICY=always -ZBOARD_HTTP_BIND=127.0.0.1 -ZBOARD_HTTP_PORT=8080 -ZBOARD_EXTERNAL_NETWORK=your_existing_docker_network -ZBOARD_DATABASE_DRIVER=mysql -ZBOARD_DATA_SOURCE='zboard:YOUR_DATABASE_PASSWORD@tcp(mysql:3306)/zboard?charset=utf8mb4&parseTime=true&loc=UTC' -ZBOARD_JWT_SECRET=YOUR_RANDOM_JWT_SECRET -ZBOARD_CREDENTIAL_ENCRYPTION_KEY=YOUR_RANDOM_ENCRYPTION_KEY -``` - -Replace the network name and all database details, including `mysql`, with your actual connection settings. `127.0.0.1` inside the container refers to the ZBoard container itself, not the host or a separate MySQL container. - -Run the following command **twice** to generate two independent values. Use one for `ZBOARD_JWT_SECRET` and the other for `ZBOARD_CREDENTIAL_ENCRYPTION_KEY`: - -```bash -openssl rand -hex 32 -``` - -Keep both values stable across restarts. The encryption key is needed to read saved node credentials; keep a backup separately from the database. - -Leave `ZBOARD_BOOTSTRAP_ADMIN_EMAIL` and `ZBOARD_BOOTSTRAP_ADMIN_PASSWORD` empty to create the administrator in the setup page. There is no default administrator password. - -## 3. Prepare storage and start - -These commands use the default host directory paths in `.env.release`. If you change them, follow the [custom directory instructions](/projects/zboard/guides/storage-and-backups#required-host-directories) before starting. - -```bash -sh ./prepare-host-dirs.sh -docker compose -f docker-compose.release.yml --env-file .env.release config --quiet -docker compose -f docker-compose.release.yml --env-file .env.release pull -docker compose -f docker-compose.release.yml --env-file .env.release up -d -docker compose -f docker-compose.release.yml --env-file .env.release ps -``` - -Check the backend from the Docker host: - -```bash -curl --fail http://127.0.0.1:8080/readyz -curl --fail http://127.0.0.1:8080/api/v1/version -``` - -`/readyz` checks the application database connection. It does not indicate whether any Zero nodes have been installed or published successfully. - -If startup fails, inspect the service logs: - -```bash -docker compose -f docker-compose.release.yml --env-file .env.release logs --tail 100 zboard -``` - -Common causes are an unset environment value, a missing external network, incorrect database credentials, or MySQL being unreachable from the container. - -## 4. Create your administrator - -Configure the host reverse proxy to send requests for your HTTPS domain to `http://127.0.0.1:8080`, then open `https://YOUR_DOMAIN/setup`. - -Complete the site settings and create the first administrator. After initialization, use `/login`. The setup page cannot create another administrator after the site is installed. - -## 5. Configure your first service - -1. **Add a node.** Enter its address and SSH connection details in the administrator console. -2. **Install Zero.** Use the node's kernel management controls and wait for installation and health checks to finish. -3. **Create a protocol service.** Choose the node and protocol, configure its listening address and port, and wait for publication to succeed. Make the service port reachable through the node's firewall. -4. **Create a node group and plan.** Add the service to the group, then select that group in the plan. -5. **Activate a user subscription.** Use the basic order workflow to create an order for the plan and confirm it as an administrator. -6. **Connect a client.** In the user's account, choose the subscription format for the client and import its link. Make a connection, then check traffic usage in the console. - -For a forwarding node or a shared upstream pool, continue with [network fronting](/projects/zboard/guides/network-fronting). Node installation and recovery are covered in the [node management guide](/projects/zboard/guides/node-management). - -## Keep your data - -Persist the database, `.env.release`, credential-encryption key, managed rules, and Zero event spool. Builds with plugin support also need their plugin directory. The [storage and backup guide](/projects/zboard/guides/storage-and-backups) explains the mounts and which data must be restored together. - -For local source development, use the [development guide](/projects/zboard/contributing/development). diff --git a/docs/projects/zboard/guides/installation.md b/docs/projects/zboard/guides/installation.md index 11ee030..aa61e87 100644 --- a/docs/projects/zboard/guides/installation.md +++ b/docs/projects/zboard/guides/installation.md @@ -1,6 +1,5 @@ # 首次安装 -[English](/projects/zboard/guides/installation-en) | [简体中文](/projects/zboard/guides/installation) 本指南使用正式发布的 Docker 镜像安装面板,并说明如何配置第一条服务。镜像已经包含后端和 Web 控制台,无需自行构建前端,也无需安装 Go 或 Node.js。 diff --git a/docs/projects/zboard/guides/storage-and-backups.md b/docs/projects/zboard/guides/storage-and-backups.md index 0c519a9..5a557d8 100644 --- a/docs/projects/zboard/guides/storage-and-backups.md +++ b/docs/projects/zboard/guides/storage-and-backups.md @@ -1,22 +1,22 @@ -# Docker storage and backups +# 数据存储与备份 -For a first installation, start with the [English guide](/projects/zboard/guides/installation-en) or [首次安装指南](/projects/zboard/guides/installation). This page covers persistent directories, database storage options, and backup/restore. +首次部署请从[安装教程](./installation)开始。本页说明需要持久保存的目录、数据库选择和备份恢复方法。 -## Required host directories +## 准备宿主机目录 {#required-host-directories} -Zboard uses two different storage trust boundaries under `/var/lib/zboard/artifacts`: +`/var/lib/zboard/artifacts` 下的两类内容使用不同的挂载权限: -- `ZBOARD_ZERO_ARTIFACT_HOST_DIR` contains trusted Zero binaries and checksum files. It is mounted read-only. -- `ZBOARD_MANAGED_RULE_HOST_DIR` contains managed Zero Rule IR sources and compiled ZRS artifacts. It is mounted read-write and must persist across container replacement. +- `ZBOARD_ZERO_ARTIFACT_HOST_DIR` 保存可信 Zero 程序及校验文件,以只读方式挂载。 +- `ZBOARD_MANAGED_RULE_HOST_DIR` 保存托管规则源文件和生成的规则产物,以读写方式挂载,重建容器时需要保留。 -Prepare both directories before the first deployment: +首次部署前执行: ```bash cd deploy/docker sh ./prepare-host-dirs.sh ``` -Custom locations can be supplied through the same environment variables used by Compose: +自定义位置时,使用与 Compose 相同的环境变量: ```bash ZBOARD_ZERO_ARTIFACT_HOST_DIR=/srv/zboard/artifacts \ @@ -24,10 +24,7 @@ ZBOARD_MANAGED_RULE_HOST_DIR=/srv/zboard/managed-rules \ sh ./prepare-host-dirs.sh ``` -MySQL deployments use only the base Compose file and do not create or mount a -SQLite data directory. For SQLite, set `ZBOARD_DATABASE_DRIVER=sqlite`, set -`ZBOARD_DATA_SOURCE=/var/lib/zboard/data/zboard.db`, optionally set -`ZBOARD_DATABASE_HOST_DIR`, and include the SQLite override: +MySQL 部署只使用基础 Compose 文件,不创建或挂载 SQLite 数据目录。使用 SQLite 时,设置 `ZBOARD_DATABASE_DRIVER=sqlite`、`ZBOARD_DATA_SOURCE=/var/lib/zboard/data/zboard.db`,按需设置 `ZBOARD_DATABASE_HOST_DIR`,并同时使用 SQLite 覆盖文件: ```bash set -a @@ -41,30 +38,31 @@ docker compose \ up -d ``` -The preparation script creates an empty `rules/` mount point under the read-only artifact directory. Compose then overlays that path with the separate writable managed-rule directory. +准备脚本会在只读制品目录中创建空的 `rules/` 挂载点,Compose 再将独立的可写规则目录挂载到这里。 -## Mount layout +## 挂载布局 {#mount-layout} ```text -/var/lib/zboard/artifacts read-only trusted artifacts -└── rules writable child bind mount +/var/lib/zboard/artifacts 只读的可信制品目录 +└── rules 独立的可写规则目录 └── - ├── source.json canonical internal Zero Rule IR - └── artifacts// compiled client artifacts + ├── source.json 规范化规则源文件 + └── artifacts// 编译后的客户端规则 ``` -Do not make the complete artifact directory writable. Managed rules are the only application-generated data below this path. +不要把整个制品目录改成可写。这个路径下由应用生成的数据仅位于托管规则目录中。 -Blue and green application instances must mount the same `ZBOARD_MANAGED_RULE_HOST_DIR`. Using separate directories causes database metadata and rule files to diverge after a traffic switch. +蓝绿部署的两个实例必须挂载同一个 `ZBOARD_MANAGED_RULE_HOST_DIR`,否则切换后可能出现数据库记录与规则文件不一致。 -## Backup and restore +## 备份与恢复 {#backup-and-restore} -The database stores managed-rule metadata and revisions, while the canonical source and compiled ZRS files live in `ZBOARD_MANAGED_RULE_HOST_DIR`. A recoverable backup therefore requires both: +数据库保存规则元数据和修订信息,规则源文件与编译产物保存在 `ZBOARD_MANAGED_RULE_HOST_DIR`。备份时应在同一备份窗口保存: -1. a consistent Zboard database backup; -2. an archive or snapshot of `ZBOARD_MANAGED_RULE_HOST_DIR` from the same backup window. +1. 一致的 ZBoard 数据库备份。 +2. 托管规则目录的归档或快照。 +3. 部署配置、凭据加密密钥及其他持久目录;插件目录的要求见下文。 -Example filesystem backup: +规则目录备份示例: ```bash managed_rule_dir=${ZBOARD_MANAGED_RULE_HOST_DIR:-./managed-rules} @@ -73,27 +71,29 @@ tar -C "$(dirname "$managed_rule_dir")" \ "$(basename "$managed_rule_dir")" ``` -Restore the database and managed-rule directory as one recovery unit before starting Zboard. Restoring only the database leaves rule records whose source and ZRS artifacts are missing; restoring only the directory can reintroduce files for revisions that the database no longer references. +启动恢复后的面板之前,应同时恢复数据库及对应的规则目录。只恢复数据库会缺少规则文件;只恢复目录则可能带回数据库已不再引用的旧修订。 -## Deployment verification +SQLite 的一致性备份与切换步骤见[系统维护](./maintenance#sqlite-备份与回滚)。 -Render the Compose configuration before applying it: +## 检查部署配置 {#deployment-verification} + +启动前先检查 Compose 配置: ```bash -docker compose -f docker-compose.release.yml --env-file .env.release config +docker compose -f docker-compose.release.yml --env-file .env.release config --quiet ``` -For SQLite, render both files together: +SQLite 部署需要同时指定两个文件: ```bash docker compose \ -f docker-compose.release.yml \ -f docker-compose.sqlite.yml \ --env-file .env.release \ - config + config --quiet ``` -After startup, verify that the parent directory is protected and the child directory is writable: +启动后检查制品目录只读、规则目录可写。以下命令仅创建并删除一个临时检查文件;SQLite 部署需同时加上 SQLite 覆盖文件: ```bash docker compose -f docker-compose.release.yml --env-file .env.release exec zboard sh -c ' @@ -103,8 +103,10 @@ docker compose -f docker-compose.release.yml --env-file .env.release exec zboard ' ``` -## Plugin persistence +## 插件数据持久化 {#plugin-persistence} + +服务将 `ZBOARD_PLUGIN_HOST_DIR`(默认 `./plugins`)挂载到 `/var/lib/zboard/plugins`。`prepare-host-dirs.sh` 会创建此私有目录。备份时同时保存插件目录、数据库和凭据加密密钥。 -The service mounts `ZBOARD_PLUGIN_HOST_DIR` (default `./plugins`) at `/var/lib/zboard/plugins`. `prepare-host-dirs.sh` creates this private directory. Back it up together with the database and credential encryption key. Add publisher public keys and the optional signed catalog URL to a custom ZBoard YAML file and mount it read-only at `/app/etc/zboard.yaml`; see [plugin setup](/projects/zboard/plugins/development). +需要配置发布者公钥或自定义市场目录时,将配置加入 ZBoard YAML,并以只读方式挂载到 `/app/etc/zboard.yaml`。具体见[插件市场](../plugins/marketplace)。 -Only one instance per database owns plugin execution. Standby instances keep core APIs available but do not issue plugin page sessions or execute plugin operations. Stop the owner and restart the replacement to transfer plugin execution; an ungraceful exit requires the one-minute lease to expire. This does not implement active-active plugin routing. +同一数据库只能由一个实例执行插件。备用实例可以提供核心接口,但不创建插件页面会话或执行插件操作。切换时停止原实例并重启接替实例;原实例异常退出后需要等待一分钟租约到期。此机制不提供多个实例同时处理插件请求的路由能力。 diff --git a/docs/projects/zboard/guides/subscription-filtering.md b/docs/projects/zboard/guides/subscription-filtering.md index f062389..0fa60ba 100644 --- a/docs/projects/zboard/guides/subscription-filtering.md +++ b/docs/projects/zboard/guides/subscription-filtering.md @@ -1,6 +1,6 @@ -# Public subscription filtering +# 订阅节点筛选 -Every public subscription URL is bound to exactly one subscription. Query parameters can derive read-only client views from that subscription without changing its authorization boundary: +每个订阅链接只对应一份订阅。可以通过查询参数筛选客户端收到的节点,筛选不会改变原订阅的权限范围。 ```text /api/v1/client/subscription/{subscription-token} @@ -15,53 +15,46 @@ Every public subscription URL is bound to exactly one subscription. Query parame &q=日本 ``` -## Authorization boundary +## 权限范围 -Filtering is an output projection, not an authorization mechanism: +面板先检查链接绑定的订阅是否属于当前用户、是否有效、是否到期以及是否还有流量,再从该订阅已经授权的节点中筛选结果。 -1. Zboard resolves the token to one `subscription_id` and verifies that the same user owns both records. -2. Zboard verifies that exact subscription is active, unexpired, and has remaining traffic. -3. `plan`, `sku`, and `node_group` may remove that source, but they cannot select a different subscription owned by the same account. -4. Zboard resolves protocol endpoints and credentials only from the token-bound subscription. -5. Endpoint filters reduce that authorized endpoint set again. -6. The result is ordered by the configured protocol delivery order and sent to the selected renderer. +筛选只能减少节点,不能添加节点组、协议服务、凭据、套餐或其他订阅。即使同一账号有多份订阅,`plan`、`sku` 和 `node_group` 也不能把当前链接切换到另一份订阅。 -A filter can only remove endpoints authorized by the token-bound subscription. It cannot add a node group, endpoint, credential, plan, SKU, or another subscription. +`Subscription-Userinfo` 响应头中的流量与到期时间始终对应这份订阅,不会汇总整个账号的数据。 -The `Subscription-Userinfo` response header and manifest quota metadata always describe the token-bound subscription only. Traffic totals and expiry are never accumulated across the account. +## 筛选参数 -## Account access API - -Authenticated users manage credentials from the target subscription: - -| Method | Path | Meaning | +| 参数 | 含义 | 匹配方式 | | --- | --- | --- | -| `GET` | `/api/v1/account/subscriptions/{id}/access` | Read or lazily provision the link for one active subscription | -| `POST` | `/api/v1/account/subscriptions/{id}/access/rotate` | Replace only that subscription's token | -| `DELETE` | `/api/v1/account/subscriptions/{id}/access` | Revoke only that subscription's token | +| `template` | 已有订阅模板标识或 `native` | 精确匹配 | +| `plan` | 套餐的稳定标识 | 多个值满足任意一个 | +| `sku` | 套餐规格代码 | 多个值满足任意一个 | +| `node_group` | 节点组代码 | 多个值满足任意一个 | +| `protocol` | 协议代码 | 多个值满足任意一个 | +| `region` | 节点区域 | 多个值满足任意一个 | +| `tag` | 协议服务标签 | 包含任意指定标签 | +| `exclude_tag` | 需要排除的协议服务标签 | 命中任意标签即排除 | +| `q` | 协议服务名称关键词 | 不区分大小写的包含匹配 | -The legacy account-level `/api/v1/subscription/access` routes are removed. Existing aggregate tokens without a `subscription_id` are invalidated during schema reconciliation, and one independent token is provisioned for each usable subscription. +不同参数需要同时满足。同一参数的多个值可以用逗号分隔,也可以重复传入查询参数;面板会规范化、去重,并限制数量与长度。 -## Parameters +例如,`protocol=vless,hysteria2®ion=jp` 表示保留日本区域的 VLESS 或 Hysteria2 节点。 -| Parameter | Meaning | Matching | -| --- | --- | --- | -| `template` | Existing renderer slug or `native` | Exact | -| `plan` | Stable plan slug | OR within the parameter | -| `sku` | Stable plan SKU code | OR within the parameter | -| `node_group` | Stable node-group code | OR within the parameter | -| `protocol` | Supported protocol code | OR within the parameter | -| `region` | Node region | OR within the parameter | -| `tag` | Structured protocol-service tag | Any requested tag | -| `exclude_tag` | Structured protocol-service tag to remove | Any match excludes | -| `q` | Protocol-service name keyword | Case-insensitive substring | +无效代码、不支持的协议、过长的值或控制字符会返回 HTTP 400。合法筛选没有匹配节点时,返回有效的空订阅,仍保留该订阅的额度信息,并使用 `Cache-Control: no-store`。 -Different dimensions use AND semantics. Values can be supplied as comma-separated items or repeated query parameters. Values are normalized, deduplicated, and bounded in count and length. +## 排序和服务状态 -Malformed stable codes, unsupported protocol values, overlong values, and control characters return HTTP 400. A valid filter that removes the token-bound source or matches no endpoint returns a valid empty subscription while keeping that subscription's quota metadata and `Cache-Control: no-store`. +筛选后的节点继续遵循管理员设置的交付顺序。关闭协议服务会同时停止其订阅交付和运行配置发布;重新启用后,通过正常发布流程恢复。 -## Delivery order and service state +## 订阅链接接口 -All native renderers consume the same ordered manifest. The administrator's protocol delivery order remains authoritative within the token-bound subscription. Endpoint identity is only a deterministic tie-breaker. +已登录用户可以针对指定订阅读取、轮换或撤销链接: + +| 方法 | 路径 | 作用 | +| --- | --- | --- | +| `GET` | `/api/v1/account/subscriptions/{id}/access` | 读取有效订阅的链接,尚未生成时按需创建 | +| `POST` | `/api/v1/account/subscriptions/{id}/access/rotate` | 仅更换该订阅的令牌 | +| `DELETE` | `/api/v1/account/subscriptions/{id}/access` | 仅撤销该订阅的令牌 | -`ProtocolEndpoint.is_active` is the protocol-service delivery switch. Disabled services are removed from public subscription output and from node runtime publication; re-enabling the service restores both through the existing runtime publish flow. +继续阅读[订阅配置与流量](./subscriptions-and-traffic)。 diff --git a/docs/projects/zboard/plugins/trust-en.md b/docs/projects/zboard/plugins/trust-en.md deleted file mode 100644 index 069a8bb..0000000 --- a/docs/projects/zboard/plugins/trust-en.md +++ /dev/null @@ -1,35 +0,0 @@ -# Plugin installation trust - -**English** · [简体中文](/projects/zboard/plugins/trust) - -ZBoard verifies package contents before accepting a signing identity. A package may include an Ed25519 public key in `signature.json.public_key`; this proves that its manifest and file hashes match the signature, but does not identify the publisher by itself. - -## Offline import - -The administrator selects a package, reviews its name, publisher, capabilities, UI surfaces and compatibility, and confirms installation. An unknown source additionally requires explicit confirmation of the signing-key fingerprint. The confirmation request binds the SHA-256 of the entire archive and the fingerprint of the verified public key. Inspection performs no installation, runtime execution or trust write. - -The host stores the public key and per-plugin trust together with the installation transaction. A failed installation grants no trust. Later versions must retain both plugin ID and publisher key; trusting one plugin does not trust other plugins from that publisher. Uninstall retains the identity pin along with the installation history, preventing another key from claiming the same plugin ID. Key rotation is deliberately rejected until a separate reviewed rotation workflow is available. - -Legacy archives without an embedded key can supply their public key through the dialog's compatibility option. Previously configured publisher keys remain supported; removing a configured key still revokes installations whose trust originated from that configuration. Explicit per-plugin trust is stored in the database and retained across restarts. - -## Market installation - -Without `plugins.catalog_url`, the market reads the [ZeroDeNet ZBoard registry](https://github.com/zerodenet/plugins/blob/main/catalogs/zboard.json). Each plugin has a detail page with platform downloads, online installation and a link to its installed management page. The detail page resolves `releases/download/v/marketplace-entry.json` from the registered GitHub repository. The release must match the registry's plugin ID, repository, publisher and version, and list platform-specific `.zbplugin` assets with SHA-256, size and the publisher's public key. No arbitrary download URL is accepted from the browser. - -Online installation selects the server's platform (or a platform-independent `any` artifact). Inspection downloads the package, checks its size, digest, identity, signature and compatibility, and displays the same confirmation used by offline import. A public listing or publisher metadata never grants trust: an unknown key requires explicit fingerprint confirmation scoped to that plugin. Confirmation re-fetches and re-validates the package against the inspected archive digest; changed packages require inspection again. Existing signing-key pins, capability admission, migrations and activation policy continue to apply. A missing release or unsupported server platform remains visible without presenting an installable package. - -The host first validates the configured catalog signature and expiry. Each signed entry may supply `public_key`, attesting that publisher key only for the entry's plugin. Before recording trust, the host checks the package digest, signature, plugin ID, publisher and version. Entry keys do not enter the global publisher configuration and cannot sign future catalogs. - -`plugins.catalog_url` must reference a signed host catalog, not the source registry JSON. The catalog signer remains a host-configured trust root. This implementation does not publish a production catalog or invent an official market key. - -Downloads allow at most four redirects. Every destination must use HTTPS on port 443, and every DNS resolution is checked against private addresses before dialing. Redirect targets may contain expiring signed queries used by release hosting services. Authorization and cookie headers are removed on redirects; package signatures and digests remain mandatory. - -## Packaging and compatibility - -`pluginpackager -source -out ` automatically creates and reuses a private local signing key beneath the user's configuration directory. Explicit `-key` and `-key-id` remain available and are required for catalog signing. OAuth's build wrapper also creates and reuses its ignored development key by default. - -The updated packager adds the optional public-key field to package signatures. Earlier hosts with strict signature decoding must be upgraded to read these new packages. Existing released archives are not rewritten; the compatibility input supports them without changing their checksums. - -Installation remains disabled initially. Core capability admission, registration policy, account ownership, configuration validation and data migrations apply independently of publisher trust. - -Plugin admission depends on the host's plugin protocol, UI bridge, supported capabilities and runtime platform, together with host authorization and data lifecycle checks. ZBoard product release numbers, including dev and RC suffixes, do not block installation, activation or active upgrades. `requires.zboard` is optional advisory metadata; `tested_zboard_versions` records publisher test coverage. An out-of-range or unrecognized host version produces a notice, not a refusal or extra activation consent. Existing signed packages need no rebuilding to adopt this host policy. Unsupported APIs, capabilities and runtime platforms remain rejected. diff --git a/docs/projects/zboard/plugins/trust.md b/docs/projects/zboard/plugins/trust.md index 29180dc..6c08094 100644 --- a/docs/projects/zboard/plugins/trust.md +++ b/docs/projects/zboard/plugins/trust.md @@ -1,6 +1,5 @@ # 插件安装信任 -[English](/projects/zboard/plugins/trust-en) · **简体中文** ZBoard 在接受签名身份前校验安装包。包可通过 `signature.json.public_key` 附带 Ed25519 公钥;这能证明签名、清单和文件摘要匹配,本身不能证明发布者身份。 diff --git a/zboard-document-migration.json b/zboard-document-migration.json index a9e9d39..f9e2464 100644 --- a/zboard-document-migration.json +++ b/zboard-document-migration.json @@ -17,9 +17,10 @@ }, { "source": "docs/getting-started.md", - "destination": "docs/projects/zboard/guides/installation-en.md", "source_sha256": "cce43ed1c3d9ad71f642248bbbe0f84a5771870290a47e75c63051e2ecb2fd8b", - "status": "retained_or_rewritten" + "status": "excluded", + "excluded_destination": "docs/projects/zboard/guides/installation-en.md", + "reason": "Duplicate English page removed; the ZBoard documentation section uses Chinese." }, { "source": "docs/core-baseline.md", @@ -100,9 +101,10 @@ }, { "source": "docs/plugin-installation-trust.md", - "destination": "docs/projects/zboard/plugins/trust-en.md", "source_sha256": "9f3f42f7291ce69c15fbed439f7f6a72ffa3f27b1f7e795fa8d460062198e9bf", - "status": "retained_or_rewritten" + "status": "excluded", + "excluded_destination": "docs/projects/zboard/plugins/trust-en.md", + "reason": "Duplicate English page removed; the ZBoard documentation section uses Chinese." }, { "source": "docs/plugin-installation-trust.zh-CN.md",