Files
MeshSate/docs/策略配置说明.md

460 lines
16 KiB
Markdown
Raw Normal View History

# MeshSafe 策略配置说明
| 项目 | 内容 |
|---|---|
| 适用对象 | 安全管理员、系统管理员 |
| 配置文件 | `config/policy.yaml` |
| 生效方式 | 修改后调用 `POST /api/v1/policies/reload` 或重启服务 |
| 文档版本 | v1.0 |
---
## 目录
1. [配置总览](#1-配置总览)
2. [字段详解](#2-字段详解)
3. [裁决流程](#3-裁决流程)
4. [调整场景手册](#4-调整场景手册)
5. [校验与错误处理](#5-校验与错误处理)
6. [变更管理](#6-变更管理)
---
## 1. 配置总览
策略文件采用 YAML 格式,路径由环境变量 `MESHSAFE_POLICY_FILE` 指定(默认 `/app/config/policy.yaml`)。
**核心原则:策略与代码分离。** 调整判定规则、阈值、白名单只需修改本文件,不需要重新构建或发布镜像。
```yaml
version: "2026.10.1"
description: "MeshSafe 默认全局策略(法院文书摆渡场景)"
global:
block_score: 70
review_score: [30, 70]
engine_failure_mode: fail_closed
max_file_size: 52428800
sync_max_size: 52428800
allow_encrypted_archive: false
allow_encrypted_document: false
allowed_extensions: [ ... ]
sandbox_required_extensions: [ ... ]
rule_overrides: { ... }
notification: { ... }
audit: { ... }
```
### 顶层结构
| 键 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `version` | string | 是 | 策略版本号,建议用日期格式。写入每条扫描结果 |
| `description` | string | 否 | 策略说明 |
| `global` | map | 是 | 全局阈值与行为开关 |
| `allowed_extensions` | list | 是 | 允许传输的扩展名白名单 |
| `sandbox_required_extensions` | list | 否 | 强制走沙箱深检的类型 |
| `rule_overrides` | map | 否 | 特定规则的强制处置 |
| `notification` | map | 否 | 判定理由的输出控制 |
| `audit` | map | 否 | 审计记录内容控制 |
---
## 2. 字段详解
### 2.1 global
#### 2.1.1 `block_score`
| 项 | 说明 |
|---|---|
| 类型 | 整数,0~100 |
| 默认 | `70` |
| 含义 | 风险评分 **≥ 此值** 时判定为 `malicious`,处置动作为 `reject` |
调整方向:调低 → 更严格(更多文件被拒),调高 → 更宽松(需积累更多信号才拒绝)。
> 注意:单条 `critical` 级信号通常权重已达 50~90,因此 `block_score` 低于 50 时,大量正常文档会因多条低级信号叠加被拒。
#### 2.1.2 `review_score`
| 项 | 说明 |
|---|---|
| 类型 | 数组 `[下界, 上界]` |
| 默认 | `[30, 70]` |
| 含义 | 评分落在该区间时判定为 `suspicious`,处置动作为 `manual_review`(转人工复核) |
**这是误报缓冲的关键参数。** 调整方向:调低下界 → 更多文件进入人工复核(更安全但人工压力大);调高下界 → 更少人工复核(但风险文件可能被直接放行)。
#### 2.1.3 `engine_failure_mode`
| 项 | 说明 |
|---|---|
| 类型 | 字符串 `fail_closed` / `fail_open` |
| 默认 | `fail_closed` |
| 含义 | 检测引擎不可用时的整体行为 |
| 取值 | 行为 | 适用 |
|---|---|---|
| `fail_closed` | 直接拒绝,并说明引擎不可用 | **生产环境必须使用此项** |
| `fail_open` | 放行但标记 | 仅限测试环境 |
> 等保三级要求"安全优先",生产环境使用 `fail_open` 会在测评时被判定为不符合项。
#### 2.1.4 `max_file_size`
| 项 | 说明 |
|---|---|
| 类型 | 整数(字节) |
| 默认 | `52428800`(50 MB) |
| 含义 | 单文件大小上限。超限直接拒绝 |
#### 2.1.5 `sync_max_size`
| 项 | 说明 |
|---|---|
| 类型 | 整数(字节) |
| 默认 | `52428800`(50 MB) |
| 含义 | 同步模式处理的文件大小上限。超限转异步 |
必须 ≤ `max_file_size`。若大于,则会出现"文件本身允许但无法同步处理"的中间态。
#### 2.1.6 `allow_encrypted_archive` / `allow_encrypted_document`
| 项 | 说明 |
|---|---|
| 类型 | 布尔 |
| 默认 | `false` |
| 含义 | 是否允许加密的压缩包 / 加密的文档 |
加密文件无法被静态分析,**在无法确认内容安全的前提下不应放行**。确需放行时,应配合人工复核流程。
### 2.2 allowed_extensions
允许传输的扩展名白名单。
```yaml
allowed_extensions:
- .docx
- .pdf
- .xlsx
- .jpg
- .png
- .zip
```
规则:
- 必须以 `.` 开头(小写),否则加载校验失败
- 比较时统一转小写,配置中的大写会被拒绝
- **列表为空表示不限制**,生产环境强烈不建议
- 只校验**顶层文件**的扩展名;归档内的子文件由各自规则判定(受 `rule_overrides` 控制)
> 白名单是第一道也是最粗的一道防线。它挡不住"扩展名正确但内容是恶意"的攻击——那是 L1/L2 层的职责。
### 2.3 sandbox_required_extensions
强制走沙箱异步深检的扩展名。
```yaml
sandbox_required_extensions:
- .exe
- .msi
- .js
- .vbs
- .iso
```
**当前版本(P3 一期)沙箱未实现**,配置此项的效果是:命中的文件会走异步模式,并在 `meta` 中标注需要深检。P4 阶段接入 CAPE 后无需修改本项。
### 2.4 rule_overrides
特定规则的强制处置。**这是绕过评分直接裁决的能力**,用于把"一票否决"型规则固化下来。
```yaml
rule_overrides:
MRaptorAutoExecSuspicious:
action: reject
reason: "文档宏具备自动执行且包含可疑行为,按策略直接拒绝"
DDEAutoExecution:
action: reject
reason: "检测到 DDE/DDEAUTO 自动执行字段,按策略直接拒绝"
```
| 字段 | 说明 |
|---|---|
| `action` | 处置动作,见下表 |
| `reason` | 判定理由,可直接展示给用户(支持中文) |
**action 取值**
| 取值 | 行为 |
|---|---|
| `pass` | 放行 |
| `pass_with_flag` | 放行并标记 |
| `manual_review` | 转人工复核(同时把评分提升至 65,确保落入复核区间) |
| `reject` | 拒绝 |
| `reject_and_notify` | 拒绝并通知(当前实现等同 `reject`) |
**生效逻辑**
1. 命中 `rule_overrides` 的规则会**优先于评分**处理
2. 若 `action` 为 `reject` 类 → 立即返回拒绝结论,不再累加评分
3. 若 `action` 为 `manual_review` → 评分提升至 65 并继续后续裁决
**为什么用覆盖而不是纯评分**:像 `PathTraversal`、`DDEAutoExecution` 这类信号,一旦出现就足以判定不可放行,不应依赖其他信号累加来"凑够"阈值。
> 规则名必须与《接口文档》§6 中的 `rule` 字段完全一致,包括大小写。写错不会报错,只是永不生效——因此**每次修改后应实际测试验证**。
### 2.5 notification
```yaml
notification:
include_reason: true
max_reason_length: 500
```
| 字段 | 说明 |
|---|---|
| `include_reason` | 是否在结果中返回判定理由。关闭后 `reason` 为空字符串 |
| `max_reason_length` | 理由最大长度,超出截断(末尾加 `...`) |
> `include_reason` 只影响**返回给调用方的内容**,不影响审计日志。审计日志始终记录完整信息。
### 2.6 audit
```yaml
audit:
log_findings: true
log_extracted_paths: true
```
| 字段 | 说明 |
|---|---|
| `log_findings` | 审计日志中是否记录命中的规则明细 |
| `log_extracted_paths` | 是否记录归档内提取出的文件路径 |
关闭 `log_findings` 可显著降低审计日志体积,代价是事后无法还原"当初为什么判定为恶意"。**建议保持开启**。
---
## 3. 裁决流程
```
┌─────────────────────────┐
检测信号 ────────▶│ 步骤 1:引擎可用性检查 │──▶ 引擎不可用 → fail_closed 拒绝
└─────────────────────────┘
│
▼
┌─────────────────────────┐
│ 步骤 2:文件大小检查 │──▶ 超限 → 拒绝
└─────────────────────────┘
│
▼
┌─────────────────────────┐
│ 步骤 3:扩展名白名单 │──▶ 不在清单 → 拒绝
└─────────────────────────┘
│
▼
┌─────────────────────────┐
│ 步骤 4:加密文件检查 │──▶ 加密且不允许 → 拒绝
└─────────────────────────┘
│
▼
┌─────────────────────────┐
│ 步骤 5:规则覆盖匹配 │──▶ 命中 reject 类 → 立即拒绝
└─────────────────────────┘
│
▼
┌─────────────────────────┐
│ 步骤 6:权重累加评分 │
└─────────────────────────┘
│
▼
┌─────────────────────────┐
│ 步骤 7:阈值映射处置 │
└─────────────────────────┘
```
### 3.1 评分计算
```
score = min(Σ(命中信号的 weight), 100)
```
已被 `rule_overrides` 处理的信号不重复累加。
### 3.2 阈值映射
| 评分区间 | verdict | action |
|---|---|---|
| `score == 0` | `clean` | `pass` |
| `0 < score < review_low` | `suspicious` | `pass_with_flag` |
| `review_low ≤ score < block_score` | `suspicious` | `manual_review` |
| `score ≥ block_score` | `malicious` | `reject` |
### 3.3 权重来源
| 层级 | 典型权重 |
|---|---|
| L0 结构层 | 10 ~ 50 |
| L1 ClamAV | 25 ~ 90 |
| L2 文档深度 | 15 ~ 80 |
| L2B YARA / 二进制 | 10 ~ 85 |
权重定义在各检测引擎内部,调整权重要改代码——**因此优先用 `rule_overrides` 表达策略意图**,而不是频繁改权重。
---
## 4. 调整场景手册
### 4.1 场景:误报过多,业务被阻塞
**症状**:大量正常文档被判为 `manual_review` 或 `reject`。
**排查步骤**
1. 查审计日志,找出被拒文件的命中规则
2. 判断是哪条规则在误报
**处理方式**
| 误报来源 | 处理 |
|---|---|
| 某条规则过于敏感 | 用 `rule_overrides` 将该规则降级为 `pass_with_flag`,并改写 `reason` 说明 |
| 阈值过低 | 提高 `review_score` 下界,或提高 `block_score` |
| 白名单缺少某类型 | 在 `allowed_extensions` 补充 |
| 正常文件确实含宏(如模板文件) | 用 `rule_overrides` 对特定规则放行,**但需评估该文件是否会成为攻击载体** |
> 建议不要直接调高 `block_score`——那会让真正的恶意文件更容易通过。优先降级具体规则。
### 4.2 场景:漏报,需要提升严格度
| 措施 | 配置 |
|---|---|
| 降低复核门槛 | 调低 `review_score` 下界 |
| 直接提高拒绝门槛 | 调低 `block_score` |
| 某类风险必须拦截 | 在 `rule_overrides` 中加 `reject` |
| 禁用某类可执行文件 | 确认 `allowed_extensions` 中不含该类型 |
| 加密文件也拦截 | 保持 `allow_encrypted_*` 为 `false` |
### 4.3 场景:新增业务通道,需要独立策略
**当前版本为全局单策略。** 如需按通道区分,两种做法:
**做法 A(不推荐,需改代码)**:在策略中引入 `channels` 段,裁决时按 `channel` 取对应子策略。
**做法 B(推荐,零代码改动)**:在摆渡系统侧做分流。摆渡系统按通道自行维护白名单,检测服务只做统一的恶意性判定。
> 本期方案已确认采用全局策略。通道字段贯穿全链路(数据库、审计日志、API),后续扩展无需重构。
### 4.4 场景:允许某类加密文件
```yaml
global:
allow_encrypted_document: true
```
**同时必须配套**:加密文件无法静态检测,风险由人工复核承担。建议同时把该类文件的处置设为 `manual_review`:
```yaml
rule_overrides:
PdfEncrypted:
action: manual_review
reason: "PDF 已加密,无法自动检测,转人工复核"
```
### 4.5 场景:新增一种文件类型要放行
1. 在 `allowed_extensions` 补充扩展名
2. 确认该类型没有对应的深度检测引擎(否则即使放行也只是"未检测",不是"已检测通过")
3. 若该类型有特殊风险(如脚本类),评估是否需要新增检测规则
---
## 5. 校验与错误处理
### 5.1 加载时校验项
策略文件在加载时执行严格校验,**任一项不通过则拒绝加载并保留原有策略**:
| 校验项 | 规则 |
|---|---|
| 根节点类型 | 必须是映射结构 |
| `review_score` | 下界必须小于上界 |
| `block_score` | 不应低于 `review_score` 上界;须在 0~100 之间 |
| `rule_overrides[].action` | 必须是合法动作枚举 |
| `allowed_extensions` | 每项必须以 `.` 开头 |
| `sync_max_size` | 须 ≤ `max_file_size` |
> **为什么校验失败要保留旧策略**:如果加载失败时回退到"默认策略"或"空策略",等于把生产环境的判定逻辑悄悄改掉了,比直接报错危险得多。
### 5.2 重载失败的表现
```json
{
"detail": "策略校验失败: block_score (50) 不应低于 review_score 上界 (70)"
}
```
原策略继续生效。修正后重新调用重载接口。
### 5.3 常见配置错误
| 错误 | 后果 | 修正 |
|---|---|---|
| 扩展名写成 `docx`(漏点) | 加载校验失败 | 改为 `.docx` |
| 扩展名大写 `.DOCX` | 加载校验失败 | 改为小写 |
| `rule_overrides` 规则名拼错 | **静默失效** | 对照接口文档 §6 核对,并实际测试 |
| `block_score` 调得极低(如 10) | 正常文件大量被拒 | 回调至 60~80 |
| `allowed_extensions` 留空 | 所有类型都被拒 | 补充清单 |
> **规则名拼错是唯一会静默失效的配置错误**,务必实测。
---
## 6. 变更管理
### 6.1 变更流程
```
提出变更 → 安全管理员评审 → 备份当前策略 → 修改配置
→ 语法校验(本地) → 重载 → 用样本文件验证 → 记录变更
```
### 6.2 变更记录要求
每次策略变更应记录:
| 项 | 说明 |
|---|---|
| 变更时间 | 精确到分钟 |
| 变更人 | 姓名与账号 |
| 变更内容 | 具体字段的前后值 |
| 变更原因 | 业务或安全需求说明 |
| 影响评估 | 是否影响在途文件、是否需要通知对接方 |
| 验证方式 | 用哪些样本文件验证、结果如何 |
### 6.3 版本追溯
每次扫描结果携带 `meta.policy_version` 与 `meta.policy_sha256`。数据库中保留策略版本快照,可用于**按历史策略复现**某一历史文件的判定结果。
### 6.4 灰度建议
策略变更影响面大时,建议:
1. 先在测试环境用真实样本文件验证
2. 对比新旧策略的判定差异(可通过 `rescan` 接口批量重跑)
3. 差异符合预期后再在生产重载
---
## 附录:完整默认策略
见 `config/policy.yaml`。本文档说明各字段含义,实际以配置文件为准。
---
**文档结束** · 配套文档:《总体方案》《接口文档》《等保三级对照表》《运维手册》