44e77dcb0e
**重构前**(旧编号 02-11): - docs/02-产品需求/ → 00 产品规划/PRD - docs/03-技术架构/ → 01-05 子目录散落 - docs/04-原型设计/ → 01-02 产品设计(HTML 原型) - docs/05-原型设计/ → screens/ - docs/06-测试素材/ → 02-E2E / 03-功能 / 04-版本测试 - docs/07-项目管理/ → 任务说明书/日报/计划 - docs/08-安全审计/ → 审计报告 - docs/09-堡垒运维/ → toolbox / deploy - docs/10-项目管理/ → 任务说明书(重复) - docs/11-历史归档/ → deploy-nas-archived **重构后**(新编号 00-07,语义化): - docs/00-产品开发流程与文档管理规范.md - docs/00-版本迭代总览.md - docs/01-产品文档/ (PRD/原型/认证/会话/AI 服务/坐席/集成) - docs/02-技术文档/ (技术方案/架构图/重构记录/前端改造/实现配置) - docs/03-测试文档/ (E2E/功能用例/版本报告/缺陷单) - docs/04-运维文档/ (部署运维/运维指南) - docs/05-运营文档/ (品牌推广/用户手册) - docs/06-安全审计/ (审计报告) - docs/07-项目管理/ (任务说明书/日报/计划/看板) **净收益**: - 目录编号与产品文档管理规范对齐(按文档阶段 01-07 编号) - 消除 02-产品需求 与 10-项目管理 的编号重叠 - 子目录按文档类型分组(如 01-产品文档/00-产品规划、01-产品文档/01-认证与登录) - 把运维/安全/项目管理从 0X 散落改为 04/06/07 合计 494 文件 + 78495 行 / - 14076 行
18 KiB
18 KiB
技术方案:安全策略检查平台
版本: v1.0 日期: 2026-07-20 状态: [草稿] 关联PRD:
01-产品文档/08-集成生态/PRD-REQ-集成-001-OpenClaw合规检查-v1.0.md
1. 系统架构
1.1 整体架构
┌─────────────────────────────────────────────────────────────────┐
│ 安全策略检查平台 │
├─────────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌───────────────────┐ │
│ │ 策略配置 │ │ 渠道配置 │ │ 任务调度 │ │
│ │ (策略管理) │ │ (渠道管理) │ │ (定时/手动) │ │
│ └──────┬───────┘ └──────┬───────┘ └────────┬──────────┘ │
│ │ │ │ │
│ └──────────────────┼─────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 策略执行引擎 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ 数据采集层 │→ │ 数据融合层 │→ │ 规则匹配层 │ │ │
│ │ │ 火绒API │ │ IP/主机名 │ │ 关键词过滤 │ │ │
│ │ │ 联软Excel │ │ MAC匹配 │ │ 白名单过滤 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 通知发送层 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ 企微应用 │ │ 企微群 │ │ (扩展)邮件 │ │ │
│ │ │ │ │ │ │ (扩展)短信 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 数据存储层 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ 策略配置 │ │ 命中记录 │ │ 执行日志 │ │ │
│ │ │ (PostgreSQL)│ │ (PostgreSQL)│ │ (PostgreSQL)│ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
1.2 模块设计
| 模块 | 职责 | 技术选型 |
|---|---|---|
| 策略配置管理 | 策略增删改查、启停 | FastAPI + SQLAlchemy |
| 渠道配置管理 | 渠道增删改查、适配器 | 策略模式 |
| 数据采集层 | 火绒API调用、联软Excel解析 | openpyxl + requests |
| 数据融合层 | IP/主机名/MAC三级匹配 | Python dict/hash |
| 规则匹配层 | 关键词过滤、白名单 | 正则表达式 |
| 通知发送层 | 企微消息发送 | 适配器模式 |
| 任务调度层 | APScheduler定时任务 | APScheduler |
| 数据存储层 | PostgreSQL | SQLAlchemy ORM |
2. 数据库设计
2.1 表结构
2.1.1 安全策略配置表 (security_strategies)
CREATE TABLE security_strategies (
id SERIAL PRIMARY KEY,
strategy_id VARCHAR(50) UNIQUE NOT NULL, -- 如: openclaw_remote
name VARCHAR(100) NOT NULL, -- 策略名称
description TEXT, -- 描述
detection_type VARCHAR(20) NOT NULL, -- 检测类型: software/usb/network
keywords TEXT NOT NULL, -- 关键词,逗号分隔
data_source VARCHAR(50) NOT NULL, -- 数据源: huorong/lianruan/both
channels JSONB NOT NULL DEFAULT '[]', -- 推送渠道配置
whitelist TEXT, -- 白名单,逗号分隔
is_enabled BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
2.1.2 渠道配置表 (notification_channels)
CREATE TABLE notification_channels (
id SERIAL PRIMARY KEY,
channel_id VARCHAR(50) UNIQUE NOT NULL, -- 如: wecom_app
name VARCHAR(100) NOT NULL, -- 渠道名称
channel_type VARCHAR(20) NOT NULL, -- 渠道类型: wecom/email/sms/dingtalk
config JSONB NOT NULL DEFAULT '{}', -- 渠道配置参数
is_enabled BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
2.1.3 命中记录表 (security_hits)
CREATE TABLE security_hits (
id SERIAL PRIMARY KEY,
strategy_id VARCHAR(50) NOT NULL, -- 策略ID
username VARCHAR(100), -- 用户名
fullname VARCHAR(100), -- 用户全名
dept VARCHAR(100), -- 部门
device_name VARCHAR(100), -- 设备名称
ip_address VARCHAR(50), -- IP地址
mac_address VARCHAR(50), -- MAC地址
hit_content TEXT NOT NULL, -- 命中内容(软件名等)
status VARCHAR(20) DEFAULT 'pending', -- pending/notified/resolved/false_positive
first_detected_at TIMESTAMP NOT NULL, -- 首次检测时间
last_detected_at TIMESTAMP NOT NULL, -- 最近检测时间
notified_at TIMESTAMP, -- 通知时间
resolved_at TIMESTAMP, -- 解决时间
resolved_by VARCHAR(100), -- 解决人
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (strategy_id) REFERENCES security_strategies(strategy_id)
);
2.1.4 状态变更历史表 (security_hit_history)
CREATE TABLE security_hit_history (
id SERIAL PRIMARY KEY,
hit_id INTEGER NOT NULL,
old_status VARCHAR(20),
new_status VARCHAR(20) NOT NULL,
changed_by VARCHAR(100),
change_reason TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (hit_id) REFERENCES security_hits(id)
);
2.1.5 执行日志表 (security_executions)
CREATE TABLE security_executions (
id SERIAL PRIMARY KEY,
strategy_id VARCHAR(50) NOT NULL,
execution_type VARCHAR(20) NOT NULL, -- scheduled/manual
total_terminals INTEGER DEFAULT 0, -- 总终端数
hit_count INTEGER DEFAULT 0, -- 命中数
notified_count INTEGER DEFAULT 0, -- 通知成功数
status VARCHAR(20) NOT NULL, -- running/success/failed
error_message TEXT,
started_at TIMESTAMP NOT NULL,
finished_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (strategy_id) REFERENCES security_strategies(strategy_id)
);
2.1.6 通知模板表 (notification_templates)
CREATE TABLE notification_templates (
id SERIAL PRIMARY KEY,
strategy_id VARCHAR(50) NOT NULL,
channel_id VARCHAR(50) NOT NULL,
title VARCHAR(200),
content TEXT NOT NULL,
is_default BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (strategy_id) REFERENCES security_strategies(strategy_id),
FOREIGN KEY (channel_id) REFERENCES notification_channels(channel_id)
);
3. 核心流程设计
3.1 定时检查流程
┌─────────────────┐
│ 定时任务触发 │
│ (APScheduler) │
└────────┬────────┘
│
▼
┌─────────────────┐ ┌─────────────────┐
│ 检查活动期间 │ │ 检查策略是否启用 │
│ (活动开关) │ │ (is_enabled) │
└────────┬────────┘ └────────┬────────┘
│ │
└───────────┬───────────┘
▼
┌─────────────┐
│ 加载策略 │
│ 获取关键词 │
│ 获取渠道 │
└──────┬──────┘
▼
┌─────────────────────┐
│ 从火绒API获取 │
│ 终端软件列表 │
└──────────┬──────────┘
▼
┌─────────────────────┐
│ 加载联软Excel │
│ 用户-终端关联 │
└──────────┬──────────┘
▼
┌─────────────────────┐
│ 三级匹配 │
│ IP → 主机名 → MAC │
└──────────┬──────────┘
▼
┌─────────────────────┐
│ 关键词过滤 │
│ 白名单过滤 │
└──────────┬──────────┘
▼
┌─────────────────────┐
│ 生成命中记录 │
│ 状态=pending │
└──────────┬──────────┘
▼
┌─────────────────────┐
│ 匹配历史记录 │
│ 状态变更判断 │
│ (自动解决逻辑) │
└──────────┬──────────┘
▼
┌─────────────────────┐
│ 发送企微通知 │
│ 更新状态 │
└──────────┬──────────┘
▼
┌─────────────────────┐
│ 记录执行日志 │
│ 更新统计 │
└─────────────────────┘
3.2 状态自动变更逻辑
def auto_update_status(new_hits, old_hits_map):
"""
new_hits: 本次检测到的命中列表
old_hits_map: 历史命中字典 {user+device: hit_record}
"""
for hit in new_hits:
key = f"{hit.username}:{hit.device_name}"
if key in old_hits_map:
old_hit = old_hits_map[key]
# 历史存在,本次仍命中 -> 保持原状态或更新为已通知
if old_hit.status == 'pending':
old_hit.status = 'notified'
old_hit.notified_at = now()
else:
# 新命中 -> 创建记录,状态=pending
create_hit_record(hit)
# 检查历史命中本次是否未命中 -> 自动标记已解决
for key, old_hit in old_hits_map.items():
if key not in new_hits_map:
if old_hit.status in ['pending', 'notified']:
old_hit.status = 'resolved'
old_hit.resolved_at = now()
old_hit.resolved_by = 'system:auto'
4. API设计
4.1 策略管理
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/security/strategies | 获取策略列表 |
| POST | /api/security/strategies | 创建策略 |
| GET | /api/security/strategies/{id} | 获取策略详情 |
| PUT | /api/security/strategies/{id} | 更新策略 |
| DELETE | /api/security/strategies/{id} | 删除策略 |
| POST | /api/security/strategies/{id}/toggle | 启用/停用策略 |
4.2 渠道管理
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/security/channels | 获取渠道列表 |
| POST | /api/security/channels | 创建渠道 |
| PUT | /api/security/channels/{id} | 更新渠道 |
| DELETE | /api/security/channels/{id} | 删除渠道 |
| POST | /api/security/channels/{id}/test | 测试渠道连接 |
4.3 命中记录
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/security/hits | 获取命中记录列表 |
| PUT | /api/security/hits/{id}/status | 更新命中状态 |
| GET | /api/security/hits/{id}/history | 获取状态变更历史 |
4.4 执行控制
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/security/execute | 手动触发检查 |
| GET | /api/security/executions | 获取执行历史 |
| GET | /api/security/executions/{id} | 获取执行详情 |
4.5 导出
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/security/export | 导出Excel报告 |
5. 扩展性设计
5.1 策略类型扩展
# 策略检测器基类
class BaseDetector(ABC):
@abstractmethod
def detect(self, terminals: List[Terminal]) -> List[Hit]:
pass
# 软件检测器
class SoftwareDetector(BaseDetector):
def detect(self, terminals):
# 关键词匹配
pass
# USB检测器
class USBDetector(BaseDetector):
def detect(self, terminals):
# USB设备检测
pass
# 注册策略检测器
DETECTOR_REGISTRY = {
'software': SoftwareDetector,
'usb': USBDetector,
}
5.2 渠道适配器扩展
# 渠道发送器基类
class BaseSender(ABC):
@abstractmethod
def send(self, template: Template, targets: List[Target]) -> SendResult:
pass
# 企微发送器
class WeComSender(BaseSender):
def send(self, template, targets):
# 企微API调用
pass
# 邮件发送器
class EmailSender(BaseSender):
def send(self, template, targets):
# SMTP发送
pass
# 注册渠道发送器
SENDER_REGISTRY = {
'wecom': WeComSender,
'email': EmailSender,
'sms': SMSSender,
}
6. 安全与合规
6.1 数据安全
- 白名单、敏感配置数据加密存储
- 操作日志记录所有管理操作
- 定期备份数据库
6.2 隐私合规
- 用户-终端关联数据仅用于通知定位
- 不存储额外个人信息
- 符合公司数据安全规范
7. 部署方案
7.1 依赖服务
| 服务 | 版本要求 |
|---|---|
| PostgreSQL | 14+ |
| Redis | 6+ (可选,用于缓存) |
| APScheduler | 3.10+ |
7.2 环境变量
# 数据库
DATABASE_URL=postgresql://user:pass@localhost:5432/security_db
# 火绒API (复用现有配置)
HUORONG_BASE_URL=
HUORONG_KEY=
HUORONG_SECRET=
# 企微应用 (复用现有配置)
WECOM_AGENT_ID=
WECOM_SECRET=
8. 验收标准
| 验收项 | 标准 |
|---|---|
| 定时执行 | 每天8:00自动执行,99%可用率 |
| 手动触发 | 点击后5分钟内完成检查 |
| 匹配准确率 | IP/主机名/MAC三级匹配成功率≥85% |
| 通知成功率 | 企微通知送达率≥95% |
| 状态自动更新 | 历史命中用户再次未命中,自动标记已解决 |
| Excel导出 | 正确导出所有命中字段 |
9. 后续扩展
| 扩展项 | 工作量 | 说明 |
|---|---|---|
| 新增检测策略 | 0.5天 | 配置关键词和数据源 |
| 新增邮件渠道 | 1天 | 开发EmailSender |
| 新增短信渠道 | 1天 | 开发SMSSender |
| 新增钉钉渠道 | 1天 | 开发DingTalkSender |