## 防篡改 (`site-tamper-guards`)

单个站点的网页防篡改设置:保护范围(首页、整页、目录)、检查范围(仅结构变化 / 整页任意变化)、篡改时返回基准页或仅告警、观察期;更新基准与看差异;属 WAF 增强。

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

### GET `/api/v2/site-tamper-guards/{site_id}`

获取站点防篡改设置 · 鉴权: 用户（部分参数仅管理员）

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

### PUT `/api/v2/site-tamper-guards/{site_id}`

设置站点防篡改 · 鉴权: 用户（部分参数仅管理员）

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `action` | string |  | 篡改时的处置。 可选值: ["restore","log"] |
| `enabled` | boolean | 有 | 是否开启。 |
| `expected_updated_at` | string |  | 乐观锁:调用方读到的 updated_at(读到为空 = 还没设置过,用 1970-01-01T00:00:00Z)。与库里当前值不等则回 409 stale_version、不保存;不带则不检查。 |
| `mode` | string |  | 检查范围。 可选值: ["structure","full"] |
| `observe_days` | integer |  | 新开启时观察的天数。 |
| `scopes` | SiteTamperScope[] |  | 保护范围。 |

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

### DELETE `/api/v2/site-tamper-guards/{site_id}`

站点防篡改恢复按方案 · 鉴权: 用户（部分参数仅管理员）

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

### GET `/api/v2/site-tamper-guards/{site_id}/diff`

看站点防篡改差异 · 鉴权: 用户（部分参数仅管理员）

查询参数:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `path` | string | 有 | 基准页路径(如 /、/about.html)。 |

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

### POST `/api/v2/site-tamper-guards/{site_id}/rebase`

更新站点防篡改基准 · 鉴权: 用户（部分参数仅管理员）

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

防篡改对象:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `action` | string |  | 篡改时的处置。 可选值: ["restore","log"] |
| `assets` | SiteTamperAsset[] |  | 指纹不符的 JS/CSS(只记录,不替换)。 |
| `base_at` | string |  | 基准时间(最近一次更新基准)。 (只读) |
| `base_ver` | integer |  | 基准版本,每次更新基准 +1;0 = 还没有基准。 (只读) |
| `changes` | SiteTamperChange[] |  | 结构变化(删掉的链接与正文变化不列)。 |
| `enabled` | boolean |  | 是否开启。 |
| `expected_updated_at` | string |  | 乐观锁:调用方读到的 updated_at(读到为空 = 还没设置过,用 1970-01-01T00:00:00Z)。与库里当前值不等则回 409 stale_version、不保存;不带则不检查。 |
| `fetch_error` | string |  | 现抓这一页没成的原因(此时 changes 为空):fetch_failed 源站非 200 或连不上;not_html 不是网页;too_large 超 1MB。抓到时不出。 可选值: ["fetch_failed","not_html","too_large"] |
| `gate` | string |  | 站点租户的 WAF 增强判定档:full 可改;readonly 到期只读缓冲内(License.readonly_days,缺省 7 天)照常生效、设置只读;basic 没开通或缓冲已过,不检测、设置保留。 可选值: ["full","readonly","basic"] (只读) |
| `gate_expired_at` | string |  | 仅管理员响应且 gate_reason=expired 时带:平台 WAF 增强授权的到期时刻;租户响应不带。 (只读) |
| `gate_owner` | WafGateOwner |  | 站点属主,仅管理员响应带;租户响应不带别人的信息。 (只读) |
| `gate_packages` | string[] |  | 仅管理员响应带:属主名下未到期的套餐名(最多 20 个);租户响应不带。 (只读) |
| `gate_reason` | WafGateReason |  | WAF 增强(waf_enhanced)没生效的原因,gate 为 full 或 readonly 时不带。package = 平台已授权但属主没有未到期且含 WAF 增强的套餐;license = 平台没开通(从未授权、服务商撤销、授权被停用);expired = 平台授权已到期且只读缓冲期(License.readonly_days,缺省 7 天)已过,已回落基础。 可选值: ["package","license","expired"] (只读) |
| `mode` | string |  | 检查范围。 可选值: ["structure","full"] |
| `observe_days` | integer |  | 新开启时观察的天数。 |
| `observe_until` | string |  | 观察期截止;为空 = 不在观察期(没开过或开时选了 0 天)。 (只读) |
| `pages` | SiteTamperPage[] |  | 基准页(按路径排序),含没纳入的保护范围与原因。 (只读) |
| `path` | string |  | 页面路径。 |
| `scopes` | SiteTamperScope[] |  | 保护范围。 |
| `site_id` | integer |  | 网站 ID (只读) |
| `source` | ProtectSiteSource |  | 站点这一项的来源:scheme 按方案(保存方案时跟着变);custom 单独设置(含关闭、存量迁移来的行)。 可选值: ["scheme","custom"] (只读) |
| `tampered` | boolean |  | 按站点检查范围算不算篡改。 |
| `updated_at` | string |  | 版本(没设过为空);修改时用 expected_updated_at。 (只读) |
