Cloud WAF/Docs 中文 EN
Cloud WAF 是企业级 Web 防护管理平台。后端 Go + Gin REST API,前端 Vue 3 SPA,附带 zcloud CLI 工具用于自动化运维。

本文档属于 Cloud WAF — 企业 Web 防护管理平台
CLI 工具:zcloud · 5 大模块:guard / sys / analytics / cli_release / auth
完整 API 索引:/api/openapi.json · 文档地图:/sitemap.xml · AI 速读:/llms.txt


API 文档

商业级 REST API 文档 · 57 个 endpoint · 80+ 图表数据接口(chart-key)· 双通道鉴权
适用对象:客户对接工程师、SRE、SaaS 集成商、AI agent
阅读顺序:先看 §0 总体约定§1 鉴权 → 再按业务模块跳转


目录

必读

公开接口(无需鉴权)

业务接口(双通道鉴权)

套餐目录

节点运维

Analytics 统计分析(74 chart-key · 单一形状契约)

参考

完整 OpenAPI: /api/openapi.json · AI 速读: /llms.txt · 错误码: /docs/errors · CLI: /docs/cli · 权限: /docs/permissions


§0 总体约定

Cloud WAF 后端基于 Gin 实现的 RESTful 服务。

0.1 基础协议

项目
协议 HTTPS(推荐)/ HTTP
数据格式 请求与响应均为 application/json(特例:POST /api/guard/certs 仍是 JSON,PEM 走字符串字段;导出/下载接口返回 text/csvapplication/pdf 等)
字符集 UTF-8
路径前缀 所有业务 API 都挂在 /api/
时间格式 Unix 毫秒时间戳(int64),不是 ISO 字符串
国际化 Accept-Language: zh-CNen-US,影响错误消息和权限名称

0.2 统一响应信封

任何 JSON 响应都遵循下面三段结构:

{
  "code": 0,
  "message": "ok",
  "data": { /* 业务载荷,类型依接口而定 */ }
}
字段 类型 含义
code number 0=成功;非 0 = 业务错误码
message string 错误描述(受 Accept-Language 影响)
data any 业务数据;列表接口为 { list, total, page, size }

特例:导出文件下载接口(POST /api/analytics/overview/exportGET /api/analytics/reports/:id/downloadPOST /api/analytics/logs/export)直接返回二进制流或 CSV/JSON 原文,包裹信封。

0.3 HTTP 状态码

