## 站点黑白名单 (`site-ip-lists`)

单个站点的永久 IP 黑名单与白名单;黑名单命中即断开,白名单命中跳过 CC 等防护。也可清空站点在各节点上的临时白名单。

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

### GET `/api/v2/site-ip-lists/{site_id}`

获取站点黑白名单 · 鉴权: 用户（部分参数仅管理员）

```sh
curl "https://panel.example.com/api/v2/site-ip-lists/{site_id}" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### PUT `/api/v2/site-ip-lists/{site_id}`

设置站点黑白名单 · 鉴权: 用户（部分参数仅管理员）

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `black` | string[] |  | 永久黑名单(命中 = 断开);条数受 protect.black_ip_max 约束。 |
| `black_items` | IpListItem[] |  | 黑名单条目(含到期时间、原因、来源);已到期的不返回。 |
| `expected_updated_at` | string |  | 乐观锁:调用方读到的 updated_at(读到 updated_at 为空 = 还没设置过,用 1970-01-01T00:00:00Z)。与库里当前值不等则回 409 stale_version、不保存;不带则不检查。 |
| `white` | string[] |  | 永久白名单(命中 = 跳过 CC 等防护);条数受 protect.white_ip_max 约束。 |
| `white_items` | IpListItem[] |  | 白名单条目(含到期时间、原因、来源);已到期的不返回。 |

```sh
curl -X PUT "https://panel.example.com/api/v2/site-ip-lists/{site_id}" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"black":["198.51.100.0/24"],"white":["203.0.113.9"]}'
```

### GET `/api/v2/site-ip-lists/{site_id}/export`

导出站点黑白名单 · 鉴权: 用户（部分参数仅管理员）

查询参数:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `list` | string | 有 | 导出哪张名单。 可选值: ["black","white"] |
| `source` | IpListSource |  | 只导出该来源的条目;不带为全部。 可选值: ["manual","import","ip_detail","api"] |
| `format` | string |  | txt(缺省,纯文本每行一条)或 csv(带表头与来源列、UTF-8 BOM)。 可选值: ["txt","csv"] 默认: "txt" |

```sh
curl "https://panel.example.com/api/v2/site-ip-lists/{site_id}/export" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/site-ip-lists/{site_id}/import`

批量导入站点黑白名单 · 鉴权: 用户（部分参数仅管理员）

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `dry_run` | boolean |  | true 只预检,不保存。 默认: false |
| `expected_updated_at` | string |  | 乐观锁:调用方读到的 updated_at(读到 updated_at 为空 = 还没设置过,用 1970-01-01T00:00:00Z)。与库里当前值不等则回 409 stale_version、不保存;不带则不检查。 |
| `list` | string | 有 | 导入到哪张名单。 可选值: ["black","white"] |
| `mode` | string |  | merge 并进现有名单(同 IP 以导入行为准);replace 用导入行替换整张名单。 可选值: ["merge","replace"] 默认: "merge" |
| `text` | string | 有 | 文件内容(txt/csv),每行 IP/CIDR[,到期时间][,原因]。 |

```sh
curl -X POST "https://panel.example.com/api/v2/site-ip-lists/{site_id}/import" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dry_run":true,"list":"black","mode":"merge","text":"198.51.100.0/24,2030-01-01T00:00:00Z,scanner\n"}'
```

### GET `/api/v2/site-ip-lists/{site_id}/ip-detail`

IP 详情 · 鉴权: 用户（部分参数仅管理员）

查询参数:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `ip` | string | 有 | IPv4 或 IPv6 地址。 |

```sh
curl "https://panel.example.com/api/v2/site-ip-lists/{site_id}/ip-detail" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/site-ip-lists/{site_id}/ip-detail`

从 IP 详情拉黑或加白 · 鉴权: 用户（部分参数仅管理员）

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `expires_at` | string |  | 到期时间;空 = 永久。须晚于当前时刻。 |
| `ip` | string | 有 | 规范化后的地址(IPv4 映射地址还原成 IPv4)。 |
| `list` | string | 有 | 导入到哪张名单。 可选值: ["black","white"] |
| `reason` | string |  | 原因(备注),最长 200 个字符。 |
| `scope` | string | 有 | site 本站名单;global 全局名单(仅管理员)。 可选值: ["site","global"] |

```sh
curl -X POST "https://panel.example.com/api/v2/site-ip-lists/{site_id}/ip-detail" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/site-ip-lists/{site_id}/tmp-white-clear`

清空站点临时白名单 · 鉴权: 用户（部分参数仅管理员）

```sh
curl -X POST "https://panel.example.com/api/v2/site-ip-lists/{site_id}/tmp-white-clear" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

