## 封禁 (`bans`)

被拉黑的 IP 记录,可手动封禁、按 IP 或整站解封并查解封记录,也包含节点上报的自动封禁。

鉴权: 用户（部分参数仅管理员） · 文档: https://www-demo.kuxitong.com/zh/docs/api/bans

### GET `/api/v2/bans`

列出封禁 · 鉴权: 用户（部分参数仅管理员）

查询参数:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `page` | integer |  | 页码,从 1 开始。 默认: 1 |
| `page_size` | integer |  | 每页条数。 默认: 20 |
| `sort` | string |  | 排序字段,逗号分隔,前缀 `-` 表示降序,如 `-created_at,id`。 |
| `tenant_id` | integer |  | 仅管理员可用:按租户过滤。租户凭据调用时忽略,只返回本租户数据。 |
| `ip` | string |  | 给单个地址精确匹配;给 CIDR 网段则返回落入该网段的全部封禁(单地址条目,及前缀不短于该网段的网段条目)。 |
| `site_id` | integer |  | 按站点过滤。 |
| `active` | boolean |  | true = 只看未到期的。 |
| `level` | string |  | 按作用范围过滤(global = 全局黑名单)。 可选值: ["site","tenant","global"] |
| `source` | string |  | 按来源过滤:manual = 面板下的(人工);node = 节点自动封的(挑战超限、规则 ban、握手洪水等)。 可选值: ["manual","node"] |
| `source_type` | string |  | 按来源细类过滤(manual / cc / waf / scan / status / tls / intel);可逗号分隔多个(如 status,tls,重复的去重),每项都须是这七个值之一,否则 422;不带为全部。 |
| `created_from` | string |  | 只看该时刻(含)及之后创建的封禁,用于「今天新增」。同一对象节点再封是续期,不改创建时刻,所以只算首次落库。 |

```sh
curl "https://panel.example.com/api/v2/bans" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/bans`

创建封禁 · 鉴权: 用户（部分参数仅管理员）

查询参数:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `tenant_id` | integer |  | 仅管理员可用:封禁所属租户。租户级必填;站点级可省(按站主),带了须与站主一致。租户凭据调用时忽略。 |

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `expires_at` | string |  | 到期时刻;null = 永久。 |
| `ip` | string | 有 | IP 或 CIDR。 |
| `level` | string | 有 | 作用范围:site = 某站点;tenant = 该租户全部站点;global = 全网(仅管理员)。 可选值: ["site","tenant","global"] |
| `reason` | string |  | 原因:人工封禁默认 manual;节点自动封的是触发规则(规则集/规则 id,如 cc.level.r5/r1)或模块名(ssl_handshake = 握手洪水),无规则的记 auto。 |
| `site_id` | integer |  | level=site 时必填的站点 id;其余为 0。 |

```sh
curl -X POST "https://panel.example.com/api/v2/bans" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ip":"198.51.100.7","level":"tenant"}'
```

### GET `/api/v2/bans/site-counts`

按站点统计封禁 · 鉴权: 用户（部分参数仅管理员）

查询参数:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `page` | integer |  | 页码,从 1 开始。 默认: 1 |
| `page_size` | integer |  | 每页条数。 默认: 20 |
| `tenant_id` | integer |  | 仅管理员可用:按租户过滤。租户凭据调用时忽略,只返回本租户数据。 |
| `source_type` | string |  | 按来源细类过滤(manual / cc / waf / scan / status / tls / intel);可逗号分隔多个(如 status,tls,重复的去重),每项都须是这七个值之一,否则 422;不带为全部。 |
| `created_from` | string |  | 只看该时刻(含)及之后创建的封禁,用于「今天新增」。同一对象节点再封是续期,不改创建时刻,所以只算首次落库。 |

```sh
curl "https://panel.example.com/api/v2/bans/site-counts" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### GET `/api/v2/bans/source-counts`

按来源细类统计封禁 · 鉴权: 用户（部分参数仅管理员）

查询参数:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `tenant_id` | integer |  | 仅管理员可用:按租户过滤。租户凭据调用时忽略,只返回本租户数据。 |
| `created_from` | string |  | 只看该时刻(含)及之后创建的封禁,用于「今天新增」。同一对象节点再封是续期,不改创建时刻,所以只算首次落库。 |

```sh
curl "https://panel.example.com/api/v2/bans/source-counts" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/bans/unban`

按 IP 解封 · 鉴权: 用户（部分参数仅管理员）

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `all` | boolean |  | true = 全站解封:清空 site_id 这个站的全部封禁,只用于 level=site,计 1 次每天解封次数。 |
| `ips` | string[] |  | 要解封的 IP/CIDR(all=true 时不带,否则必填);一次条数受 protect.unban_batch_max 约束,租户每天次数受 protect.unban_daily_max 约束。 |
| `level` | string | 有 | 作用范围:site = 某站点;tenant = 该租户全部站点;global = 全网(仅管理员)。 可选值: ["site","tenant","global"] |
| `site_id` | integer |  | level=site 时必填的站点 id;其余为 0。 |

```sh
curl -X POST "https://panel.example.com/api/v2/bans/unban" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ips":["198.51.100.7"],"level":"tenant"}'
```

### GET `/api/v2/bans/unban-quota`

解封配额与今日已用 · 鉴权: 用户（部分参数仅管理员）

```sh
curl "https://panel.example.com/api/v2/bans/unban-quota" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### GET `/api/v2/bans/unbans`