状态码 何时出现
200 业务成功(仍需检查 code
201 资源创建成功
400 入参错误(参数缺失、格式非法、超出范围)
401 未登录、token 过期、API Key 已吊销
403 已登录但权限不足 / 跨 OEM 越权(参见 权限矩阵
404 资源不存在或不在可见范围
429 限流(默认每 Key 每秒 100 请求)
5xx 服务端异常

0.4 列表接口分页约定

所有列表接口统一使用 page + size不是 page_size):

字段 类型 默认 范围
page int 1 ≥ 1
size int 20 1 - 100

响应:

{
  "code": 0,
  "data": {
    "list": [ /* ... */ ],
    "total": 42,
    "page": 1,
    "size": 20
  }
}

0.5 跨模块设计标记(D*)

文档中少量 D* 标记来自跨模块设计决策,用于提醒对接方不要使用不存在或语义错误的字段:

标记 含义
D4 percentile / p50 / p95 / p99 不作为通用字段暴露;仅时间窗 ≤ 24h 时走实时 ES percentile 计算
D7 报表模板枚举为闭集,超出枚举的模板名不可调用
D8 缓存价值字段以 total_cache_* 为准,不存在 cache_count / cache_bytes / cache_hit 这类单字段
D10 告警/风险处置闭环字段以 process_uid / process_time / status / level 为准,不使用旧字段 handle_user / handle_time / risk_score / alert_status

0.6 三类读者的阅读路径

读者 入口 优先用
人类对接工程师 本文档 + 快速上手 curl / Postman 调单接口
脚本 / CI / 第三方系统 本文档 + API Key 管理 API Key + 受限 scopes
机器 / AI agent /api/openapi.json / /llms.txt / /llms-full.txt OpenAPI v3 schema

§1 鉴权(先读)

Cloud WAF 当前支持两条认证通道,同一请求只能选其中一种

场景 请求头 适用对象 说明
人工登录 / Web 控制台 / CLI 交互登录 Authorization: Bearer <token> token 由 POST /api/auth/login 颁发,会过期,适合短期会话
脚本 / CI / 第三方系统集成 Authorization: ApiKey zck_<prefix>.<secret> 机器调用 API Key 明文仅签发时返回一次,适合长期自动化对接

公开接口(无需鉴权)只有 4 个:

其它所有接口都必须携带上述任一认证头。下面各接口示例默认使用 Bearer;如改用 API Key,只需把请求头替换为 Authorization: ApiKey zck_<prefix>.<secret>,并确保该 Key 的 scopes 覆盖接口所需权限。

1.1 API Key 权限规则

effective_perms = user.RBAC ∩ key.scope

API Key 的权限不会超过签发用户当前的 RBAC;scope 只能收窄,不能放大。中间件认证通过后会注入与会话通道一致的 user_id / role_id 上下文,下游 RBAC/OEM 隔离保持一致。

安全约束

API Key 管理接口的完整说明见 §4.2


§2 CLI 发布(公开接口)

供 zcloud CLI 自更新与一键安装使用,无需鉴权。

GET /api/cli/version — 查询 CLI 最新版本

用途:客户端启动时自检版本;安装脚本 /api/cli/install.sh 内部依赖此接口决定下载哪个二进制。

鉴权:无(公开)

输入参数:无

输出字段

字段 类型 说明
data.version string 形如 v0.1.0-31,对齐 git tag
data.binaries[] array 4 个 os/arch 组合的下载地址
data.binaries[].os string linux / darwin
data.binaries[].arch string amd64 / arm64
data.binaries[].download_url string 拼接服务地址即可下载

可视化建议:纯文本展示(版本徽章),不适合图表。前端可用作"系统设置 - CLI 版本"页面的 KPI 数字卡。

示例响应

{
  "code": 0,
  "message": "ok",
  "data": {
    "version": "v0.1.0-31",
    "binaries": [
      { "os": "linux",  "arch": "amd64", "download_url": "/api/cli/download/linux-amd64" },
      { "os": "linux",  "arch": "arm64", "download_url": "/api/cli/download/linux-arm64" },
      { "os": "darwin", "arch": "amd64", "download_url": "/api/cli/download/darwin-amd64" },
      { "os": "darwin", "arch": "arm64", "download_url": "/api/cli/download/darwin-arm64" }
    ]
  }
}

GET /api/cli/install.sh — 一键安装脚本

用途:在 Linux/macOS 上一行命令完成 CLI 安装。返回 text/x-shellscript,可直接 curl ... | sh

鉴权:无(公开)

输入参数:无

输出字段:纯 shell 脚本文本,走 JSON 信封。

可视化建议:不适合图表,作为代码片段展示。

示例

curl -fsSL https://waf.example.com/api/cli/install.sh | sh

GET /api/cli/download/{filename} — 下载指定二进制

用途:拉取特定平台的 zcloud 二进制(已签名)。filename 取自 /api/cli/version 返回的 download_url 的最后一段,如 linux-amd64

鉴权:无(公开)

输入参数

字段 类型 必填 说明
filename path linux-amd64 / linux-arm64 / darwin-amd64 / darwin-arm64 其一

输出字段:二进制流(application/octet-stream)。

可视化建议:不适合图表。


GET /api/cli/checksums.txt — 二进制校验和

用途:配合 /api/cli/download/* 做 SHA256 完整性校验,安装脚本会先 fetch 这个文件再下载二进制。

鉴权:无(公开)

输入参数:无

输出字段:纯文本 text/plain,每行一个 <sha256> <filename>

可视化建议:不适合图表。


§3 用户认证

POST /api/auth/login — 登录

用途:用用户名 + 密码换取一个会话 token。Web 控制台、CLI 交互式登录、移动端均走此接口。

鉴权:无(公开)

输入参数(请求体):

字段 类型 必填 说明
username string 用户名
password string 密码(前端 base64 编码后传入,后端 decode 后再 bcrypt 比对,兼容老系统)

输出字段

字段 类型 说明
data.token string 32 位会话 token,用于后续 Authorization: Bearer <token>
data.user_id string 用户唯一 ID
data.user_name string 用户名
data.nick_name string 显示名
data.need_change_password bool true 表示首次登录需强制改密码

可视化建议:登录响应不直接做图,但 need_change_password=true 时前端应跳转改密页。

示例请求

curl -X POST https://waf.example.com/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"'$(echo -n 'your_password' | base64)'"}'

示例响应

{
  "code": 0,
  "message": "ok",
  "data": {
    "token": "550e8400-e29b-41d4-a716-446655440000",
    "user_id": "u-admin",
    "user_name": "admin",
    "nick_name": "系统管理员",
    "need_change_password": false
  }
}

常见误用


POST /api/auth/logout — 注销

用途:主动失效当前 Bearer token;再次请求该 token 返回 401。

鉴权Bearer <token>(API Key 通道无 logout 概念,吊销走 DELETE /api/sys/api-keys/:id

输入参数:无

输出字段datanull

可视化建议:不适合图表。

示例请求

curl -X POST https://waf.example.com/api/auth/logout \
  -H "Authorization: Bearer $TOKEN"

§4 系统管理

4.1 用户管理

适用场景:在"系统设置 - 用户管理"页面增删改查用户。所有用户接口都受 OEM 隔离,跨 OEM 操作会返回 403。

GET /api/sys/users — 用户列表(分页)

用途:在"用户管理"页面渲染用户表格,支持关键字模糊搜索 + 分页。

鉴权sys.user.list

输入参数

字段 类型 必填 取值/示例 说明
page int 1 页码,从 1 起
size int 20 每页条数,1-100
keyword string admin 用户名/显示名模糊搜索

输出字段data.list[]):

字段 类型 说明
user_id string 用户唯一 ID
user_name string 登录用户名
nick_name string 显示名
email string 邮箱
mobile string 手机号
locked int 0=正常,非 0=锁定
role_ids int64[] 角色 ID 列表(可多角色)
roles[] array 角色摘要 {role_id, name, level}
ctime int64 创建时间,Unix 毫秒

可视化建议:表格展示。locked 列建议用徽章(绿/红);roles 用 chip 标签。

示例请求

curl -H "Authorization: Bearer $TOKEN" \
  "https://waf.example.com/api/sys/users?page=1&size=20&keyword=admin"

示例响应

{
  "code": 0,
  "message": "ok",
  "data": {
    "list": [
      {
        "user_id": "u-001",
        "user_name": "admin",
        "nick_name": "系统管理员",
        "email": "admin@example.com",
        "mobile": "",
        "locked": 0,
        "role_ids": [1],
        "roles": [{ "role_id": 1, "name": "超级管理员", "level": 1 }],
        "ctime": 1714521600000
      }
    ],
    "total": 42,
    "page": 1,
    "size": 20
  }
}

常见误用


POST /api/sys/users — 创建用户

用途:在"用户管理"页面提交"新建用户"表单。

鉴权sys.user.create

输入参数(请求体):

字段 类型 必填 取值/示例 说明
user_name string u1 2-255 字符
password string InitPassw0rd! 6-72 字符(bcrypt 上限)
nick_name string 运维 A ≤ 100 字符
email string u1@x.com 标准邮箱格式
mobile string 13800138000 ≤ 20 字符
comment string 值班同事 备注

输出字段:返回新建用户对象,结构同列表项。

可视化建议:不适合图表,是一次性写操作;前端应在成功后刷新用户列表。

示例请求

curl -X POST https://waf.example.com/api/sys/users \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"user_name":"u1","password":"InitPassw0rd!","nick_name":"运维 A","email":"u1@example.com"}'

DELETE /api/sys/users/{id} — 删除用户

用途:用户管理页面"删除"按钮的后端接口。删除会级联清理会话、API Key、角色绑定。

鉴权sys.user.delete

输入参数

字段 类型 必填 说明
id path 用户 user_id

输出字段datanull

可视化建议:不适合图表。


PUT /api/sys/users/{id}/password — 重置密码

用途:管理员替用户重置密码。被重置用户下次登录后强制改密码。

鉴权sys.user.resetpwd

输入参数

字段 类型 必填 说明
id path 用户 user_id
password string 新密码(明文,6-72 字符;后端自动 bcrypt)

输出字段datanull

可视化建议:不适合图表。

示例请求

curl -X PUT https://waf.example.com/api/sys/users/u-001/password \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"password":"NewPassw0rd!"}'

常见误用


4.2 API Key 管理

适用场景:在"系统设置 - API Key"页面发放/回收脚本调用凭证。配合 /api/sys/api-keys/:id/logs|stats|audit-actions 做调用审计。

POST /api/sys/api-keys — 签发新 API Key

用途:为脚本/CI/第三方系统签发一条机器调用凭证。明文 api_key 字段仅此一次返回,前端必须立即让用户复制保存。

鉴权sys.apikey.create

输入参数(请求体):

字段 类型 必填 取值/示例 说明
name string 生产对接 ≤ 100 字符,用于审计识别
scopes string[] ["guard.domain.list"] 权限 full key 列表;空数组 = 完整继承签发用户当前 RBAC
expires_in_days int 90 过期天数,默认 90,最大 365
allowed_ip_cidrs string[] ["203.0.113.0/24"] E14 IP 白名单 CIDR;为空表示不限制来源 IP

输出字段

字段 类型 说明
data.key_id string API Key 唯一 ID(吊销/查日志用此 ID)
data.name string 与请求一致
data.api_key string 完整明文 prefix.secret,仅此一次返回
data.prefix string 形如 zck_abc12345,可写入日志
data.last4 string secret 末 4 位,前端用于"我刚签的那条"识别
data.expires_at int64 过期时间,Unix 毫秒

错误码

可视化建议:签发响应是一次性写操作,建议前端用模态框 + 一次性复制按钮 + 遮码展示明文(参考行业惯例 GitHub/Stripe)。

示例请求

curl -X POST https://waf.example.com/api/sys/api-keys \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"name":"生产对接","scopes":["guard.domain.list"],"expires_in_days":90}'

示例响应

{
  "code": 0,
  "data": {
    "key_id": "8f21c0c5-55ae-4cbd-a60a-8e64a6e2b1d0",
    "name": "生产对接",
    "api_key": "zck_abc12345.A1b2C3d4E5f6G7h8I9j0K1L2M3n4O5p6Q7r8S9t0",
    "prefix": "zck_abc12345",
    "last4": "5t0",
    "expires_at": 1732982400000
  }
}

常见误用


GET /api/sys/api-keys — 查询 API Key 列表

用途:在 API Key 管理页面展示当前用户/OEM 内的 Key 清单与状态。

鉴权sys.apikey.list

输入参数

字段 类型 必填 说明
page int 默认 1
size int 默认 20,最大 100

输出字段data.list[]):

字段 类型 说明
key_id string API Key 唯一 ID
name string 名称
prefix string zck_xxx 前缀
last4 string secret 末 4 位
user_id string 持有人
oem_id string OEM 隔离边界
scopes string[] 限定权限列表
allowed_ip_cidrs string[] E14 IP 白名单
status int 1=active,2=revoked
expires_at int64 过期时间
last_used_at int64 最近调用时间;从未用为 0
last_used_ip string 最近调用 IP;从未用为 ""
ctime int64 签发时间

可见范围

可视化建议:表格展示。status 用徽章(绿=active/灰=revoked),expires_at 即将到期(< 7d)建议高亮。配合 /stats 接口可做柱状图"调用量 TOP 5 Key"。

示例请求

curl -H "Authorization: Bearer $TOKEN" \
  "https://waf.example.com/api/sys/api-keys?page=1&size=20"

DELETE /api/sys/api-keys/{id} — 吊销 API Key

用途:软吊销(statusrevoked),保留审计痕迹。中间件认证时 status != active 直接拒绝。

鉴权sys.apikey.delete

输入参数

字段 类型 必填 说明
id path API Key key_id

输出字段datanull

幂等性:重复吊销返回 200,前端反复操作不报错。

可操作范围

错误码1051 API Key 不存在或不在可见范围。

可视化建议:不适合图表;前端"吊销"按钮触发,建议加二次确认对话框。

示例请求(用 API Key 调用)

curl -X DELETE https://waf.example.com/api/sys/api-keys/8f21c0c5-55ae-4cbd-a60a-8e64a6e2b1d0 \
  -H "Authorization: ApiKey zck_abc12345.A1b2C3d4..."

GET /api/sys/api-keys/{id}/logs — 查询某 Key 的调用流水(E12)

用途:审计某条 API Key 的调用历史。返回该 Key 在审计表 api_key_audit_logs 中的事件列表。

鉴权sys.apikey.logs

输入参数

字段 类型 必填 说明
id path API Key key_id
event string call(默认,调用流水)/ manage(管理操作)
page int 默认 1
size int 默认 20,最大 100

输出字段(每条记录):

字段 类型 说明
id int 自增主键
event_type string call / manage
key_id string 关联的 API Key ID
user_id string 操作主体(call=key 持有人;manage=操作人)
auth_mode string apikey / session,记录请求通过的认证通道
action string call=<METHOD> <PATH>;manage=create / revoke / renew / revoke-all
status_code int HTTP 响应状态码(call 类型有效)
biz_code int 业务错码(0 = 成功;call 类型有效)
client_ip string 客户端 IP
user_agent string UA(≤ 255 字符,超长截断)
extra string JSON 字符串,承载续期 / 批量动作等结构化扩展字段
ctime int Unix 毫秒时间戳

可视化建议

可见范围

错误码1051 API Key 不存在或不在可见范围。


GET /api/sys/api-keys/{id}/stats — 查询某 Key 的聚合统计

用途:在 API Key 详情页展示该 Key 的调用聚合 KPI(总次数、成功率、QPS、TOP 接口)。仅基于 event_type=call 的记录。

鉴权sys.apikey.stats

输入参数

字段 类型 必填 说明
id path API Key key_id
since string/int 聚合窗口起点;支持 24h / 7d / 30m 相对值,或纯整数 = 毫秒时间戳;留空 = 全量历史

输出字段

字段 类型 说明
total_calls int 窗口内总调用次数
success int 200 ≤ status_code < 400 的次数
client_err int 400 ≤ status_code < 500 的次数
server_err int status_code ≥ 500 的次数
top_endpoints array 调用次数 Top 5 的 action({action, count},按次数降序)
last_1h_qps float 最近 1 小时 QPS(次数 / 3600)

可视化建议

错误码400 since 解析失败;1051 API Key 不存在或不在可见范围。

示例请求

curl -H "Authorization: Bearer $TOKEN" \
  "https://waf.example.com/api/sys/api-keys/8f21c0c5-55ae-4cbd-a60a-8e64a6e2b1d0/stats?since=24h"

GET /api/sys/api-keys/audit-actions — 查询管理操作流水(E13)

用途:跨 Key 的审计视图,返回 API Key 管理动作(创建 / 吊销 / 续期 / 批量吊销)的流水。

鉴权sys.apikey.audit

输入参数page / size,标准分页。

输出字段:与 GET /api/sys/api-keys/{id}/logs 相同;event_type 全部为 manage

可见范围

可视化建议


4.3 权限树

GET /api/sys/permissions/tree — 权限树

用途:返回当前 OEM 下的完整权限树(含模块/资源/动作三层 + i18n 名)。前端"角色权限"页用此渲染勾选树;签发 API Key 选 scope 时也用同一颗树。

鉴权:登录态(无具体权限要求)

输入参数:可附加 Accept-Language: en-US 切换权限名语言。

输出字段(节选,data[]):

字段 类型 说明
module string 模块名,如 guard / sys / analytics
resources[] array 该模块下的资源列表
resources[].prefix string 资源前缀,如 guard.domain
resources[].name string 资源 i18n 显示名
resources[].actions[] array 该资源的动作列表
resources[].actions[].key string 动作短 key,如 list / create
resources[].actions[].name string 动作 i18n 显示名
resources[].actions[].full_key string 完整权限 key,如 guard.domain.list

可视化建议

示例响应(节选):

{
  "code": 0,
  "data": [
    {
      "module": "guard",
      "resources": [
        {
          "prefix": "guard.domain",
          "name": "域名",
          "actions": [
            { "key": "list",   "name": "列表",   "full_key": "guard.domain.list" },
            { "key": "view",   "name": "查看",   "full_key": "guard.domain.view" },
            { "key": "create", "name": "创建",   "full_key": "guard.domain.create" }
          ]
        }
      ]
    }
  ]
}

§5 Guard 资源管理

📦 Guard 资源管理 · 30 个 endpoint · 用于配置防护对象(域名/证书/策略/CC&ACL 规则/名单/转发/调度/WAF 规则),是 WAF 防护能力的"配置面"
完整 schema 见 /api/openapi.json,本节给出对接最关键的字段名、枚举与典型踩坑点。

5.1 域名 /api/guard/domains

域名是 Guard 的核心资源——所有防护策略、证书绑定、统计聚合都以 domain_id 为锚点。

GET /api/guard/domains — 域名列表

用途:在"防护管理 - 域名"页面渲染域名表格,按审核状态筛选 + 关键字搜索。

鉴权guard.domain.list

输入参数

字段 类型 必填 取值/示例 说明
page int 1 页码
size int 20 每页条数,1-100(不是 page_size
keyword string api.example 模糊搜索 domainasset_name
audit_status int 4 1=未审核 2=审核中 3=未通过 4=通过

输出字段data.list[]DomainVO):

字段 类型 说明
domain_id string 域名唯一 ID
domain string 域名本身,如 api.example.com
asset_name string 资产备注名
user_id string 归属用户 UUID(保留兼容老平台)
user_name string 归属用户名(P1.3 新增,来源 cloud sys.users
policy_id string 关联策略 ID
cname string 后端为该域名分配的 CNAME
auto_cert bool 是否启用自动签发证书
mode int32 接入模式(1=反代等,参见运维文档)
audit_status int32 1=未审核 2=审核中 3=未通过 4=通过
switches map<string,int32> 保护开关,key 取自 waf/cc/acl/bot/cache,1=开 0=关
ctime / utime int64 创建/更新时间

可视化建议

示例请求

curl -H "Authorization: ApiKey $ZCLOUD_API_KEY" \
  "https://waf.example.com/api/guard/domains?page=1&size=20&audit_status=4"

示例响应

{
  "code": 0,
  "data": {
    "list": [
      {
        "domain_id": "d_8a3b1c",
        "domain": "api.example.com",
        "asset_name": "线上 API 网关",
        "user_id": "u_abc",
        "policy_id": "p_default",
        "cname": "api.example.com.cname.zcloud.io",
        "auto_cert": false,
        "mode": 1,
        "audit_status": 4,
        "switches": { "waf": 1, "cc": 1, "acl": 1, "bot": 0, "cache": 1 },
        "ctime": 1714521600000,
        "utime": 1714608000000
      }
    ],
    "total": 8,
    "page": 1,
    "size": 20
  }
}

常见误用


POST /api/guard/domains — 创建域名

用途:在"添加域名"表单提交后调用,创建一条新的防护域名。

鉴权guard.domain.create

输入参数(请求体 DomainCreateReq):

字段 类型 必填 说明
domain string 域名本身,如 api.example.com
asset_name string 资产备注名
policy_id string 绑定策略;不传走默认

重要domain 是唯一必填项;证书绑定走 POST /api/guard/certs/:id/bind不要通过 create-domain 设置;origin_addr / port / cert_id 字段不存在

输出字段:返回 DomainVO(结构同列表项),含分配的 domain_idcname

可视化建议:不适合图表。建议创建成功后立即跳转域名详情页或刷新列表。


GET /api/guard/domains/{id} — 域名详情

用途:进入域名详情页时拉单条详情。

鉴权guard.domain.view

输入参数:path id = domain_id

输出字段DomainVO,与列表项完全一致。

可视化建议:表单展示。switches 渲染为开关组;audit_status 用徽章。


PUT /api/guard/domains/{id} — 更新域名

用途:编辑域名的资产名、策略绑定、自动证书等可变字段。

鉴权guard.domain.edit

输入参数(请求体 DomainUpdateReq):

字段 类型 必填 说明
asset_name string 资产备注名
policy_id string 切换策略
auto_cert bool 切换自动签发开关
mode int32 接入模式

输出字段:返回更新后的 DomainVO

可视化建议:不适合图表。


DELETE /api/guard/domains/{id} — 删除域名

用途:从防护列表中移除域名。删除会级联清理 settings、证书绑定、统计快照。

鉴权guard.domain.delete

输入参数:path id = domain_id

输出字段datanull

可视化建议:不适合图表。建议删除前二次确认,提示"会清理统计与绑定"。


GET /api/guard/domains/{id}/settings — 域名设置查询

用途:在域名详情页"高级设置"标签下展示当前生效的 settings(保护模块开关、缓存策略、CC 限速等)。

鉴权guard.domain.view

输入参数:path id = domain_id

输出字段

字段 类型 说明
data.settings map<string,string> key 取自后端 settings.* 字典,典型 waf/cc/acl/bot/cache,value 是 stringified 配置 JSON

可视化建议:表单展示,每个 key 一行配置卡片。


PUT /api/guard/domains/{id}/settings — 域名设置更新

用途:修改域名的 settings map。

鉴权guard.domain.edit

输入参数(请求体 DomainSettingsUpdateReq):

字段 类型 必填 说明
settings map<string,string> key 必须取自 GET /settings 返回的 settings.* 键名;非法 key 后端会拒绝

输出字段datanull,调用方应紧接调用 GET 拉新值。

可视化建议:不适合图表。

常见误用


5.2 证书 /api/guard/certs

证书管理走"上传 PEM 文本 → 绑定域名"两步流程;Content-Type 是 application/json,不是 multipart/form-data

GET /api/guard/certs — 证书列表

用途:"防护管理 - 证书"页面表格。

鉴权guard.cert.list

输入参数page / size / keyword(搜索 name/common_name)。

输出字段data.list[] = CertVO):

字段 类型 说明
id uint64 证书唯一 ID
name string 自定义名称
user_name string 归属用户名(P1.3 替换原 user_id,来源 cloud sys.users
certificate_type int32 证书类型枚举
common_name string 证书 CN
issuer string 颁发者
expired_at int64 到期时间,Unix 毫秒
auto_cert bool 是否自动续期
ctime / utime int64 创建/更新时间

不存在 bound_domains 字段;要查证书绑定哪些域名,调 GET /api/guard/certs/{id}/domains

可视化建议


POST /api/guard/certs — 上传证书

用途:上传一条 PEM 证书。客户对接最容易踩的坑就是误用 multipart/form-data,请务必用 JSON。

鉴权guard.cert.create

安全提示:直接集成本接口时,cert / key 仍按 JSON PEM 文本传入;但不要把私钥写入 AI 对话、工单、日志或可观测埋点。若通过 Aegeon Cloud 对话助手操作证书,优先使用其"安全证书附件"上传入口:浏览器将证书/私钥上传到 Aegeon 后只在对话中保留附件引用,私钥不会进入 AI 消息内容。

输入参数(请求体 CertUploadReqapplication/json):

字段 类型 必填 说明
name string 证书名
cert string PEM 文本字符串(含 -----BEGIN CERTIFICATE----- 头尾)
key string 私钥 PEM 文本字符串
sign_cert string 国密签名证书 PEM(可选)
sign_key string 国密签名私钥 PEM(可选)

输出字段:返回新建 CertVO

可视化建议:不适合图表。前端上传组件应支持"粘贴 PEM 文本"和"读取本地文件"两种方式。

示例请求

curl -X POST https://waf.example.com/api/guard/certs \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"name":"prod-2026","cert":"-----BEGIN CERTIFICATE-----\nMII...\n-----END CERTIFICATE-----","key":"-----BEGIN PRIVATE KEY-----\nMII...\n-----END PRIVATE KEY-----"}'

常见误用


GET /api/guard/certs/{id} — 证书详情

用途:详情页展示,含完整 PEM 文本。

鉴权guard.cert.view

输入参数:path id

输出字段CertDetailVO = CertVO + cert + sign_cert(PEM 文本,方便下载)。

可视化建议:表单展示。可加"下载证书"按钮(前端拼 PEM 触发下载)。


PUT /api/guard/certs/{id} — 更新证书

用途:直接替换 PEM 文本(无需先删后建)。

鉴权guard.cert.edit

输入参数(请求体 CertUpdateReq,字段同 Upload 但全部可选):name / cert / key / sign_cert / sign_key

输出字段:返回更新后的 CertVO


DELETE /api/guard/certs/{id} — 删除证书

鉴权guard.cert.delete

输入参数:path id

输出字段datanull

副作用:删除前会自动解绑该证书绑定的所有域名。


GET /api/guard/certs/{id}/domains — 查询证书已绑定的域名

用途:在证书详情页展示"该证书正在保护哪些域名"。

鉴权guard.cert.view

输入参数:path id

输出字段data[] = CertDomainVO[]):

字段 类型 说明
domain_id string 域名 ID
domain string 域名
cert_id uint64 证书 ID(即 path id
ctime int64 绑定时间

可视化建议:表格展示。


POST /api/guard/certs/{id}/bind — 绑定证书到域名

用途:把指定证书绑到一个域名上。

鉴权guard.cert.edit

输入参数(请求体 CertBindReq):

字段 类型 必填 说明
domain_id string 目标域名 ID

输出字段datanull

可视化建议:不适合图表。


DELETE /api/guard/certs/{id}/bind/{domainId} — 解绑证书与域名

用途:解除证书与某个域名的绑定关系。

鉴权guard.cert.edit

输入参数:path id = 证书 ID;path domainId = 域名 ID。

输出字段datanull

路径:是 DELETE /bind/{domainId}不是 POST /unbind


5.3 策略 /api/guard/policies

策略是规则的容器:CC / ACL / 黑白名单 都挂在策略下。一个域名绑一个策略。

GET /api/guard/policies — 策略列表

鉴权guard.policy.list

输入参数page / size / keyword

输出字段data.list[] = PolicyVO):

字段 类型 说明
policy_id string 策略 ID
name string 策略名
comment string 备注(不是 remark
user_id string 归属用户 UUID(保留兼容老平台)
user_name string 归属用户名(P1.3 新增,来源 cloud sys.users
default_main_rule_version string 默认主规则版本
is_default bool 是否系统默认策略
schema_id int64 schema 版本
cc_rule_count int32 该策略下的 CC 规则数
bwl_rule_count int32 黑白名单规则数
acl_rule_count int32 ACL 规则数
ctime / utime int64 创建/更新时间

可视化建议:表格 + 三个 chip(cc/bwl/acl 数量)。


POST /api/guard/policies — 创建策略

鉴权guard.policy.create

输入参数PolicyCreateReq):name(必填)/ comment

输出字段:返回新建 PolicyVO


GET /api/guard/policies/{id} — 策略详情

鉴权guard.policy.view

输入参数:path id

输出字段PolicyVO


PUT /api/guard/policies/{id} — 更新策略

鉴权guard.policy.edit

输入参数PolicyUpdateReq):name / comment

输出字段:返回更新后的 PolicyVO


DELETE /api/guard/policies/{id} — 删除策略

鉴权guard.policy.delete

输入参数:path id

输出字段datanull。删除前需保证该策略未被任何域名引用。


5.4 CC 规则 /api/guard/policies/{id}/cc/rules

CC = HTTP 速率限制规则(Connection / Concurrency Control)。挂在策略下,按 policy_id 隔离。

GET /api/guard/policies/{id}/cc/rules — CC 规则列表

鉴权guard.cc.list

输入参数:path id = policy_id;query page / size

输出字段data.list[] = CcRuleVO):

字段 类型 说明
rule_id int64 规则 ID
name string 规则名
describe string 描述
matches[] array 匹配条件结构(路径/方法/头部等)
stats object 统计聚合维度
limit object 速率限制阈值
action object 命中动作(拦截/验证码/限速等)
stime / etime int64 生效起止时间
status int32 1=启用 2=禁用
ctime / utime int64 创建/更新时间

可视化建议:表格 + status 徽章。matches 太复杂建议折叠为"详情"按钮弹出。


POST /api/guard/policies/{id}/cc/rules — 创建 CC 规则

鉴权guard.cc.create

输入参数CcRuleCreateReq):

字段 类型 必填 说明
name string 规则名
describe string 描述
matches[] array 至少 1 项匹配条件
stats object 统计维度(IP/URI/UA 等)
limit object 速率上限
action object 命中动作
stime / etime int64 生效时间窗

复杂结构建议先调 list 取一条样本作为模板。

输出字段:返回新建 CcRuleVO


GET /api/guard/policies/{id}/cc/rules/{rid} — CC 规则详情

鉴权guard.cc.view

输入参数:path id = policy_idrid = rule_id。会校验 rule_id 是否归属当前 policy_id,跨策略读取返回 NotFound

输出字段CcRuleVO


PUT /api/guard/policies/{id}/cc/rules/{rid} — 更新 CC 规则

鉴权guard.cc.edit

输入参数:path id + rid,body 同 Create。

输出字段:返回更新后的 CcRuleVO


DELETE /api/guard/policies/{id}/cc/rules/{rid} — 删除 CC 规则

鉴权guard.cc.delete

输入参数:path id + rid

输出字段datanull


PUT /api/guard/policies/{id}/cc/rules/{rid}/status — 切换 CC 规则状态

用途:在列表页用开关组件启用/禁用规则。

鉴权guard.cc.edit

输入参数CcRuleStatusReq):

字段 类型 必填 取值
status int32 1=启用 2=禁用

重要statusint32 数字,不是 "enabled" / "disabled" 字符串。

输出字段datanull

示例请求

curl -X PUT https://waf.example.com/api/guard/policies/p_default/cc/rules/12345/status \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"status":1}'

5.5 ACL 规则 /api/guard/policies/{id}/acl/rules

ACL = 访问控制列表(基于 IP / Header / URI 的放行/拦截)。结构与 CC 规则相似但没有 priority 字段。

GET /api/guard/policies/{id}/acl/rules — ACL 规则列表

鉴权guard.acl.list

输入参数:path id,query page / size

输出字段data.list[] = AclRuleVO):

字段 类型 说明
rule_id int64 规则 ID
name string 规则名
describe string 描述
matches[] array 匹配条件
action object 命中动作(block/page/pass
stime / etime int64 生效起止时间
status int32 1=启用 2=禁用
ctime / utime int64 创建/更新时间

可视化建议:表格 + status 徽章 + action.type chip 染色(block 红 / pass 绿 / page 蓝)。


POST /api/guard/policies/{id}/acl/rules — 创建 ACL 规则

鉴权guard.acl.create

输入参数AclRuleCreateReq):name / describe / matches[](≥1)/ action / stime / etime

action.typeblock / pagecontent 字段服务端会 base64 编码存储;调用方传明文。

输出字段:返回新建 AclRuleVO


GET /api/guard/policies/{id}/acl/rules/{rid} — ACL 规则详情

鉴权guard.acl.view

输入参数:path id + rid

输出字段AclRuleVO


PUT /api/guard/policies/{id}/acl/rules/{rid} — 更新 ACL 规则

鉴权guard.acl.edit

输入参数:path id + rid,body 同 Create。

输出字段:返回更新后的 AclRuleVO


DELETE /api/guard/policies/{id}/acl/rules/{rid} — 删除 ACL 规则

鉴权guard.acl.delete

输入参数:path id + rid

输出字段datanull


PUT /api/guard/policies/{id}/acl/rules/{rid}/status — 切换 ACL 规则状态

鉴权guard.acl.edit

输入参数AclRuleStatusReq):status int32(1=启用 2=禁用,数字)。

输出字段datanull


5.6 黑白名单 /api/guard/bwlist

黑白名单分两层:集合(set) 是逻辑容器(黑/白/灰黑/灰白),IP 是集合内的具体条目。灰黑、灰白会在配置生成时分别按黑名单、白名单下发。

GET /api/guard/bwlist/sets — 名单集合列表

鉴权guard.bwlist.list

输入参数page / size / keyword

输出字段data.list[] = IPSetVO):

字段 类型 说明
id uint64 集合 ID
user_name string 归属用户名(P1.3 替换原 user_id,来源 cloud sys.users
name string 集合名
policy_id string 关联策略
ip_set_type int32 1=黑名单 2=白名单 3=灰黑名单 4=灰白名单(数字枚举,不是字符串
status int32 1=禁用 2=启用
count int64 总条目数
enable_count int64 启用条目数
unable_count int64 禁用条目数
describe string 描述(不是 remark
is_default bool 是否默认集合
is_private bool 是否私有
private_domain_id string 私有集合关联的域名
ctime / utime int64 时间戳

可视化建议


POST /api/guard/bwlist/sets — 创建名单集合

鉴权guard.bwlist.create

输入参数BWListSetCreateReq):

字段 类型 必填 说明
name string 集合名
ip_set_type int32 1=黑名单 2=白名单 3=灰黑名单 4=灰白名单
policy_id string 关联策略
status int32 1=禁用 2=启用,默认 2
describe string 描述

输出字段:返回新建 IPSetVO

policy_id 非空时,后端会把集合同步到策略与该策略下域名的黑白名单配置;后续添加、批量添加或删除 IP 会触发配置下发。


PUT /api/guard/bwlist/sets/{id} — 更新名单集合

鉴权guard.bwlist.edit

输入参数BWListSetUpdateReq):name / status / describe(全部可选)。

输出字段:返回更新后的 IPSetVO

修改 status 会同步策略/域名配置并触发下发:启用集合进入黑/白名单,禁用集合进入禁用列表。


DELETE /api/guard/bwlist/sets/{id} — 删除名单集合

鉴权guard.bwlist.delete

输入参数:path id

输出字段datanull会级联删除集合内所有 IP 条目

删除集合会同时从策略/域名黑白名单配置中解绑,并触发相关域名重新下发。


GET /api/guard/bwlist/sets/{id}/ips — 集合内 IP 列表

鉴权guard.bwlist.ip_list

输入参数:path id = 集合 ID;query page / size

输出字段data.list[] = IPVO):

字段 类型 说明
id uint64 条目 ID
ipset_id uint64 所属集合
ip_addr string IP 或 CIDR(不是 ip
status bool true=启用 false=禁用,默认 true
ctime / utime int64 时间戳

不存在 expires_at / remark 字段。

可视化建议:表格。


POST /api/guard/bwlist/sets/{id}/ips — 单条添加 IP

鉴权guard.bwlist.ip_add

输入参数BWListIPAddReq):

字段 类型 必填 说明
ip_addr string IP 或 CIDR
status bool 默认 true

输出字段:返回新建 IPVO


POST /api/guard/bwlist/sets/{id}/ips/batch — 批量添加 IP

用途:一次导入数百条 IP(如威胁情报源),减少多次往返开销。

鉴权guard.bwlist.ip_add

输入参数BWListIPBatchAddReq):

字段 类型 必填 说明
ips[] array 至少 1 项;每项 {ip_addr, status?}

输出字段datanull 或返回新增 ID 列表(按实现)。


POST /api/guard/bwlist/sets/{id}/ips/batch/delete — 批量删除 IP

用途:一次删除集合下多条 IP(如清理过期封禁),一个事务原子完成,避免逐条删除的部分失败与审计刷屏。

鉴权guard.bwlist.ip_delete

输入参数BWListIPBatchDeleteReq):

字段 类型 必填 说明
ip_ids[] array<int64> 至少 1 项;要删除的 IP 条目 ID。删除范围限定在集合 {id} 内,不属于该集合的 ID 会被忽略

输出字段data.deleted 为实际删除条数。集合内无任一匹配返回 404


DELETE /api/guard/bwlist/ips/{id} — 删除单条 IP

重要:删除路径是顶级路径 DELETE /api/guard/bwlist/ips/{id}不是嵌套在 sets 下的 DELETE /sets/{sid}/ips/{id}

鉴权guard.bwlist.ip_delete

输入参数:path id = IP 条目 ID。

输出字段datanull


5.7 IP 转发 /api/guard/forwards

这是 TCP/UDP 端口转发(4 层),不是路径转发 / 反向代理(7 层)。

GET /api/guard/forwards — IP 转发列表

鉴权guard.forward.list

输入参数

字段 类型 说明
page / size int 标准分页
user_id string 按归属用户过滤
domain_id string 按域名过滤
status int32 1=禁用 2=启用
keyword string 搜索 domain / describe

输出字段data.list[] = ForwardVO):

字段 类型 说明
id uint64 转发 ID
user_id string 归属用户 UUID(保留兼容老平台)
user_name string 归属用户名(P1.3 新增,来源 cloud sys.users
domain string 转发的域名/IP
domain_id string 关联域名 ID
schema int32 3=TCP 4=UDP,默认 3
port int32 端口 1-65535
node_ipaddrs string 源 IP 列表(逗号分隔)
describe string 描述
status int32 1=禁用 2=启用
src_setting json 源设置 raw JSON
adv_settings json 高级设置 raw JSON
node_setting json 节点设置 raw JSON
dev_setting string 设备设置
ctime / utime int64 时间戳

可视化建议


POST /api/guard/forwards — 创建 IP 转发

鉴权guard.forward.create

输入参数ForwardCreateReq):

字段 类型 必填 取值 说明
domain string *.example.com 转发域名
domain_id string d_8a3b1c 关联域名
port int32 443 1-65535
schema int32 3 3=TCP(默认)/4=UDP
node_ipaddrs string 10.0.0.1,10.0.0.2 源 IP 列表
describe string 描述
status int32 2 1=禁 2=启用
src_setting / adv_settings / node_setting json raw JSON 配置
dev_setting string 设备配置

不存在 source_path / target 字段。

输出字段:返回新建 ForwardVO


GET /api/guard/forwards/{id} — IP 转发详情

鉴权guard.forward.view

输入参数:path id

输出字段ForwardVO


PUT /api/guard/forwards/{id} — 更新 IP 转发

鉴权guard.forward.edit

输入参数:path id,body 同 Create(字段全部可选)。

输出字段:返回更新后的 ForwardVO


DELETE /api/guard/forwards/{id} — 删除 IP 转发

鉴权guard.forward.delete

输入参数:path id

输出字段datanull


5.8 调度管理 /api/guard/schedules

本模块只做 DNS 解析调度(域名解析模式切换 / 批量启停记录)。 旧版 cron 定时任务接口已下架。

⚠️ 异步生效约定:本组接口不直接调用三方 DNS API,所有写操作仅落库老平台 guard_db.dns_records + guard_db.dns_affairs,最终通过 NSQ topic=dns 通知 zdns 服务异步生效。前端 / 调用方必须轮询 affairs 接口获取最终状态(初始 AffairsStatus_StartAffairsStatus_Succeed / AffairsStatus_Faild)。

⚠️ 数据真值源dns_records.group_type 是模式真相源,guard_configs.parsing_state 异步同步,均来自老平台 guard_db;存在最长 30s 不一致窗口。VO 同时返回两者,前端在不一致时显示"同步中" badge。

5.8.1 域名调度

GET /api/guard/schedules/domains — 域名列表

鉴权guard.schedule.list

输入参数

字段 类型 说明
page / size int 分页(size 上限 100)
keyword string 按域名模糊搜索
user_id string 按归属用户过滤(仅超管/总代有效)
mode int32 0=全部 / 1=源站(SRC) / 2=节点(NODE)

输出字段data = ScheduleDomainListResp):

字段 类型 说明
list[].domain_id string 域名 ID(guard_configs.domain_id
list[].domain_name string 域名
list[].user_id / user_name string 归属用户
list[].parsing_state int32 guard_configs.parsing_state(1=SRC / 2=NODE)
list[].dns_group_type int32 dns_records.group_type 多数票(真值源,1=SRC / 2=NODE)
list[].src_count int group_type=1 的记录数
list[].node_count int group_type=2 的记录数
list[].src_records[] array 源站解析摘要:subdomain / record_type / record_line / value / status
list[].node_records[] array 节点解析摘要:subdomain / record_type / record_line / value / status
list[].last_affair_status string 最近一条事务状态(AffairsStatus_Start / AffairsStatus_Succeed / AffairsStatus_Faild
list[].last_affair_ctime int64 最近一条事务创建时间(毫秒)
list[].last_affair_message string 最近一条事务消息(HTML 片段)
total int64 总条数

POST /api/guard/schedules/domains/{id}/switch-mode — 切换源站/节点

鉴权guard.schedule.switch

输入参数

字段 类型 必填 说明
path id string domain_id
body target_mode int32 1=源站(SRC) / 2=节点(NODE)
body comment string 事务备注(写入 dns_affairs.message

实现要点:guard_db 单库事务内 SELECT FOR UPDATE 锁住该域名全部 dns_records → 更新 group_typeswitch_state=2(切换中)→ INSERT dns_affairsstatus=AffairsStatus_Start)→ 提交后 NSQ Cmd=0 通知。

输出字段:返回新建 ScheduleAffairVO,前端应将 affairs_id 写入轮询轮换。


POST /api/guard/schedules/domains/{id}/init — 初始化解析

鉴权guard.schedule.init

输入参数:path iddomain_id);body 可选 comment

实现要点:读取 guard_domain_settings 的源站/调度配置与 domain_node_ships 节点绑定,锁住该域名旧 dns_records 后删除并重建源站/节点记录;随后 INSERT dns_affairs,以 NSQ Cmd=0 通知 zdns 同步一次。

输出字段:返回新建 ScheduleAffairVO


POST /api/guard/schedules/domains/{id}/reset — 重置解析

鉴权guard.schedule.reset

输入参数:path iddomain_id);body 可选 comment

实现要点:所有 dns_records.switch_state 归位为 1status 回滚到 last_status;落事务后 NSQ Cmd=0 通知。

输出字段:返回新建 ScheduleAffairVO


GET /api/guard/schedules/domains/{id}/records — 域名解析记录

鉴权guard.schedule.records

输入参数

字段 类型 说明
path id string domain_id
group_type int32 1=SRC / 2=NODE
status int32 1=禁用 / 2=启用
page / size int 分页

输出字段data = ScheduleRecordsResp):

字段 类型 说明
list[] DnsRecordVO 解析记录视图
list[].record_id string 主键
list[].associated_id string DNS 服务商侧解析记录 ID,用于确认记录已在 ZDNS/服务商侧重建或关联
list[].domain / subdomain / value string 域 / 子域 / 解析值
list[].record_type int32 DNS 记录类型内部编码
list[].record_line int32 解析线路
list[].ttl int64 TTL(秒)
list[].status / last_status int32 1=禁用 / 2=启用
list[].group_type int32 1=SRC / 2=NODE
list[].switch_state int32 1=就绪 / 2=切换中
list[].ctime / utime int64 时间戳(毫秒)

直查 zdns_db.dns_records,只读,不落事务。


5.8.2 解析调度

POST /api/guard/schedules/records/batch-status — 批量启停记录

鉴权guard.schedule.batch

输入参数ScheduleBatchStatusReq):

字段 类型 必填 说明
record_ids string[] 目标 record_id 集合
status int32 1=禁用 / 2=启用
comment string 事务备注

实现要点UPDATE dns_records SET last_status=status, status=? WHERE record_id IN (?);落事务后 NSQ Cmd=0 通知。

输出字段:返回新建 ScheduleAffairVO


5.8.3 事务记录

GET /api/guard/schedules/affairs — 事务列表

鉴权guard.schedule.affairs

输入参数

字段 类型 说明
page / size int 分页
user_id string 按归属用户过滤
status string AffairsStatus_Start / AffairsStatus_Succeed / AffairsStatus_Faild
ctime_from / ctime_to int64 时间范围(毫秒)
domain_id string 按受影响 domain 过滤(实现走 content LIKE

输出字段data = ScheduleAffairListResp):见下方 ScheduleAffairVO


GET /api/guard/schedules/affairs/{id} — 事务详情

鉴权guard.schedule.affairs

输入参数:path idaffairs_id)。

输出字段data = ScheduleAffairVO):

字段 类型 说明
affairs_id string 事务 ID,格式 {ts}_{rand10}
user_id / user_name string 操作人
status string AffairsStatus_Start / AffairsStatus_Succeed / AffairsStatus_Faild(字符串枚举,对齐老平台 MarshalJSON 行为)
message string 事务消息,含 HTML 片段(如 <br>
content string 受影响 domain_id,逗号分隔
json_content object 扩展 JSON,含 outbox 重试计数等
affairs_oper string AffairsOperType_Page / AffairsOperType_Cron / AffairsOperType_Cli
ctime / utime int64 创建/更新时间(毫秒)

轮询建议:前端发起写操作后,每 2~5s 轮询一次本接口,直到 status 切换为 SucceedFaild;若长时间停在 Start,说明 outbox 重试中,可在 UI 显示"同步中"。


5.9 WAF 规则 /api/guard/waf/rules

WAF 规则组挂在策略(policy_id)下,一个规则组含若干子规则(rules[]),由网关侧匹配 zone / pattern 决定命中后 action(拦截 / 记录 / 验证码)。

⚠️ 状态约定:本组接口的 status 字段统一约定 1=禁用 2=启用(S-6 修复后已与 forwards / bwlist / schedules 对齐)。POST /status 接口的 oneof 校验也是 1|2

⚠️ 路径 ID 取 tagPUT/DELETE /api/guard/waf/rules/{id}{id} 是规则组的 tag(uint64 主键),不是 rule_id(业务编号)。前端从列表的 tag 字段取值。

GET /api/guard/waf/rules — WAF 规则组列表

鉴权guard.waf.list

输入参数

字段 类型 说明
page / size int 标准分页
policy_id string 按策略过滤(不传则返回当前用户可见的全部规则组)

输出字段data.list[] = WafGroupVO):

字段 类型 说明
tag uint64 规则组主键(路径 {id} 用)
rule_id int64 业务规则编号
name string 规则组名称
describe string 描述
waf_type int32 WAF 类型内部编码
sub_rule_condition int32 子规则组合逻辑(0=AND / 1=OR,按 model 实现为准)
scope string 作用域(domain / path / 留空 = 全部)
action int32 1=block(拦截) 2=log(记录) 3=captcha(验证码)
status int32 1=禁用 2=启用
policy_id string 所属策略 ID
rules[] WafRuleVO 子规则列表(每条含 zone / pattern / pattern_type / is_not)
ctime / utime int64 时间戳(毫秒)

WafRuleVO(子规则)字段

字段 类型 说明
tag uint64 子规则主键
rule_id int64 业务规则编号
group_id int64 所属规则组(关联 WafGroupVO.tag / rule_id
zone string 匹配区域(如 URL / ARGS / HEADER / BODY
sub_field string 区域内的子字段(如 header name)
pattern_type int32 匹配类型(精确 / 正则 / 包含等内部编码)
pattern string 匹配表达式
describe string 描述
is_not bool true = 取反匹配
ctime / utime int64 时间戳(毫秒)

可视化建议


POST /api/guard/waf/rules — 创建 WAF 规则组

鉴权guard.waf.create

输入参数WafGroupCreateReq):

字段 类型 必填 取值 说明
name string "SQL 注入防护" 规则组名称
policy_id string "1" 挂载策略
rule_id int64 业务编号,不传由后端生成
describe string 描述
waf_type int32 WAF 类型内部编码
sub_rule_condition int32 子规则组合逻辑
scope string "*.example.com" 作用域
action int32 1 1=block / 2=log / 3=captcha
status int32 2 1=禁用 2=启用
rules[] object[] 子规则列表(字段同 WafRuleReq,见下)

WafRuleReq(子规则请求体)

字段 类型 说明
rule_id int64 业务编号,不传由后端生成
zone string 匹配区域
sub_field string 区域内的子字段
pattern_type int32 匹配类型
pattern string 匹配表达式
describe string 描述
is_not bool true = 取反

示例

curl -X POST https://waf.example.com/api/guard/waf/rules \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "SQL 注入防护",
    "policy_id": "1",
    "describe": "OWASP Top 10 SQLi 黑名单",
    "action": 1,
    "status": 2,
    "rules": [
      { "zone": "ARGS", "pattern_type": 2, "pattern": "union\\s+select", "describe": "SQLi: union select" }
    ]
  }'

输出字段:返回新建 WafGroupVO(含 tagrules[] 已落库的子规则)。

不存在字段:enabled 布尔(用 status 整数)/ description(用 describe)/ domains[](作用域用 scope 字符串)。


PUT /api/guard/waf/rules/{id} — 更新 WAF 规则组

鉴权guard.waf.edit

输入参数(path id = 规则组 tag;body WafGroupUpdateReq,字段全部可选,按 flag 增量更新;rules[] 全量替换):

字段 类型 说明
name string 规则组名称
describe string 描述
waf_type *int32 指针类型,未传不动
sub_rule_condition *int32 指针类型
scope string 作用域
action *int32 指针类型
rules[] object[] 全量替换子规则列表

本接口不更新 status——启停切换走独立的 PUT /api/guard/waf/rules/{id}/status

输出字段:返回更新后的 WafGroupVO


DELETE /api/guard/waf/rules/{id} — 删除 WAF 规则组

鉴权guard.waf.delete

输入参数:path id(规则组 tag)。

实现要点:级联删除子规则(waf_rules.group_id = tag)。

输出字段datanull


PUT /api/guard/waf/rules/{id}/status — 切换 WAF 规则组启停

鉴权guard.waf.status

输入参数(path id = 规则组 tag;body WafStatusReq):

字段 类型 必填 取值 说明
status int32 1 / 2 1=禁用 2=启用,oneof=1 2 校验

示例

curl -X PUT https://waf.example.com/api/guard/waf/rules/42/status \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "status": 1 }'

输出字段datanull


§6 Analytics 统计分析

📊 Analytics 统计分析 · 18 paths(含 80+ chart-key 单图接口)· 用于构建 WAF 监控大屏、运营报表、处置闭环
所有 /api/analytics/* 路径已对外,只能增加字段或新增接口,不能修改或删除已发布路径
完整 chart-key → 数据形态映射见各小节"chart-key 索引表",每行都明确推荐图表。

6.0 本章统一调用约定

Analytics 接口数量多但大多是同构的图表查询。本章用"统一约定 + 索引表 + 特殊接口展开"组织。

鉴权与权限

HeaderAuthorization: Bearer <token>Authorization: ApiKey zck_...,可附加 Accept-Language: zh-CN / en-US

权限分三类:

类型 判断方式 示例
页面级只读 analytics.<page>.view GET /api/analytics/overview/kpi 需要 analytics.overview.view
特殊动作 表格或小节单独标出 POST /api/analytics/overview/export 需要 analytics.overview.export
登录态 只要求认证,不要求具体业务权限 GET /api/analytics/glossary

使用 API Key 时,Key 的 scopes 必须覆盖接口所需权限。例如调用 GET /api/analytics/access/status,Key 至少包含 analytics.access.view

单图 GET 调用模板

curl -sS 'https://waf.example.com/api/analytics/access/status?window=last_24h&site_id=site-001' \
  -H "Authorization: ApiKey $ZCLOUD_API_KEY" \
  -H 'Accept-Language: zh-CN'

返回统一 JSON 信封,图表 data 固定使用 Chart 统一契约docs/specs/chart-contract.md)。这是新系统对外唯一契约;老数据库表、聚合表和 ES 索引只作为内部数据源,不影响调用方入参或响应结构。

图表 data 固定 5 字段,禁止 series / totals / kpis / points / list 作为对外顶层字段

字段 类型 说明
chart_key string 与请求 <chart> 完全一致
render_hint enum 8 词汇之一:kpi / categorical_distribution / categorical_distribution_over_time / time_series_single / time_series_multi / topn / geo / table,前端据此选渲染器
schema object 列元信息 {dimensions:[{name,type,unit?,values?}], measures:[{name,type,unit?,format?}]}
rows array tidy 长表,一行一个观测(禁止横铺),空数据返回 []
meta object 调试字段 {source, cache, latency_ms, partial?, available?, ...}

window.granularity 不是入参:客户传 window=last_24h,后端按时间窗大小自动选择 5m/1h/1d 聚合表,并在响应里回填实际命中的 granularity

Batch 调用模板

适用于 POST /api/analytics/batchPOST /api/analytics/<page>/batch

curl -sS -X POST https://waf.example.com/api/analytics/overview/batch \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
        "time_window": "last_24h",
        "site_id": "",
        "domain_id": "",
        "compare": false,
        "charts": [
          { "key": "kpi" },
          { "key": "bandwidth" }
        ]
      }'

Batch 响应的 data.data 以 chart-key 为键;data.meta 给出整体耗时、缓存命中率、失败图表数和实际时间窗。单个 chart 失败时优先查看该 chart 节点里的 partial / error 字段。


6.1 术语表

GET /api/analytics/glossary — 统计术语表

用途:返回统计分析术语表,前端 tooltip 用此渲染"什么是 QPS / 拦截率"等说明。

鉴权:登录态

输入参数:无。

输出字段

字段 类型 说明
data.terms map<string,string> key=术语短名,value=多语言解释

可视化建议

示例响应

{
  "code": 0,
  "data": {
    "terms": {
      "qps": "每秒请求数",
      "block_rate": "拦截率"
    }
  }
}

6.2 跨页 Batch

POST /api/analytics/batch — 跨页通用批量查询

用途:在前端大屏页面初始化时一次性请求多个 chart-key,省去 N 次单图 GET 往返。后端并行执行各子查询并合并响应。

鉴权:按 page 字段映射到对应 analytics.<page>.view

输入参数(请求体):

字段 类型 必填 取值/示例 说明
page string overview 必须是当前已支持页面之一:overview / access / protect / ai / bot / alert / health / ops / closure / cache
time_window string last_24h window
stime / etime int64 1746748800000 自定义时间戳
site_id string 站点过滤
domain_id string 域名过滤
target_user_id string 客户级切换被查看用户
compare bool false 是否启用上一周期对比
charts[] array [{key:"kpi"}] 至少 1 项 chart-key

logs(Phase 1 原始日志)和 reports(Phase 4 报表中心)是独立 group,不走 batch 模式

输出字段

字段 类型 说明
data.data map key=chart-key;value 固定为 {chart_key, render_hint, schema, rows, meta} 5 字段 Chart 统一契约
data.meta.elapsed_ms int 整体耗时
data.meta.cache_hit_ratio float 缓存命中率(0-1)
data.meta.total_charts int 请求 chart 总数
data.meta.failed_charts int 失败 chart 数
data.meta.window object 实际命中时间窗

可视化建议

示例请求/响应

// 请求
{
  "page": "overview",
  "time_window": "last_24h",
  "compare": false,
  "charts": [
    { "key": "kpi" },
    { "key": "bandwidth" }
  ]
}
// 响应
{
  "code": 0,
  "data": {
    "data": {
      "kpi": {
        "chart_key": "overview/kpi",
        "render_hint": "kpi",
        "schema": {
          "dimensions": [],
          "measures": [
            { "name": "domain_count", "type": "integer", "unit": "" },
            { "name": "requests",     "type": "integer", "unit": "requests" },
            { "name": "blocked",      "type": "integer", "unit": "events" },
            { "name": "block_rate",   "type": "percent", "unit": "%" },
            { "name": "qps",          "type": "float",   "unit": "qps" },
            { "name": "ai_detect",    "type": "integer", "unit": "events" }
          ]
        },
        "rows": [
          { "domain_count": 8, "requests": 12345, "blocked": 678, "block_rate": 5.49, "qps": 0.143, "ai_detect": 0 }
        ],
        "meta": { "source": "postgres", "cache": "miss", "latency_ms": 10 }
      },
      "event-type": {
        "chart_key": "overview/event-type",
        "render_hint": "categorical_distribution",
        "schema": {
          "dimensions": [{ "name": "event_type", "type": "string" }],
          "measures": [{ "name": "count", "type": "integer", "unit": "events" }]
        },
        "rows": [
          { "event_type": "sql_injection", "count": 1234 },
          { "event_type": "xss", "count": 567 }
        ],
        "meta": { "source": "elasticsearch", "cache": "miss", "latency_ms": 15, "partial": false }
      }
    },
    "meta": {
      "elapsed_ms": 22,
      "cache_hit_ratio": 0,
      "total_charts": 2,
      "failed_charts": 0,
      "window": { "stime": 1746662400000, "etime": 1746748800000, "granularity": "1h" }
    }
  }
}

注意:上例中 kpi 的 measure 名 requests / blocked 是对外契约真值名(与 pkg/chart/contract 真值结构体对齐)。底层数据库字段名不对外暴露,前端严格按 schema.measures[].name 取值。


POST /api/analytics/{page}/batch — 页面级 Batch

用途:与 POST /api/analytics/batch 等价,但 page 由 URL 决定(前端固定页面调用更直观)。

鉴权:根据 {page} 映射到对应 analytics.<page>.view

支持的 page 值

URL 权限
POST /api/analytics/overview/batch analytics.overview.view
POST /api/analytics/access/batch analytics.access.view
POST /api/analytics/protect/batch analytics.protect.view
POST /api/analytics/ai/batch analytics.ai.view
POST /api/analytics/bot/batch analytics.bot.view
POST /api/analytics/alert/batch analytics.alert.view
POST /api/analytics/health/batch analytics.health.view
POST /api/analytics/ops/batch analytics.ops.view
POST /api/analytics/closure/batch analytics.closure.view
POST /api/analytics/cache/batch analytics.cache.view

输入/输出:与 POST /api/analytics/batch 完全一致;调用方不需要在请求体里再传 page,即使传了也以路径中的页面名为准。

可视化建议:同上。


6.3 单图 GET 调用入口

GET /api/analytics/{page}/{chart} — 单图通用入口

用途:拉取单个 chart-key 的数据。{page} 取值同 batch;{chart} 取值参见各页面小节的 chart-key 索引表。

鉴权:根据 {page} 映射到 analytics.<page>.view(少数特殊 chart 用独立权限,详见各小节)。

输入参数:见 §A 通用查询参数

输出字段:统一信封 + data

可视化建议:前端按 render_hint 自动分发到对应图表组件;复杂图表的列定义以 schema 为准。


6.4 总览页面(Overview)

适用场景:WAF 防护监控大屏首页 KPI + 趋势 + 排行 + 地图。

下表所有 GET 接口都用 §6.0 单图 GET 调用模板§A 通用查询参数 和 Chart 统一契约响应结构。

API chart-key render_hint 推荐图表 说明
GET /api/analytics/overview/kpi kpi kpi KpiGroupCard(6 measure) 站点数 / requests / blocked / block_rate / qps / ai_detect
GET /api/analytics/overview/bandwidth bandwidth time_series_multi 折线图(双 Y 轴) 总带宽与回源带宽时序
GET /api/analytics/overview/request-attack request-attack time_series_multi 折线图(双系列) 请求量 vs 攻击量对比
GET /api/analytics/overview/event-type event-type categorical_distribution 饼图 / 环形图 事件类型分布(dim=event_type, measure=count)
GET /api/analytics/overview/waf-type waf-type categorical_distribution 饼图 / 环形图 WAF 命中类型分布
GET /api/analytics/overview/geo geo geo 中国/世界地图热力 攻击来源地理分布
GET /api/analytics/overview/top-domains top-domains topn 横向 bar / 表格 被攻击域名 TOP 5
GET /api/analytics/overview/recent-events recent-events table 时间线 / 表格(50 条) 最近 WAF 事件流

chart-key 数据形态详解

kpirender_hint = kpi

schema.measures 共 6 项:

measure name type unit 说明
domain_count integer (空) 站点数
requests integer requests 时间窗内总请求量
blocked integer events 时间窗内总拦截量
block_rate percent % 拦截率 = blocked / requests
qps float qps QPS = requests / 窗口秒数
ai_detect integer events AI 识别数(当前固定 0,后续接 ES 实数)

rows 单行:[ { domain_count, requests, blocked, block_rate, qps, ai_detect } ]

对外字段名requests / blocked 是 API 契约字段名。底层数据库若仍使用 request_today / attack_today 等历史字段,由后端在服务层转换,不暴露给调用方。

推荐图表KpiGroupCard(6 个 KPI 数字卡),block_rate 用百分比 + 进度条;qps 配迷你 sparkline。


bandwidth / request-attack — 时序双系列

输出 [{ctime: int64ms, bandwidth: float, origin_bandwidth: float}, ...][{ctime, requests, attacks}, ...]

推荐图表:折线图,X 轴 ctime,Y 轴双系列。


event-typerender_hint = categorical_distribution

schema 部分 内容
dimensions [{ name: "event_type", type: "string" }]
measures [{ name: "count", type: "integer", unit: "events" }]

rows 长表:[ { event_type: "sql_injection", count: 1234 }, { event_type: "xss", count: 567 }, ... ]

推荐图表PieCard(≤8 类自动饼图)/ BarCard(>8 类自动横向 bar);前端按 categorical_distribution 词汇分发。


waf-type — 维度分布

输出 [{key: string, count: int}, ...]

推荐图表:饼图(≤ 8 类)或环形图。


geo — 地理热力

输出 [{region: string, count: int}, ...],region 为国家/省份名。

推荐图表:地图热力(中国地图 + 世界地图叠加)。


top-domains — 域名排行

输出 [{host: string, attack_count: int}, ...],按 attack_count DESC,最多 5 条。

推荐图表:横向 bar 图。


recent-events — 最近事件流

输出 [{ctime, domain, attack_type, severity, ...}, ...],最多 50 条。

推荐图表:时间线 / 表格(按 ctime 倒序),可点击进入详情。


POST /api/analytics/overview/export — 总览页导出

用途:把 KPI 与图表快照导出为 CSV 或 JSON 文件,供线下分析或汇报。返回原文文件流,不走信封

鉴权analytics.overview.export

输入参数(请求体):

字段 类型 必填 取值/示例 说明
format string csv / json 导出格式
window string last_24h 时间窗
charts[] array [{key:"kpi"}] 要导出的 chart-key 列表

输出:直接返回文件流,Content-Type: text/csvapplication/jsonContent-Disposition: attachment

可视化建议:不适合图表;触发后浏览器下载。


6.5 访问分析页面(Access)

适用场景:流量与质量分析大屏 — 看请求量、流量、缓存命中、状态码、耗时分布、运营商、TOP IP/URL、地域。

API chart-key render_hint 推荐图表 说明
GET /api/analytics/access/request-hm request-hm time_series_single(无 compare)/ time_series_multi(compare) LineCard 请求量趋势;compare=true 走子形态 B(period 维度区分 current/previous)
GET /api/analytics/access/flow-hm flow-hm time_series_multi LineCard 多线 5 measure:total_bytes / request_bytes / response_bytes / upstream_send / upstream_receive
GET /api/analytics/access/cache-hm cache-hm time_series_multi 折线图(双 Y 轴) 缓存命中次数 + 缓存字节趋势
GET /api/analytics/access/bandwidth bandwidth time_series_multi LineCard 多线 4 measure:bandwidth / origin_bandwidth / up_bandwidth / down_bandwidth
GET /api/analytics/access/status status categorical_distribution_over_time StackedBarCard 4 类 HTTP 状态码(dim=status_class enum["2xx","3xx","4xx","5xx"] + time)按时间堆叠
GET /api/analytics/access/flow-duration flow-duration time_series_multi 折线图(3 分位) 请求耗时 P50/P95/P99(D4:仅时间窗 ≤ 24h 走实时计算)
GET /api/analytics/access/isp isp categorical_distribution 饼图 运营商分布(移动/联通/电信/其它)
GET /api/analytics/access/top-ip top-ip topn 表格 / 横向 bar(含地理) 访问 IP TOP(默认 10,可调 top
GET /api/analytics/access/top-url top-url topn 表格 / 横向 bar URL TOP,可按 order=bytes_desc/cache_desc 切换排序
GET /api/analytics/access/geo geo geo 中国/世界地图热力 访问来源地理分布

chart-key 数据形态详解

request-hm

无 compare(render_hint = time_series_single):

schema 部分 内容
dimensions [{ name: "time", type: "timestamp", unit: "ms" }]
measures [{ name: "requests", type: "integer", unit: "requests" }]

rows[ { time: 1746748800000, requests: 1234 }, ... ]

开 compare(render_hint = time_series_multi 子形态 B:1 categorical + 1 ts + 1 measure):

schema 部分 内容
dimensions [{ name: "period", type: "enum", values: ["current","previous"] }, { name: "time", type: "timestamp", unit: "ms" }]
measures [{ name: "requests", type: "integer", unit: "requests" }]

rows[ { period: "current", time: ..., requests: ... }, { period: "previous", time: ..., requests: ... }, ... ] 长表,按 period pivot 成 2 条 series。

推荐图表LineCard;compare 模式按 period pivot 双色实虚线,前端自动处理。


flow-hmrender_hint = time_series_multi

schema 部分 内容
dimensions [{ name: "time", type: "timestamp", unit: "ms" }]
measures 5 项:total_bytes / request_bytes / response_bytes / upstream_send / upstream_receive(type=integer,unit=bytes,format=iec)

rows[ { time: ..., total_bytes: ..., request_bytes: ..., response_bytes: ..., upstream_send: ..., upstream_receive: ... }, ... ]

推荐图表LineCard 多线(5 条)/ 堆叠面积。


cache-hm — 缓存趋势

输出 [{ctime, cache_count, cache_bytes, cache_response}, ...]

真值字段(D8):底层用 total_cache_count / total_cache_bytes / total_cache_response_bytes;返回时映射为 cache_count / cache_bytes / cache_response

推荐图表:双 Y 轴折线(左轴次数,右轴字节)。


bandwidthrender_hint = time_series_multi

schema 部分 内容
dimensions [{ name: "time", type: "timestamp", unit: "ms" }]
measures 4 项:bandwidth / origin_bandwidth / up_bandwidth / down_bandwidth(type=float,unit=bps)

rows[ { time: ..., bandwidth: ..., origin_bandwidth: ..., up_bandwidth: ..., down_bandwidth: ... }, ... ]

推荐图表LineCard 多线(4 条)。


statusrender_hint = categorical_distribution_over_time

schema 部分 内容
dimensions [{ name: "status_class", type: "enum", values: ["2xx","3xx","4xx","5xx"] }, { name: "time", type: "timestamp", unit: "ms" }]
measures [{ name: "count", type: "integer", unit: "requests" }]

rows tidy 长表(禁止横铺 c2xx/c3xx/c4xx/c5xx):

[
  { "status_class": "2xx", "time": 1746748800000, "count": 1200 },
  { "status_class": "3xx", "time": 1746748800000, "count": 30 },
  { "status_class": "4xx", "time": 1746748800000, "count": 8 },
  { "status_class": "5xx", "time": 1746748800000, "count": 0 },
  { "status_class": "2xx", "time": 1746752400000, "count": 1340 },
  ...
]

每个时间点必须覆盖 4 个 status_class(缺则补 count: 0,前端堆叠柱图依赖完整网格)。

推荐图表StackedBarCard(按 status_class 堆叠时序)。前端按 categorical_distribution_over_time 词汇分发。


flow-duration — 耗时分位

输出 {p50, p95, p99} 或时序数组。

真值边界(D4):百分位字段仅时间窗 ≤ 24h 时由 ES 实时计算;窗口更长时该接口返回 available:false

推荐图表:折线图(3 分位曲线)或 KPI 数字卡(3 个)。


isp — 运营商分布

输出 {mobile, unicom, telecom, other}

推荐图表:饼图(4 段)。


top-ip — IP TOP

输出 [{remote_addr, count, country, region, isp}, ...],最多 top 条。

推荐图表:表格(含国旗 + 地区 + 运营商);或横向 bar 图。


top-url — URL TOP

输出 [{url, request_count, request_bytes, cache_bytes}, ...]

推荐图表:表格(默认);或横向 bar(可按字节/缓存切换)。


geo — 地理热力

输出 [{region, count}, ...]

推荐图表:地图热力。


6.6 防护分析页面(Protect)

适用场景:WAF / CC / DDoS 三大防护引擎的命中分析。

API chart-key render_hint 推荐图表 说明
GET /api/analytics/protect/overview overview kpi 多 KPI 卡 WAF/CC/DDoS 总量汇总(时序由 statistics 系列独立 chart 提供)
GET /api/analytics/protect/waf/statistics waf/statistics time_series_multi 折线图 WAF 命中趋势(waf 命中数 + 总攻击数)
GET /api/analytics/protect/waf/types waf/types categorical_distribution 饼图 / 横向 bar WAF 命中类型分布(SQL 注入/XSS/扫描器等)
GET /api/analytics/protect/waf/top-ip waf/top-ip topn RankingCard / 横向 bar dim=ip(string), measure=count(events),country/province 进 meta.row_extras
GET /api/analytics/protect/waf/geo waf/geo geo GeoHeatmapCard dim=country(geo), measure=count(events);provinces 暂存 meta.provinces
GET /api/analytics/protect/cc/statistics cc/statistics time_series_single 折线图 CC 命中趋势
GET /api/analytics/protect/cc/top-ip cc/top-ip topn 表格 / 横向 bar CC 攻击 IP TOP
GET /api/analytics/protect/cc/geo cc/geo geo 地图热力 CC 攻击地域
GET /api/analytics/protect/cc/top-url cc/top-url topn 表格 CC 攻击 URL TOP
GET /api/analytics/protect/ddos/statistics ddos/statistics time_series_multi 折线图(双 Y 轴) DDoS 事件数 + 峰值带宽时序
GET /api/analytics/protect/ddos/types ddos/types categorical_distribution 饼图 / 横向 bar DDoS 攻击类型分布(syn flood/udp flood 等)
GET /api/analytics/protect/ddos/top-ip ddos/top-ip topn 表格 DDoS 源 IP TOP(含峰值带宽)

chart-key 数据形态详解(关键差异)

overviewrender_hint = kpirows = [{waf, cc, ddos_bytes}](单行汇总,dimensions=[],measures=waf/cc/ddos_bytes)。推荐 3 KPI 卡;时序由 protect/waf/statisticsprotect/ddos/statistics 独立 chart 提供。

waf/statisticsrender_hint = time_series_multirows = [{time, waf, attack_count}, ...] tidy 长表(time=ms 时间戳,2 measure 双线)。推荐折线图(双系列)。

waf/types / ddos/typesrender_hint = categorical_distributionrows = [{waf_type, count}, ...] / [{ddos_type, count}, ...] tidy 长表,用饼图或横向 bar。

waf/top-iprender_hint = topn

schema 部分 内容
dimensions [{ name: "ip", type: "string" }]
measures [{ name: "count", type: "integer", unit: "events" }]

rows[ { ip: "1.2.3.4", count: 1234 }, { ip: "5.6.7.8", count: 567 }, ... ],已按 count DESC 排序。country / province 等附加列进 meta.row_extras(前端按需取,不入 schema 列)。

推荐图表RankingCard / 横向 bar 图。


ddos/top-ip:含地理的 IP TOP,推荐含国旗的表格。


waf/georender_hint = geo

schema 部分 内容
dimensions [{ name: "country", type: "geo" }]
measures [{ name: "count", type: "integer", unit: "events" }]

rows[ { country: "China", count: 1234 }, { country: "US", count: 567 }, ... ]

provinces 数据暂存 meta.provinces(结构 [{province, count}])。当前前端 GeoHeatmapCard 渲染主图用 rows,省级钻取用 meta.provinces;后续如需要省级独立图表,再新增 protect/waf/geo-provinces chart-key。

推荐图表GeoHeatmapCard(中国 / 世界地图热力)。


cc/georender_hint = georows = [{country, count}, ...],地图热力。

ddos/statisticsrender_hint = time_series_multirows = [{time, events, bandwidth}, ...] tidy 长表(events=integer events,bandwidth=float bytes/iec)。推荐双 Y 轴折线。


6.7 AI 识别页面(AI)

当前 AI 页面路径已发布。/logs 走独立 analytics.ai.logs 权限,其它走 analytics.ai.view
第一版多数 chart 返回 BatchChartResult 占位(rows: []meta.available = falsemeta.reason 说明原因),路径与契约稳定,后端可在保持路径不变的前提下逐步升级真实数据。

API chart-key 推荐图表 说明
GET /api/analytics/ai/attack-trend attack-trend 折线图 AI 攻击趋势
GET /api/analytics/ai/top-ip top-ip 表格 / 横向 bar AI 命中 IP TOP
GET /api/analytics/ai/top-url top-url 表格 AI 命中 URL TOP
GET /api/analytics/ai/detection detection KPI 数字卡 / 雷达图 AI 检测能力面板
GET /api/analytics/ai/test-results test-results 表格 / 柱图 AI 测试结果
GET /api/analytics/ai/logs logs 表格(明细,分页) AI 命中日志明细(独立权限 analytics.ai.logs

占位响应:未升级的 chart 返回标准 BatchChartResult(5 字段齐全,rows: []meta.available = falsemeta.reason 说明原因),前端应渲染"暂无数据"占位卡片,不展示假数据。


6.8 主动防护 / Bot 页面

适用场景:识别和分析爬虫/Bot 流量。

API chart-key 推荐图表 说明
GET /api/analytics/bot/statistics statistics KPI(6 个) Bot 请求/会话/IP/已知未知 Bot 总览(趋势线由独立 chart 提供,未拆时不展示)
GET /api/analytics/bot/advance-warn advance-warn 表格 Bot 预警列表
GET /api/analytics/bot/browser browser 饼图 浏览器分布(chrome/safari/firefox/edge/wechat/other)
GET /api/analytics/bot/operating operating 饼图 操作系统分布(android/ios/windows/mac/other)
GET /api/analytics/bot/geo geo 地图热力 Bot 地域分布
GET /api/analytics/bot/top-agent top-agent 表格 / 横向 bar User-Agent TOP
GET /api/analytics/bot/top-ip top-ip 表格(含地理) Bot IP TOP
GET /api/analytics/bot/scatter scatter 散点图 Bot 预警散点(X=ctime / Y=top_visit_count,size=top_ip_count)
GET /api/analytics/bot/sessions sessions 表格(分页) Bot 会话列表(独立权限 analytics.bot.session
GET /api/analytics/bot/sessions/{sid} - 时间线 单个 Bot 会话时间线详情(独立权限 analytics.bot.session

chart-key 数据形态详解

statisticsrender_hint = kpirows = [{requests, sessions, ips, known_bot, unknown_bot, req_per_session}](单行汇总,6 measure)。推荐 6 个 KPI 卡;请求/会话趋势由独立 chart 提供(当前未拆,需要时新增 bot/sessions-trend)。

browserrender_hint = categorical_distributionrows = [{browser, count}, ...](6 行 enum:chrome/safari/firefox/edge/wechat/other),饼图。

operatingrender_hint = categorical_distributionrows = [{os, count}, ...](5 行 enum:android/ios/windows/mac/other),饼图。

scatterrender_hint = table(无 scatter hint,table 兜底),rows = [{time, session_id, top_visit_count, top_ip_count, top_ua_count}, ...],由前端解析 X/Y/size 渲染散点图。

sessions/{sid}render_hint = tablerows = [{time, uri, remote_addr, method, status}, ...](5 字段裁剪),是该 session 的全量访问记录时间线;未传 session_id(通过 query order 参数)时返空。


6.9 告警统计页面(Alert)

适用场景:告警总览 + 列表 + 单条详情 + 确认。

API 方法 chart-key 推荐图表 说明
GET /api/analytics/alert/total GET total KPI 数字卡 告警总数
GET /api/analytics/alert/hm GET hm 折线图 / 热力图 告警趋势(按 ctime 聚合 count)
GET /api/analytics/alert/types GET types 饼图 告警类型分布(按 policy_type)
GET /api/analytics/alert/domains GET domains 横向 bar / 表格 告警域名排行
GET /api/analytics/alert/list GET list 表格(分页) 告警列表
GET /api/analytics/alert/{id} GET - 详情卡片 单条告警详情(含处置元信息)
PATCH /api/analytics/alert/{id}/ack PATCH - 不适合图表 确认指定告警

GET /api/analytics/alert/{id} 输出字段

字段 类型 说明
id int 告警 ID
uuid string 告警 UUID
policy_type string 告警类型
title / body string 告警标题 / 内容
domain / domain_id string 关联域名
status int 告警状态(0/1/2/3,参见 D10)
ctime int64 创建时间
last_update_timestamp int64 最后更新时间
process_uid string 处置人(D10 真值)
process_time int64 处置时间(D10 真值)
user_id string 归属用户

非超管按 user_id 强制过滤;越权读取返回 404。所需权限 analytics.alert.view

PATCH /api/analytics/alert/{id}/ack 请求

鉴权analytics.alert.ack

输入:path id,body 可空。

输出datanull


6.10 业务健康(Health · Phase 3)

适用场景:分析业务可用性 + 源站质量 + 慢 URI + 地域质量。

API chart-key 推荐图表 说明
GET /api/analytics/health/summary summary KPI 数字卡(6 个) c2xx/c3xx/c4xx/c5xx/n4xx/n5xx 总数
GET /api/analytics/health/status-breakdown status-breakdown 堆叠柱图(时序) 状态码三层 c/n/a 拆分(c=客户端、n=网关、a=应用)
GET /api/analytics/health/origin-errors origin-errors 表格 / 横向 bar 源站异常排行(ES upstream_addr terms,仅 upstream_status >= 500)
GET /api/analytics/health/origin-latency origin-latency 折线图(3 系列) 源站时延(移动/联通/电信 平均时延)
GET /api/analytics/health/slow-uri slow-uri 表格 慢 URI TOP(第一版按命中次数 TOP;慢请求排序后续按真实耗时数据接入)
GET /api/analytics/health/availability availability KPI / 多线折线 HTTP/Ping/DNS/TCP/Page/IPv6 可用率 + 不可用时长
GET /api/analytics/health/geo-isp-quality geo-isp-quality 表格 / 地图 地域/运营商质量

真值边界:percentile / p50 / p95 / p99 在 chart 与 statistic 包均无字段;时间窗 ≤ 24h 才走 ES 实时 percentile(D4)。可用性表 m_ava_domain.*AvailableDomain 主键是 domain_or_ip(不是 domain_id)。


6.11 平台运维(Ops · Phase 5)

适用场景:平台级运营视角 — 看高流量/高错误用户和域名、源站异常、节点容量。

权限边界analytics.ops.view 只读全平台数据,不允许target_user_id 切换视角;analytics.ops.admin 才能切换。普通客户级账号即使有 view 也不能访问 ops。

API chart-key 推荐图表 说明
GET /api/analytics/ops/summary summary KPI 数字卡(6 个) 全平台容量摘要(请求/字节/峰值带宽/源站带宽/活跃域名/活跃用户)
GET /api/analytics/ops/traffic-users traffic-users 横向 bar / 表格 高流量用户 TOP(按 total_bytes DESC)
GET /api/analytics/ops/traffic-domains traffic-domains 横向 bar / 表格 高流量域名 TOP
GET /api/analytics/ops/error-users error-users 表格 高错误用户 TOP(按 c5xx DESC,含 c4xx/n5xx)
GET /api/analytics/ops/error-domains error-domains 表格 高错误域名 TOP
GET /api/analytics/ops/origin-errors origin-errors 表格 源站异常排行
GET /api/analytics/ops/nodes nodes 表格 / 拓扑图 节点/机房视图(RPC GetWafIpWithMachineRoom + ES server_addr/bind_addr
GET /api/analytics/ops/query-pressure query-pressure 折线图(占位) ES 查询压力(依赖埋点,第一版返回 available:false

真值边界:节点系统指标(CPU/内存/磁盘)chart 不存,需走外部 zabbix。本期不实现。node_id / server_node 是禁字段。


6.12 处置闭环(Closure · Phase 6)

适用场景:在一个页面同时处理告警和风险队列;支持批量确认。

真值字段(D10):process_uid / process_time / status / level禁字段handle_user / handle_time / risk_score / alert_status。AlertRecord.status (0/1/2/3) 与 RiskRecord.status (1/2) 语义不同,前端 i18n key 不可共用。

API 方法 chart-key 推荐图表 说明
GET /api/analytics/closure/summary GET summary KPI 数字卡(5 个) 待处理告警/风险数 + 已处置数 + 平均处置时长(ms)
GET /api/analytics/closure/alerts GET alerts 表格(分页) 待处理告警队列(status=0)
GET /api/analytics/closure/risks GET risks 表格(分页) 待处理风险队列(后续接 RiskRecord 表;当前无数据时返回空列表)
GET /api/analytics/closure/trend GET trend 折线图 / 堆叠柱 处置历史趋势(按 ctime + status 分组)
POST /api/analytics/closure/alerts/confirm POST - 不适合图表 批量确认告警(代理 /api/alert/records/confirm
POST /api/analytics/closure/risks/confirm POST - 不适合图表 批量确认风险(代理 /api/chart/risk/events/:event_id/confirm

summary 输出字段

{
  "alerts_pending": 12,
  "alerts_handled_today": 8,
  "risks_pending": 0,
  "risks_handled_today": 0,
  "avg_handle_time_ms": 0
}

confirm 接口请求体

{
  "ids": ["a1", "a2", "a3"],
  "remark": "已加黑名单"
}

鉴权analytics.closure.confirm

输出datanull


6.13 缓存收益(Cache · Phase 6)

适用场景:分析 CDN/边缘缓存对回源带宽的节省价值。

真值字段(D8):total_cache_count / total_cache_bytes / total_cache_response_bytes禁字段cache_count / cache_bytes / cache_hit 单字段命名(不存在)。

API chart-key 推荐图表 说明
GET /api/analytics/cache/summary summary KPI 数字卡(4 个) 命中率 / 节省回源字节 / 命中次数 / 平均缓存对象大小
GET /api/analytics/cache/trend trend 折线图(双 Y 轴) 命中率趋势(请求数 vs 缓存命中数)
GET /api/analytics/cache/top-uri top-uri 表格 / 横向 bar URI TOP(命中次数/命中率/节省字节)
GET /api/analytics/cache/content-types content-types 饼图 内容类型分布(response_content_type 聚合)

summary 输出字段

字段 类型 说明
hit_rate float 缓存命中率 = total_cache_count / request_count
saved_response_bytes int 节省回源带宽(源站本应承担但缓存挡住的字节)
total_cache_count int 命中次数
total_cache_bytes int 命中字节
avg_object_bytes float 平均缓存对象大小 = total_cache_bytes / total_cache_count
request_count int 总请求数

业务化指标


6.14 原始日志(Logs · Phase 1)

原始日志是明细查询,不是图表单图接口;它使用统一鉴权方式,但请求/响应以列表、详情、导出为主。

API 方法 权限 推荐图表 说明
GET /api/analytics/logs GET analytics.logs.view 表格(分页 + 12 字段筛选) 分页查询原始访问/攻击日志
GET /api/analytics/logs/{uuid} GET analytics.logs.view 详情卡片(7 区块) 单条日志详情(basic/request/response/upstream/protection/waf_detail/ai_detail)
POST /api/analytics/logs/export POST analytics.logs.export 不适合图表 字段白名单导出(csv/json,size ≤ 10000,超出走异步任务)

GET /api/analytics/logs 筛选字段

12 字段筛选:uuid / session_id / remote_addr / host / uri / method / status / z_final_action / z_final_type / z_final_mod / z_final_action_type / z_white

真值边界z_final_action 整数枚举 0=放行 / 1=拦截 / 2=验证码z_white 是独立 bool 字段(白名单命中),不参与 action 枚举。禁字段match_content / match_area / hit_rule / rule_desc(chart 与 statistic 包均无)。

第一版兜底响应

第一版 stub 返回:

{ "available": false, "reason": "原始日志 ES 查询待接入..." }

列表/详情/导出契约稳定,后续接 ES zcloud-access-*


6.15 报表中心(Reports · Phase 4)

报表中心是模板、生成、下载类接口,不使用单图响应结构。列表和详情仍使用统一 JSON 信封;下载接口返回文件流。

API 方法 权限 推荐图表 说明
GET /api/analytics/reports/templates GET analytics.reports.view 表格 / 卡片网格 模板列表(含 platform_only 标记)
GET /api/analytics/reports GET analytics.reports.view 表格(分页) 报表历史列表
GET /api/analytics/reports/{id} GET analytics.reports.view 详情卡片 单条报表详情(状态、参数、产物 URL)
POST /api/analytics/reports/generate POST analytics.reports.generate 不适合图表 触发生成(platform-summary 模板需 analytics.reports.platform
GET /api/analytics/reports/{id}/download GET analytics.reports.download 不适合图表 下载产物(pdf/csv/json/html)

模板枚举(D7):protection-value / asset-risk / attack-source / business-health / platform-summary仅平台运维/超管) / raw-log-export

异步阈值:预估行数 ≤ 100k 走同步;超出强制异步返回 task_id,前端轮询 /reports/:id 获取状态 + 下载链接。第一版同步生成超时 30 秒,超时降级为异步。

generate 请求体

{
  "template": "protection-value",
  "format": "pdf",
  "window": "last_30d",
  "stime": 1735660800000,
  "etime": 1738339200000,
  "filters": {}
}
字段 类型 必填 说明
template string 模板名(D7 闭集)
format string pdf / csv / json / html
window string 时间窗别名
stime / etime int64 自定义时间戳
filters object 模板专属筛选条件

6.16 CLI 对应关系

Analytics API 均由 zcloud analytics 命令适配:

# 原 6 page
zcloud analytics overview kpi --format json
zcloud analytics access status --window last_24h --format json
zcloud analytics protect waf/types --format json
zcloud analytics ai logs --page 1 --size 20 --format json
zcloud analytics bot session <session-id> --format json
zcloud analytics alert ack <alert-id>

# 2026-04-30 chart-rebuild 6 phase 扩展(13 条新命令)
zcloud analytics health summary --window last_24h --format json
zcloud analytics ops traffic-users --top 20 --format json
zcloud analytics closure summary --format json
zcloud analytics cache summary --format json
zcloud analytics logs list --window last_24h --status 403 --format json
zcloud analytics logs detail req-abc123 --format json
zcloud analytics logs export --format csv --fields ctime,uuid,host,uri,status > logs.csv
zcloud analytics closure alerts confirm --ids a1,a2,a3
zcloud analytics closure risks confirm --ids ev_001,ev_002
zcloud analytics reports templates --format json
zcloud analytics reports list --format json
zcloud analytics reports describe r-001 --format json
zcloud analytics reports generate --template protection-value --window last_30d --format pdf
zcloud analytics reports download r-001 --output report.pdf

后续如果新增 Analytics API,必须同步增加或确认已有 CLI 适配;如果只是新增 chart-key,至少要更新 CLI chart-key 清单与文档。


§7 套餐目录(Plan)

对外开放范围说明:仅以下两个只读接口对外开放,用于查询套餐目录。套餐的创建/编辑/删除、为用户开通、订阅查询,以及订单的续费/变更/退款/审核/api/plan/orders/*),均属平台控制台管理操作,直接操作在线计费数据,不在对外对接 API/CLI 范围(仅平台运维经控制台 + RBAC 使用)。

GET /api/plan/plans — 套餐列表(分页)

查询套餐目录,支持按产品类型和关键词过滤,分页返回。

所需权限plan.plan.list

Query 参数

参数 类型 必填 默认值 说明
page int 1 页码(从 1 开始)
size int 20 每页条数
prod_type int 0 (全部) 产品类型过滤:2=WAF · 4=Monitor · 32=GFIP
keyword string 套餐名称关键词模糊搜索

响应 data 字段

{
  "list": [ { "plan_id": "...", "name": "基础版", "prod_type": 2, "price": 99.00, "valid": 365, "level": 1, "open_status": true, ... } ],
  "total": 10,
  "page": 1,
  "size": 20
}

示例

# Bearer Session
curl -H "Authorization: Bearer $TOKEN" \
  "$API/api/plan/plans?prod_type=2&keyword=基础&page=1&size=20"

# API Key
curl -H "Authorization: ApiKey zck_prefix.secret" \
  "$API/api/plan/plans?prod_type=2"

GET /api/plan/plans/{id} — 套餐详情

按套餐 ID 查询单个套餐的完整信息(含 content 配额 JSON)。

所需权限plan.plan.view

Path 参数

参数 类型 必填 说明
id string 套餐 ID(UUID)

响应 data 字段(PlanVO

字段 类型 说明
plan_id string 套餐唯一 ID(UUID)
name string 套餐名称
content object 套餐配额 JSON(各产品类型对应字段不同)
price float 套餐价格(保留 2 位小数)
scene string 适用场景描述
comment string 备注
open_status bool 是否公开售卖
valid int64 有效期(天数)
effect int32 生效方式
level int64 套餐等级
creator_id string 创建者 ID
ctime int64 创建时间(Unix 毫秒)
utime int64 更新时间(Unix 毫秒)
version string 套餐来源版本(cloud / zmod)
prod_type int32 产品类型(2=WAF 4=Monitor 32=GFIP)

示例

curl -H "Authorization: Bearer $TOKEN" \
  "$API/api/plan/plans/550e8400-e29b-41d4-a716-446655440000"

CLI 等价命令

zcloud plan list --prod-type 1 --keyword 基础版
zcloud plan describe <plan_id>

§8 节点安装 / 升级(Node Install)

用途:在防护节点主机上一键安装 / 升级 skynet-node。链路分两侧:管理面(平台登录态 + RBAC)注册安装包、生成一次性命令、查询任务、撤销 token;安装机侧(仅认安装 token)拉脚本、下载包/env、回报结果。
后端实现:src/backend/internal/node/{handler,service,repo}/install.go、路由 src/backend/internal/node/route.go、回收任务 src/backend/internal/app/install_reaper.go

8.0 鉴权与状态码

维度 管理面接口 安装机侧接口
路径 /install/artifacts /commands /upgrades /jobs /tokens/:id/revoke /install/script /package /env /report
鉴权 平台统一登录态(Bearer Session / API Key)+ RBAC Authorization: Bearer <install_token>
RBAC action(perms.NodeNode artifact / install / upgrade / job / revoke 无(token 自鉴权)
鉴权失败 401 / 403(平台统一信封) 401,并带 WWW-Authenticate: Bearer realm="node-install"(challenge)

要点:

8.1 POST /api/node/install/artifacts — 注册本地安装包并预检

注册后端主机上已存在的安装包,扫描并计算 sha256、跑预检。

curl -sS -X POST https://<cloud>/api/node/install/artifacts \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"name":"skynet-node-1.0.0.tar.gz","version":"1.0.0","package_path":"/data/artifacts/skynet-node-1.0.0.tar.gz"}'

约束:

响应(节选,package_path 仅回文件名,不暴露后端绝对路径):

{"code":0,"data":{
  "artifact_id":"8f1c…","name":"skynet-node-1.0.0.tar.gz","version":"1.0.0",
  "sha256":"…64hex…","status":"ready",
  "precheck":{"passed":true,"checks":[
    {"key":"required_env","severity":"error","passed":true,"message":"required env keys found"},
    {"key":"binary_version_drift","severity":"warning","passed":true,"message":"…"}
  ]}
}}

GET /api/node/install/artifacts 列出已注册包;列表里的 package_path 同样只展示文件名,前端/示例不要展示后端真实绝对路径

8.2 POST /api/node/install/commands · POST /api/node/install/upgrades · POST /api/node/install/uninstalls — 生成一次性命令

curl -sS -X POST https://<cloud>/api/node/install/commands \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{
        "artifact_id":"8f1c…",
        "node_id":"可选-目标节点UUID",
        "server_url":"https://<cloud>",
        "ttl_seconds":3600,
        "max_uses":20,
        "env":{
          "ZCLOUD_NGX_ACCESS_TOPIC":"cloud/ngx",
          "ZCLOUD_CC_TOPIC":"cc/sync",
          "ZCLOUD_SYNC_TOPIC":"zcloud-sync",
          "ZCLOUD_DELTA_TOPIC":"zcloud-delta",
          "ZCLOUD_BLOCK_TOPIC":"zcloud-block"
        }
      }'

升级命令用 /upgrades,等价于 action=upgrade,请求体相同。

卸载命令用 /uninstalls,等价于 action=uninstall,请求体相同(同 install/upgrade 的 artifact_id 必填、server_url 必填、env/ttl_seconds/max_uses 可选)。与升级一样作用于已有节点,node_id 必填(缺省 → 400「卸载必须指定目标节点」)。响应同样是一次性 commandcurl … | sudo bash 一行,明文 token 只出现一次)。权限:node.node.uninstall

⚠️ 破坏性、不可恢复:引导脚本据 GET /api/node/install/package 返回的服务端权威响应头 X-Install-Action(值取自 token 绑定 job 的动作,此处为 uninstall)决定跑包内 uninstall.sh 而非 install.sh,并用 here-string 自动应答其交互式 [y/N] 确认。uninstall.sh停止并移除该节点上的全部防护服务(nginx / agent / waf-spoa 等)及其数据目录,操作不可恢复。

范围:卸载只移除节点主机上的服务不删除云端节点列表里的节点记录。如需同时清掉节点记录,运维另行调用 DELETE /api/node/nodes/:id

响应:

{"code":0,"data":{
  "job_id":"…","token_id":"…","token_prefix":"nit_xxxxxxx",
  "expires_at":1735900000000,
  "command":"curl -fsSL --connect-timeout 10 --max-time 60 -H 'Authorization: Bearer nit_…' 'https://<cloud>/api/node/install/script' | sudo bash -s -- --token 'nit_…' --server 'https://<cloud>'"
}}

约束 / 行为:

8.3 安装机侧:script / package / env / report

command 拉取并执行的脚本(GET /install/script)会:set -euo pipefail + 退出清理临时目录 → 带 --connect-timeout/--max-time/--retry 下载 package、env → 校验 X-Artifact-SHA256 与本地 sha256sum 一致(不一致上报 failed 并退出)→ 用云端 env 覆盖包内 env.conf若注册变量含 AGENT_PORT 则注入解压出的 install*.sh(把 agent 监听/注册端口从默认 33020 改为该值,仅改解压副本,不动已校验包文件)→ 执行包内 install.sh → 经 /report 回报 running / success / failed

token 配额语义(关键)

接口 鉴权方式 是否消耗 max_usesuse_count 计数 / 副作用
GET /install/script 校验 token 有效性 ValidateBearerNoUse 不消耗,便于脚本可被重复拉取
GET /install/package 校验并占用 use_count+1 响应头 X-Artifact-SHA256 / X-Install-Job-ID;job 置 running
GET /install/env 校验并占用 use_count+1 返回 env 文本;env 载荷不可用时 403
POST /install/report ValidateBearerForReport 独立 report_count+1消耗 max_uses

安装机侧手动联调:

TOKEN=nit_xxx; BASE=https://<cloud>
curl -fsSL -H "Authorization: Bearer $TOKEN" "$BASE/api/node/install/script"
curl -fsSL -D - -o pkg.tar.gz -H "Authorization: Bearer $TOKEN" "$BASE/api/node/install/package"
curl -fsSL -H "Authorization: Bearer $TOKEN" "$BASE/api/node/install/env"
curl -fsS -X POST "$BASE/api/node/install/report" \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"status":"success","message":"done","hostname":"node-1","node_version":"1.0.0"}'

8.4 GET /api/node/install/jobs · /jobs/:id — 查询任务

curl -sS -H "Authorization: Bearer $TOKEN" https://<cloud>/api/node/install/jobs        # 最近 50 条
curl -sS -H "Authorization: Bearer $TOKEN" https://<cloud>/api/node/install/jobs/<job_id>  # 含 reports[]

statuspendingrunningsuccess / failedstarted_at / finished_at 为毫秒时间戳,0 表示未发生。详情接口附最近 reports(最多 20 条)与 recent_report

8.5 POST /api/node/install/tokens/:id/revoke — 撤销 token

curl -sS -X POST -H "Authorization: Bearer $TOKEN" \
  https://<cloud>/api/node/install/tokens/<token_id>/revoke

8.6 Stale job 回收(reaper)

后端单进程后台扫帚 install_reaper.go:启动时立即跑一次,之后每 10m 一次。把 ctime 早于 now - 24hStaleJobMaxAge)且仍处于 pending/running 的 job 原子置为 failedfinished_at=nowmessage="install job timed out without report"),并在同一事务内 revoke 指向这些 job 的仍 active 的 token —— 防止被强杀的安装机事后再用 bearer token 复活已关闭的 job。终态 job 不会被改写;多副本下事务 WHERE 子句保证幂等(仅首个进程命中,其余 RowsAffected=0 静默退出)。

8.7 前端展示约定

8.8 POST /api/node/reg — 节点 agent 自注册

节点 agent 自注册端点。公共端点:不挂 RBAC、不需要 Bearer 鉴权,与 POST /api/node/install/report 同类(属 agent 基础设施,无 zcloud CLI 命令)。唯一访问门槛是请求体里的共享口令 dummy_token——必须等于 agent 端硬编码的固定常量值,不匹配即拒绝。

后端实现:src/backend/internal/node/{handler,service}/reg.go、路由 src/backend/internal/node/route.gorg.POST("/reg", h.RegNode))。

请求体字段(注意 manger_addr 是 agent 既有拼写,缺 a,不能改成 manager_addr):

字段 类型 必填 说明
node_id string 首次安装为空;非空表示 agent 已持有节点 ID(命中既有节点则复用,不新建)
manger_addr string 管理地址 host:port,agent 用 ip route get 自动探测后上报。端口缺失时回落默认端口 33020
node_type string proto 枚举名字符串,如 "NODE_1_WAF"仅支持 WAF 防护节点(空 / "NODE_1_WAF" / "waf" / "1" 均映射为 WAF,其它值返回非零 code
extend_config string url-escape 后的扩展配置,自注册暂不消费
dummy_token string 共享口令,必须等于 agent 硬编码的固定常量值,否则拒绝
plugin string 插件列表,如 "waf,detect,agent,ebpf"
only_acl bool 仅 ACL 模式标记,自注册节点不走该路径
ip string only_acl 关联参数,标准注册为空
acl_tags string only_acl 关联参数
ip_groups string only_acl 关联参数
curl -sS -X POST https://<cloud>/api/node/reg \
  -H 'Content-Type: application/json' \
  -d '{
        "node_id":"",
        "manger_addr":"192.168.14.171:33020",
        "node_type":"NODE_1_WAF",
        "dummy_token":"<agent 硬编码共享口令>",
        "plugin":"waf,detect,agent,ebpf"
      }'

响应:标准信封 {code, message, data}dataRegNodeResponse

{"code":0,"message":"success","data":{
  "node_id":"3f2c…",
  "listen_addr":":33020",
  "tls":false,
  "cert":"",
  "key":"",
  "settings":{},
  "plugin":{}
}}
响应字段 类型 说明
node_id string 节点 ID。幂等命中既有节点时返回既有 ID;首次注册返回新建 ID
listen_addr string 监听地址,形如 ":33020",取自管理地址端口(缺失回落默认 33020
tls bool 新平台(NSQ)固定 false(不再用 etcd 下发每节点证书)
cert string 新平台返回空串
key string 新平台返回空串
settings object 下发配置。新平台配置走 NSQ 发布订阅,固定返回空映射 {}
plugin object 插件配置。新平台固定返回空映射 {}

语义要点


§A Analytics 通用查询参数

适用于所有单图 GET 接口(GET /api/analytics/<page>/<chart>)。未传参数时后端使用默认值;传入无权限的 target_user_id 或跨 OEM 资源时返回 403。

参数 类型 必填 取值/示例 说明
window string last_1h / last_24h / last_7d 时间窗口别名;为空时后端默认 last_24h
stime int64 1746748800000 自定义起始时间 Unix 毫秒(与 etime 配对,比 window 优先级高)
etime int64 1746835200000 自定义结束时间 Unix 毫秒
site_id string site-001 站点过滤
domain_id string d_8a3b1c 域名过滤
target_user_id string u-tenant-001 客户级切换被查看用户;后端统一做越权校验
compare bool false 是否启用上一周期对比(仅部分 chart 支持)
top int 10 TopN,默认 10,最大 100
order string bytes_desc 排序方式,具体含义由图表定义(如 top-url 支持 request_count_desc/bytes_desc/cache_desc
page int 1 列表类图表分页
size int 20 列表类分页每页条数,最大 100

单图响应骨架

{
  "code": 0,
  "message": "ok",
  "data": {
    "chart_key": "access/status",
    "render_hint": "categorical_distribution_over_time",
    "schema": {
      "dimensions": [
        { "name": "status_class", "type": "enum", "values": ["2xx", "3xx", "4xx", "5xx"] },
        { "name": "time", "type": "timestamp", "unit": "ms" }
      ],
      "measures": [
        { "name": "count", "type": "integer", "unit": "requests" }
      ]
    },
    "rows": [],
    "meta": {
      "cache": "miss",
      "source": "postgres",
      "latency_ms": 12,
      "window": {
        "stime": 1777526400000,
        "etime": 1777530000000,
        "granularity": "5m",
        "bucket_table": "tfs_flow_domains"
      }
    }
  }
}

window.granularity响应字段,描述实际命中的聚合粒度(5m / 1h / 1d),不是用户输入参数。客户传 window=last_24h,后端按窗口大小自动选表。


§B 可视化建议总表

B.1 Chart 统一契约 — render_hint 速查

所有 chart-key 由前端按 render_hint 自动分发到 6 个 chart 组件之一。这是契约真值(docs/specs/chart-contract.md §2),不可自创新词。

render_hint schema 形状 推荐前端组件 典型场景
kpi 0~1 dim + 1+ measure KpiGroupCard 多指标数字卡组(如 overview/kpi 的 6 测度)
categorical_distribution 1 categorical dim + 1 measure PieCard(≤8 类)/ BarCard(>8 类) 一维占比(如 overview/event-type)
categorical_distribution_over_time 1 categorical + 1 timestamp + 1 measure StackedBarCard / LineCard 多 series 多分类按时间堆叠(如 access/status)
time_series_single 1 timestamp + 1 measure LineCard 单测度时序(如 access/request-hm 无 compare)
time_series_multi 1 timestamp + ≥2 measures, 1 categorical + 1 timestamp + 1 measure LineCard 多线 多测度时序(如 access/flow-hm 5 测度);compare 走子形态 B
topn 1 string dim + 1 measure BarCard 横向 / RankingCard 已排序 TOP-N(如 protect/waf/top-ip)
geo 1 geo dim + 1 measure GeoHeatmapCard 地理分布(如 protect/waf/geo)
table 任意 TableCard 不适合可视化的兜底

新增 hint 词汇必须双方评审通过(cloud + Aegeon),不可单边扩词汇表。

B.2 数据形态速查

下表把"输出数据形态 → 推荐图表"的映射汇总在一起,对接前端时可作为速查表。实际响应仍以 Chart 统一契约的 schema + rows 为准。

数据形态 典型字段示例 推荐图表 不推荐
单值(标量) {count: 12345} KPI 数字卡 折线 / 饼图
多 KPI(4-6 个标量) {domain_count, requests, blocked, block_rate, qps} 多 KPI 卡阵 / 雷达图 单饼图
时序单系列 [{ctime, value}, ...] 折线图 / 面积图 饼图
时序多系列 [{ctime, requests, attacks}, ...] 多线折线 / 堆叠面积 饼图
时序对比(compare) {current:[...], previous:[...]} 双线对比折线(实虚线) 单折线
维度分布(少类 ≤ 8) [{key, count}, ...] 饼图 / 环形图 表格
维度分布(多类 > 8) [{key, count}, ...] 横向 bar / 柱图 饼图(碎片化)
地理分布 [{region, count}, ...] 中国/世界地图热力 表格
排行 TOP [{key, count, ...}, ...] 横向 bar / 表格(含明细列) 折线 / 饼图
二维矩阵 [[v11, v12], [v21, v22]] 热力图 折线
散点 [{x, y, size, ...}, ...] 散点图 / 气泡图 饼图
列表分页 {list, total, page, size} 表格(分页) 任何图表
时间线明细 {items: [{ctime, ...}]} 时间线(vertical timeline) 饼图
占位 {available: false, ...} 不渲染图表,渲染 n-empty 占位卡片 假数据

配色建议


§C 相关文档


完整 API 索引

REST 全集导出为 OpenAPI v3:

GET /api/openapi.json

可直接导入 Postman / Insomnia / Swagger UI。所有路由含完整 schema、参数、响应示例与所需权限 key。


Cloud WAF · REST API Documentation · 完整索引以 /api/openapi.json 为准