站点黑白名单对象:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `added` | integer |  | 新增条数。 |
| `applied` | boolean |  | 是否已保存(dry_run 或有挡导入的问题时为 false)。 |
| `black` | string[] |  | 永久黑名单(命中 = 断开);条数受 protect.black_ip_max 约束。 |
| `black_items` | IpListItem[] |  | 黑名单条目(含到期时间、原因、来源);已到期的不返回。 |
| `block_denied` | string |  | 不能拉黑的原因:private 内网/回环/链路本地、node 节点 IP(只回管理员)、self 调用者自己的 IP、other 其他原因(租户遇到节点 IP 回这个,不暴露节点地址);能拉黑不回。 可选值: ["private","node","self","other"] |
| `dry_run` | boolean |  | true 只预检,不保存。 默认: false |
| `expected_updated_at` | string |  | 乐观锁:调用方读到的 updated_at(读到 updated_at 为空 = 还没设置过,用 1970-01-01T00:00:00Z)。与库里当前值不等则回 409 stale_version、不保存;不带则不检查。 |
| `expires_at` | string |  | 到期时间;空 = 永久。须晚于当前时刻。 |
| `geo` | GeoipLookup |  | IP 归属地查询结果。 |
| `global_black` | IpListItem |  | IP 名单条目(IP 详情里是命中该 IP 的那一条,没命中不回)。 |
| `global_white` | IpListItem |  | IP 名单条目(IP 详情里是命中该 IP 的那一条,没命中不回)。 |
| `ip` | string |  | 规范化后的地址(IPv4 映射地址还原成 IPv4)。 |
| `issues` | IpListImportIssue[] |  | 逐行问题(最多 1000 条,按行号升序)。 |
| `lines` | integer |  | 有效条目数(去重后)。 |
| `list` | string | 有 | 导入到哪张名单。 可选值: ["black","white"] |
| `mode` | string |  | merge 并进现有名单(同 IP 以导入行为准);replace 用导入行替换整张名单。 可选值: ["merge","replace"] 默认: "merge" |
| `reason` | string |  | 原因(备注),最长 200 个字符。 |
| `removed` | integer |  | replace 模式下原有、新名单里没有的条数(同 IP 的算「更新」,不算在内)。 |
| `scope` | string | 有 | site 本站名单;global 全局名单(仅管理员)。 可选值: ["site","global"] |
| `site_black` | IpListItem |  | IP 名单条目(IP 详情里是命中该 IP 的那一条,没命中不回)。 |
| `site_id` | integer |  | 网站 ID (只读) |
| `site_white` | IpListItem |  | IP 名单条目(IP 详情里是命中该 IP 的那一条,没命中不回)。 |
| `task_id` | integer |  | 下发节点的后台任务 id(GET /tasks/{id} 查进度)。 |
| `text` | string | 有 | 文件内容(txt/csv),每行 IP/CIDR[,到期时间][,原因]。 |
| `updated` | integer |  | 已在名单里、被导入行更新的条数。 |
| `updated_at` | string |  | 更新时间 (只读) |
| `white` | string[] |  | 永久白名单(命中 = 跳过 CC 等防护);条数受 protect.white_ip_max 约束。 |
| `white_items` | IpListItem[] |  | 白名单条目(含到期时间、原因、来源);已到期的不返回。 |