列出解封记录 · 鉴权: 用户（部分参数仅管理员）

查询参数:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `page` | integer |  | 页码,从 1 开始。 默认: 1 |
| `page_size` | integer |  | 每页条数。 默认: 20 |
| `tenant_id` | integer |  | 仅管理员可用:按租户过滤。租户凭据调用时忽略,只返回本租户数据。 |
| `site_id` | integer |  | 按站点过滤(只含站点级解封)。 |
| `since` | string |  | 只列这个时刻及之后的(如数今天用了几次)。 |
| `by_admin` | boolean |  | 按是否管理员代站主解封过滤;数站主今天用掉的次数传 false(代解不占站主次数)。 |

```sh
curl "https://panel.example.com/api/v2/bans/unbans" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### DELETE `/api/v2/bans/{id}`

删除封禁 · 鉴权: 用户（部分参数仅管理员）

```sh
curl -X DELETE "https://panel.example.com/api/v2/bans/{id}" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

封禁对象:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `all` | boolean |  | true = 全站解封:清空 site_id 这个站的全部封禁,只用于 level=site,计 1 次每天解封次数。 |
| `batch_max` | integer |  | 一次最多解封几个 IP(配置 protect.unban_batch_max)。 |
| `by_admin` | boolean |  | true = 管理员代站主解封(记在站主名下、站主可见,不占站主每天次数)。 |
| `count` | integer |  | 未到期封禁条数。 |
| `created_at` | string |  | 创建时间 (只读) |
| `daily_max` | integer |  | 租户每天最多解封几次(配置 protect.unban_daily_max)。 |
| `expires_at` | string |  | 到期时刻;null = 永久。 |
| `filter_id` | string |  | 触发的过滤器(规则集或模块),由 reason 拆出,如 cc.level.r5、waf、scan.builtin、ssl_handshake;手工封禁与无规则的 auto 不给。 (只读) |
| `id` | integer |  | 记录 ID (只读) |
| `intel` | BanIntel |  | 封禁 IP 在平台高危 IP 库里的现状(列表时按当前库现查;库没在下发、已出库或库没给的字段不返回)。 |
| `intel_hit` | boolean |  | 该 IP 是否在平台高危 IP 库;null = 尚未判定(高危 IP 库上线前恒为 null)。 |
| `ip` | string |  | IP 或 CIDR。 |
| `ip_count` | integer |  | 解封的 IP/CIDR 条数(全站解封为 0)。 |
| `ips` | string[] |  | 要解封的 IP/CIDR(all=true 时不带,否则必填);一次条数受 protect.unban_batch_max 约束,租户每天次数受 protect.unban_daily_max 约束。 |
| `items` | BanSourceCount[] |  | 本页条目 |
| `level` | string |  | 作用范围:site = 某站点;tenant = 该租户全部站点;global = 全网(仅管理员)。 可选值: ["site","tenant","global"] |
| `reason` | string |  | 原因:人工封禁默认 manual;节点自动封的是触发规则(规则集/规则 id,如 cc.level.r5/r1)或模块名(ssl_handshake = 握手洪水),无规则的记 auto。 |
| `removed` | integer |  | 同时从封禁表删除的条数。 |
| `rule_id` | string |  | 触发的规则号,由 reason 拆出(cc.level.r5/r1 的 r1、waf:941100 的 941100);没有规则号的不给。 (只读) |
| `site_id` | integer |  | level=site 时必填的站点 id;其余为 0。 |
| `source` | string |  | manual = 面板下的;node = 节点自动封后上报的(同一对象未到期时只留一行,再封续期)。解封两者一样:删除或 /bans/unban。 可选值: ["manual","node"] (只读) |
| `source_type` | BanSourceType |  | 来源细类:manual = 面板下的;cc = CC 规则组(含 cc.level.*、cc.user.*、auto 及其余规则集);waf = WAF 规则连续命中;scan = 扫描器内置集;status = 状态码内置集;tls = 握手洪水;intel = 平台高危 IP 库。节点自动封的永不是 manual。 可选值: ["manual","cc","waf","scan","status","tls","intel"] |
| `status` | string |  | 下发任务状态 pending/running/done/failed;任务已被清理为 null。 |
| `task_id` | integer |  | 下发节点的后台任务 id(GET /tasks/{id} 查进度)。 |
| `tenant_id` | integer |  | 所属租户;null = 平台对象(内置或管理员建,租户只读)。 (只读) |
| `updated_at` | string |  | 更新时间 (只读) |
| `used` | integer |  | 本租户今天(UTC 零点起)自己解封的次数;管理员代解不计,管理员调用时为 0。 |
