mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-07-10 14:28:43 +02:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
# Eino 多代理改造说明(DeepAgent)
|
||||
|
||||
本文档记录 **Eino 单代理(ADK)** 与 **多 Agent(CloudWeGo Eino `adk/prebuilt`)** 的改造范围、进度与后续事项。原生 ReAct 执行路径已移除。
|
||||
|
||||
## 总体结论
|
||||
|
||||
- **改造已可用于生产试验**:流式对话、MCP 工具桥接、配置开关、前端模式切换均已落地。
|
||||
- **入口策略**:**单代理** 走 `/api/eino-agent/stream`;多代理走 `/api/multi-agent/stream`,请求体 **`orchestration`** 指定编排。模式定位按 Eino ADK 最佳实践区分:**Deep** 适合复杂安全测试与 task 子代理协作;**Plan-Execute** 适合目标明确的规划 → 执行 → 重规划闭环;**Supervisor** 适合多个专业子代理动态分派的专家路由场景。机器人默认 `robot_default_agent_mode: eino_single`;批量队列默认 `eino_single`,多代理模式需 `multi_agent.enabled`。
|
||||
|
||||
## 已完成项
|
||||
|
||||
| 项 | 说明 |
|
||||
|----|------|
|
||||
| 依赖与代理 | `go.mod` 直接依赖 `github.com/cloudwego/eino`、`eino-ext/.../openai`;`go.mod` 注释与 `scripts/bootstrap-go.sh` 指导 **GOPROXY**(如 `https://goproxy.cn,direct`)。 |
|
||||
| 配置 | `config.yaml` → `agent.max_iterations` 为全局 ReAct 上限(主/子代理统一);`multi_agent`:`enabled`、`robot_use_multi_agent`、`sub_agents`(含可选 `bind_role`)、`eino_skills`、`eino_middleware` 等;结构体见 `internal/config/config.go`。 |
|
||||
| Markdown 子代理 / 主代理 | 在 `agents_dir` 下放 `*.md`。**子代理**:供 Deep `task` 与 `supervisor` `transfer`。**主代理(按模式分离)**:`orchestrator.md`(或 `kind: orchestrator` 的**单个**其他 .md)→ **Deep**;固定名 `orchestrator-plan-execute.md` → **plan_execute**;固定名 `orchestrator-supervisor.md` → **supervisor**。正文优先于 YAML:`multi_agent.orchestrator_instruction`、`orchestrator_instruction_plan_execute`、`orchestrator_instruction_supervisor`;plan_execute / supervisor **不会**回退到 Deep 的 `orchestrator_instruction`。皆空时 plan_execute / supervisor 使用代码内置默认提示。管理:**Agents → Agent管理**;API:`/api/multi-agent/markdown-agents*`。 |
|
||||
| MCP 桥 | `internal/einomcp`:`ToolsFromDefinitions` + 会话 ID 持有者,执行走 `Agent.ExecuteMCPToolForConversation`。 |
|
||||
| 编排 | `internal/multiagent/runner.go`:`deep.New` + 子 `ChatModelAgent` + `adk.NewRunner`(`EnableStreaming: true`,可选 `CheckPointStore`),事件映射为现有 SSE `tool_call` / `response_delta` 等。 |
|
||||
| HTTP | `POST /api/multi-agent`(非流式)、`POST /api/multi-agent/stream`(SSE);路由**常注册**,是否可用由运行时 `multi_agent.enabled` 决定(流式未启用时 SSE 内 `error` + `done`)。 |
|
||||
| 会话准备 | `internal/handler/multi_agent_prepare.go`:`prepareMultiAgentSession`(含 **WebShell** `CreateConversationWithWebshell`、工具白名单与单代理一致)。 |
|
||||
| 单 Agent | `internal/agent` 为 MCP/工具层(`ToolsForRole`、`ExecuteMCPToolForConversation`);单代理编排走 `RunEinoSingleChatModelAgent`(`/api/eino-agent*`)。 |
|
||||
| 前端 | 主聊天 / WebShell:**Eino 单代理**(`/api/eino-agent/stream`)与 **Deep / Plan-Execute / Supervisor**(`/api/multi-agent/stream` + `orchestration`);`multi_agent.enabled` 控制多代理选项是否展示。 |
|
||||
| 流式兼容 | Eino 单/多代理与 Web UI 共用 `handleStreamEvent`:`conversation`、`progress`、`response_start` / `response_delta`、`thinking` / `thinking_stream_*`、`tool_*`、`response`、`done` 等。 |
|
||||
| 批量任务 | 队列 `agentMode` 为 `deep` / `plan_execute` / `supervisor` 时子任务带对应 `orchestration` 调用 `RunDeepAgent`;旧值 `multi` 与「`agentMode` 为空且 `batch_use_multi_agent: true`」均按 `deep`。 |
|
||||
| 配置 API | `GET /api/config` 返回 `multi_agent: { enabled, robot_use_multi_agent, sub_agent_count }`;`PUT /api/config` 可更新 `enabled`、`robot_use_multi_agent`(不覆盖 `sub_agents`)。 |
|
||||
| OpenAPI | 多代理路径说明已更新(流式未启用为 SSE 错误事件)。 |
|
||||
| 机器人 | `ProcessMessageForRobot` 按 `robot_default_agent_mode`(默认 `eino_single`)调用 `RunEinoSingleChatModelAgent` 或 `RunDeepAgent`。 |
|
||||
| 预置编排 | 聊天 / WebShell:`POST /api/multi-agent*` 请求体 `orchestration`:`deep` \| `plan_execute` \| `supervisor`(缺省 `deep`)。`deep` 使用 task 子代理协作;`plan_execute` 不构建 YAML/Markdown 子代理;`plan_execute_loop_max_iterations` 仍来自配置;`supervisor` 至少需一个子代理,只有一个子代理时会提示其专家路由空间有限。 |
|
||||
| Eino 中间件 | `multi_agent.eino_middleware`(可选):`patchtoolcalls`(默认开)、`toolsearch`(按阈值拆分 MCP 工具列表)、`plantask`(需 `eino_skills`)、`reduction`(大工具输出截断/落盘)、`checkpoint_dir`(Runner 断点)、`deep_output_key` / `deep_model_retry_max_retries` / `task_tool_description_prefix`(Deep 与 supervisor 主代理共享其中模型重试与 OutputKey)。**`plan_execute`**:Executor 使用 Eino 官方允许的自定义 `adk.ChatModelAgent`,保持官方 Plan/UserInput/ExecutedSteps session contract,同时挂载与 Deep/Supervisor 主代理同源的 middleware(patch → reduction → toolsearch → plantask → filesystem → skill → summarization tail)。Planner/Replanner 仅 summarization tail + prompt 预算截断,不跑 MCP 工具链。当前 Eino 官方 `planexecute.NewExecutor` 尚未暴露 Handlers 字段,因此该自定义 Executor 是保留 middleware 的对齐实现。 |
|
||||
|
||||
## 进行中 / 待办( backlog )
|
||||
|
||||
| 优先级 | 项 | 说明 |
|
||||
|--------|----|------|
|
||||
| P3 | **观测与计费** | Eino 事件可进一步打结构化日志 / trace id,便于排障。 |
|
||||
| P3 | **测试** | 增加 `internal/multiagent` 与 einomcp 的集成测试(mock model 或录屏回放)。 |
|
||||
|
||||
## 关键文件索引
|
||||
|
||||
- `internal/multiagent/runner.go` — DeepAgent / plan_execute / supervisor 组装与事件循环
|
||||
- `internal/multiagent/eino_orchestration.go` — PlanExecute 根节点与 Executor 中间件栈(`buildPlanExecuteExecutorHandlers`)
|
||||
- `internal/handler/multi_agent.go` — SSE 与(同步)HTTP
|
||||
- `internal/handler/multi_agent_prepare.go` — 会话准备(含 WebShell)
|
||||
- `internal/einomcp/` — MCP → Eino Tool
|
||||
- `config.yaml` — `multi_agent` 示例块
|
||||
- `web/static/js/chat.js` — 模式选择与 stream URL
|
||||
- `web/static/js/webshell.js` — WebShell AI 流式 URL 与主聊天模式对齐
|
||||
- `web/static/js/settings.js` — 多代理标量保存
|
||||
|
||||
## 版本记录
|
||||
|
||||
| 日期 | 说明 |
|
||||
|------|------|
|
||||
| 2026-03-22 | 首版:Eino DeepAgent + stream + 前端开关 + GOPROXY 脚本。 |
|
||||
| 2026-03-22 | 补充:进度文档、`prepareMultiAgentSession` 抽取、WebShell 后端对齐、`POST /api/multi-agent`、OpenAPI `/api/multi-agent*` 条目。 |
|
||||
| 2026-03-22 | 路由常注册、流式未启用 SSE 错误、`robot_use_multi_agent`、设置页持久化、WebShell/机器人多代理、`bind_role` 子代理 Skills/tools。 |
|
||||
| 2026-03-22 | `tool_result.toolCallId`、`ReasoningContent`→思考流、`batch_use_multi_agent` 与批量队列 Eino 执行。 |
|
||||
| 2026-03-22 | 流式工具事件:按稳定签名去重,避免每 chunk 刷屏与「未知工具」;最终回复去重相同段落;内置调度显示为 `task`。 |
|
||||
| 2026-03-22 | `agents/*.md` 子代理定义、`agents_dir`、合并进 `RunDeepAgent`、前端 Agents 菜单与 CRUD API。 |
|
||||
| 2026-03-22 | `orchestrator.md` / `kind: orchestrator` 主代理、列表主/子标记、与 `orchestrator_instruction` 优先级。 |
|
||||
| 2026-04-19 | 主聊天「对话模式」:原生 ReAct 与 Deep / Plan-Execute / Supervisor;`POST /api/multi-agent*` 请求体 `orchestration` 与界面一致;`config.yaml` / 设置页不再维护预置编排字段(机器人/批量默认 `deep`)。 |
|
||||
| 2026-04-21 | 移除角色 `skills` 与 `/api/roles/skills/list`;`bind_role` 仅继承 tools;Skills 仅通过 Eino `skill` 工具按需加载。 |
|
||||
| 2026-07-06 | **最佳实践对齐**:Deep / Plan-Execute / Supervisor 改为中性适用场景描述;Supervisor 标为专家路由特定场景并收紧 transfer/exit 约束;plan_execute Executor 明确为遵循官方 session contract 的自定义 ChatModelAgent,保留 middleware 并补类型保护。 |
|
||||
| 2026-07-02 | **plan_execute Executor 中间件对齐**:`ExecPreMiddlewares` 与 Deep 主代理同源;`buildPlanExecuteExecutorHandlers` + 回归测试;文档更正。 |
|
||||
| 2026-06-02 | **移除原生 ReAct**:删除 `/api/agent-loop*` 执行入口与 `AgentLoopWithProgress`;统一 Eino ADK(单代理 `/api/eino-agent*`,多代理 `/api/multi-agent*`);任务 cancel/tasks API 保留。 |
|
||||
@@ -0,0 +1,29 @@
|
||||
# 中文文档
|
||||
|
||||
- [部署指南](deployment.md):部署形态、HTTPS、反向代理、systemd、备份、升级和验收。
|
||||
- [运维 Runbooks](runbooks.md):生产部署、外部 MCP、知识库、Web 测试、C2 清理和工具排障的操作步骤。
|
||||
- [配置画像](configuration-profiles.md):本地开发、内网团队、知识库、高审计生产、C2 演练等推荐配置。
|
||||
- [安全加固指南](security-hardening.md):上线前基线、反向代理、HITL 白名单、文件权限和周期巡检。
|
||||
- [API Recipes](api-recipes.md):登录、Agent、流式、多代理、上传、漏洞、知识库、MCP 和审计导出示例。
|
||||
- [贡献规范](contributing-guide.md):新增 API、配置、工具、前端、数据库、高风险能力和文档的 checklist。
|
||||
- [配置参考](configuration.md):`config.yaml` 字段、热应用边界、参数建议和源码锚点。
|
||||
- [安全模型](security-model.md):信任边界、HITL、工具执行、C2/WebShell 与数据安全。
|
||||
- [架构说明](architecture.md):请求路径、模块关系、复杂度热点和设计取舍。
|
||||
- [API 参考](api-reference.md):认证、OpenAPI、SSE、稳定性分层和常用接口。
|
||||
- [排错指南](troubleshooting.md):诊断顺序、最小命令、常见误判和故障模板。
|
||||
- [审计与监控](audit-and-monitoring.md):平台审计、工具监控、HITL 日志和保留策略。
|
||||
- [知识库](knowledge-base.md):索引链路、检索调参、日志分析和内容写法。
|
||||
- [C2 使用说明](c2.md):生命周期、任务分级、事件复盘和安全建议。
|
||||
- [WebShell 管理](webshell.md):操作分层、连接命名、AI 约束和排错。
|
||||
- [MCP 联邦](mcp-federation.md):内置 MCP、外部 MCP、生命周期和工具命名。
|
||||
- [Agent 与角色](agent-and-role-guide.md):角色、子代理、Skill、编排模式和工具可见性。
|
||||
- [Skills 指南](skills-guide.md):Skill 结构、渐进式披露、反模式和本地工具风险。
|
||||
- [插件开发](plugin-development.md):API 插件、MCP 插件、资源包插件和安全边界。
|
||||
- [发布流程](release-process.md):发布风险、配置兼容、数据库迁移和验收。
|
||||
- [测试指南](testing.md):测试分层、回归重点、测试数据和失败用例。
|
||||
- [图编排使用说明](workflow-graph.md)
|
||||
- [人机协同最佳实践](hitl-best-practices.md)
|
||||
- [机器人使用说明](robot.md)
|
||||
- [视觉分析](VISION.md)
|
||||
- [前端国际化方案](frontend-i18n.md)
|
||||
- [Eino 多代理改造说明](MULTI_AGENT_EINO.md)
|
||||
@@ -0,0 +1,45 @@
|
||||
# 视觉分析(analyze_image)
|
||||
|
||||
## 概述
|
||||
|
||||
- **工具名**:`analyze_image`(MCP 内置)
|
||||
- **行为**:读取本地图片 → `imaging` 缩放/JPEG 压缩 → 调用独立 **Vision** 模型 → 返回**纯文本**给 Agent
|
||||
- **上下文**:图片字节**不会**写入对话历史;仅路径与文字摘要进入 Agent 上下文
|
||||
|
||||
## 配置(`config.yaml` → `vision`)
|
||||
|
||||
```yaml
|
||||
vision:
|
||||
enabled: true
|
||||
model: qwen-vl-max # 必填
|
||||
api_key: # 留空 → openai.api_key
|
||||
base_url: # 留空 → openai.base_url
|
||||
provider: # 留空 → openai.provider
|
||||
max_image_bytes: 5242880
|
||||
max_dimension: 2048
|
||||
jpeg_quality: 82
|
||||
max_payload_bytes: 524288
|
||||
skip_preprocess_below_bytes: 2097152 # 低于 2MB 且长边<=max_dimension 时原图直传;0=始终 JPEG 压缩
|
||||
detail: low # low | high | auto
|
||||
timeout_seconds: 60
|
||||
```
|
||||
|
||||
`enabled: false` 时不注册工具。
|
||||
|
||||
## Web 设置
|
||||
|
||||
**系统设置 → 基本设置 → 视觉分析(analyze_image)** 可配置启用开关、视觉模型、API Key/Base URL(留空复用 OpenAI)、预处理参数;**保存并应用** 后写入 `config.yaml` 并重新注册 MCP 工具。
|
||||
|
||||
## 路径
|
||||
|
||||
`analyze_image` 可读取服务器上任意可读的图片文件路径(绝对路径或相对于进程工作目录的相对路径)。仍校验图片扩展名与常规文件类型。
|
||||
|
||||
## Agent 使用
|
||||
|
||||
系统提示已说明:遇图片调用 `analyze_image`,勿用 `read_file` 读二进制图。
|
||||
|
||||
`multi_agent.eino_middleware.tool_search_always_visible_tools` 建议包含 `analyze_image`。
|
||||
|
||||
## 合规
|
||||
|
||||
启用后图片会发往 Vision API 配置的上游;敏感环境请使用可信网关或保持 `enabled: false`。
|
||||
@@ -0,0 +1,197 @@
|
||||
# Agent 与角色指南
|
||||
|
||||
CyberStrikeAI 的 Agent 行为由三类资源共同决定:角色、子代理和 Skills。角色决定当前任务身份和可用工具;子代理决定多代理分工;Skills 提供可按需加载的专题知识与流程。
|
||||
|
||||
## 角色
|
||||
|
||||
角色文件位于 `roles/`,格式为 YAML。角色通常包含:
|
||||
|
||||
- 名称。
|
||||
- 描述。
|
||||
- 系统提示词。
|
||||
- 可用工具列表。
|
||||
|
||||
设计原则:
|
||||
|
||||
- 专用角色只绑定必要工具。
|
||||
- 提示词明确授权边界。
|
||||
- 对高风险操作要求先说明影响并等待审批。
|
||||
- 输出格式尽量稳定,便于报告和复盘。
|
||||
|
||||
示例方向:
|
||||
|
||||
- 信息收集。
|
||||
- Web 应用扫描。
|
||||
- API 安全测试。
|
||||
- 云安全审计。
|
||||
- 数字取证。
|
||||
- 二进制分析。
|
||||
- CTF。
|
||||
|
||||
## 单代理
|
||||
|
||||
单代理接口:
|
||||
|
||||
- `POST /api/eino-agent`
|
||||
- `POST /api/eino-agent/stream`
|
||||
|
||||
适合:
|
||||
|
||||
- 快速问答。
|
||||
- 单目标测试。
|
||||
- 工具链较短的任务。
|
||||
- 需要稳定上下文的交互式分析。
|
||||
|
||||
## 多代理模式
|
||||
|
||||
多代理接口:
|
||||
|
||||
- `POST /api/multi-agent`
|
||||
- `POST /api/multi-agent/stream`
|
||||
|
||||
编排模式:
|
||||
|
||||
- `deep`:主代理拆解任务,按需调用子代理。
|
||||
- `plan_execute`:先规划,再执行,必要时重规划。
|
||||
- `supervisor`:主管代理根据进展转交不同子代理。
|
||||
|
||||
适合:
|
||||
|
||||
- 多阶段渗透测试。
|
||||
- 大范围信息收集。
|
||||
- 需要并行角色分工的分析。
|
||||
- 长任务和批量任务。
|
||||
|
||||
## 子代理 Markdown
|
||||
|
||||
子代理位于 `agents/*.md`。Front matter 示例:
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: Attack Surface Enumeration
|
||||
id: attack-surface-enumeration
|
||||
description: 枚举目标暴露面并整理可验证线索
|
||||
tools:
|
||||
- subfinder
|
||||
- nmap
|
||||
- http-framework-test
|
||||
bind_role: 信息收集
|
||||
max_iterations: 300
|
||||
---
|
||||
```
|
||||
|
||||
正文写系统提示词。建议包含:
|
||||
|
||||
- 职责边界。
|
||||
- 输入期望。
|
||||
- 使用工具顺序。
|
||||
- 输出格式。
|
||||
- 禁止事项。
|
||||
|
||||
## 主代理
|
||||
|
||||
主代理可用:
|
||||
|
||||
- `agents/orchestrator.md`
|
||||
- `agents/orchestrator-plan-execute.md`
|
||||
- `agents/orchestrator-supervisor.md`
|
||||
|
||||
或在 front matter 中设置 `kind: orchestrator`。每种编排只应有一个主代理定义。
|
||||
|
||||
## 工具选择
|
||||
|
||||
工具选择顺序建议:
|
||||
|
||||
1. 角色绑定最小工具集。
|
||||
2. 子代理按任务补充专用工具。
|
||||
3. `tool_search` 动态解锁大量工具。
|
||||
4. 高风险工具由 HITL 审批。
|
||||
|
||||
不要给所有角色默认绑定全部工具,否则上下文成本和误调用风险都会上升。
|
||||
|
||||
## 提示词建议
|
||||
|
||||
好的角色提示词应说明:
|
||||
|
||||
- 只在授权范围内行动。
|
||||
- 先确认目标和约束。
|
||||
- 对写入、删除、爆破、持久化、C2、WebShell 等操作请求审批。
|
||||
- 输出可复核证据。
|
||||
- 不确定时标注假设,不编造结果。
|
||||
|
||||
## 调试
|
||||
|
||||
如果 Agent 选错工具:
|
||||
|
||||
- 缩小角色工具列表。
|
||||
- 增强工具 `short_description`。
|
||||
- 开启或调整 `tool_search_always_visible_tools`。
|
||||
- 在角色提示词中明确工具使用顺序。
|
||||
|
||||
如果多代理跑偏:
|
||||
|
||||
- 检查子代理描述是否过宽。
|
||||
- 降低 `sub_agent_user_context_max_runes` 或明确任务输入。
|
||||
- 优化 orchestrator 提示词。
|
||||
- 查看过程详情和工具执行监控。
|
||||
|
||||
## 角色、子代理、Skill 的职责边界
|
||||
|
||||
三者经常混用,建议这样分工:
|
||||
|
||||
| 资源 | 解决的问题 | 不适合承载 |
|
||||
| --- | --- | --- |
|
||||
| Role | 当前对话的身份、语气、工具边界和授权规则 | 大量参考资料 |
|
||||
| Agent Markdown | 多代理中的专业分工、交接格式和局部策略 | 一次性任务事实 |
|
||||
| Skill | 可复用方法论、检查清单、模板和长参考资料 | 权限控制 |
|
||||
|
||||
如果把授权边界写进 Skill,而角色没有限制工具,Agent 仍可能在未加载 Skill 前选错工具。权限边界应优先放在 Role 和 HITL 中。
|
||||
|
||||
## 编排模式选择
|
||||
|
||||
| 模式 | 适合 | 不适合 |
|
||||
| --- | --- | --- |
|
||||
| `eino_single` | 短任务、交互式分析、需要稳定上下文 | 多阶段大任务 |
|
||||
| `deep` | 主代理动态拆分任务,子代理按需深入 | 需要严格步骤顺序的流程 |
|
||||
| `plan_execute` | 有明确阶段、需要执行后复盘和重规划 | 用户频繁打断的即兴对话 |
|
||||
| `supervisor` | 专家分工明确,需要主管路由 | 子代理定义含糊或过多 |
|
||||
|
||||
经验上,普通安全测试先用 `eino_single`;复杂项目用 `plan_execute`;需要多个专业角色时用 `deep` 或 `supervisor`。
|
||||
|
||||
## 工具可见性如何影响行为
|
||||
|
||||
多代理里 `tool_search` 会让模型一开始只看见部分常驻工具。结果是:
|
||||
|
||||
- 工具页面显示可用,不代表模型当前上下文可见。
|
||||
- `tool_search_always_visible_tools` 里的工具更容易被模型调用。
|
||||
- 工具描述越清晰,越容易被搜索命中。
|
||||
- 子代理自己的 `tools` 限制仍然很重要。
|
||||
|
||||
调试“Agent 为什么不用某工具”时,要同时检查角色工具、子代理工具、tool_search 配置和工具描述。
|
||||
|
||||
## 好的子代理输出格式
|
||||
|
||||
子代理不要只返回“已完成”。建议固定格式:
|
||||
|
||||
```markdown
|
||||
## 结论
|
||||
|
||||
## 证据
|
||||
- 命令/工具:
|
||||
- 关键输出:
|
||||
- 置信度:
|
||||
|
||||
## 风险
|
||||
|
||||
## 建议下一步
|
||||
```
|
||||
|
||||
这样主代理才能继续编排,也方便攻击链和项目事实沉淀。
|
||||
|
||||
## 源码锚点
|
||||
|
||||
- Markdown Agent 解析:`internal/agents/markdown.go`
|
||||
- 多代理准备:`internal/handler/multi_agent_prepare.go`
|
||||
- 编排实现:`internal/multiagent/eino_orchestration.go`
|
||||
- 工具搜索中间件:`internal/multiagent/eino_middleware.go`
|
||||
- 子代理上下文:`internal/multiagent/sub_agent_context_test.go`
|
||||
@@ -0,0 +1,153 @@
|
||||
# API Recipes
|
||||
|
||||
[English](../en-US/api-recipes.md)
|
||||
|
||||
本文给出外部脚本或插件常用的 API 调用配方。完整字段以 `/api-docs` 和 `/api/openapi/spec` 为准。
|
||||
|
||||
## Recipe 1:登录并验证
|
||||
|
||||
```bash
|
||||
curl -k https://127.0.0.1:8080/api/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"password":"<password>"}'
|
||||
```
|
||||
|
||||
后续请求推荐使用:
|
||||
|
||||
```bash
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
验证:
|
||||
|
||||
```bash
|
||||
curl -k https://127.0.0.1:8080/api/auth/validate \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
## Recipe 2:创建对话并发送消息
|
||||
|
||||
最简单方式是不先创建空对话,直接调用 Agent:
|
||||
|
||||
```bash
|
||||
curl -k https://127.0.0.1:8080/api/eino-agent \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"message":"对 127.0.0.1 做授权的基础信息收集,只做只读操作"}'
|
||||
```
|
||||
|
||||
如果需要先创建对话:
|
||||
|
||||
```bash
|
||||
curl -k https://127.0.0.1:8080/api/conversations \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"title":"Web 测试"}'
|
||||
```
|
||||
|
||||
然后把返回的 `conversationId` 放入 Agent 请求。
|
||||
|
||||
## Recipe 3:流式调用 Agent
|
||||
|
||||
```bash
|
||||
curl -k -N https://127.0.0.1:8080/api/eino-agent/stream \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"message":"总结当前项目事实并列出下一步,只读"}'
|
||||
```
|
||||
|
||||
注意:
|
||||
|
||||
- `-N` 禁用 curl 缓冲。
|
||||
- 反向代理也要关闭 buffering。
|
||||
- 收到 `done` 才算本轮结束。
|
||||
|
||||
## Recipe 4:调用多代理
|
||||
|
||||
```bash
|
||||
curl -k -N https://127.0.0.1:8080/api/multi-agent/stream \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"message":"对授权目标做分阶段 Web 安全测试,先规划再执行只读步骤",
|
||||
"orchestration":"plan_execute"
|
||||
}'
|
||||
```
|
||||
|
||||
可选 `orchestration`:
|
||||
|
||||
- `deep`
|
||||
- `plan_execute`
|
||||
- `supervisor`
|
||||
|
||||
## Recipe 5:上传附件
|
||||
|
||||
```bash
|
||||
curl -k https://127.0.0.1:8080/api/chat-uploads \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-F "file=@./request.txt"
|
||||
```
|
||||
|
||||
大文件建议上传后在消息中引用,不要直接塞进 prompt。
|
||||
|
||||
## Recipe 6:写入漏洞
|
||||
|
||||
```bash
|
||||
curl -k https://127.0.0.1:8080/api/vulnerabilities \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"title":"示例 SQL 注入",
|
||||
"severity":"high",
|
||||
"target":"https://example.com/item?id=1",
|
||||
"description":"参数 id 存在可验证 SQL 注入",
|
||||
"evidence":"只读验证输出...",
|
||||
"remediation":"使用参数化查询"
|
||||
}'
|
||||
```
|
||||
|
||||
字段以 OpenAPI 为准。
|
||||
|
||||
## Recipe 7:查询知识库
|
||||
|
||||
```bash
|
||||
curl -k https://127.0.0.1:8080/api/knowledge/search \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"query":"SQL 注入如何判断字段数",
|
||||
"riskType":"SQL Injection",
|
||||
"topK":5,
|
||||
"threshold":0.4
|
||||
}'
|
||||
```
|
||||
|
||||
如果结果为空,先调用 categories 看风险类型名称是否匹配。
|
||||
|
||||
## Recipe 8:检查外部 MCP 状态
|
||||
|
||||
```bash
|
||||
curl -k https://127.0.0.1:8080/api/external-mcp/stats \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
如果服务 running 但 Agent 找不到工具,检查角色工具限制和 `tool_search`。
|
||||
|
||||
## Recipe 9:获取工具 schema
|
||||
|
||||
```bash
|
||||
curl -k https://127.0.0.1:8080/api/config/tools/nmap/schema \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
插件或自动化脚本应根据 schema 构造参数,不要猜字段名。
|
||||
|
||||
## Recipe 10:导出审计日志
|
||||
|
||||
```bash
|
||||
curl -k "https://127.0.0.1:8080/api/audit/logs/export" \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-o audit.csv
|
||||
```
|
||||
|
||||
导出文件可能包含敏感操作信息,应加密保存。
|
||||
@@ -0,0 +1,239 @@
|
||||
# API 参考
|
||||
|
||||
CyberStrikeAI 内置 OpenAPI 规格和 API 文档页面。启动服务后访问:
|
||||
|
||||
```text
|
||||
/api-docs
|
||||
```
|
||||
|
||||
OpenAPI JSON:
|
||||
|
||||
```text
|
||||
GET /api/openapi/spec
|
||||
```
|
||||
|
||||
`/api/openapi/spec` 需要登录认证,避免未授权用户直接枚举接口结构。
|
||||
|
||||
## 认证
|
||||
|
||||
登录:
|
||||
|
||||
```http
|
||||
POST /api/auth/login
|
||||
Content-Type: application/json
|
||||
|
||||
{"password":"your-password"}
|
||||
```
|
||||
|
||||
认证成功后,前端通常使用 Cookie 会话。外部客户端也可参考 OpenAPI 中的 Bearer Token 描述,按实际返回字段接入。
|
||||
|
||||
常用认证接口:
|
||||
|
||||
- `POST /api/auth/login`
|
||||
- `POST /api/auth/logout`
|
||||
- `POST /api/auth/change-password`
|
||||
- `GET /api/auth/validate`
|
||||
|
||||
## 对话与 Agent
|
||||
|
||||
单代理:
|
||||
|
||||
- `POST /api/eino-agent`
|
||||
- `POST /api/eino-agent/stream`
|
||||
|
||||
多代理:
|
||||
|
||||
- `POST /api/multi-agent`
|
||||
- `POST /api/multi-agent/stream`
|
||||
|
||||
多代理请求体通过 `orchestration` 指定:
|
||||
|
||||
- `deep`
|
||||
- `plan_execute`
|
||||
- `supervisor`
|
||||
|
||||
对话管理:
|
||||
|
||||
- `POST /api/conversations`
|
||||
- `GET /api/conversations`
|
||||
- `GET /api/conversations/:id`
|
||||
- `PUT /api/conversations/:id`
|
||||
- `DELETE /api/conversations/:id`
|
||||
- `POST /api/conversations/:id/delete-turn`
|
||||
- `GET /api/messages/:id/process-details`
|
||||
|
||||
## 项目、漏洞、攻击链
|
||||
|
||||
项目:
|
||||
|
||||
- `GET /api/projects`
|
||||
- `POST /api/projects`
|
||||
- `GET /api/projects/:id`
|
||||
- `PUT /api/projects/:id`
|
||||
- `DELETE /api/projects/:id`
|
||||
- `GET /api/projects/:id/facts`
|
||||
- `POST /api/projects/:id/facts`
|
||||
- `GET /api/projects/:id/fact-graph`
|
||||
|
||||
漏洞:
|
||||
|
||||
- `GET /api/vulnerabilities`
|
||||
- `POST /api/vulnerabilities`
|
||||
- `GET /api/vulnerabilities/:id`
|
||||
- `PUT /api/vulnerabilities/:id`
|
||||
- `DELETE /api/vulnerabilities/:id`
|
||||
- `GET /api/vulnerabilities/export`
|
||||
|
||||
攻击链:
|
||||
|
||||
- `GET /api/attack-chain/:conversationId`
|
||||
- `POST /api/attack-chain/:conversationId/regenerate`
|
||||
|
||||
## 工具、MCP、配置
|
||||
|
||||
配置:
|
||||
|
||||
- `GET /api/config`
|
||||
- `PUT /api/config`
|
||||
- `POST /api/config/apply`
|
||||
- `GET /api/config/tools`
|
||||
- `GET /api/config/tools/:name/schema`
|
||||
- `POST /api/config/test-openai`
|
||||
- `POST /api/config/test-vision`
|
||||
- `POST /api/config/list-models`
|
||||
|
||||
MCP:
|
||||
|
||||
- `POST /api/mcp`
|
||||
- `GET /api/external-mcp`
|
||||
- `PUT /api/external-mcp/:name`
|
||||
- `POST /api/external-mcp/:name/start`
|
||||
- `POST /api/external-mcp/:name/stop`
|
||||
- `DELETE /api/external-mcp/:name`
|
||||
|
||||
## 知识库、Skills、角色、Agent
|
||||
|
||||
知识库:
|
||||
|
||||
- `GET /api/knowledge/categories`
|
||||
- `GET /api/knowledge/items`
|
||||
- `POST /api/knowledge/scan`
|
||||
- `POST /api/knowledge/index`
|
||||
- `POST /api/knowledge/search`
|
||||
|
||||
角色:
|
||||
|
||||
- `GET /api/roles`
|
||||
- `POST /api/roles`
|
||||
- `GET /api/roles/:name`
|
||||
- `PUT /api/roles/:name`
|
||||
- `DELETE /api/roles/:name`
|
||||
|
||||
Skills:
|
||||
|
||||
- `GET /api/skills`
|
||||
- `POST /api/skills`
|
||||
- `GET /api/skills/:name`
|
||||
- `PUT /api/skills/:name`
|
||||
- `DELETE /api/skills/:name`
|
||||
- `GET /api/skills/:name/files`
|
||||
- `GET /api/skills/:name/file`
|
||||
- `PUT /api/skills/:name/file`
|
||||
|
||||
Markdown 子代理:
|
||||
|
||||
- `GET /api/multi-agent/markdown-agents`
|
||||
- `POST /api/multi-agent/markdown-agents`
|
||||
- `GET /api/multi-agent/markdown-agents/:filename`
|
||||
- `PUT /api/multi-agent/markdown-agents/:filename`
|
||||
- `DELETE /api/multi-agent/markdown-agents/:filename`
|
||||
|
||||
## 高风险能力
|
||||
|
||||
WebShell:
|
||||
|
||||
- `GET /api/webshell/connections`
|
||||
- `POST /api/webshell/connections`
|
||||
- `POST /api/webshell/exec`
|
||||
- `POST /api/webshell/file`
|
||||
|
||||
C2:
|
||||
|
||||
- `GET /api/c2/listeners`
|
||||
- `POST /api/c2/listeners`
|
||||
- `GET /api/c2/sessions`
|
||||
- `POST /api/c2/tasks`
|
||||
- `POST /api/c2/payloads/build`
|
||||
|
||||
终端:
|
||||
|
||||
- `POST /api/terminal/run`
|
||||
- `POST /api/terminal/run/stream`
|
||||
- `GET /api/terminal/ws`
|
||||
|
||||
这些接口应只开放给可信管理员,并配合 HTTPS、强密码、网络隔离和审计。
|
||||
|
||||
## 调用建议
|
||||
|
||||
- 优先使用 `/api-docs` 查看完整参数和响应结构。
|
||||
- 流式接口使用 SSE,反向代理需关闭缓冲。
|
||||
- 所有修改类接口都应处理 401、403、404、409、500。
|
||||
- 外部集成建议创建最小权限网络路径,不要把 Web 管理面直接暴露到公网。
|
||||
|
||||
## 认证细节
|
||||
|
||||
认证中间件会按顺序提取 token:
|
||||
|
||||
1. `Authorization: Bearer <token>`
|
||||
2. `Authorization: <token>`
|
||||
3. 查询参数 `?token=<token>`
|
||||
4. Cookie `auth_token`
|
||||
|
||||
这意味着外部脚本最稳妥的方式是使用 `Authorization: Bearer`。查询参数虽然支持,但容易进入代理日志,不建议生产使用。
|
||||
|
||||
## SSE 客户端注意事项
|
||||
|
||||
`/api/eino-agent/stream` 和 `/api/multi-agent/stream` 是长连接。客户端应处理:
|
||||
|
||||
- 网络中断后不要盲目重放破坏性请求。
|
||||
- 收到 `error` 事件后读取错误正文。
|
||||
- 收到 `done` 才视为本轮结束。
|
||||
- 代理层不能缓冲。
|
||||
- 请求体中的 `conversationId` 决定是否接续已有对话。
|
||||
|
||||
## API 稳定性分层
|
||||
|
||||
| API 类型 | 稳定性 | 集成建议 |
|
||||
| --- | --- | --- |
|
||||
| `/api/auth/*` | 高 | 可直接集成 |
|
||||
| `/api/eino-agent*` | 高 | 推荐外部对话入口 |
|
||||
| `/api/openapi/spec` | 高 | 用于生成客户端 |
|
||||
| `/api/config*` | 中 | 管理工具使用,谨慎自动化 |
|
||||
| `/api/c2/*`、`/api/webshell/*` | 中 | 高风险,必须加权限边界 |
|
||||
| 前端私有调用细节 | 低 | 不建议插件依赖 |
|
||||
|
||||
## Curl 示例
|
||||
|
||||
登录并提取 token 的返回字段可能随实现调整,建议先看 `/api-docs`。如果已有 token:
|
||||
|
||||
```bash
|
||||
curl -k https://127.0.0.1:8080/api/conversations \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
发送非流式单代理请求:
|
||||
|
||||
```bash
|
||||
curl -k https://127.0.0.1:8080/api/eino-agent \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"message":"对 127.0.0.1 做授权的基础信息收集,先不要执行高风险操作"}'
|
||||
```
|
||||
|
||||
## 源码锚点
|
||||
|
||||
- 路由:`internal/app/app.go`
|
||||
- 认证:`internal/security/auth_middleware.go`
|
||||
- OpenAPI:`internal/handler/openapi.go`
|
||||
- 单代理:`internal/handler/eino_single_agent.go`
|
||||
- 多代理:`internal/handler/multi_agent.go`
|
||||
@@ -0,0 +1,171 @@
|
||||
# 架构说明
|
||||
|
||||
CyberStrikeAI 是一个以 Web 管理面为入口、以 Agent 和 MCP 工具为执行核心的安全测试编排平台。
|
||||
|
||||
## 总览
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
U["Web / Robot / API 用户"] --> R["Gin Router"]
|
||||
R --> H["Handlers"]
|
||||
H --> DB["SQLite"]
|
||||
H --> A["Agent / Multi-Agent"]
|
||||
A --> M["MCP Server"]
|
||||
M --> T["内置工具 / YAML 工具 / Skills FS"]
|
||||
M --> EM["外部 MCP"]
|
||||
A --> K["知识库检索"]
|
||||
H --> W["Workflow 图编排"]
|
||||
H --> C2["内置 C2"]
|
||||
H --> WS["WebShell"]
|
||||
H --> AU["Audit / Monitor"]
|
||||
```
|
||||
|
||||
## Web 层
|
||||
|
||||
入口在 `cmd/server/`,应用组装在 `internal/app/`。Web 使用 Gin:
|
||||
|
||||
- `web/templates/index.html`:主页面。
|
||||
- `web/templates/api-docs.html`:API 文档页面。
|
||||
- `web/static/js/`:各业务模块前端逻辑。
|
||||
- `web/static/css/`:样式。
|
||||
|
||||
路由注册集中在 `internal/app/app.go`。
|
||||
|
||||
## Handler 层
|
||||
|
||||
`internal/handler/` 按业务拆分:
|
||||
|
||||
- `agent.go`、`eino_single_agent.go`、`multi_agent.go`
|
||||
- `workflow.go`、`workflow_run.go`
|
||||
- `knowledge.go`
|
||||
- `webshell.go`
|
||||
- `c2.go`
|
||||
- `audit.go`
|
||||
- `monitor.go`
|
||||
- `project.go`
|
||||
- `vulnerability.go`
|
||||
- `config.go`
|
||||
- `openapi.go`
|
||||
|
||||
Handler 负责参数解析、权限中间件后的业务协调和 HTTP 响应。
|
||||
|
||||
## Agent 层
|
||||
|
||||
单代理和多代理主要在:
|
||||
|
||||
- `internal/agent/`
|
||||
- `internal/multiagent/`
|
||||
- `internal/agents/`
|
||||
- `agents/`
|
||||
|
||||
Eino ADK 提供单代理、Deep、Plan-Execute、Supervisor 等执行模式。多代理子 Agent 由 Markdown 文件定义。
|
||||
|
||||
## MCP 与工具
|
||||
|
||||
MCP 相关:
|
||||
|
||||
- `internal/mcp/`:Server、外部 MCP、连接恢复。
|
||||
- `internal/einomcp/`:Eino 与 MCP 工具适配。
|
||||
- `tools/`:YAML 命令工具。
|
||||
- `internal/app/*_tools.go`:Go 内置工具注册。
|
||||
|
||||
工具调用会进入监控记录,并可受 HITL 审批影响。
|
||||
|
||||
## Workflow
|
||||
|
||||
图编排在 `internal/workflow/`,HTTP 入口在 `internal/handler/workflow*.go`。它支持 start、agent、tool、condition、hitl、output、end 等节点。
|
||||
|
||||
详细使用见 [图编排使用说明](workflow-graph.md)。
|
||||
|
||||
## 知识库
|
||||
|
||||
知识库在 `internal/knowledge/`,包括:
|
||||
|
||||
- Markdown/文本内容管理。
|
||||
- chunk。
|
||||
- embedding。
|
||||
- SQLite 向量索引。
|
||||
- multi-query。
|
||||
- rerank。
|
||||
- 检索日志。
|
||||
|
||||
启用后会向 Agent 暴露知识检索工具。
|
||||
|
||||
## 数据层
|
||||
|
||||
`internal/database/` 封装 SQLite 访问,保存:
|
||||
|
||||
- 对话、消息、过程详情。
|
||||
- 分组。
|
||||
- 工具执行记录。
|
||||
- HITL 日志。
|
||||
- 知识库索引和检索日志。
|
||||
- WebShell、C2、项目、漏洞、批量任务等业务数据。
|
||||
|
||||
默认数据库文件:
|
||||
|
||||
- `data/conversations.db`
|
||||
- `data/knowledge.db`
|
||||
|
||||
## 安全与审计
|
||||
|
||||
`internal/security/` 提供认证、限流、Shell 执行和命令流处理。`internal/audit/` 和 `internal/monitor/` 分别负责平台审计和执行监控。
|
||||
|
||||
高风险模块包括:
|
||||
|
||||
- Terminal。
|
||||
- WebShell。
|
||||
- C2。
|
||||
- 外部 MCP。
|
||||
- 文件系统和 Shell Skills。
|
||||
|
||||
这些模块应结合角色、HITL 和部署隔离使用。
|
||||
|
||||
## 一次对话请求的真实路径
|
||||
|
||||
以 `/api/eino-agent/stream` 为例:
|
||||
|
||||
1. Gin 路由进入认证中间件。
|
||||
2. Handler 解析请求体、会话 ID、角色、附件和 WebShell 上下文。
|
||||
3. Agent 构建模型输入,包括历史消息、角色提示、项目事实、工具列表。
|
||||
4. Eino Runner 调用模型。
|
||||
5. 模型需要工具时走 MCP Tool。
|
||||
6. 工具调用前可能触发 HITL。
|
||||
7. 工具执行结果写入过程详情和监控。
|
||||
8. 模型继续推理并生成最终回答。
|
||||
9. SSE 将进度、工具事件、文本增量推给前端。
|
||||
10. 会话、消息、过程详情写入 SQLite。
|
||||
|
||||
这个路径解释了为什么问题可能出在很多层:认证、会话、模型、工具、HITL、MCP、数据库、SSE 或前端渲染。
|
||||
|
||||
## 横向模块依赖
|
||||
|
||||
几个模块不是独立页面,而是横向能力:
|
||||
|
||||
- Project facts:会被注入 Agent 上下文,影响多轮和跨对话判断。
|
||||
- HITL:插在工具调用前,影响所有 Agent/MCP 工具。
|
||||
- Monitor:记录工具执行,影响任务取消、复盘和通知。
|
||||
- Audit:记录平台管理动作,影响安全运营。
|
||||
- Tool search:影响模型看见哪些工具,而不仅仅是工具页面显示。
|
||||
|
||||
改这些模块时要看全局调用点,不要只测单个页面。
|
||||
|
||||
## 复杂度热点
|
||||
|
||||
维护时优先警惕:
|
||||
|
||||
- `internal/app/app.go`:组装所有服务,容易引入初始化顺序问题。
|
||||
- `internal/handler/config.go`:热应用配置,影响模型、知识库、C2、机器人和 MCP。
|
||||
- `internal/multiagent/`:中间件多,流式、重试、摘要和工具调用交错。
|
||||
- `internal/security/`:Shell 和认证是安全边界。
|
||||
- `internal/database/`:SQLite 结构演进必须兼容旧数据。
|
||||
|
||||
## 设计取舍
|
||||
|
||||
项目选择单体 Go 服务 + SQLite + 静态前端,是为了降低部署门槛。但代价是:
|
||||
|
||||
- 多实例横向扩展不天然成立,尤其 SQLite 写入和内存 session。
|
||||
- 运行态配置和本地文件强绑定,需要良好备份。
|
||||
- 高权限工具和 Web 管理面在同一进程内,部署隔离更重要。
|
||||
|
||||
这些不是缺陷,而是部署时必须理解的边界。
|
||||
@@ -0,0 +1,148 @@
|
||||
# 审计与监控
|
||||
|
||||
CyberStrikeAI 有两类常用可观测数据:平台操作审计和工具执行监控。二者用途不同,建议同时开启。
|
||||
|
||||
## 平台审计
|
||||
|
||||
配置:
|
||||
|
||||
```yaml
|
||||
audit:
|
||||
enabled: true
|
||||
retention_days: 15
|
||||
max_detail_bytes: 8192
|
||||
auth_failure_cooldown_seconds: 60
|
||||
```
|
||||
|
||||
审计记录覆盖登录、配置、资源管理等平台操作。它不会完整记录对话正文,也不逐条记录所有工具调用正文。
|
||||
|
||||
接口:
|
||||
|
||||
- `GET /api/audit/meta`
|
||||
- `GET /api/audit/summary`
|
||||
- `GET /api/audit/logs`
|
||||
- `GET /api/audit/logs/:id`
|
||||
- `GET /api/audit/logs/export`
|
||||
|
||||
建议关注:
|
||||
|
||||
- 登录失败和异常来源 IP。
|
||||
- 密码修改。
|
||||
- 配置修改。
|
||||
- 外部 MCP 增删改。
|
||||
- C2/WebShell/知识库等高风险资源操作。
|
||||
|
||||
## 工具执行监控
|
||||
|
||||
配置:
|
||||
|
||||
```yaml
|
||||
monitor:
|
||||
retention_days: 90
|
||||
```
|
||||
|
||||
工具执行监控用于查看 MCP 工具调用、命令状态、耗时、取消和结果摘要。
|
||||
|
||||
接口:
|
||||
|
||||
- `GET /api/monitor`
|
||||
- `GET /api/monitor/execution/:id`
|
||||
- `POST /api/monitor/execution/:id/cancel`
|
||||
- `DELETE /api/monitor/execution/:id`
|
||||
- `DELETE /api/monitor/executions`
|
||||
- `GET /api/monitor/stats`
|
||||
- `GET /api/monitor/calls-timeline`
|
||||
- `POST /api/monitor/executions/names`
|
||||
|
||||
## 通知摘要
|
||||
|
||||
接口:
|
||||
|
||||
- `GET /api/notifications/summary`
|
||||
- `POST /api/notifications/read`
|
||||
|
||||
通知用于提示待处理事项、未读状态或运行中任务概况。具体展示取决于前端页面。
|
||||
|
||||
## HITL 日志
|
||||
|
||||
HITL 决策日志独立管理:
|
||||
|
||||
- `GET /api/hitl/pending`
|
||||
- `GET /api/hitl/logs`
|
||||
- `GET /api/hitl/logs/:id`
|
||||
- `DELETE /api/hitl/logs`
|
||||
- `POST /api/hitl/decision`
|
||||
- `POST /api/hitl/dismiss`
|
||||
|
||||
建议将 HITL 日志与平台审计结合,用于复盘 Agent 为什么执行或没有执行某个工具。
|
||||
|
||||
## 保留策略
|
||||
|
||||
建议:
|
||||
|
||||
- 审计日志保留 15 到 90 天,按组织要求调整。
|
||||
- 工具执行记录保留 30 到 180 天。
|
||||
- C2、WebShell、上传附件和任务结果按项目周期单独清理。
|
||||
- 导出日志时注意脱敏和访问权限。
|
||||
|
||||
## 运维巡检
|
||||
|
||||
每周检查:
|
||||
|
||||
- 是否有异常登录失败。
|
||||
- 是否有未授权配置变更。
|
||||
- 长时间运行或失败率高的工具。
|
||||
- 外部 MCP 连接状态。
|
||||
- 数据库文件大小和磁盘空间。
|
||||
|
||||
每次演练结束:
|
||||
|
||||
- 导出必要审计证据。
|
||||
- 删除无用 WebShell/C2 会话和 payload。
|
||||
- 清理上传附件和临时工作区。
|
||||
- 归档报告、漏洞和项目事实。
|
||||
|
||||
## 审计和监控的边界
|
||||
|
||||
两者经常被混用,但语义不同:
|
||||
|
||||
- 审计回答“谁在平台上做了什么管理动作”。
|
||||
- 监控回答“工具调用运行得怎么样”。
|
||||
- HITL 日志回答“某个工具调用为什么被放行、修改或拒绝”。
|
||||
- 对话过程详情回答“Agent 当时如何推理和串联步骤”。
|
||||
|
||||
一次安全复盘通常要把四类信息合在一起看。只看审计,会漏掉具体工具输出;只看监控,会漏掉谁修改了配置。
|
||||
|
||||
## 关键事件解释
|
||||
|
||||
建议重点关注这些事件类型:
|
||||
|
||||
| 事件 | 为什么重要 |
|
||||
| --- | --- |
|
||||
| 登录失败 | 暴力尝试、密码泄露或误配置 |
|
||||
| 修改密码 | 所有旧 session 会被撤销,可能影响正在使用的人 |
|
||||
| 更新配置 | 可能改变模型、工具、C2、知识库、审计策略 |
|
||||
| 外部 MCP 变更 | 新工具可能拥有本机或远端执行能力 |
|
||||
| C2 listener/task | 直接影响授权目标和网络暴露面 |
|
||||
| WebShell 连接变更 | 可能引入真实业务系统执行通道 |
|
||||
| HITL 拒绝 | 说明 Agent 或用户请求触达风险边界 |
|
||||
|
||||
## 日志保留不是越久越好
|
||||
|
||||
安全工具日志往往包含目标、漏洞、路径、命令输出和组织内部信息。保留时间应平衡复盘价值与泄露风险:
|
||||
|
||||
- 短期演练:15-30 天。
|
||||
- 持续红队平台:90-180 天。
|
||||
- 合规要求:按组织规范归档,但导出后应加密。
|
||||
|
||||
如果没有专门日志平台,不要无限期保留 SQLite 中的所有明细。
|
||||
|
||||
## 源码锚点
|
||||
|
||||
- 审计服务:`internal/audit/service.go`
|
||||
- 审计脱敏:`internal/audit/sanitize.go`
|
||||
- 审计保留:`internal/audit/retention.go`
|
||||
- 审计接口:`internal/handler/audit.go`
|
||||
- 监控 reconcile:`internal/monitor/reconcile.go`
|
||||
- 监控接口:`internal/handler/monitor.go`
|
||||
- HITL 日志:`internal/handler/hitl_logs.go`
|
||||
@@ -0,0 +1,172 @@
|
||||
# 内置 C2 使用说明
|
||||
|
||||
内置 C2 用于授权环境中的会话管理、任务下发、payload 生成和结果回收。不使用时建议关闭。
|
||||
|
||||
```yaml
|
||||
c2:
|
||||
enabled: false
|
||||
```
|
||||
|
||||
## 功能组成
|
||||
|
||||
主要对象:
|
||||
|
||||
- Listener:监听器,负责接收会话。
|
||||
- Session:上线会话。
|
||||
- Task:下发给会话的任务。
|
||||
- Payload:生成的载荷或 one-liner。
|
||||
- Profile:通信配置模板。
|
||||
- Event:监听器、会话、任务产生的事件。
|
||||
- File:给 implant 下载或任务结果回收的文件。
|
||||
|
||||
Web API 前缀是 `/api/c2`。关闭 C2 时接口返回 `503 c2_disabled`。
|
||||
|
||||
## 监听器
|
||||
|
||||
常用接口:
|
||||
|
||||
- `GET /api/c2/listeners`
|
||||
- `POST /api/c2/listeners`
|
||||
- `POST /api/c2/listeners/:id/start`
|
||||
- `POST /api/c2/listeners/:id/stop`
|
||||
- `DELETE /api/c2/listeners/:id`
|
||||
|
||||
建议给监听器使用清晰命名,标明演练项目、网络区域和授权范围。
|
||||
|
||||
## 会话
|
||||
|
||||
常用接口:
|
||||
|
||||
- `GET /api/c2/sessions`
|
||||
- `GET /api/c2/sessions/:id`
|
||||
- `PUT /api/c2/sessions/:id/sleep`
|
||||
- `DELETE /api/c2/sessions/:id`
|
||||
|
||||
`sleep` 用于调整会话轮询间隔。间隔越短,交互越实时,但流量和暴露面更高。
|
||||
|
||||
## 任务
|
||||
|
||||
常用接口:
|
||||
|
||||
- `GET /api/c2/tasks`
|
||||
- `POST /api/c2/tasks`
|
||||
- `POST /api/c2/sessions/:id/tasks`
|
||||
- `POST /api/c2/tasks/:id/cancel`
|
||||
- `GET /api/c2/tasks/:id/wait`
|
||||
- `GET /api/c2/tasks/:id/result-file`
|
||||
|
||||
任务应和授权目标一致。高风险任务建议走 HITL,并在审计日志中保留操作痕迹。
|
||||
|
||||
## Payload
|
||||
|
||||
常用接口:
|
||||
|
||||
- `POST /api/c2/payloads/oneliner`
|
||||
- `POST /api/c2/payloads/build`
|
||||
- `GET /api/c2/payloads/:id/download`
|
||||
|
||||
生成前确认:
|
||||
|
||||
- 回连地址是否正确。
|
||||
- 平台和架构是否匹配。
|
||||
- 是否需要代理、sleep、profile。
|
||||
- 文件是否只在授权环境分发。
|
||||
|
||||
## 文件
|
||||
|
||||
常用接口:
|
||||
|
||||
- `POST /api/c2/files/upload`
|
||||
- `GET /api/c2/files`
|
||||
- `GET /api/c2/tasks/:id/result-file`
|
||||
|
||||
上传文件可供 implant 下载。结果文件可能包含敏感信息,应按项目保密级别保存和清理。
|
||||
|
||||
## MCP 工具
|
||||
|
||||
C2 启用后会注册相关 MCP 工具,供 Agent 管理监听器、会话、任务、payload 等。建议:
|
||||
|
||||
- 不把 C2 工具加入全局免审批白名单。
|
||||
- 在角色提示词中限制项目、目标、任务类型。
|
||||
- 对执行命令、上传文件、生成 payload 的步骤开启人工审批。
|
||||
|
||||
## 安全建议
|
||||
|
||||
- 仅在授权环境启用。
|
||||
- 不在公网暴露管理 Web。
|
||||
- Listener 暴露端口与 Web 管理端口分离。
|
||||
- 定期清理会话、任务、payload 和事件。
|
||||
- 演练结束后关闭监听器并删除无用 payload。
|
||||
- 保留必要审计证据,但不要长期保存敏感输出。
|
||||
|
||||
## 排错
|
||||
|
||||
监听器无法启动:
|
||||
|
||||
- 端口被占用。
|
||||
- 权限不足,低端口需要额外权限。
|
||||
- 防火墙或安全组未放行。
|
||||
|
||||
会话不上线:
|
||||
|
||||
- payload 回连地址错误。
|
||||
- 目标无法访问监听器。
|
||||
- TLS/Profile 不匹配。
|
||||
- 被安全产品阻断。
|
||||
|
||||
任务无结果:
|
||||
|
||||
- 会话 sleep 较长。
|
||||
- 会话已离线。
|
||||
- 命令在目标端卡住。
|
||||
- 结果过大,需要通过结果文件下载。
|
||||
|
||||
## 生命周期视角
|
||||
|
||||
C2 的正确使用不是“创建 listener 然后下命令”,而是一个生命周期:
|
||||
|
||||
1. 授权确认:项目、目标、时间窗口、允许动作。
|
||||
2. Profile 设计:通信方式、sleep、回连地址、文件通道。
|
||||
3. Listener 启动:确认端口、网络路径和日志。
|
||||
4. Payload 生成:记录 hash、用途、投递方式。
|
||||
5. Session 接入:确认目标身份、权限和环境。
|
||||
6. Task 下发:只执行与授权目标一致的任务。
|
||||
7. 结果归档:必要输出写入项目事实或报告。
|
||||
8. 清理:停止 listener、删除 payload、清理 session/task/event。
|
||||
|
||||
跳过前两步会导致后续每个操作都不可审计。
|
||||
|
||||
## 任务分级
|
||||
|
||||
| 等级 | 示例 | 审批建议 |
|
||||
| --- | --- | --- |
|
||||
| L1 只读识别 | `whoami`、主机名、当前目录 | 可由审计 Agent 放行 |
|
||||
| L2 环境枚举 | 网络接口、进程、用户组 | 建议人工或严格审计 |
|
||||
| L3 文件访问 | 读取配置、下载结果文件 | 人工确认目标和路径 |
|
||||
| L4 执行变更 | 上传文件、修改 sleep、运行脚本 | 人工审批 |
|
||||
| L5 持久化/横向/破坏 | 自启、凭证、删除、加密、扩散 | 默认拒绝,除非授权明确 |
|
||||
|
||||
把这个分级写进 HITL 提示词,比单纯“危险则拒绝”更可操作。
|
||||
|
||||
## 事件复盘
|
||||
|
||||
一次 C2 操作复盘至少回答:
|
||||
|
||||
- 哪个 listener 接收了哪个 session?
|
||||
- payload 是谁生成的,什么时候生成的?
|
||||
- session 属于哪个授权目标?
|
||||
- 下发了哪些 task?
|
||||
- task 输出是否写入报告或项目事实?
|
||||
- 是否停止 listener 并清理 payload?
|
||||
|
||||
如果这些问题答不上来,说明 C2 过程管理还不够闭环。
|
||||
|
||||
## 源码锚点
|
||||
|
||||
- C2 Manager:`internal/c2/manager.go`
|
||||
- Listener:`internal/c2/listener.go`
|
||||
- HTTP Listener:`internal/c2/listener_http.go`
|
||||
- TCP Listener:`internal/c2/listener_tcp.go`
|
||||
- Payload:`internal/c2/payload_builder.go`
|
||||
- Handler:`internal/handler/c2.go`
|
||||
- MCP 工具:`internal/app/c2_tools.go`
|
||||
@@ -0,0 +1,194 @@
|
||||
# 配置画像
|
||||
|
||||
[English](../en-US/configuration-profiles.md)
|
||||
|
||||
本文给出几套常用配置画像。它们不是完整 `config.yaml`,而是部署时最容易影响安全和可用性的关键段落。
|
||||
|
||||
## 本地开发画像
|
||||
|
||||
目标:方便调试,允许较多本地能力。
|
||||
|
||||
常用启动:
|
||||
|
||||
```bash
|
||||
chmod +x run.sh && ./run.sh
|
||||
```
|
||||
|
||||
```yaml
|
||||
server:
|
||||
host: 127.0.0.1
|
||||
port: 8080
|
||||
tls_enabled: true
|
||||
tls_auto_self_sign: true
|
||||
auth:
|
||||
password: "dev-only-change-me"
|
||||
audit:
|
||||
enabled: true
|
||||
retention_days: 7
|
||||
c2:
|
||||
enabled: false
|
||||
multi_agent:
|
||||
enabled: true
|
||||
eino_skills:
|
||||
filesystem_tools: true
|
||||
```
|
||||
|
||||
适用:
|
||||
|
||||
- 本地功能开发。
|
||||
- 调试前端和 Handler。
|
||||
- 调试 Skills、本地文件工具。
|
||||
|
||||
不适用:
|
||||
|
||||
- 多人共享。
|
||||
- 公网访问。
|
||||
|
||||
## 内网团队画像
|
||||
|
||||
目标:团队共享,保留审计,限制高风险能力。
|
||||
|
||||
```yaml
|
||||
server:
|
||||
host: 127.0.0.1
|
||||
port: 8080
|
||||
tls_enabled: false
|
||||
auth:
|
||||
password: "<long-random-password>"
|
||||
audit:
|
||||
enabled: true
|
||||
retention_days: 30
|
||||
monitor:
|
||||
retention_days: 90
|
||||
c2:
|
||||
enabled: false
|
||||
mcp:
|
||||
enabled: false
|
||||
hitl:
|
||||
default_reviewer: human
|
||||
tool_whitelist: [read_file, glob, grep, tool_search]
|
||||
```
|
||||
|
||||
配合:
|
||||
|
||||
- Nginx/Traefik 终止 HTTPS。
|
||||
- 反向代理 IP 白名单。
|
||||
- 定期备份 `data/`。
|
||||
|
||||
## 只启用知识库画像
|
||||
|
||||
目标:把 CyberStrikeAI 作为知识增强助手,尽量关闭攻击面。
|
||||
|
||||
```yaml
|
||||
c2:
|
||||
enabled: false
|
||||
mcp:
|
||||
enabled: false
|
||||
knowledge:
|
||||
enabled: true
|
||||
base_path: knowledge_base
|
||||
retrieval:
|
||||
top_k: 5
|
||||
similarity_threshold: 0.4
|
||||
multi_agent:
|
||||
eino_skills:
|
||||
filesystem_tools: false
|
||||
```
|
||||
|
||||
建议:
|
||||
|
||||
- 角色只绑定知识库和只读工具。
|
||||
- 禁用外部 MCP。
|
||||
- 不保存真实客户敏感材料。
|
||||
|
||||
## 高审计生产画像
|
||||
|
||||
目标:生产红队或长期安全平台。
|
||||
|
||||
```yaml
|
||||
auth:
|
||||
password: "<managed-secret>"
|
||||
session_duration_hours: 8
|
||||
audit:
|
||||
enabled: true
|
||||
retention_days: 90
|
||||
max_detail_bytes: 8192
|
||||
monitor:
|
||||
retention_days: 180
|
||||
hitl:
|
||||
default_reviewer: human
|
||||
retention_days: 180
|
||||
tool_whitelist: [read_file, glob, grep, tool_search]
|
||||
c2:
|
||||
enabled: false
|
||||
multi_agent:
|
||||
eino_callbacks:
|
||||
enabled: true
|
||||
mode: log_only
|
||||
sse_trace_to_client: false
|
||||
```
|
||||
|
||||
配合:
|
||||
|
||||
- 反向代理认证。
|
||||
- 独立运行用户。
|
||||
- 日志采集。
|
||||
- 备份加密。
|
||||
- 明确项目结束清理流程。
|
||||
|
||||
## C2 演练画像
|
||||
|
||||
目标:只在授权演练窗口临时启用 C2。
|
||||
|
||||
```yaml
|
||||
c2:
|
||||
enabled: true
|
||||
hitl:
|
||||
default_reviewer: human
|
||||
tool_whitelist: [read_file, glob, grep, tool_search]
|
||||
audit:
|
||||
enabled: true
|
||||
monitor:
|
||||
retention_days: 180
|
||||
```
|
||||
|
||||
操作要求:
|
||||
|
||||
- 演练前确认授权范围。
|
||||
- Listener 端口和 Web 管理端口分离。
|
||||
- 演练结束执行 C2 清理 Runbook。
|
||||
- 结束后恢复 `c2.enabled: false`。
|
||||
|
||||
## 外部 MCP 自动化画像
|
||||
|
||||
目标:接入可信的内部工具服务。
|
||||
|
||||
```yaml
|
||||
external_mcp:
|
||||
servers: {}
|
||||
multi_agent:
|
||||
eino_middleware:
|
||||
tool_search_enable: true
|
||||
tool_search_min_tools: 20
|
||||
hitl:
|
||||
default_reviewer: audit_agent
|
||||
tool_whitelist: [read_file, glob, grep, tool_search]
|
||||
```
|
||||
|
||||
建议:
|
||||
|
||||
- 每个 MCP 工具都写清楚 schema。
|
||||
- 高风险 MCP 工具不进白名单。
|
||||
- stdio MCP 用独立工作目录。
|
||||
- HTTP MCP 必须有认证。
|
||||
|
||||
## 画像选择决策
|
||||
|
||||
| 需求 | 选择 |
|
||||
| --- | --- |
|
||||
| 单人开发 | 本地开发画像 |
|
||||
| 多人内网使用 | 内网团队画像 |
|
||||
| 文档/知识问答 | 只启用知识库画像 |
|
||||
| 长期生产平台 | 高审计生产画像 |
|
||||
| 授权 C2 演练 | C2 演练画像 |
|
||||
| 接内部工具平台 | 外部 MCP 自动化画像 |
|
||||
@@ -0,0 +1,275 @@
|
||||
# 配置参考
|
||||
|
||||
CyberStrikeAI 的主配置文件是 `config.yaml`。大多数配置也可以在 Web 的“系统设置”中修改,保存后再应用。生产环境中,建议把敏感值放在受控配置系统中,并限制 `config.yaml` 的文件权限。
|
||||
|
||||
## 基础配置
|
||||
|
||||
```yaml
|
||||
version: "v1.6.51"
|
||||
server:
|
||||
host: 0.0.0.0
|
||||
port: 8080
|
||||
tls_enabled: true
|
||||
tls_auto_self_sign: true
|
||||
auth:
|
||||
password: "change-me"
|
||||
session_duration_hours: 12
|
||||
log:
|
||||
level: info
|
||||
output: stdout
|
||||
```
|
||||
|
||||
- `version`:前端展示版本。
|
||||
- `server.host/port`:Web 服务监听地址和端口。
|
||||
- `server.tls_*`:HTTPS 配置。生产环境建议使用 `tls_cert_path` 和 `tls_key_path`。
|
||||
- `auth.password`:Web 登录密码,必须改为强密码。
|
||||
- `auth.session_duration_hours`:登录会话有效期。
|
||||
- `log.output`:可以是 `stdout`、`stderr` 或文件路径。
|
||||
|
||||
## 模型配置
|
||||
|
||||
```yaml
|
||||
openai:
|
||||
provider: openai
|
||||
base_url: https://api.openai.com/v1
|
||||
api_key: sk-...
|
||||
model: gpt-4.1
|
||||
max_total_tokens: 120000
|
||||
reasoning:
|
||||
mode: on
|
||||
effort: high
|
||||
allow_client_reasoning: true
|
||||
profile: openai_compat
|
||||
```
|
||||
|
||||
- `provider`:`openai` 表示 OpenAI 兼容接口;`claude` 会桥接到 Anthropic Claude Messages API。
|
||||
- `base_url/api_key/model`:主模型配置。
|
||||
- `max_total_tokens`:上下文压缩、攻击链构建、多代理摘要等共用的总预算。
|
||||
- `reasoning`:控制推理扩展字段。不同网关支持差异较大,异常时先尝试 `mode: off`。
|
||||
|
||||
## Agent
|
||||
|
||||
```yaml
|
||||
agent:
|
||||
max_iterations: 12000
|
||||
tool_timeout_minutes: 60
|
||||
shell_no_output_timeout_seconds: 1200
|
||||
workspace_root_dir: ""
|
||||
system_prompt_path: ""
|
||||
```
|
||||
|
||||
- `max_iterations`:单代理、多代理主执行器和子代理的默认迭代上限。
|
||||
- `tool_timeout_minutes`:单次工具最长运行时间。
|
||||
- `shell_no_output_timeout_seconds`:Shell 长时间无输出时终止。
|
||||
- `workspace_root_dir`:会话工作区根目录,建议不要设置到系统 `/tmp`。
|
||||
- `system_prompt_path`:单代理系统提示词覆盖文件。
|
||||
|
||||
## HITL
|
||||
|
||||
```yaml
|
||||
hitl:
|
||||
default_reviewer: audit_agent
|
||||
retention_days: 90
|
||||
tool_whitelist: [read_file, list_dir, glob, grep, tool_search]
|
||||
audit_model:
|
||||
provider: ""
|
||||
base_url: ""
|
||||
api_key: ""
|
||||
model: ""
|
||||
```
|
||||
|
||||
- `default_reviewer`:`human` 或 `audit_agent`。
|
||||
- `tool_whitelist`:全局免审批工具列表,会与会话白名单合并。
|
||||
- `audit_model`:审计 Agent 独立模型;留空复用主模型。
|
||||
- `audit_agent_prompt` / `audit_agent_prompt_review_edit`:可覆盖默认审批策略。
|
||||
|
||||
更多策略见 [人机协同最佳实践](hitl-best-practices.md)。
|
||||
|
||||
## 多代理
|
||||
|
||||
```yaml
|
||||
multi_agent:
|
||||
enabled: true
|
||||
robot_default_agent_mode: eino_single
|
||||
batch_use_multi_agent: false
|
||||
eino_skills:
|
||||
disable: false
|
||||
filesystem_tools: true
|
||||
skill_tool_name: skill
|
||||
```
|
||||
|
||||
支持模式:
|
||||
|
||||
- `eino_single`:Eino 单代理。
|
||||
- `deep`:DeepAgent 风格多代理。
|
||||
- `plan_execute`:规划、执行、重规划。
|
||||
- `supervisor`:主管代理转交子代理。
|
||||
|
||||
`agents_dir` 指向 Markdown 子代理目录。单个代理可在 front matter 中设置 `tools`、`bind_role`、`max_iterations`。
|
||||
|
||||
## 工具与 MCP
|
||||
|
||||
```yaml
|
||||
security:
|
||||
tools_dir: tools
|
||||
tool_description_mode: full
|
||||
mcp:
|
||||
enabled: false
|
||||
host: 0.0.0.0
|
||||
port: 8081
|
||||
auth_header: "X-MCP-Token"
|
||||
auth_header_value: ""
|
||||
external_mcp:
|
||||
servers: {}
|
||||
```
|
||||
|
||||
- `security.tools_dir`:内置工具 YAML 目录。
|
||||
- `tool_description_mode`:`short` 更省 token,`full` 更完整。
|
||||
- `mcp.enabled`:是否启动独立 HTTP MCP 服务。
|
||||
- `mcp.auth_header_value`:外部调用 MCP 时的共享密钥,生产环境必须设置。
|
||||
- `external_mcp.servers`:外部 MCP 联邦配置。
|
||||
|
||||
工具 YAML 规则见 `tools/README.md`。
|
||||
|
||||
## 知识库
|
||||
|
||||
```yaml
|
||||
knowledge:
|
||||
enabled: false
|
||||
base_path: knowledge_base
|
||||
embedding:
|
||||
provider: openai
|
||||
model: text-embedding-v4
|
||||
base_url: ""
|
||||
api_key: ""
|
||||
retrieval:
|
||||
top_k: 5
|
||||
similarity_threshold: 0.4
|
||||
indexing:
|
||||
chunk_size: 512
|
||||
chunk_overlap: 50
|
||||
batch_size: 10
|
||||
```
|
||||
|
||||
启用后会注册知识库检索工具,并开放管理接口。详细说明见 [知识库](knowledge-base.md)。
|
||||
|
||||
## 数据库
|
||||
|
||||
```yaml
|
||||
database:
|
||||
path: data/conversations.db
|
||||
knowledge_db_path: data/knowledge.db
|
||||
```
|
||||
|
||||
默认使用 SQLite。`knowledge_db_path` 为空时可复用会话数据库;独立文件更便于迁移知识库。
|
||||
|
||||
## 审计与监控
|
||||
|
||||
```yaml
|
||||
audit:
|
||||
enabled: true
|
||||
retention_days: 15
|
||||
max_detail_bytes: 8192
|
||||
monitor:
|
||||
retention_days: 90
|
||||
```
|
||||
|
||||
- `audit` 记录平台操作,不记录对话正文和每次工具调用正文。
|
||||
- `monitor` 管理工具执行记录保留时间。
|
||||
|
||||
## C2、WebShell、项目
|
||||
|
||||
```yaml
|
||||
c2:
|
||||
enabled: true
|
||||
project:
|
||||
enabled: true
|
||||
fact_index_max_runes: 65000
|
||||
```
|
||||
|
||||
- `c2.enabled`:关闭后不启动 C2 监听器,也不注册 C2 MCP 工具。
|
||||
- WebShell 连接配置存 SQLite,没有单独的主配置开关。
|
||||
- `project` 控制跨对话事实黑板注入预算。
|
||||
|
||||
## 机器人
|
||||
|
||||
`robots` 支持个人微信 iLink、企业微信、钉钉、飞书、Telegram、Slack、Discord、QQ。详细配置步骤见 [机器人使用说明](robot.md)。
|
||||
|
||||
## 配置修改建议
|
||||
|
||||
- 先在测试环境验证模型、MCP、知识库和高风险工具。
|
||||
- 改动 `tools_dir`、`roles_dir`、`skills_dir`、`agents_dir` 后,检查 Web 页面是否能列出对应资源。
|
||||
- 生产环境避免开启不需要的 C2、WebShell、终端和外部 MCP。
|
||||
- 修改敏感配置后,检查审计页面是否有异常登录或配置变更记录。
|
||||
|
||||
## 配置应用机制
|
||||
|
||||
配置不是所有字段都同等“热更新”。`/api/config/apply` 会做一组协调动作:更新模型配置、工具描述模式、重新注册部分 MCP 工具、初始化或更新知识库、重启机器人连接、按配置启停 C2。这个逻辑在 `internal/handler/config.go` 中由 `ConfigHandler` 协调。
|
||||
|
||||
实务判断:
|
||||
|
||||
| 配置段 | 应用后通常立即生效 | 需要额外动作 |
|
||||
| --- | --- | --- |
|
||||
| `openai` | 新请求使用新模型配置 | 旧的流式请求不会被强制切换 |
|
||||
| `agent.max_iterations` | 新 Agent 任务生效 | 已运行任务按启动时状态继续 |
|
||||
| `security.tool_description_mode` | 工具重新暴露时生效 | 模型已有上下文不会回滚 |
|
||||
| `hitl.tool_whitelist` | 新工具调用审批判断生效 | 已挂起审批不自动重判 |
|
||||
| `knowledge.enabled` | 会尝试初始化/更新组件 | 启用后仍需扫描和索引 |
|
||||
| `knowledge.embedding` | 检索器/索引器配置更新 | 已有向量通常需要重建索引 |
|
||||
| `robots` | 会触发连接重启 | 平台回调配置仍需在平台侧正确 |
|
||||
| `c2.enabled` | 会协调 C2 runtime | 已暴露端口和会话要人工确认 |
|
||||
| `server.port/tls` | 通常需要重启进程 | 监听地址不是普通热更新 |
|
||||
|
||||
## 配置优先级和派生关系
|
||||
|
||||
几个字段有“留空复用”的关系:
|
||||
|
||||
- `vision.api_key/base_url/provider` 留空时复用 `openai`。
|
||||
- `hitl.audit_model` 留空时复用 `openai`。
|
||||
- `knowledge.embedding.base_url/api_key` 留空时复用主模型或 embedding 默认配置。
|
||||
- `knowledge.retrieval.rerank.base_url/api_key` 留空时复用 embedding/openai。
|
||||
- `database.knowledge_db_path` 留空时可以复用主会话数据库,但独立文件更利于备份。
|
||||
|
||||
这类配置排障时不要只看子配置段,也要看它会回落到哪个上级配置。
|
||||
|
||||
## 参数取值建议
|
||||
|
||||
| 参数 | 保守值 | 激进值 | 判断依据 |
|
||||
| --- | --- | --- | --- |
|
||||
| `agent.tool_timeout_minutes` | 10-30 | 60+ | 扫描工具是否常跑长任务 |
|
||||
| `shell_no_output_timeout_seconds` | 300-600 | 1200+ | 工具是否长时间静默 |
|
||||
| `knowledge.indexing.batch_size` | 5-10 | 20+ | embedding 服务批量限制 |
|
||||
| `knowledge.indexing.rate_limit_delay_ms` | 300-800 | 0-100 | 服务商 RPM 和 429 情况 |
|
||||
| `retrieval.top_k` | 3-5 | 8-12 | 内容质量和上下文预算 |
|
||||
| `similarity_threshold` | 0.35-0.45 | 0.5+ | 召回优先还是精度优先 |
|
||||
| `audit.retention_days` | 15-30 | 90+ | 合规要求和磁盘空间 |
|
||||
| `monitor.retention_days` | 30-90 | 180+ | 是否需要长周期复盘 |
|
||||
|
||||
## 变更前后验证模板
|
||||
|
||||
修改配置前记录:
|
||||
|
||||
```text
|
||||
变更目的:
|
||||
涉及配置段:
|
||||
预期影响:
|
||||
回滚方式:
|
||||
验证接口:
|
||||
```
|
||||
|
||||
修改后验证:
|
||||
|
||||
```bash
|
||||
curl -k https://127.0.0.1:8080/api/auth/validate \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
再按配置类型验证模型、工具、知识库、C2 或机器人。不要只看 Web 保存成功提示。
|
||||
|
||||
## 源码锚点
|
||||
|
||||
- 配置结构:`internal/config/config.go`
|
||||
- 环境变量展开:`internal/config/envexpand.go`
|
||||
- Web 配置接口:`internal/handler/config.go`
|
||||
- 路由注册:`internal/app/app.go`
|
||||
- C2 配置协调:`internal/app/c2_lifecycle.go`
|
||||
@@ -0,0 +1,115 @@
|
||||
# 贡献规范
|
||||
|
||||
[English](../en-US/contributing-guide.md)
|
||||
|
||||
本文定义向 CyberStrikeAI 增加功能、接口、工具、前端页面或文档时的基本要求。
|
||||
|
||||
## 总原则
|
||||
|
||||
- 新功能要有文档入口。
|
||||
- 新 API 要更新 OpenAPI。
|
||||
- 新前端文案要补中英文 i18n。
|
||||
- 新配置要说明是否支持热应用。
|
||||
- 新高风险工具要说明 HITL 策略。
|
||||
- 新数据库字段要兼容旧库。
|
||||
- 新长任务要有状态、取消或恢复策略。
|
||||
|
||||
## 新增 API Checklist
|
||||
|
||||
- Handler 参数校验明确。
|
||||
- 错误响应包含稳定 `error` 和可读 `message`。
|
||||
- 接口受认证保护,除非明确是平台回调。
|
||||
- 修改类接口写审计。
|
||||
- 长任务写监控或任务状态。
|
||||
- 更新 `internal/handler/openapi.go`。
|
||||
- 更新 API 文档或 Recipe。
|
||||
- 增加 Handler 测试。
|
||||
|
||||
## 新增配置 Checklist
|
||||
|
||||
- `config.Config` 结构体有字段。
|
||||
- `config.yaml` 示例有注释。
|
||||
- 省略字段时有安全默认值。
|
||||
- 旧配置能启动。
|
||||
- 说明是否热应用。
|
||||
- Web 设置页不会误删未知字段。
|
||||
- 如影响高风险能力,更新安全文档。
|
||||
|
||||
## 新增工具 Checklist
|
||||
|
||||
适用于 YAML 工具和 Go 内置 MCP 工具。
|
||||
|
||||
- 工具名稳定、具体、避免重名。
|
||||
- `short_description` 能被 `tool_search` 搜到。
|
||||
- 输入 schema 明确,不用裸 `cmd` 包所有行为。
|
||||
- 输出可读且结构稳定。
|
||||
- 超时和错误路径可控。
|
||||
- 高风险操作不进全局白名单。
|
||||
- 文档说明使用场景和风险。
|
||||
|
||||
## 新增前端页面 Checklist
|
||||
|
||||
- 复用现有 `apiFetch`、modal、通知和状态样式。
|
||||
- 所有可见文案补 `zh-CN.json` 和 `en-US.json`。
|
||||
- 有 loading、empty、error 状态。
|
||||
- 删除/高风险操作有确认。
|
||||
- 长文本和英文按钮不溢出。
|
||||
- 浏览器控制台无错误。
|
||||
|
||||
## 新增数据库变更 Checklist
|
||||
|
||||
- 迁移幂等。
|
||||
- 旧库可升级。
|
||||
- 字段默认值合理。
|
||||
- 大表索引谨慎。
|
||||
- 测试空库和旧库。
|
||||
- 发布说明提醒备份。
|
||||
|
||||
## 新增高风险能力 Checklist
|
||||
|
||||
高风险包括:Shell、WebShell、C2、外部 MCP 写入/执行、凭证访问、批量扫描。
|
||||
|
||||
必须回答:
|
||||
|
||||
- 谁能调用?
|
||||
- 是否需要 HITL?
|
||||
- 审计记录什么?
|
||||
- 如何取消?
|
||||
- 如何清理?
|
||||
- 如何禁用?
|
||||
- 默认是否关闭?
|
||||
|
||||
## 文档要求
|
||||
|
||||
每个重要功能至少补:
|
||||
|
||||
- 用途。
|
||||
- 配置。
|
||||
- 操作流程。
|
||||
- 风险边界。
|
||||
- 排错。
|
||||
- 源码锚点。
|
||||
|
||||
中英文文档要保持文件名一致,分别放在:
|
||||
|
||||
```text
|
||||
docs/zh-CN/
|
||||
docs/en-US/
|
||||
```
|
||||
|
||||
更新导航:
|
||||
|
||||
- `docs/README.md`
|
||||
- `docs/zh-CN/README.md`
|
||||
- `docs/en-US/README.md`
|
||||
|
||||
## Review 关注点
|
||||
|
||||
代码评审优先看:
|
||||
|
||||
- 行为回归。
|
||||
- 安全边界。
|
||||
- 旧数据兼容。
|
||||
- 错误处理。
|
||||
- 测试缺口。
|
||||
- 文档和 OpenAPI 是否同步。
|
||||
@@ -0,0 +1,249 @@
|
||||
# 部署指南
|
||||
|
||||
本文说明 CyberStrikeAI 的常见部署方式。生产环境部署前,请先阅读 [安全模型](security-model.md),确认授权范围、认证、HITL、审计和高风险功能开关。
|
||||
|
||||
## 部署前准备
|
||||
|
||||
基础依赖:
|
||||
|
||||
- Go:用于源码运行或构建二进制。
|
||||
- Python:部分 MCP 服务或工具脚本需要 Python 运行环境。
|
||||
- SQLite:默认使用文件型数据库,无需单独服务。
|
||||
- 安全工具:`tools/` 中的 YAML 只是工具定义,实际命令如 `nmap`、`sqlmap`、`nuclei` 仍需安装到系统 PATH。
|
||||
- 模型服务:需要 OpenAI 兼容 API,或配置 `openai.provider: claude` 走 Claude 桥接。
|
||||
|
||||
建议目录:
|
||||
|
||||
```text
|
||||
CyberStrikeAI-main/
|
||||
config.yaml
|
||||
data/
|
||||
tools/
|
||||
roles/
|
||||
skills/
|
||||
agents/
|
||||
knowledge_base/
|
||||
```
|
||||
|
||||
`data/`、`config.yaml`、自定义 `tools/roles/skills/agents/knowledge_base` 是最重要的持久化内容,升级前应备份。
|
||||
|
||||
## 快速启动
|
||||
|
||||
仓库提供 `run.sh`,适合本地体验和小规模部署:
|
||||
|
||||
```bash
|
||||
chmod +x run.sh && ./run.sh
|
||||
```
|
||||
|
||||
默认配置中 `server.tls_enabled: true` 且 `tls_auto_self_sign: true`,访问地址通常是:
|
||||
|
||||
```text
|
||||
https://127.0.0.1:8080/
|
||||
```
|
||||
|
||||
自签证书会触发浏览器安全提示,这是本地测试的正常现象。生产环境建议配置真实证书。
|
||||
|
||||
`run.sh` 是最常用的启动入口,适合:
|
||||
|
||||
- 本机体验。
|
||||
- 开发调试。
|
||||
- 小团队临时内网使用。
|
||||
- 升级后快速验证新版是否能启动。
|
||||
|
||||
如果需要长期运行、开机自启、日志托管或进程崩溃自动恢复,建议改用 systemd 托管二进制。
|
||||
|
||||
## 源码运行
|
||||
|
||||
适合开发调试:
|
||||
|
||||
```bash
|
||||
go run ./cmd/server --config config.yaml
|
||||
```
|
||||
|
||||
如果依赖下载较慢,可以先配置 Go 代理:
|
||||
|
||||
```bash
|
||||
go env -w GOPROXY=https://goproxy.cn,direct
|
||||
```
|
||||
|
||||
## 构建二进制
|
||||
|
||||
```bash
|
||||
go build -o cyberstrike-ai ./cmd/server
|
||||
./cyberstrike-ai --config config.yaml
|
||||
```
|
||||
|
||||
交付二进制时仍需要携带:
|
||||
|
||||
- `web/templates/`
|
||||
- `web/static/`
|
||||
- `tools/`
|
||||
- `roles/`
|
||||
- `skills/`
|
||||
- `agents/`
|
||||
- `config.yaml`
|
||||
|
||||
## HTTPS
|
||||
|
||||
本地测试可以使用自签:
|
||||
|
||||
```yaml
|
||||
server:
|
||||
tls_enabled: true
|
||||
tls_auto_self_sign: true
|
||||
```
|
||||
|
||||
生产环境建议使用证书文件:
|
||||
|
||||
```yaml
|
||||
server:
|
||||
host: 0.0.0.0
|
||||
port: 8080
|
||||
tls_enabled: true
|
||||
tls_cert_path: /etc/letsencrypt/live/example.com/fullchain.pem
|
||||
tls_key_path: /etc/letsencrypt/live/example.com/privkey.pem
|
||||
```
|
||||
|
||||
启用 TLS 后,同端口 HTTP 请求默认会 308 跳转到 HTTPS。若前面有反向代理负责 TLS,可以关闭应用内 TLS,在代理层处理 HTTPS。
|
||||
|
||||
## 反向代理
|
||||
|
||||
Nginx 示例:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name cyberstrike.example.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/cyberstrike.example.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/cyberstrike.example.com/privkey.pem;
|
||||
|
||||
client_max_body_size 200m;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8080;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_buffering off;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`proxy_buffering off` 对 SSE 流式输出和 WebSocket 终端更友好。
|
||||
|
||||
## systemd
|
||||
|
||||
示例服务:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=CyberStrikeAI
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/opt/CyberStrikeAI
|
||||
ExecStart=/opt/CyberStrikeAI/cyberstrike-ai --config /opt/CyberStrikeAI/config.yaml
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
Environment=GIN_MODE=release
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
启用:
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now cyberstrikeai
|
||||
sudo journalctl -u cyberstrikeai -f
|
||||
```
|
||||
|
||||
## 数据与备份
|
||||
|
||||
重点备份:
|
||||
|
||||
- `config.yaml`
|
||||
- `data/conversations.db`
|
||||
- `data/knowledge.db`
|
||||
- `data/eino-checkpoints/`
|
||||
- 自定义 `tools/roles/skills/agents/knowledge_base`
|
||||
- 上传文件目录 `chat_uploads/`
|
||||
|
||||
SQLite 热备份时最好先停止服务,或至少复制 `*.db`、`*.db-wal`、`*.db-shm` 三类文件。
|
||||
|
||||
## 升级
|
||||
|
||||
推荐流程:
|
||||
|
||||
1. 停止服务。
|
||||
2. 备份 `config.yaml`、`data/` 和自定义目录。
|
||||
3. 拉取或替换新版代码/二进制。
|
||||
4. 保留原配置,按新版 `config.yaml` 示例补新增字段。
|
||||
5. 启动服务,检查登录、模型测试、工具列表、知识库状态。
|
||||
|
||||
仓库提供 `upgrade.sh`,适合无兼容性问题的快速升级;生产环境仍建议先备份再运行。
|
||||
|
||||
## 回滚
|
||||
|
||||
回滚时同时恢复:
|
||||
|
||||
- 上一版本二进制或代码。
|
||||
- 升级前的 `config.yaml`。
|
||||
- 升级前的 `data/`。
|
||||
|
||||
如果新版已经写入数据库结构变更,单独回滚二进制可能不够,建议整体恢复备份。
|
||||
|
||||
## 生产部署决策表
|
||||
|
||||
| 场景 | 推荐部署 | 关键配置 | 不建议 |
|
||||
| --- | --- | --- | --- |
|
||||
| 单人本机测试 | `./run.sh` + 自签 HTTPS | `tls_auto_self_sign: true` | 暴露公网 |
|
||||
| 小团队内网 | 二进制 + systemd + 内网 HTTPS | 强密码、审计、备份、限制来源 IP | 所有人共用弱密码 |
|
||||
| 生产红队平台 | 反向代理 + 独立运行用户 + 日志采集 | 真实证书、反向代理认证、C2 按需启用 | Web 管理面直连公网 |
|
||||
| 只做知识库/对话 | 关闭 C2,禁用不需要的外部 MCP | `c2.enabled: false` | 默认开启所有高风险模块 |
|
||||
| 多工具自动化 | 独立工作目录 + HITL + 工具白名单 | `workspace_root_dir`、`hitl`、`monitor` | 让 Agent 拥有全局 Shell 权限且免审批 |
|
||||
|
||||
## 运行时文件分层
|
||||
|
||||
部署时最容易出问题的是“代码、配置、运行数据混在一起”。建议按下面方式理解:
|
||||
|
||||
- 可替换:二进制、`web/`、默认 `tools/roles/skills/agents/docs`。
|
||||
- 必须保留:`config.yaml`、`data/`、自定义工具/角色/技能/子代理、`knowledge_base/`、`chat_uploads/`。
|
||||
- 可清理但要谨慎:`data/eino-checkpoints/`、临时 workspace、旧 payload、旧工具执行记录。
|
||||
|
||||
升级时如果覆盖整个目录,应先把自定义目录和 `data/` 移出或备份。很多“升级后配置丢了”的问题,本质是把运行态文件当成发布包的一部分覆盖掉。
|
||||
|
||||
## 启动后验收清单
|
||||
|
||||
启动成功不代表可用,至少做下面检查:
|
||||
|
||||
1. 打开 `/`,确认 HTTPS/反向代理没有跳转循环。
|
||||
2. 登录后访问 `/api/auth/validate`,确认会话可用。
|
||||
3. 系统设置中执行模型测试。
|
||||
4. 打开工具列表,确认 `tools/` 被加载,核心工具 schema 正常。
|
||||
5. 若启用知识库,访问知识库页,确认 `index-status` 正常。
|
||||
6. 若启用外部 MCP,查看外部 MCP 状态和工具是否出现在对话侧。
|
||||
7. 若启用 C2,只在授权网络启动一个测试 listener,并确认停止/删除正常。
|
||||
8. 查看审计页面,确认登录和配置读取有记录。
|
||||
|
||||
## 反向代理容易踩的坑
|
||||
|
||||
- SSE 被缓冲:表现为 Agent 一直不输出,结束时一次性吐出。关闭 `proxy_buffering`。
|
||||
- WebSocket 失败:终端或事件流异常。检查 `Upgrade` 和 `Connection` 头。
|
||||
- HTTPS 混用:应用内 TLS 和 Nginx TLS 同时启用时,`proxy_pass` 协议必须匹配。
|
||||
- 上传失败:调大 `client_max_body_size`,并检查应用侧上传限制。
|
||||
- 308 循环:如果应用启用同端口 HTTPS 跳转,而代理又用 HTTP 回源,需要关闭应用 TLS 或改代理回源 HTTPS。
|
||||
|
||||
## 源码锚点
|
||||
|
||||
- 服务组装和路由:`internal/app/app.go`
|
||||
- HTTPS 和自签证书:`internal/app/main_server_tls.go`
|
||||
- HTTP 到 HTTPS 跳转:`internal/app/main_server_http_redirect.go`
|
||||
- 配置结构和默认值:`internal/config/config.go`
|
||||
- 配置应用逻辑:`internal/handler/config.go`
|
||||
@@ -0,0 +1,178 @@
|
||||
# 开发者指南
|
||||
|
||||
本文面向二次开发者,说明项目结构、启动方式、主要扩展点和开发习惯。
|
||||
|
||||
## 项目结构
|
||||
|
||||
```text
|
||||
cmd/server/ Web 服务入口
|
||||
internal/app/ 应用组装、路由注册、MCP 工具注册
|
||||
internal/handler/ HTTP Handler
|
||||
internal/database/ SQLite 数据访问
|
||||
internal/security/ 认证、限流、Shell 执行
|
||||
internal/mcp/ MCP Server、外部 MCP 管理
|
||||
internal/multiagent/ Eino 单代理、多代理、中间件
|
||||
internal/workflow/ 图编排运行时
|
||||
internal/knowledge/ 知识库索引与检索
|
||||
internal/c2/ 内置 C2
|
||||
internal/project/ 项目事实黑板
|
||||
web/static/ 前端 JS/CSS/资源
|
||||
web/templates/ HTML 模板
|
||||
tools/ 命令工具 YAML
|
||||
roles/ 角色 YAML
|
||||
agents/ 多代理 Markdown 定义
|
||||
skills/ Agent Skills
|
||||
docs/ 项目文档
|
||||
```
|
||||
|
||||
## 启动开发环境
|
||||
|
||||
```bash
|
||||
go run ./cmd/server --config config.yaml
|
||||
```
|
||||
|
||||
前端是静态页面,模板在 `web/templates/`,JS/CSS 在 `web/static/`。修改后刷新浏览器即可验证,多数场景不需要单独前端构建。
|
||||
|
||||
## 路由
|
||||
|
||||
路由集中在 `internal/app/app.go` 的 `registerRoutes` 中。新增业务接口通常需要:
|
||||
|
||||
1. 在 `internal/handler/` 增加 Handler。
|
||||
2. 在 `internal/database/` 增加必要的数据访问。
|
||||
3. 在 `internal/app/app.go` 构造并注册路由。
|
||||
4. 如需对外文档,更新 `internal/handler/openapi.go`。
|
||||
5. 如需前端调用,更新 `web/static/js/`。
|
||||
|
||||
## 数据库
|
||||
|
||||
默认 SQLite。新增表或字段时:
|
||||
|
||||
- 将迁移逻辑放到数据库初始化或对应模块迁移函数。
|
||||
- 保持向后兼容,避免破坏已有 `data/conversations.db`。
|
||||
- 添加针对迁移和核心查询的单测。
|
||||
|
||||
## 新增工具
|
||||
|
||||
命令工具优先通过 `tools/*.yaml` 增加,不必改 Go 代码。需要 Go 内置工具时:
|
||||
|
||||
- 在合适模块注册 MCP Tool。
|
||||
- 定义清晰 `InputSchema`。
|
||||
- 处理超时、错误、审计和 HITL 上下文。
|
||||
- 避免把高风险操作默认免审批。
|
||||
|
||||
工具 YAML 规则见 `tools/README.md`。
|
||||
|
||||
## 新增角色
|
||||
|
||||
角色通过 `roles/*.yaml` 管理。常见字段包括名称、描述、系统提示词和工具列表。角色应遵循最小工具集原则,不要把所有工具默认交给专用角色。
|
||||
|
||||
## 新增子代理
|
||||
|
||||
多代理子 Agent 放在 `agents/*.md`。Front matter 示例:
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: Vulnerability Triage
|
||||
id: vulnerability-triage
|
||||
description: 对漏洞线索进行验证、定级和修复建议整理
|
||||
tools:
|
||||
- nmap
|
||||
- nuclei
|
||||
bind_role: 综合漏洞扫描
|
||||
max_iterations: 200
|
||||
---
|
||||
```
|
||||
|
||||
正文是系统提示词。主代理可使用固定文件名或 `kind: orchestrator`。
|
||||
|
||||
## 新增 Skill
|
||||
|
||||
Skill 放在 `skills/<name>/SKILL.md`。用于提供专题能力、流程说明或附属资料。详见 [Skills 指南](skills-guide.md)。
|
||||
|
||||
## 前端开发
|
||||
|
||||
前端代码按功能拆分在 `web/static/js/`。新增页面或模块时:
|
||||
|
||||
- 复用现有 `apiFetch`、modal、通知、i18n 工具。
|
||||
- 同步更新 `web/static/i18n/zh-CN.json` 和 `en-US.json`。
|
||||
- 避免把敏感 Key 放到前端。
|
||||
- 高风险按钮要有确认和清晰状态反馈。
|
||||
|
||||
i18n 规范见 [前端国际化方案](frontend-i18n.md)。
|
||||
|
||||
## OpenAPI
|
||||
|
||||
`internal/handler/openapi.go` 维护内置 OpenAPI 输出。新增公开接口后建议同步补:
|
||||
|
||||
- path
|
||||
- method
|
||||
- summary/description
|
||||
- requestBody
|
||||
- responses
|
||||
- security
|
||||
|
||||
这样 `/api-docs` 才能反映最新接口。
|
||||
|
||||
## 开发习惯
|
||||
|
||||
- 优先保持现有模块边界。
|
||||
- 大模型、外部 API、文件系统、Shell 相关改动必须考虑超时和错误路径。
|
||||
- 高风险能力要接入 HITL 或至少有清晰审计。
|
||||
- 代码变更后运行相关包单测。
|
||||
|
||||
## 新增业务模块的完整配方
|
||||
|
||||
不要只加一个 Handler。完整模块通常要考虑:
|
||||
|
||||
1. 数据模型:是否需要 SQLite 表和迁移。
|
||||
2. Handler:HTTP 参数、错误码、分页、过滤。
|
||||
3. Audit:管理动作是否要审计。
|
||||
4. Monitor:如果会执行长任务,是否要记录执行状态。
|
||||
5. MCP:是否要暴露给 Agent。
|
||||
6. HITL:MCP 工具是否有审批边界。
|
||||
7. OpenAPI:是否更新 `/api/openapi/spec`。
|
||||
8. Frontend:是否需要 i18n、状态、空态、错误提示。
|
||||
9. Tests:数据库、handler、边界条件。
|
||||
10. Docs:配置、使用、排错和安全影响。
|
||||
|
||||
少做其中一项,后面通常会以“用户看不懂”“Agent 调错”“接口没人会用”的形式返工。
|
||||
|
||||
## Handler 错误设计
|
||||
|
||||
建议错误响应保持:
|
||||
|
||||
```json
|
||||
{
|
||||
"error": "machine_readable_code",
|
||||
"message": "给用户看的说明"
|
||||
}
|
||||
```
|
||||
|
||||
不要只返回 Go error 字符串。前端需要稳定字段,用户需要可操作建议,日志需要详细错误。
|
||||
|
||||
## 长任务设计
|
||||
|
||||
扫描、索引、批量任务、C2 等都可能长时间运行。设计时要回答:
|
||||
|
||||
- 是否能取消?
|
||||
- 是否能查询进度?
|
||||
- 失败后能否重试?
|
||||
- 结果写在哪里?
|
||||
- 页面刷新后状态是否还在?
|
||||
- 是否会阻塞 HTTP 请求?
|
||||
|
||||
如果答案是否定的,应考虑接入任务表、事件流或监控模块。
|
||||
|
||||
## 测试优先级
|
||||
|
||||
最值得补测试的地方:
|
||||
|
||||
- 配置热应用。
|
||||
- HITL 审批分支。
|
||||
- Shell 超时和无输出。
|
||||
- 外部 MCP 失败恢复。
|
||||
- 知识库索引和检索后处理。
|
||||
- WebShell 编码和系统识别。
|
||||
- SQLite 迁移兼容。
|
||||
|
||||
这些地方比普通 getter/setter 更容易出现真实用户故障。
|
||||
@@ -0,0 +1,335 @@
|
||||
## CyberStrikeAI 前端国际化方案
|
||||
|
||||
本文档说明 CyberStrikeAI Web 前端(`web/templates/index.html` + `web/static/js/*.js`)的国际化设计与开发规范,确保在不引入打包工具和不改动后端路由的前提下,实现可扩展、低返工的多语言支持。
|
||||
|
||||
当前目标:
|
||||
|
||||
- **支持中英文切换(zh-CN / en-US)**
|
||||
- 后续可方便扩展更多语言(如 ja-JP、ko-KR 等)
|
||||
|
||||
---
|
||||
|
||||
## 一、总体设计原则
|
||||
|
||||
- **前端主导的客户端国际化**:所有 UI 文案在浏览器端根据当前语言动态渲染,后端 Go 仅负责结构和数据,不参与语言分发。
|
||||
- **单一 HTML 模板**:继续使用一份 `index.html` 模板,不为不同语言复制模板文件。
|
||||
- **文案与逻辑分离**:所有可见文本通过「键值表」管理(多语言 JSON),HTML / JS 只写 key,不直接写中文/英文常量。
|
||||
- **渐进式改造**:先覆盖 header / 登录 / 侧边栏 / 系统设置等关键区域,其他页面按模块逐步迁移,避免一次性大改动。
|
||||
- **可回退默认语言**:即使目标语言未完全翻译,也能回退到默认中文,不出现原始 key。
|
||||
|
||||
---
|
||||
|
||||
## 二、技术选型与目录结构
|
||||
|
||||
### 2.1 技术选型
|
||||
|
||||
- **i18n 引擎**:使用 [i18next](https://www.i18next.com/) 的浏览器 UMD 版本(通过 CDN 引入),无需打包器。
|
||||
- **资源格式**:每种语言一份 JSON 文件,采用「域 + 语义」的层级 key 方案,例如:
|
||||
- `common.ok`
|
||||
- `nav.dashboard`
|
||||
- `header.apiDocs`
|
||||
- `settings.robot.wecom.token`
|
||||
|
||||
### 2.2 目录结构
|
||||
|
||||
- `web/templates/index.html`
|
||||
- 页面骨架 + 所有静态文案位置,将逐步改为 `data-i18n` 标记。
|
||||
- `web/static/js/i18n.js`
|
||||
- 前端 i18n 初始化与 DOM 应用逻辑(本方案新增)。
|
||||
- `web/static/i18n/`(新增目录)
|
||||
- `zh-CN.json`:中文文案(默认语言)
|
||||
- `en-US.json`:英文文案
|
||||
- 未来可新增:`ja-JP.json`、`ko-KR.json` 等。
|
||||
|
||||
---
|
||||
|
||||
## 三、文案组织规范
|
||||
|
||||
### 3.1 Key 命名约定
|
||||
|
||||
- 采用「**模块.语义**」形式,最多 2–3 级,确保可读性:
|
||||
- 导航:`nav.dashboard`、`nav.chat`、`nav.settings`
|
||||
- 头部:`header.title`、`header.apiDocs`、`header.logout`
|
||||
- 登录:`login.title`、`login.subtitle`、`login.passwordLabel`、`login.submit`
|
||||
- 仪表盘:`dashboard.title`、`dashboard.refresh`、`dashboard.runningTasks`
|
||||
- 系统设置:`settings.title`、`settings.nav.basic`、`settings.nav.robot`、`settings.apply`
|
||||
- 机器人配置:`settings.robot.wecom.enabled`、`settings.robot.wecom.token` 等。
|
||||
- 尽量按「界面区域」而不是「文件名」划分域,便于非开发人员理解。
|
||||
|
||||
### 3.2 JSON 示例
|
||||
|
||||
`web/static/i18n/zh-CN.json` 示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"common": {
|
||||
"ok": "确定",
|
||||
"cancel": "取消"
|
||||
},
|
||||
"nav": {
|
||||
"dashboard": "仪表盘",
|
||||
"chat": "对话",
|
||||
"infoCollect": "信息收集",
|
||||
"tasks": "任务管理",
|
||||
"vulnerabilities": "漏洞管理",
|
||||
"settings": "系统设置"
|
||||
},
|
||||
"header": {
|
||||
"title": "CyberStrikeAI",
|
||||
"apiDocs": "API 文档",
|
||||
"logout": "退出登录",
|
||||
"language": "界面语言"
|
||||
},
|
||||
"login": {
|
||||
"title": "登录 CyberStrikeAI",
|
||||
"subtitle": "请输入配置中的访问密码",
|
||||
"passwordLabel": "密码",
|
||||
"passwordPlaceholder": "输入登录密码",
|
||||
"submit": "登录"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
英文文件 `en-US.json` 保持相同 key,不同 value:
|
||||
|
||||
```json
|
||||
{
|
||||
"common": {
|
||||
"ok": "OK",
|
||||
"cancel": "Cancel"
|
||||
},
|
||||
"nav": {
|
||||
"dashboard": "Dashboard",
|
||||
"chat": "Chat",
|
||||
"infoCollect": "Recon",
|
||||
"tasks": "Tasks",
|
||||
"vulnerabilities": "Vulnerabilities",
|
||||
"settings": "Settings"
|
||||
},
|
||||
"header": {
|
||||
"title": "CyberStrikeAI",
|
||||
"apiDocs": "API Docs",
|
||||
"logout": "Sign out",
|
||||
"language": "Interface language"
|
||||
},
|
||||
"login": {
|
||||
"title": "Sign in to CyberStrikeAI",
|
||||
"subtitle": "Enter the access password from config",
|
||||
"passwordLabel": "Password",
|
||||
"passwordPlaceholder": "Enter password",
|
||||
"submit": "Sign in"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> 约定:**新增界面时,必须先定义 i18n key,再在 HTML/JS 中使用 key**,禁止直接写死中文/英文。
|
||||
|
||||
---
|
||||
|
||||
## 四、HTML 标记规范(data-i18n)
|
||||
|
||||
### 4.1 基本规则
|
||||
|
||||
- 使用 `data-i18n` 将元素文本与某个 key 绑定:
|
||||
|
||||
```html
|
||||
<span data-i18n="nav.dashboard">仪表盘</span>
|
||||
```
|
||||
|
||||
- 默认行为:脚本会替换元素的 `textContent`。
|
||||
- 同时翻译属性时,额外使用 `data-i18n-attr`,逗号分隔多个属性名:
|
||||
|
||||
```html
|
||||
<button
|
||||
class="openapi-doc-btn"
|
||||
onclick="window.open('/api-docs', '_blank')"
|
||||
data-i18n="header.apiDocs"
|
||||
data-i18n-attr="title"
|
||||
title="API 文档">
|
||||
<span data-i18n="header.apiDocs">API 文档</span>
|
||||
</button>
|
||||
```
|
||||
|
||||
### 4.2 默认文本的作用
|
||||
|
||||
- HTML 内的中文默认值作为「**无 JS / 初始化前**」的占位内容:
|
||||
- 页面在 JS 尚未加载完成时不会出现空白或 key。
|
||||
- JS 初始化后会用当前语言覆盖这些文本。
|
||||
|
||||
---
|
||||
|
||||
## 五、JavaScript 中的文案规范
|
||||
|
||||
### 5.1 全局翻译函数 `t()`
|
||||
|
||||
由 `i18n.js` 暴露以下全局函数:
|
||||
|
||||
- `window.t(key: string): string`
|
||||
- 返回当前语言下的翻译文本,若缺失则回退到默认语言,再不行则返回 key 本身。
|
||||
- `window.changeLanguage(lang: string): Promise<void>`
|
||||
- 切换语言并刷新页面文案(不会刷新整页)。
|
||||
|
||||
示例(以 `web/static/js/settings.js` 为例):
|
||||
|
||||
```js
|
||||
// 之前
|
||||
alert('加载配置失败: ' + error.message);
|
||||
|
||||
// 之后
|
||||
alert(t('settings.loadConfigFailed') + ': ' + error.message);
|
||||
```
|
||||
|
||||
> 规范:**JS 内所有面向用户的提示、按钮文字、对话框标题都应通过 `t()` 获取**,不直接写死中文/英文。
|
||||
|
||||
### 5.2 渐进迁移建议
|
||||
|
||||
- 优先改造:
|
||||
- 频繁弹出的错误提示 / 成功提示;
|
||||
- 登录相关、系统设置相关文案。
|
||||
- 低优先级:
|
||||
- 仅面向运维人员的调试提示,可以暂时保留英文/中文常量。
|
||||
|
||||
---
|
||||
|
||||
## 六、i18n 初始化与语言切换实现
|
||||
|
||||
### 6.1 语言选择策略
|
||||
|
||||
- 默认语言:`zh-CN`。
|
||||
- 优先级(从高到低):
|
||||
1. `localStorage` 中的用户选择(key:`csai_lang`)。
|
||||
2. 浏览器 `navigator.language`(`zh` 开头 → `zh-CN`,否则 `en-US`)。
|
||||
3. 默认 `zh-CN`。
|
||||
|
||||
### 6.2 初始化流程(`i18n.js`)
|
||||
|
||||
1. 读取初始语言。
|
||||
2. 初始化 i18next:
|
||||
- `lng` 为当前语言;
|
||||
- `fallbackLng` 为 `zh-CN`;
|
||||
- 资源先留空,采用按需加载。
|
||||
3. 通过 `fetch` 拉取 `/static/i18n/{lng}.json` 并 `i18next.addResources`。
|
||||
4. 更新:
|
||||
- `<html lang="...">` 属性;
|
||||
- 所有带 `data-i18n` / `data-i18n-attr` 的元素。
|
||||
5. 暴露 `window.t` 与 `window.changeLanguage`。
|
||||
|
||||
### 6.3 DOM 应用逻辑
|
||||
|
||||
伪代码:
|
||||
|
||||
```js
|
||||
function applyTranslations(root = document) {
|
||||
const elements = root.querySelectorAll('[data-i18n]');
|
||||
elements.forEach(el => {
|
||||
const key = el.getAttribute('data-i18n');
|
||||
if (!key) return;
|
||||
const text = i18next.t(key);
|
||||
if (text) {
|
||||
el.textContent = text;
|
||||
}
|
||||
|
||||
const attrList = el.getAttribute('data-i18n-attr');
|
||||
if (attrList) {
|
||||
attrList.split(',').map(s => s.trim()).forEach(attr => {
|
||||
if (!attr) return;
|
||||
const val = i18next.t(key);
|
||||
if (val) el.setAttribute(attr, val);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
> 对于由 JS 动态插入的元素,需要在插入后再次调用 `applyTranslations(新容器)`。
|
||||
|
||||
---
|
||||
|
||||
## 七、语言切换 UI 规范
|
||||
|
||||
### 7.1 位置与形态
|
||||
|
||||
- 位置:`index.html` header 右侧 `API 文档` 按钮附近(靠近用户头像)。
|
||||
- 交互形式:
|
||||
- 一个紧凑的语言切换组件,例如:
|
||||
- `🌐` 图标 + 当前语言文本(`中文` / `English`)的下拉按钮;
|
||||
- 下拉内容列出所有可用语言。
|
||||
|
||||
### 7.2 示例结构
|
||||
|
||||
```html
|
||||
<div class="lang-switcher">
|
||||
<button class="btn-secondary lang-switcher-btn" onclick="toggleLangDropdown()" data-i18n="header.language">
|
||||
<span class="lang-switcher-icon">🌐</span>
|
||||
<span id="current-lang-label">中文</span>
|
||||
</button>
|
||||
<div id="lang-dropdown" class="lang-dropdown" style="display: none;">
|
||||
<div class="lang-option" data-lang="zh-CN" onclick="onLanguageSelect('zh-CN')">中文</div>
|
||||
<div class="lang-option" data-lang="en-US" onclick="onLanguageSelect('en-US')">English</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
对应 JS(在 `i18n.js` 中):
|
||||
|
||||
```js
|
||||
function onLanguageSelect(lang) {
|
||||
changeLanguage(lang).then(updateLangLabel).catch(console.error);
|
||||
closeLangDropdown();
|
||||
}
|
||||
|
||||
function updateLangLabel() {
|
||||
const labelEl = document.getElementById('current-lang-label');
|
||||
if (!labelEl) return;
|
||||
const lang = i18next.language || 'zh-CN';
|
||||
labelEl.textContent = lang.startsWith('zh') ? '中文' : 'English';
|
||||
}
|
||||
```
|
||||
|
||||
> 规范:**语言切换只更新文案,不刷新整页,也不修改 URL hash**。
|
||||
|
||||
---
|
||||
|
||||
## 八、开发流程建议
|
||||
|
||||
### 8.1 新增 / 修改界面的流程
|
||||
|
||||
1. 设计界面时,先列出所有文案。
|
||||
2. 在对应语言 JSON 中补充/修改 key 与翻译。
|
||||
3. 在 HTML 中使用 `data-i18n`,在 JS 中使用 `t('...')`。
|
||||
4. 在浏览器中切换中英文,确认两种语言显示都正确。
|
||||
|
||||
### 8.2 渐进式改造顺序(推荐)
|
||||
|
||||
1. **阶段 1(已规划)**
|
||||
- 引入 i18next 与 `i18n.js`。
|
||||
- 新建 `zh-CN.json` / `en-US.json`(先覆盖 header / 登录 / 左侧导航)。
|
||||
- 实现 header 区域语言切换组件。
|
||||
2. **阶段 2**(已完成)
|
||||
- 系统设置页面(包括机器人配置页面)全部文案 i18n 化。
|
||||
- `settings.js` 中的提示与错误信息改用 `t()`。
|
||||
3. **阶段 3**(进行中)
|
||||
- 仪表盘、任务管理、漏洞管理、MCP、Skills、Roles 等页面按模块逐步迁移。
|
||||
4. **阶段 4**
|
||||
- 清理 JS / HTML 中残留的硬编码中文,统一通过 i18n。
|
||||
|
||||
---
|
||||
|
||||
## 九、后续扩展新语言
|
||||
|
||||
当需要新增语言时:
|
||||
|
||||
1. 在 `web/static/i18n/` 中新增 `{lang}.json`,复制现有英文/中文文件结构,补充对应翻译。
|
||||
2. 在语言切换下拉中添加对应选项,例如:
|
||||
- `data-lang="ja-JP"` / 文本 `日本語`
|
||||
3. 无需修改 `i18n.js` 或现有 HTML/JS 逻辑,即可支持新语言。
|
||||
|
||||
---
|
||||
|
||||
## 十、注意事项与坑点
|
||||
|
||||
- **不要复制多份 HTML 模板** 来做多语言,那样维护成本极高,本方案统一由前端 i18n 控制。
|
||||
- **避免 key 直接用中文/英文句子**,统一采用「模块.语义」短 key,便于 diff 与搜索。
|
||||
- 避免在 CSS 中写死文本(如 `content: "xxx"`),如确有需要,应通过 JS 设置并走 i18n。
|
||||
- 对于后端返回的可本地化错误文本(未来可能支持),优先由后端根据 `Accept-Language` 返回对应语言,前端只负责展示。
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
# 人机协同(HITL)最佳实践
|
||||
|
||||
[English](../en-US/hitl-best-practices.md)
|
||||
|
||||
人机协同用于在 Agent 执行工具前做审批拦截。它适合控制高风险操作、保留审计痕迹,并在人工审计压力过大时让审计 Agent 接管常规审批。
|
||||
|
||||
## 配置入口
|
||||
|
||||
Web 端进入 **系统设置 → 人机协同**,可配置:
|
||||
|
||||
- 全局默认审批方:`human` 或 `audit_agent`
|
||||
- 审计 Agent 专用模型:`hitl.audit_model`
|
||||
- 已决策审计日志保留天数
|
||||
- 免审批工具白名单:`hitl.tool_whitelist`
|
||||
- 审批模式与审查编辑模式的审计提示词
|
||||
|
||||
对应的 `config.yaml` 示例:
|
||||
|
||||
```yaml
|
||||
hitl:
|
||||
default_reviewer: human
|
||||
audit_model:
|
||||
provider: ""
|
||||
base_url: ""
|
||||
api_key: ""
|
||||
model: "" # 可填小模型;留空复用 openai.model
|
||||
retention_days: 90
|
||||
tool_whitelist: [read_file, list_dir, glob, grep, tool_search]
|
||||
```
|
||||
|
||||
`audit_model` 的字段可以只填一部分。空字段会自动继承主 `openai` 配置,因此常见做法是只填 `model`,让审计 Agent 使用更便宜的小模型。
|
||||
|
||||
## 推荐审批策略
|
||||
|
||||
### 1. 默认人工,逐步放权
|
||||
|
||||
刚开始建议:
|
||||
|
||||
- `default_reviewer: human`
|
||||
- 仅把明显只读工具加入 `tool_whitelist`
|
||||
- 对写文件、执行命令、C2 任务、WebShell 操作保持人工审批
|
||||
|
||||
运行一段时间后,观察审计日志,把重复、低风险、误报少的工具加入白名单。
|
||||
|
||||
### 2. 人工审不过来时,用小模型接管常规审批
|
||||
|
||||
当待审批积压明显时,可以切换为:
|
||||
|
||||
```yaml
|
||||
hitl:
|
||||
default_reviewer: audit_agent
|
||||
audit_model:
|
||||
model: "your-small-reviewer-model"
|
||||
```
|
||||
|
||||
建议让小模型处理:
|
||||
|
||||
- 只读查询
|
||||
- 信息收集
|
||||
- 端口与服务扫描
|
||||
- 目录枚举
|
||||
- 无破坏性的验证命令
|
||||
|
||||
仍建议人工处理:
|
||||
|
||||
- 删除、覆盖、清空数据
|
||||
- 修改权限、密码、账号
|
||||
- 持久化、横向移动、C2 高风险任务
|
||||
- 对生产目标的写入操作
|
||||
|
||||
### 3. 用提示词定义组织策略
|
||||
|
||||
审计 Agent 的提示词应该写成策略,而不是泛泛地说“谨慎审批”。建议明确:
|
||||
|
||||
- 默认放行哪些低风险操作
|
||||
- 必须拒绝哪些破坏性操作
|
||||
- 哪些情况需要人工升级
|
||||
- 审查编辑模式下允许怎样收窄参数
|
||||
|
||||
示例策略片段:
|
||||
|
||||
```text
|
||||
常规信息收集、只读查询、端口扫描默认 approve。
|
||||
涉及删除文件、清空数据库、修改账号权限、写入持久化后门、停止关键服务时必须 reject。
|
||||
若目标范围超出用户授权范围,应 reject。
|
||||
审查编辑模式下,可将路径、目标、命令参数收窄后 approve,但不得扩大攻击面。
|
||||
```
|
||||
|
||||
### 4. 白名单只放稳定低风险工具
|
||||
|
||||
白名单工具会跳过审批,因此要保守维护。推荐放:
|
||||
|
||||
- `read_file`
|
||||
- `list_dir`
|
||||
- `glob`
|
||||
- `grep`
|
||||
- `tool_search`
|
||||
|
||||
不建议直接全局白名单:
|
||||
|
||||
- 任意 shell 执行工具
|
||||
- 文件写入/删除工具
|
||||
- C2 任务工具
|
||||
- WebShell 命令执行工具
|
||||
|
||||
## 模式选择
|
||||
|
||||
| 模式 | 适用场景 |
|
||||
|------|----------|
|
||||
| 关闭 | 本地实验、完全信任工具链 |
|
||||
| 审批模式 | 只需要通过/拒绝 |
|
||||
| 审查编辑 | 希望审计 Agent 收窄参数后放行 |
|
||||
|
||||
如果你已经配置了小模型审计,推荐从 **审批模式** 开始。只有当你希望 AI 自动收窄路径、目标范围或命令参数时,再开启 **审查编辑**。
|
||||
|
||||
## 运维建议
|
||||
|
||||
- 定期查看 **人机协同 → 审计日志**,调整白名单和提示词。
|
||||
- 高风险环境下保持 `default_reviewer: human`,只让审计 Agent 辅助给出建议。
|
||||
- 小模型审批失败时默认保守拒绝,这是预期行为。
|
||||
- 修改 `hitl.audit_model` 后先在页面点击 **测试审计模型**。
|
||||
- 对生产、客户、真实业务系统操作前,应保留人工最终确认。
|
||||
@@ -0,0 +1,272 @@
|
||||
# 知识库
|
||||
|
||||
知识库用于把本地安全知识、漏洞手册、测试方法和组织经验转成可检索上下文,供 Agent 在任务中按需引用。
|
||||
|
||||
## 启用
|
||||
|
||||
```yaml
|
||||
knowledge:
|
||||
enabled: true
|
||||
base_path: knowledge_base
|
||||
embedding:
|
||||
provider: openai
|
||||
model: text-embedding-v4
|
||||
base_url: ""
|
||||
api_key: ""
|
||||
database:
|
||||
knowledge_db_path: data/knowledge.db
|
||||
```
|
||||
|
||||
`embedding.base_url/api_key` 留空时会复用 `openai` 配置。建议知识库数据库独立保存,便于迁移和复用。
|
||||
|
||||
## 内容目录
|
||||
|
||||
默认目录是 `knowledge_base/`。项目中已有示例:
|
||||
|
||||
```text
|
||||
knowledge_base/
|
||||
SQL Injection/
|
||||
README.md
|
||||
MySQL Injection.md
|
||||
Prompt Injection/
|
||||
README.md
|
||||
```
|
||||
|
||||
推荐用一级目录表示风险类型或知识域,如:
|
||||
|
||||
- `SQL Injection`
|
||||
- `XSS`
|
||||
- `File Upload`
|
||||
- `Cloud Security`
|
||||
- `Incident Response`
|
||||
|
||||
## 管理流程
|
||||
|
||||
常见流程:
|
||||
|
||||
1. 把 Markdown 知识文件放到 `knowledge_base/`。
|
||||
2. 在 Web 知识库页面扫描目录。
|
||||
3. 重建索引。
|
||||
4. 用搜索功能验证召回效果。
|
||||
5. 在角色或任务中要求 Agent 优先查询知识库。
|
||||
|
||||
接口入口包括:
|
||||
|
||||
- `GET /api/knowledge/categories`
|
||||
- `GET /api/knowledge/items`
|
||||
- `POST /api/knowledge/scan`
|
||||
- `POST /api/knowledge/index`
|
||||
- `POST /api/knowledge/search`
|
||||
- `GET /api/knowledge/index-status`
|
||||
- `GET /api/knowledge/retrieval-logs`
|
||||
|
||||
## 索引
|
||||
|
||||
索引配置:
|
||||
|
||||
```yaml
|
||||
knowledge:
|
||||
indexing:
|
||||
chunk_size: 512
|
||||
chunk_overlap: 50
|
||||
max_chunks_per_item: 0
|
||||
max_rpm: 0
|
||||
rate_limit_delay_ms: 300
|
||||
max_retries: 3
|
||||
retry_delay_ms: 1000
|
||||
chunk_strategy: markdown_then_recursive
|
||||
request_timeout_seconds: 120
|
||||
prefer_source_file: false
|
||||
batch_size: 10
|
||||
sub_indexes: []
|
||||
```
|
||||
|
||||
建议:
|
||||
|
||||
- 文档结构清晰时用 `markdown_then_recursive`。
|
||||
- 嵌入接口限制严格时降低 `batch_size`,增加 `rate_limit_delay_ms`。
|
||||
- 单篇超长文档可设置 `max_chunks_per_item` 控制成本。
|
||||
- 需要按业务域隔离时使用 `sub_indexes` 和 `sub_index_filter`。
|
||||
|
||||
## 检索
|
||||
|
||||
```yaml
|
||||
knowledge:
|
||||
retrieval:
|
||||
top_k: 5
|
||||
similarity_threshold: 0.4
|
||||
multi_query:
|
||||
max_queries: 4
|
||||
post_retrieve:
|
||||
prefetch_top_k: 20
|
||||
max_context_chars: 0
|
||||
max_context_tokens: 0
|
||||
```
|
||||
|
||||
检索链路大致为:
|
||||
|
||||
1. 用户查询或 Agent 查询。
|
||||
2. MultiQuery 改写出多个语义变体。
|
||||
3. 向量检索获取候选块。
|
||||
4. rerank 精排。
|
||||
5. 后处理去重、限长。
|
||||
6. 返回给 Agent 或 API 调用方。
|
||||
|
||||
`similarity_threshold` 太高会漏召回,太低会带入噪声。初始建议 0.35 到 0.45。
|
||||
|
||||
## Rerank
|
||||
|
||||
```yaml
|
||||
knowledge:
|
||||
retrieval:
|
||||
rerank:
|
||||
provider: ""
|
||||
model: ""
|
||||
base_url: ""
|
||||
api_key: ""
|
||||
```
|
||||
|
||||
留空时会根据 `base_url` 推断。DashScope 常用 `gte-rerank`;其他 OpenAI 兼容端点可能走 `/v1/rerank`。如果服务商不支持 rerank,检索质量可能下降,建议降低 `top_k` 并提高知识条目质量。
|
||||
|
||||
## MCP 工具
|
||||
|
||||
启用知识库后,会注册类似以下能力:
|
||||
|
||||
- 列出风险类型。
|
||||
- 搜索知识库。
|
||||
- 获取相关知识片段。
|
||||
|
||||
角色提示词中可以写明:
|
||||
|
||||
```text
|
||||
遇到漏洞验证、修复建议或检测方法不确定时,先检索知识库,再给出结论。
|
||||
```
|
||||
|
||||
## 内容编写建议
|
||||
|
||||
每篇知识建议包含:
|
||||
|
||||
- 适用场景。
|
||||
- 检测方法。
|
||||
- 验证步骤。
|
||||
- 常见误报。
|
||||
- 修复建议。
|
||||
- 工具命令示例。
|
||||
- 参考链接或内部标准。
|
||||
|
||||
避免把无关主题堆在同一篇长文中。小而清晰的文档更利于 chunk 和召回。
|
||||
|
||||
## 排错
|
||||
|
||||
索引失败:
|
||||
|
||||
- 检查 embedding API Key、模型名、base_url。
|
||||
- 降低 `batch_size`。
|
||||
- 增大 `request_timeout_seconds`。
|
||||
- 查看服务日志中的 400/401/429/5xx。
|
||||
|
||||
检索为空:
|
||||
|
||||
- 检查是否已重建索引。
|
||||
- 降低 `similarity_threshold`。
|
||||
- 查看 `categories` 是否识别到风险类型。
|
||||
- 搜索时不要使用过窄的 `riskType`。
|
||||
|
||||
召回不准:
|
||||
|
||||
- 优化标题层级。
|
||||
- 把混杂内容拆成多篇。
|
||||
- 增加关键术语和同义词。
|
||||
- 调整 `top_k`、`prefetch_top_k` 和 rerank 配置。
|
||||
|
||||
## 内部数据流
|
||||
|
||||
知识库链路不是“全文搜索”,而是一个多阶段检索系统:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
F["Markdown / Web 知识项"] --> M["Manager"]
|
||||
M --> C["Chunker"]
|
||||
C --> E["Embedding"]
|
||||
E --> V["SQLite Vector Index"]
|
||||
Q["Agent 查询"] --> MQ["MultiQuery 改写"]
|
||||
MQ --> V
|
||||
V --> R["Rerank"]
|
||||
R --> P["Post-process 去重/限长"]
|
||||
P --> A["Agent 上下文"]
|
||||
```
|
||||
|
||||
因此检索质量取决于四件事:原文结构、chunk 粒度、embedding 质量、rerank 可用性。单纯调 `top_k` 往往不是最有效的办法。
|
||||
|
||||
## 知识项写作反例
|
||||
|
||||
不好的知识:
|
||||
|
||||
```text
|
||||
SQL注入很危险,可以用sqlmap扫,修复就是过滤。
|
||||
```
|
||||
|
||||
好的知识:
|
||||
|
||||
```markdown
|
||||
# MySQL UNION 注入验证
|
||||
|
||||
## 触发条件
|
||||
- 参数进入 SELECT 查询并直接拼接。
|
||||
- 页面返回字段数量错误或类型错误。
|
||||
|
||||
## 验证步骤
|
||||
1. 使用 `' order by 1-- -` 递增列数。
|
||||
2. 使用 `union select null,...` 校验回显位。
|
||||
3. 用只读函数确认数据库类型,例如 `database()`。
|
||||
|
||||
## 误报排除
|
||||
- WAF 注入拦截页可能模拟 SQL 错误。
|
||||
- 统一错误页不能直接证明注入。
|
||||
|
||||
## 修复
|
||||
- 参数化查询。
|
||||
- 最小数据库权限。
|
||||
- 统一错误处理但不吞掉安全日志。
|
||||
```
|
||||
|
||||
第二种写法能给 chunk 足够的标题、术语和步骤信号,Agent 也能直接执行。
|
||||
|
||||
## 调参方法
|
||||
|
||||
先固定一组测试问题,例如:
|
||||
|
||||
```text
|
||||
MySQL union 注入怎么判断字段数?
|
||||
SSRF 如何验证云元数据访问?
|
||||
文件上传黑名单绕过有哪些误报?
|
||||
```
|
||||
|
||||
然后逐项调:
|
||||
|
||||
1. 搜索为空:降低 `similarity_threshold`,确认索引完成。
|
||||
2. 结果主题错:提高文档标题质量,增加风险类型过滤。
|
||||
3. 结果片段断裂:增大 `chunk_overlap` 或降低 `chunk_size` 后重建索引。
|
||||
4. 噪声多:提高 `similarity_threshold`,启用/修复 rerank。
|
||||
5. 成本高:降低 `multi_query.max_queries`、`prefetch_top_k`、`top_k`。
|
||||
|
||||
每次只改一个参数,并记录查询结果,否则无法判断哪个变量有效。
|
||||
|
||||
## 检索日志怎么用
|
||||
|
||||
检索日志不只是排错用,还可以反向改进知识库:
|
||||
|
||||
- 高频无结果查询:说明缺知识或同义词不足。
|
||||
- 高频低分查询:说明文档标题和术语不匹配。
|
||||
- 同一问题召回多个重复文档:说明需要合并或加 category。
|
||||
- Agent 常忽略知识库结果:说明结果太长、太散或缺明确结论。
|
||||
|
||||
## 源码锚点
|
||||
|
||||
- 知识管理:`internal/knowledge/manager.go`
|
||||
- 索引流水线:`internal/knowledge/index_pipeline.go`
|
||||
- Eino chunk:`internal/knowledge/chunk_eino.go`
|
||||
- 检索器:`internal/knowledge/retriever.go`
|
||||
- Eino 检索链:`internal/knowledge/eino_retrieve_chain.go`
|
||||
- rerank:`internal/knowledge/rerank_http.go`
|
||||
- MCP 工具:`internal/knowledge/tool.go`
|
||||
@@ -0,0 +1,189 @@
|
||||
# MCP 联邦
|
||||
|
||||
CyberStrikeAI 同时支持内置 MCP 工具、独立 HTTP MCP 服务和外部 MCP 联邦。MCP 是 Agent 调用工具的主要协议层。
|
||||
|
||||
## 内置 MCP
|
||||
|
||||
Web 服务内部会创建 MCP Server,并注册:
|
||||
|
||||
- YAML 命令工具。
|
||||
- 内置安全执行工具。
|
||||
- 知识库工具。
|
||||
- 项目事实工具。
|
||||
- C2 工具。
|
||||
- WebShell 工具。
|
||||
- 批量任务工具。
|
||||
- 视觉分析工具。
|
||||
|
||||
前端和 Agent 通常通过应用内部调用,不需要额外配置。
|
||||
|
||||
## HTTP MCP 服务
|
||||
|
||||
配置:
|
||||
|
||||
```yaml
|
||||
mcp:
|
||||
enabled: true
|
||||
host: 0.0.0.0
|
||||
port: 8081
|
||||
auth_header: "X-MCP-Token"
|
||||
auth_header_value: "random-secret"
|
||||
```
|
||||
|
||||
生产环境必须设置 `auth_header_value`,并限制网络访问。
|
||||
|
||||
## Web 内 MCP 端点
|
||||
|
||||
登录后可通过:
|
||||
|
||||
```text
|
||||
POST /api/mcp
|
||||
```
|
||||
|
||||
该端点复用 Web 认证,适合内部页面或受控集成。
|
||||
|
||||
## 外部 MCP
|
||||
|
||||
外部 MCP 配置在:
|
||||
|
||||
```yaml
|
||||
external_mcp:
|
||||
servers: {}
|
||||
```
|
||||
|
||||
也可以通过 Web 的 MCP 管理页面新增、启动、停止和删除。
|
||||
|
||||
接口:
|
||||
|
||||
- `GET /api/external-mcp`
|
||||
- `GET /api/external-mcp/stats`
|
||||
- `GET /api/external-mcp/:name`
|
||||
- `PUT /api/external-mcp/:name`
|
||||
- `POST /api/external-mcp/:name/start`
|
||||
- `POST /api/external-mcp/:name/stop`
|
||||
- `DELETE /api/external-mcp/:name`
|
||||
|
||||
## stdio
|
||||
|
||||
stdio MCP 适合本机命令启动的工具服务。
|
||||
|
||||
关注点:
|
||||
|
||||
- 命令路径必须存在。
|
||||
- 工作目录正确。
|
||||
- 环境变量完整。
|
||||
- 进程退出会导致工具不可用。
|
||||
- 日志中查看启动失败原因。
|
||||
|
||||
## HTTP / SSE
|
||||
|
||||
HTTP 或 SSE MCP 适合远端或长期运行服务。
|
||||
|
||||
关注点:
|
||||
|
||||
- URL 可达。
|
||||
- 认证头正确。
|
||||
- TLS 证书可信。
|
||||
- 代理和防火墙放行。
|
||||
- 服务端协议版本兼容。
|
||||
|
||||
## 工具暴露策略
|
||||
|
||||
工具过多会增加上下文成本和误选概率。多代理中可通过:
|
||||
|
||||
```yaml
|
||||
multi_agent:
|
||||
eino_middleware:
|
||||
tool_search_enable: true
|
||||
tool_search_min_tools: 20
|
||||
tool_search_always_visible: 12
|
||||
tool_search_always_visible_tools:
|
||||
- read_file
|
||||
- glob
|
||||
- grep
|
||||
- tool_search
|
||||
```
|
||||
|
||||
让常用工具常驻,其余工具由 `tool_search` 动态解锁。
|
||||
|
||||
## 安全建议
|
||||
|
||||
- 外部 MCP 只接入可信服务。
|
||||
- 远端 MCP 必须认证。
|
||||
- 高风险工具不要常驻上下文。
|
||||
- 外部 MCP 的文件系统和命令执行能力要单独评估。
|
||||
- 变更外部 MCP 后查看审计日志。
|
||||
|
||||
## 调试
|
||||
|
||||
排查顺序:
|
||||
|
||||
1. `/api/external-mcp/stats` 查看状态。
|
||||
2. 检查服务日志。
|
||||
3. 单独运行 stdio 命令。
|
||||
4. 用 curl 测试 HTTP/SSE 地址。
|
||||
5. 检查工具是否被角色或 tool_search 策略隐藏。
|
||||
|
||||
## MCP 生命周期
|
||||
|
||||
外部 MCP 的生命周期不是简单的“添加 URL”:
|
||||
|
||||
1. 注册配置:名称、类型、命令或 URL、环境变量。
|
||||
2. 启动连接:stdio 拉起进程,HTTP/SSE 建立客户端。
|
||||
3. 拉取工具列表:工具名、描述、schema 进入平台。
|
||||
4. 暴露给 Agent:受角色、tool_search、HITL 影响。
|
||||
5. 执行工具:参数校验、调用、记录监控。
|
||||
6. 连接恢复:进程退出或网络失败后尝试恢复。
|
||||
7. 停止/删除:从运行时和配置中移除。
|
||||
|
||||
排错时要确认卡在哪一步。
|
||||
|
||||
## 工具命名规范
|
||||
|
||||
工具名应:
|
||||
|
||||
- 稳定。
|
||||
- 小写或 snake_case。
|
||||
- 表达动作和对象。
|
||||
- 避免和内置工具重名。
|
||||
|
||||
不建议:
|
||||
|
||||
```text
|
||||
run
|
||||
execute
|
||||
scan
|
||||
tool1
|
||||
```
|
||||
|
||||
建议:
|
||||
|
||||
```text
|
||||
burp_send_to_repeater
|
||||
asset_lookup_domain
|
||||
cloud_list_public_buckets
|
||||
```
|
||||
|
||||
好的工具名会提升 tool_search 命中率,也降低误调用。
|
||||
|
||||
## 外部 MCP 安全审查清单
|
||||
|
||||
接入前问:
|
||||
|
||||
- 它能读写本机文件吗?
|
||||
- 它能执行命令吗?
|
||||
- 它会访问哪些网络?
|
||||
- 它是否把请求发给第三方?
|
||||
- 它的工具描述是否可信?
|
||||
- 它的输出是否可能包含 prompt injection?
|
||||
- 它是否需要独立运行用户或容器隔离?
|
||||
|
||||
只要答案不清楚,就不要放进生产环境常驻工具池。
|
||||
|
||||
## 源码锚点
|
||||
|
||||
- 外部 MCP Manager:`internal/mcp/external_manager.go`
|
||||
- 连接恢复:`internal/mcp/connection_recovery.go`
|
||||
- MCP 工具适配:`internal/einomcp/mcp_tools.go`
|
||||
- 外部 MCP Handler:`internal/handler/external_mcp.go`
|
||||
- 工具调用通知:`internal/einomcp/tool_invoke_notify.go`
|
||||
@@ -0,0 +1,157 @@
|
||||
# 插件开发
|
||||
|
||||
CyberStrikeAI 当前仓库中的插件主要位于 `plugins/`,示例是 Burp Suite 扩展。插件通常通过 HTTP API、MCP 或本地文件与主应用集成。
|
||||
|
||||
## 目录
|
||||
|
||||
```text
|
||||
plugins/
|
||||
README.md
|
||||
burp-suite/
|
||||
cyberstrikeai-burp-extension/
|
||||
src/main/java/burp/
|
||||
README.md
|
||||
README.zh-CN.md
|
||||
build.gradle
|
||||
pom.xml
|
||||
```
|
||||
|
||||
## 插件类型
|
||||
|
||||
常见集成方式:
|
||||
|
||||
- 浏览器或安全工具扩展:调用 CyberStrikeAI API。
|
||||
- MCP Server:向 CyberStrikeAI 暴露新工具。
|
||||
- 文件型扩展:提供 tools、roles、skills、agents。
|
||||
- Webhook/机器人:通过平台回调与 CyberStrikeAI 对话。
|
||||
|
||||
## Burp Suite 扩展
|
||||
|
||||
Burp 插件目录包含 Java 源码和构建脚本。典型能力:
|
||||
|
||||
- 读取 Burp 中的 HTTP 请求/响应。
|
||||
- 格式化消息。
|
||||
- 调用 CyberStrikeAI API。
|
||||
- 在 Burp 标签页展示 AI 分析结果。
|
||||
|
||||
构建前确认:
|
||||
|
||||
- JDK 可用。
|
||||
- Gradle 或 Maven 可用。
|
||||
- CyberStrikeAI 服务地址和认证配置正确。
|
||||
|
||||
## API 对接建议
|
||||
|
||||
插件调用主应用时:
|
||||
|
||||
- 先登录或使用受控认证方式。
|
||||
- 优先调用 `/api/eino-agent` 或 `/api/eino-agent/stream`。
|
||||
- 大文件通过 `/api/chat-uploads` 上传,再在消息中引用。
|
||||
- 查询结果或漏洞可写入 `/api/vulnerabilities`。
|
||||
- 项目信息可写入 `/api/projects/:id/facts`。
|
||||
|
||||
完整接口以 `/api-docs` 为准。
|
||||
|
||||
## MCP 插件
|
||||
|
||||
如果插件的目标是给 Agent 增加工具,优先实现 MCP Server。然后在外部 MCP 管理中接入:
|
||||
|
||||
- stdio:本机启动。
|
||||
- HTTP/SSE:长期服务。
|
||||
|
||||
MCP 工具设计建议:
|
||||
|
||||
- schema 明确。
|
||||
- 参数最小化。
|
||||
- 输出结构稳定。
|
||||
- 错误信息可读。
|
||||
- 高风险动作拆成独立工具,方便 HITL 审批。
|
||||
|
||||
## 文件型扩展
|
||||
|
||||
插件也可以交付:
|
||||
|
||||
- `tools/*.yaml`
|
||||
- `roles/*.yaml`
|
||||
- `skills/<name>/SKILL.md`
|
||||
- `agents/*.md`
|
||||
|
||||
这种方式简单可靠,适合内部方法论或工具链沉淀。
|
||||
|
||||
## 发布检查
|
||||
|
||||
发布插件前确认:
|
||||
|
||||
- 不包含 API Key、Cookie、目标信息。
|
||||
- README 有安装、配置、卸载说明。
|
||||
- 错误提示清晰。
|
||||
- 与当前 CyberStrikeAI API 版本兼容。
|
||||
- 高风险能力有明显说明。
|
||||
|
||||
## 版本兼容
|
||||
|
||||
插件应避免依赖未公开的前端内部实现。优先依赖:
|
||||
|
||||
- `/api/openapi/spec`
|
||||
- 稳定 HTTP API。
|
||||
- MCP 协议。
|
||||
- 文件目录规范。
|
||||
|
||||
如果必须依赖内部接口,插件 README 中应标注兼容版本。
|
||||
|
||||
## 插件设计的三个层次
|
||||
|
||||
| 层次 | 例子 | 优点 | 代价 |
|
||||
| --- | --- | --- | --- |
|
||||
| API 插件 | Burp 扩展调用 `/api/eino-agent` | 易实现,适合 UI 集成 | 依赖认证和 API 稳定性 |
|
||||
| MCP 插件 | 提供新工具给 Agent | Agent 可主动调用 | 需要 schema 和安全设计 |
|
||||
| 资源包插件 | 交付 tools/roles/skills/agents | 最简单,可版本化 | 交互能力弱 |
|
||||
|
||||
插件一开始不必做成 MCP。如果只是“把 Burp 请求交给 AI 分析”,API 插件更直接;如果要让 Agent 主动调用 Burp 扫描或查询结果,再做 MCP。
|
||||
|
||||
## API 插件请求设计
|
||||
|
||||
发送给 Agent 的内容应包含:
|
||||
|
||||
- 来源工具和上下文。
|
||||
- 目标 URL、方法、关键 header。
|
||||
- 请求体和响应体的截断策略。
|
||||
- 用户希望 AI 做什么。
|
||||
- 授权边界。
|
||||
|
||||
不要把完整大响应直接塞进消息。大文件应走上传接口或做摘要。
|
||||
|
||||
## MCP 插件 schema 设计
|
||||
|
||||
坏 schema:
|
||||
|
||||
```json
|
||||
{"cmd":{"type":"string"}}
|
||||
```
|
||||
|
||||
好 schema:
|
||||
|
||||
```json
|
||||
{
|
||||
"target_url": {"type":"string","description":"授权目标 URL"},
|
||||
"scan_profile": {"type":"string","enum":["passive","active-safe"]},
|
||||
"max_requests": {"type":"integer","description":"最大请求数"}
|
||||
}
|
||||
```
|
||||
|
||||
schema 越具体,HITL 越容易判断风险,Agent 也越不容易发散。
|
||||
|
||||
## 插件安全边界
|
||||
|
||||
插件不要绕过平台安全控制:
|
||||
|
||||
- 不要直接执行本机高风险命令而不暴露给 HITL。
|
||||
- 不要在插件内保存明文长期凭证。
|
||||
- 不要默认把目标数据发给第三方服务。
|
||||
- 不要依赖浏览器本地状态绕过登录。
|
||||
|
||||
## 源码锚点
|
||||
|
||||
- Burp 插件 Java 代码:`plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/`
|
||||
- OpenAPI:`internal/handler/openapi.go`
|
||||
- 外部 MCP:`internal/handler/external_mcp.go`
|
||||
@@ -0,0 +1,169 @@
|
||||
# 发布流程
|
||||
|
||||
本文用于维护者或部署者发布、升级和回滚 CyberStrikeAI。
|
||||
|
||||
## 版本准备
|
||||
|
||||
发布前检查:
|
||||
|
||||
- `README.md` 和 `README_CN.md` 的功能说明是否更新。
|
||||
- `docs/` 是否补充新功能文档。
|
||||
- `config.yaml` 示例是否包含新增配置。
|
||||
- OpenAPI 是否包含新增接口。
|
||||
- 中英文 i18n 是否同步。
|
||||
- 高风险功能是否有安全说明。
|
||||
|
||||
## 测试
|
||||
|
||||
至少运行:
|
||||
|
||||
```bash
|
||||
go test ./internal/...
|
||||
```
|
||||
|
||||
如果修改了入口、构建或命令:
|
||||
|
||||
```bash
|
||||
go test ./cmd/...
|
||||
go build -o cyberstrike-ai ./cmd/server
|
||||
```
|
||||
|
||||
如果修改前端,手动验证:
|
||||
|
||||
- 登录。
|
||||
- 对话流式输出。
|
||||
- 设置保存和应用。
|
||||
- 工具列表。
|
||||
- 相关页面无控制台错误。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
go build -o cyberstrike-ai ./cmd/server
|
||||
```
|
||||
|
||||
发布包应包含:
|
||||
|
||||
- `cyberstrike-ai`
|
||||
- `web/templates/`
|
||||
- `web/static/`
|
||||
- `config.yaml` 示例。
|
||||
- `tools/`
|
||||
- `roles/`
|
||||
- `skills/`
|
||||
- `agents/`
|
||||
- `docs/`
|
||||
- `README.md` / `README_CN.md`
|
||||
- `LICENSE`
|
||||
|
||||
不要把本地 `data/`、真实 `config.yaml` 密钥、上传附件和日志打进公开发布包。
|
||||
|
||||
## 升级检查清单
|
||||
|
||||
升级前:
|
||||
|
||||
- 停服务。
|
||||
- 备份 `config.yaml`。
|
||||
- 备份 `data/`。
|
||||
- 备份自定义 `tools/roles/skills/agents/knowledge_base`。
|
||||
- 记录当前版本和启动方式。
|
||||
|
||||
升级后:
|
||||
|
||||
- 启动服务。
|
||||
- 登录。
|
||||
- 测试模型。
|
||||
- 检查工具列表。
|
||||
- 检查知识库状态。
|
||||
- 检查外部 MCP。
|
||||
- 检查 C2/WebShell 是否按预期启用或关闭。
|
||||
- 查看日志和审计。
|
||||
|
||||
## 回滚
|
||||
|
||||
触发回滚的常见情况:
|
||||
|
||||
- 服务无法启动。
|
||||
- 数据库迁移失败。
|
||||
- 核心对话功能不可用。
|
||||
- 高风险功能行为异常。
|
||||
|
||||
回滚步骤:
|
||||
|
||||
1. 停止新版本。
|
||||
2. 恢复旧二进制或旧代码。
|
||||
3. 恢复升级前 `config.yaml`。
|
||||
4. 恢复升级前 `data/`。
|
||||
5. 启动旧版本并验证。
|
||||
|
||||
如果新版已修改数据库结构,必须恢复数据库备份,不能只替换二进制。
|
||||
|
||||
## Changelog 建议
|
||||
|
||||
每个版本记录:
|
||||
|
||||
- 新增功能。
|
||||
- 行为变更。
|
||||
- 配置变更。
|
||||
- 数据库变更。
|
||||
- 安全修复。
|
||||
- 兼容性说明。
|
||||
- 升级注意事项。
|
||||
|
||||
高风险模块的变更要单独标出,例如 C2、WebShell、终端、外部 MCP、HITL。
|
||||
|
||||
## 发布风险分级
|
||||
|
||||
| 改动 | 风险 | 必测 |
|
||||
| --- | --- | --- |
|
||||
| 文档、图片 | 低 | 链接和渲染 |
|
||||
| 前端页面 | 中 | 登录、页面状态、API 错误 |
|
||||
| Handler/API | 中 | OpenAPI、权限、错误码 |
|
||||
| 配置结构 | 高 | 旧配置兼容、ApplyConfig |
|
||||
| 数据库结构 | 高 | 旧库迁移、回滚策略 |
|
||||
| Agent/MCP/HITL | 高 | 工具调用、审批、流式中断 |
|
||||
| C2/WebShell/Terminal | 极高 | 授权环境、审计、禁用开关 |
|
||||
|
||||
发布说明里要按风险级别提示用户,而不是只列功能点。
|
||||
|
||||
## 配置兼容策略
|
||||
|
||||
新增配置字段要遵循:
|
||||
|
||||
- 省略时有安全默认值。
|
||||
- 旧配置能启动。
|
||||
- 示例 `config.yaml` 有注释。
|
||||
- Web 设置页不会把未知字段误删。
|
||||
- 热应用和重启两种路径都验证。
|
||||
|
||||
如果新增字段默认开启高风险功能,应重新考虑默认值。
|
||||
|
||||
## 数据库变更策略
|
||||
|
||||
SQLite 迁移要考虑:
|
||||
|
||||
- 用户可能从很老版本直接升级。
|
||||
- 迁移中断后再次启动是否幂等。
|
||||
- 新字段是否允许空值。
|
||||
- 索引是否会锁表太久。
|
||||
- 是否需要数据回填。
|
||||
|
||||
发布说明必须写清楚“升级前备份 data/”。
|
||||
|
||||
## Release 验收脚本思路
|
||||
|
||||
最小自动化:
|
||||
|
||||
```bash
|
||||
go test ./internal/...
|
||||
go test ./cmd/...
|
||||
go build -o cyberstrike-ai ./cmd/server
|
||||
```
|
||||
|
||||
手动冒烟:
|
||||
|
||||
```text
|
||||
登录 -> 模型测试 -> 新建对话 -> 工具列表 -> HITL -> 知识库 -> 外部 MCP -> 关闭/开启 C2
|
||||
```
|
||||
|
||||
对高风险模块,宁可多做一个授权靶场测试,也不要只靠单测放行。
|
||||
@@ -0,0 +1,491 @@
|
||||
# CyberStrikeAI 机器人使用说明
|
||||
|
||||
[English](../en-US/robot.md)
|
||||
|
||||
本文档说明如何通过**个人微信**、**钉钉**、**飞书**与 **企业微信** 与 CyberStrikeAI 对话(长连接 / 回调模式),在手机端即可使用,无需在服务器上打开网页。按下面步骤操作可避免常见弯路。
|
||||
|
||||
---
|
||||
|
||||
## 一、在 CyberStrikeAI 里从哪里配置
|
||||
|
||||
1. 登录 CyberStrikeAI Web 端
|
||||
2. 左侧导航进入 **系统设置**
|
||||
3. 在左侧设置分类中点击 **机器人设置**(位于「基本设置」与「安全设置」之间)
|
||||
4. 按平台配置:
|
||||
- **个人微信**:点击「微信 / iLink」→「生成二维码并绑定」,用微信扫码确认(见 [3.4 个人微信](#34-个人微信-wechat--ilink))
|
||||
- **钉钉**:勾选并填写 Client ID / Client Secret
|
||||
- **飞书**:勾选并填写 App ID / App Secret
|
||||
5. 点击 **应用配置** 保存(微信扫码绑定成功后会**自动保存并启用**,一般无需再点)
|
||||
6. **重启 CyberStrikeAI 应用**(钉钉/飞书:只保存不重启,长连接不会建立;微信绑定成功后会自动重启连接,通常无需手动重启)
|
||||
|
||||
配置会写入 `config.yaml` 的 `robots` 段,也可在配置文件中直接编辑。**修改钉钉/飞书配置后必须重启,长连接才会生效。** 个人微信绑定成功后程序会自动写入 `robots.wechat` 并重启 iLink 长轮询。
|
||||
|
||||
---
|
||||
|
||||
## 二、支持的平台(长连接 / 回调)
|
||||
|
||||
| 平台 | 说明 |
|
||||
|----------|------|
|
||||
| 个人微信 | 使用微信 iLink 协议,Web 端扫码绑定后长轮询收消息,**无需公网回调** |
|
||||
| 钉钉 | 使用 Stream 长连接,程序主动连接钉钉接收消息 |
|
||||
| 飞书 | 使用长连接,程序主动连接飞书接收消息 |
|
||||
| 企业微信 | 使用 HTTP 回调接收消息,被动回包 + 主动调用企业微信发送消息 API |
|
||||
| Telegram | Bot API 长轮询(getUpdates),**无需公网回调** |
|
||||
| Slack | Socket Mode(出站 WebSocket),**无需公网回调** |
|
||||
| Discord | Gateway WebSocket,**无需公网回调** |
|
||||
| QQ 机器人 | QQ 开放平台 WebSocket(C2C / 群 @),**无需公网回调** |
|
||||
|
||||
下面第三节会按平台写清:在开放平台要做什么、要复制哪些字段、填到 CyberStrikeAI 的哪一栏。
|
||||
|
||||
---
|
||||
|
||||
## 三、各平台配置项与详细步骤
|
||||
|
||||
### 3.1 钉钉
|
||||
|
||||
**先搞清楚:两种钉钉机器人不一样**
|
||||
|
||||
| 类型 | 从哪里创建 | 能否做「用户发消息→机器人回复」 | 本程序是否支持 |
|
||||
|------|------------|----------------------------------|----------------|
|
||||
| **自定义机器人** | 钉钉群里:群设置 → 添加机器人 → 自定义(Webhook) | ❌ 不能,只能你往群里发消息 | ❌ 不支持 |
|
||||
| **企业内部应用机器人** | [钉钉开放平台](https://open.dingtalk.com) 创建应用并开通机器人 | ✅ 能 | ✅ 支持 |
|
||||
|
||||
如果你手里是「自定义机器人」的 Webhook 地址(`oapi.dingtalk.com/robot/send?access_token=xxx`)和加签密钥(`SEC...`),**不能直接填到本程序**,必须按下面步骤在开放平台创建「企业内部应用」并拿到 **Client ID**、**Client Secret**。
|
||||
|
||||
---
|
||||
|
||||
**钉钉配置完整步骤(按顺序做)**
|
||||
|
||||
1. **打开钉钉开放平台**
|
||||
浏览器访问 [https://open.dingtalk.com](https://open.dingtalk.com),用**企业管理员**账号登录。
|
||||
|
||||
2. **进入应用开发**
|
||||
左侧选 **应用开发** → **企业内部开发** → 点击 **创建应用**(或选择已有应用)。填写应用名称等基本信息后创建。
|
||||
|
||||
3. **拿到 Client ID 和 Client Secret**
|
||||
- 左侧点 **凭证与基础信息**(在「基础信息」下)。
|
||||
- 页面上有 **Client ID(原 AppKey)** 和 **Client Secret(原 AppSecret)**。
|
||||
- 点击复制,**不要手打**,注意:数字 **0** 和字母 **o**、数字 **1** 和字母 **l** 容易抄错(例如 `ding9gf9tiozuc504aer` 中间是数字 **504** 不是 5o4)。
|
||||
|
||||
4. **开通机器人并选 Stream 模式**
|
||||
- 左侧 **应用能力** → **机器人**。
|
||||
- 打开「机器人配置」开关。
|
||||
- 填写机器人名称、简介等(必填项按提示填)。
|
||||
- **关键**:消息接收方式要选 **「Stream 模式」**(流式接入)。若只有「HTTP 回调」或未选 Stream,本程序收不到消息。
|
||||
- 保存。
|
||||
|
||||
5. **权限与发布**
|
||||
- 左侧 **权限管理**:搜索「机器人」「消息」等,勾选**接收消息**、**发送消息**等机器人相关权限,并确认授权。
|
||||
- 左侧 **版本管理与发布**:若有未发布配置,点击 **发布新版本** / **上线**,否则修改不生效。
|
||||
|
||||
6. **填回 CyberStrikeAI**
|
||||
- 回到 CyberStrikeAI → 系统设置 → 机器人设置 → 钉钉。
|
||||
- 勾选「启用钉钉机器人」。
|
||||
- **Client ID (AppKey)** 粘贴第 3 步复制的 Client ID。
|
||||
- **Client Secret** 粘贴第 3 步复制的 Client Secret。
|
||||
- 点击 **应用配置**,然后**重启 CyberStrikeAI**。
|
||||
|
||||
---
|
||||
|
||||
**CyberStrikeAI 钉钉栏位对照**
|
||||
|
||||
| CyberStrikeAI 中填写项 | 在钉钉开放平台的来源 |
|
||||
|------------------------|------------------------|
|
||||
| 启用钉钉机器人 | 勾选即启用 |
|
||||
| Client ID (AppKey) | 凭证与基础信息 → **Client ID(原 AppKey)** |
|
||||
| Client Secret | 凭证与基础信息 → **Client Secret(原 AppSecret)** |
|
||||
|
||||
---
|
||||
|
||||
### 3.2 飞书 (Lark)
|
||||
|
||||
| 配置项 | 说明 |
|
||||
|--------|------|
|
||||
| 启用飞书机器人 | 勾选后启动飞书长连接 |
|
||||
| App ID | 飞书开放平台应用凭证中的 App ID |
|
||||
| App Secret | 飞书开放平台应用凭证中的 App Secret |
|
||||
| Verify Token | 事件订阅用(可选) |
|
||||
|
||||
**飞书配置简要步骤**:登录 [飞书开放平台](https://open.feishu.cn) → 创建企业自建应用 → 在「凭证与基础信息」中获取 **App ID**、**App Secret** → 在「应用能力」中开通**机器人**并启用相应权限 → **在「事件订阅」中添加事件**(见下)→ 发布应用 → 将 App ID、App Secret 填到 CyberStrikeAI 机器人设置 → 保存。
|
||||
|
||||
**重要:事件订阅**
|
||||
飞书长连接只有在开放平台订阅了「接收消息」事件后才会收到用户消息。请在该应用的 **事件订阅** 页面点击「添加事件」,在「消息与群组」下勾选 **接收消息(im.message.receive_v1)** 或同类事件;若未添加,连接会建立成功但收不到任何消息,表现为发消息后本地无日志、机器人无回复。
|
||||
|
||||
**飞书权限配置(必读)**
|
||||
在 **权限管理** 中需开通以下权限(与开放平台列表中的名称、标识一致);修改后需在 **版本管理与发布** 中发布新版本才生效。
|
||||
|
||||
| 权限名称(开放平台中显示) | 权限标识 | 说明 |
|
||||
|----------------------------|----------|------|
|
||||
| 获取与发送单聊、群组消息 | `im:message` | 收发消息的基础权限,**必须开通**。 |
|
||||
| 接收群聊中@机器人消息事件 | `im:message.group_at_msg:readonly` | 群聊中 @ 机器人时收消息,需开通。 |
|
||||
| 读取用户发给机器人的单聊消息 | `im:message.p2p_msg:readonly` | 单聊收消息,**必须开通**,否则私聊发消息没反应。 |
|
||||
| 获取单聊、群组消息 | `im:message:readonly` | 读取消息内容,**必须开通**。 |
|
||||
|
||||
**事件订阅**(与权限分开配置):在 **事件订阅** 中添加 **接收消息(im.message.receive_v1)**,否则长连接收不到消息推送。
|
||||
|
||||
- **单聊**:在飞书里打开与机器人的私聊窗口,直接发「帮助」或任意文字即可,无需 @。
|
||||
- **群聊**:在群里只有 **@ 机器人** 后发送的内容才会被机器人收到并回复。
|
||||
|
||||
---
|
||||
|
||||
### 3.3 企业微信 (WeCom)
|
||||
|
||||
> 企业微信目前采用「HTTP 回调 + 主动发送消息 API」的方式工作:
|
||||
> - 用户发消息 → 企业微信以加密 XML **回调到你的服务器**(本程序的 `/api/robot/wecom`);
|
||||
> - CyberStrikeAI 解密并调用 AI → 使用企业微信的 `message/send` 接口**主动发消息给用户**。
|
||||
|
||||
**配置概览:**
|
||||
|
||||
- 在企业微信管理后台创建或选择一个**自建应用**。
|
||||
- 在该应用的「接收消息」处配置回调 URL、Token、EncodingAESKey。
|
||||
- 在 CyberStrikeAI 的 `config.yaml` 中填入:
|
||||
- `robots.wecom.corp_id`:企业 ID(CorpID)
|
||||
- `robots.wecom.agent_id`:应用的 AgentId
|
||||
- `robots.wecom.token`:消息回调使用的 Token
|
||||
- `robots.wecom.encoding_aes_key`:消息回调使用的 EncodingAESKey
|
||||
- `robots.wecom.secret`:该应用的 Secret(用于调用企业微信主动发送消息接口)
|
||||
|
||||
> **重要:IP 白名单(errcode 60020)**
|
||||
> CyberStrikeAI 使用 `https://qyapi.weixin.qq.com/cgi-bin/message/send` 主动发送 AI 回复。
|
||||
> 若企业微信日志或本程序日志中出现 `errcode 60020 not allow to access from your ip`:
|
||||
>
|
||||
> - 说明你的服务器出口 IP **没有加入企业微信的 IP 白名单**;
|
||||
> - 请在企业微信管理后台中找到该自建应用的**「安全设置 / IP 白名单」**(具体入口可能因版本略有不同),将运行 CyberStrikeAI 的服务器公网 IP(如 `110.xxx.xxx.xxx`)加入白名单;
|
||||
> - 保存后等待生效,再次发送消息测试。
|
||||
>
|
||||
> 如果 IP 未加入白名单,企业微信会拒绝主动发送消息,表现为:
|
||||
> - 回调接口 `/api/robot/wecom` 能正常收到并处理消息;
|
||||
> - 但手机端**始终收不到 AI 回复**,日志中有 `not allow to access from your ip` 提示。
|
||||
|
||||
---
|
||||
|
||||
### 3.4 个人微信 (WeChat / iLink)
|
||||
|
||||
> 个人微信采用「Web 扫码绑定 + iLink 长轮询」方式工作:
|
||||
> - 在 CyberStrikeAI Web 端生成二维码 → 用**手机微信**扫码并确认绑定;
|
||||
> - 绑定成功后自动写入 `config.yaml` 的 `robots.wechat`,并启动 iLink 长轮询(程序主动连接 `ilinkai.weixin.qq.com` 收消息);
|
||||
> - **无需**在服务器上配置公网回调 URL,也**无需**去微信开放平台注册应用。
|
||||
|
||||
**与企业微信的区别**
|
||||
|
||||
| 项目 | 个人微信 (iLink) | 企业微信 (WeCom) |
|
||||
|------|------------------|------------------|
|
||||
| 使用场景 | 个人微信私聊 | 企业微信自建应用 |
|
||||
| 配置方式 | Web 端扫码绑定 | 管理后台配置回调 URL + Token |
|
||||
| 是否需要公网 | 否(长轮询出站即可) | 是(需可被企业微信访问的 HTTPS 回调) |
|
||||
| 配置段 | `robots.wechat` | `robots.wecom` |
|
||||
|
||||
**绑定步骤(按顺序做)**
|
||||
|
||||
1. **登录 CyberStrikeAI Web 端**
|
||||
左侧 **系统设置** → **机器人设置** → 点击 **微信 / iLink** 卡片。
|
||||
|
||||
2. **(可选)勾选「启用微信机器人」**
|
||||
首次绑定可跳过;绑定成功后会自动勾选并启用。
|
||||
|
||||
3. **生成二维码**
|
||||
点击 **「生成二维码并绑定」**。页面会显示二维码(约 **5 分钟**有效;过期请重新生成)。
|
||||
|
||||
4. **微信扫码确认**
|
||||
- 用手机微信扫描页面二维码;
|
||||
- 按手机提示完成确认;
|
||||
- 若手机微信弹出**配对数字**,在 Web 页面对应输入框填写并点击 **提交**(仅部分账号需要)。
|
||||
|
||||
5. **等待绑定完成**
|
||||
页面显示「绑定成功,微信机器人已启用」即完成。`bot_token`、`ilink_bot_id` 等会自动写入 `config.yaml`,程序会自动重启 iLink 长轮询,**一般无需手动重启服务**。
|
||||
|
||||
6. **在手机微信里测试**
|
||||
打开与 CyberStrikeAI 机器人的**私聊**(绑定后微信内会出现对应会话),发送「帮助」或任意文字测试。
|
||||
|
||||
**CyberStrikeAI 微信栏位说明**
|
||||
|
||||
| 栏位 | 说明 |
|
||||
|------|------|
|
||||
| 启用微信机器人 | 勾选后启动 iLink 长轮询;绑定成功后会自动勾选 |
|
||||
| 生成二维码并绑定 | 发起扫码绑定流程 |
|
||||
| **高级设置**(一般保持默认即可) | |
|
||||
| API Base URL | 默认 `https://ilinkai.weixin.qq.com` |
|
||||
| Bot Type | 默认 `3` |
|
||||
| Bot Agent | 默认 `CyberStrikeAI/1.0` |
|
||||
| iLink Bot ID | 绑定成功后自动填充,只读 |
|
||||
|
||||
**使用方式**
|
||||
|
||||
- 仅支持在与机器人的**私聊**中对话,直接发送文字即可,**不需要 @**。
|
||||
- 不支持群聊 @ 机器人(与钉钉/飞书群聊不同)。
|
||||
- 仅处理**文本消息**;图片、语音等会忽略或提示暂不支持。
|
||||
|
||||
**重新绑定**
|
||||
|
||||
- 若需更换绑定的微信账号,在机器人设置页点击 **「重新绑定」**,再次扫码即可。
|
||||
- 若提示「该微信已绑定过,无需重复绑定」,说明该账号此前已完成绑定。
|
||||
|
||||
**常见问题**
|
||||
|
||||
| 现象 | 处理 |
|
||||
|------|------|
|
||||
| 二维码过期 | 重新点击「生成二维码并绑定」(有效期约 5 分钟) |
|
||||
| 扫码后要求输入数字 | 查看手机微信显示的配对数字,在 Web 页面输入并提交 |
|
||||
| 绑定成功但发消息无回复 | 看程序日志是否有 `微信 iLink 长轮询已启动`、`微信收到消息`;确认已勾选「启用微信机器人」 |
|
||||
| 断网或睡眠后无回复 | 程序会自动重连(约 5~60 秒);仍无回复可重启 CyberStrikeAI |
|
||||
| 无法生成二维码 | 确认服务器能访问 `https://ilinkai.weixin.qq.com`(出站 HTTPS) |
|
||||
|
||||
---
|
||||
|
||||
### 3.5 Telegram
|
||||
|
||||
> Telegram 使用 **Bot API 长轮询**(`getUpdates`):程序主动连接 `api.telegram.org` 收消息,**无需公网回调**。
|
||||
|
||||
**配置步骤:**
|
||||
|
||||
1. 在 Telegram 中找 **@BotFather**,发送 `/newbot` 创建机器人,获得 **Bot Token**。
|
||||
2. CyberStrikeAI → **系统设置** → **机器人设置** → **Telegram**。
|
||||
3. 勾选「启用 Telegram 机器人」,粘贴 **Bot Token**。
|
||||
4. (可选)填写 Bot Username(不含 `@`),或留空由程序自动 `getMe`。
|
||||
5. (可选)勾选「允许群聊」— 群聊中仅响应 **@机器人** 的消息。
|
||||
6. 点击 **应用配置**(会自动重启长轮询连接)。
|
||||
|
||||
**使用:** 与机器人私聊直接发消息;群聊需 @ 机器人(且已勾选允许群聊)。
|
||||
|
||||
---
|
||||
|
||||
### 3.6 Slack
|
||||
|
||||
> Slack 使用 **Socket Mode**(出站 WebSocket):需 **Bot Token** 与 **App-Level Token**,**无需公网回调**。
|
||||
|
||||
**配置步骤:**
|
||||
|
||||
1. 在 [Slack API](https://api.slack.com/apps) 创建 App → 启用 **Socket Mode**。
|
||||
2. **Basic Information** → **App-Level Tokens** → 创建 token(scope: `connections:write`),即 **xapp-** 开头。
|
||||
3. **OAuth & Permissions** → 添加 Bot Token Scopes:`app_mentions:read`、`chat:write`、`im:history`、`im:read` 等 → 安装到工作区,获得 **xoxb-** Bot Token。
|
||||
4. **Event Subscriptions** → 订阅 `message.im`、`app_mention` 等(Socket Mode 下在应用内配置)。
|
||||
5. 在 CyberStrikeAI 填入 Bot Token 与 App-Level Token → **应用配置**。
|
||||
|
||||
**使用:** 与 Bot 私聊直接发;频道中需 @ 机器人。
|
||||
|
||||
---
|
||||
|
||||
### 3.7 Discord
|
||||
|
||||
> Discord 使用 **Gateway WebSocket**:程序主动连接 Discord Gateway,**无需公网回调**。
|
||||
|
||||
**配置步骤:**
|
||||
|
||||
1. 在 [Discord Developer Portal](https://discord.com/developers/applications) 创建应用 → **Bot** → 复制 **Token**。
|
||||
2. 开启 **Privileged Gateway Intents** 中的 **Message Content Intent**(否则读不到消息正文)。
|
||||
3. OAuth2 → URL Generator → scopes: `bot` → 权限勾选 **Send Messages**、**Read Message History** 等 → 邀请 Bot 到服务器。
|
||||
4. CyberStrikeAI → **机器人设置** → **Discord** → 填入 Token → **应用配置**。
|
||||
5. (可选)勾选「允许服务器频道」— 频道中仅响应 **@机器人**。
|
||||
|
||||
**使用:** 与 Bot 私聊直接发;服务器频道需 @ 机器人(且已勾选允许服务器频道)。
|
||||
|
||||
---
|
||||
|
||||
### 3.8 QQ 机器人
|
||||
|
||||
> QQ 机器人使用 **QQ 开放平台 WebSocket**(官方 `botgo` SDK):支持 C2C 私聊与群 @,**无需公网回调**(WebSocket 出站连接)。
|
||||
|
||||
**配置步骤:**
|
||||
|
||||
1. 在 [QQ 机器人开放平台](https://q.qq.com) 创建机器人,获取 **App ID** 与 **Client Secret**。
|
||||
2. 在沙箱中添加测试成员(上线前仅沙箱可对话)。
|
||||
3. 订阅 **C2C 消息**、**群 @ 消息** 等事件(WebSocket 模式)。
|
||||
4. CyberStrikeAI → **机器人设置** → **QQ 机器人** → 填入 App ID、Client Secret。
|
||||
5. 测试阶段勾选 **沙箱环境**;正式上线后取消沙箱并发布。
|
||||
6. 点击 **应用配置**。
|
||||
|
||||
**使用:** 与机器人 C2C 私聊直接发;QQ 群中需 @ 机器人。
|
||||
|
||||
> 注意:QQ 官方正逐步推广 Webhook 回调;当前实现使用 WebSocket(与钉钉/飞书类似的长连接模式)。若配置变更后连接未刷新,可重启 CyberStrikeAI 进程。
|
||||
|
||||
---
|
||||
|
||||
## 四、机器人命令
|
||||
|
||||
在任一已接入平台(钉钉/飞书/微信/Telegram/Slack/Discord/QQ 等)向机器人发送以下**文本命令**(仅支持文本):
|
||||
|
||||
| 命令 | 说明 |
|
||||
|------|------|
|
||||
| **帮助** | 显示命令帮助与说明 |
|
||||
| **列表** 或 **对话列表** | 列出所有对话的标题与对话 ID |
|
||||
| **切换 \<对话ID\>** 或 **继续 \<对话ID\>** | 指定对话 ID,后续消息在该对话中继续 |
|
||||
| **新对话** | 开启一个新对话,后续消息在新对话中 |
|
||||
| **清空** | 清空当前对话上下文(效果等同「新对话」) |
|
||||
| **当前** | 显示当前对话 ID 与标题 |
|
||||
| **停止** | 中断当前正在执行的任务 |
|
||||
| **角色** 或 **角色列表** | 列出所有可用角色(渗透测试、CTF、Web 应用扫描等) |
|
||||
| **角色 \<角色名\>** 或 **切换角色 \<角色名\>** | 切换当前使用的角色 |
|
||||
| **删除 \<对话ID\>** | 删除指定对话 |
|
||||
| **版本** | 显示当前 CyberStrikeAI 版本号 |
|
||||
|
||||
除以上命令外,**直接输入任意文字**会作为用户消息发给 AI,与 Web 端对话逻辑一致(渗透测试/安全分析等)。
|
||||
|
||||
---
|
||||
|
||||
## 五、如何使用(要 @ 机器人吗?)
|
||||
|
||||
- **个人微信**:在与 CyberStrikeAI 机器人的**私聊**中直接发送即可,**不需要 @**(不支持群聊)。
|
||||
- **钉钉 / 飞书单聊(推荐)**:**搜索并打开该机器人**,进入**私聊**,直接输入「帮助」或任意文字即可,**不需要 @**。
|
||||
- **钉钉 / 飞书群聊**:若机器人被添加到群里,在群内只有 **@机器人** 后发送的消息才会被机器人收到并回复;不 @ 的群消息不会触发机器人。
|
||||
|
||||
总结:**个人微信、单聊时直接发**;**钉钉/飞书在群里用时需要 @机器人** 再发内容。
|
||||
|
||||
---
|
||||
|
||||
## 六、推荐使用流程(避免漏步骤)
|
||||
|
||||
**个人微信(最简单,无需开放平台)**
|
||||
|
||||
1. CyberStrikeAI Web 端 → 系统设置 → 机器人设置 → **微信 / iLink** → **生成二维码并绑定**。
|
||||
2. 手机微信扫码确认(如需配对数字则在 Web 页填写)。
|
||||
3. 绑定成功后,在手机微信私聊中发「帮助」测试。
|
||||
|
||||
**钉钉 / 飞书**
|
||||
|
||||
1. **在开放平台**:按第三节完成应用创建、凭证复制、机器人开通(钉钉务必选 **Stream 模式**)、权限与发布。
|
||||
2. **在 CyberStrikeAI**:系统设置 → 机器人设置 → 勾选对应平台,粘贴 Client ID/App ID、Client Secret/App Secret → 点击 **应用配置**。
|
||||
3. **重启 CyberStrikeAI 进程**(否则长连接不会建立)。
|
||||
4. **在手机钉钉/飞书**:找到该机器人(单聊直接发,群聊需 @机器人),发「帮助」或任意内容测试。
|
||||
|
||||
若发消息没反应,先看 **第九节排查** 和 **第十节常见弯路**。
|
||||
|
||||
---
|
||||
|
||||
## 七、配置文件示例
|
||||
|
||||
`config.yaml` 中机器人相关片段示例:
|
||||
|
||||
```yaml
|
||||
robots:
|
||||
wechat: # 个人微信 iLink(扫码绑定后自动写入,一般无需手填)
|
||||
enabled: true
|
||||
bot_token: "your_bot_token@im.bot:..."
|
||||
ilink_bot_id: "your_bot_id@im.bot"
|
||||
ilink_user_id: "your_user_id@im.wechat"
|
||||
base_url: "https://ilinkai.weixin.qq.com"
|
||||
bot_type: "3"
|
||||
bot_agent: "CyberStrikeAI/1.0"
|
||||
dingtalk:
|
||||
enabled: true
|
||||
client_id: "your_dingtalk_app_key"
|
||||
client_secret: "your_dingtalk_app_secret"
|
||||
lark:
|
||||
enabled: true
|
||||
app_id: "your_lark_app_id"
|
||||
app_secret: "your_lark_app_secret"
|
||||
verify_token: ""
|
||||
wecom:
|
||||
enabled: false
|
||||
corp_id: ""
|
||||
agent_id: 0
|
||||
token: ""
|
||||
encoding_aes_key: ""
|
||||
secret: ""
|
||||
telegram:
|
||||
enabled: false
|
||||
bot_token: ""
|
||||
allow_group_messages: false
|
||||
slack:
|
||||
enabled: false
|
||||
bot_token: ""
|
||||
app_token: ""
|
||||
discord:
|
||||
enabled: false
|
||||
bot_token: ""
|
||||
allow_guild_messages: false
|
||||
qq:
|
||||
enabled: false
|
||||
app_id: ""
|
||||
client_secret: ""
|
||||
sandbox: true
|
||||
```
|
||||
|
||||
修改钉钉/飞书/企业微信/Telegram/Slack/Discord/QQ 配置后,点击 **应用配置** 会自动重启对应长连接。个人微信扫码绑定成功后会自动写入并重启 iLink 连接。
|
||||
|
||||
---
|
||||
|
||||
## 八、如何验证是否可用(无需钉钉/飞书客户端)
|
||||
|
||||
在未安装钉钉或飞书时,可用**测试接口**验证机器人逻辑是否正常:
|
||||
|
||||
1. 先登录 CyberStrikeAI Web 端(保证有登录态)。
|
||||
2. 使用 curl 调用测试接口(需携带登录后的 Cookie):
|
||||
|
||||
```bash
|
||||
# 将 YOUR_COOKIE 替换为登录后获得的 Cookie(浏览器 F12 → 网络 → 任意请求 → 请求头中的 Cookie)
|
||||
curl -X POST "http://localhost:8080/api/robot/test" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Cookie: YOUR_COOKIE" \
|
||||
-d '{"platform":"dingtalk","user_id":"test_user","text":"帮助"}'
|
||||
```
|
||||
|
||||
若返回 JSON 中含有 `"reply":"【CyberStrikeAI 机器人命令】..."`,说明命令处理正常。可再试 `"text":"列表"`、`"text":"当前"` 等。
|
||||
|
||||
接口说明:`POST /api/robot/test`(需登录),请求体 `{"platform":"可选","user_id":"可选","text":"必填"}`,响应 `{"reply":"回复内容"}`。
|
||||
|
||||
---
|
||||
|
||||
## 九、发消息没反应时排查
|
||||
|
||||
### 9.1 个人微信
|
||||
|
||||
按顺序检查:
|
||||
|
||||
1. **是否已完成扫码绑定**
|
||||
机器人设置页应显示「已连接」或已绑定 Bot ID;`config.yaml` 中 `robots.wechat.bot_token` 不应为空。
|
||||
|
||||
2. **是否已启用**
|
||||
确认「启用微信机器人」已勾选;若刚修改过,可重启 CyberStrikeAI 进程。
|
||||
|
||||
3. **看程序日志**
|
||||
- 启动后应看到:`微信 iLink 长轮询已启动`;
|
||||
- 发消息后应有:`微信收到消息`;若没有,多为未绑定成功或 `bot_token` 失效,可尝试 **重新绑定**。
|
||||
- 若出现 `微信 iLink 长轮询异常,将自动重连`,等待自动重连或重启进程。
|
||||
|
||||
4. **网络**
|
||||
服务器需能访问 `https://ilinkai.weixin.qq.com`(出站 HTTPS)。绑定阶段若无法生成二维码,优先检查此项。
|
||||
|
||||
5. **断网或睡眠后**
|
||||
与钉钉/飞书类似,程序会**自动重连**(约 5~60 秒);仍无回复可重启 CyberStrikeAI。
|
||||
|
||||
### 9.2 钉钉
|
||||
|
||||
按顺序检查:
|
||||
|
||||
0. **笔记本合盖睡眠 / 断网后**
|
||||
钉钉、飞书均使用长连接收消息,睡眠或断网后连接会断开。程序会**自动重连**(约 5 秒~60 秒内重试)。唤醒或恢复网络后稍等一会儿再发消息;若仍无反应,可重启 CyberStrikeAI 进程。
|
||||
|
||||
1. **Client ID / Client Secret 是否与开放平台完全一致**
|
||||
从「凭证与基础信息」里**复制粘贴**,不要手打。注意数字 **0** 与字母 **o**、数字 **1** 与字母 **l**(例如 `ding9gf9tiozuc504aer` 中间是 **504** 不是 5o4)。
|
||||
|
||||
2. **是否在保存配置后重启了应用**
|
||||
机器人长连接在**应用启动时**建立。在 Web 端点击「应用配置」只写入配置文件,**必须重启 CyberStrikeAI 进程**后钉钉连接才会生效。
|
||||
|
||||
3. **看程序日志**
|
||||
- 启动后应看到:`钉钉 Stream 正在连接…`、`钉钉 Stream 已启动(无需公网),等待收消息`。
|
||||
- 若出现 `钉钉 Stream 长连接退出` 且带错误信息,多为 **Client ID / Client Secret 错误**或**开放平台未开通流式接入**。
|
||||
- 在钉钉里发一条消息后,若有收到,应有日志:`钉钉收到消息`;若没有,说明钉钉未把消息推到本程序(回头检查开放平台「机器人」是否开通、是否选用 **Stream 模式**)。
|
||||
|
||||
4. **开放平台侧**
|
||||
应用需已**发布**;在「机器人」能力中需开启**流式接入(Stream)** 用于接收消息(仅 HTTP 回调不够);权限管理里需有机器人接收、发送消息等权限。
|
||||
|
||||
---
|
||||
|
||||
## 十、常见弯路(避免踩坑)
|
||||
|
||||
- **个人微信与企业微信混淆**:个人微信走 `robots.wechat` + Web 扫码绑定;企业微信走 `robots.wecom` + 管理后台回调 URL,二者完全不同。
|
||||
- **个人微信二维码过期**:二维码约 5 分钟有效,过期需重新生成,不要一直扫旧码。
|
||||
- **用错了机器人类型**:在钉钉**群里**添加的「自定义」机器人(Webhook + 加签)**不能**用来做对话,本程序只支持**开放平台「企业内部应用」**里的机器人。
|
||||
- **只保存没重启**:钉钉/飞书改完配置后必须**重启应用**,否则长连接不会建立(个人微信扫码绑定会自动重启连接)。
|
||||
- **Client ID 抄错**:开放平台是 `504` 就填 `504`,不要填成 `5o4`;尽量用复制粘贴。
|
||||
- **钉钉只开了 HTTP 回调没开 Stream**:本程序通过 **Stream 长连接**收消息,开放平台里机器人的消息接收方式必须选 **Stream 模式**。
|
||||
- **应用没发布**:开放平台里修改了机器人或权限后,要在「版本管理与发布」里**发布新版本**,否则不生效。
|
||||
|
||||
---
|
||||
|
||||
## 十一、注意事项
|
||||
|
||||
- 各平台均**仅处理文本消息**;其他类型(如图片、语音)会提示暂不支持或忽略。
|
||||
- 个人微信仅支持**私聊**,不支持群聊 @ 机器人。
|
||||
- 会话与 Web 端共用同一套对话数据:在机器人里创建的对话会在 Web 端「对话」列表中看到,反之亦然。
|
||||
- 机器人执行与 **Eino 单/多代理** 相同逻辑(`ProcessMessageForRobot`,含进度回调与过程详情入库),仅不向客户端推送 SSE,最后一次性回复个人微信/钉钉/飞书/企业微信。默认 `robot_default_agent_mode: eino_single`。
|
||||
@@ -0,0 +1,223 @@
|
||||
# 运维 Runbooks
|
||||
|
||||
[English](../en-US/runbooks.md)
|
||||
|
||||
Runbook 是“遇到一个真实任务时照着做”的步骤清单。本文覆盖 CyberStrikeAI 最常见的运维和安全测试操作。
|
||||
|
||||
## Runbook 1:生产实例从 0 到可用
|
||||
|
||||
适用:内网团队或生产红队平台首次部署。
|
||||
|
||||
如果只是本地或临时验证,优先用仓库自带脚本启动:
|
||||
|
||||
```bash
|
||||
chmod +x run.sh && ./run.sh
|
||||
```
|
||||
|
||||
确认可用后,再决定是否升级为 systemd + 反向代理的长期部署。
|
||||
|
||||
### 前置确认
|
||||
|
||||
- 运行主机已纳入资产管理。
|
||||
- 访问路径确定:内网、VPN、堡垒机或反向代理。
|
||||
- 有模型 API Key 和允许使用的模型。
|
||||
- 已决定是否启用 C2、WebShell、外部 MCP。
|
||||
|
||||
### 步骤
|
||||
|
||||
1. 准备目录:
|
||||
|
||||
```bash
|
||||
mkdir -p /opt/CyberStrikeAI
|
||||
```
|
||||
|
||||
2. 放置二进制和资源目录:
|
||||
|
||||
```text
|
||||
cyberstrike-ai
|
||||
web/
|
||||
tools/
|
||||
roles/
|
||||
skills/
|
||||
agents/
|
||||
docs/
|
||||
config.yaml
|
||||
```
|
||||
|
||||
3. 修改关键配置:
|
||||
|
||||
```yaml
|
||||
auth:
|
||||
password: "<long-random-password>"
|
||||
server:
|
||||
host: 127.0.0.1
|
||||
port: 8080
|
||||
tls_enabled: false
|
||||
audit:
|
||||
enabled: true
|
||||
c2:
|
||||
enabled: false
|
||||
```
|
||||
|
||||
4. 配置反向代理 HTTPS,并限制来源 IP。
|
||||
5. 使用 systemd 托管进程。
|
||||
6. 登录 Web,测试模型。
|
||||
7. 检查工具列表和审计日志。
|
||||
8. 建立备份策略。
|
||||
|
||||
### 验收
|
||||
|
||||
- `/api/auth/validate` 登录后返回成功。
|
||||
- 模型测试成功。
|
||||
- `tools/` 能正常加载。
|
||||
- 审计页面能看到登录事件。
|
||||
- C2 在不需要时访问返回禁用状态。
|
||||
|
||||
### 回滚
|
||||
|
||||
恢复:
|
||||
|
||||
- 上一版二进制。
|
||||
- 上一版 `config.yaml`。
|
||||
- 升级前 `data/`。
|
||||
|
||||
## Runbook 2:接入外部 MCP
|
||||
|
||||
适用:接入本地工具服务、Burp 辅助服务、资产查询服务等。
|
||||
|
||||
### 前置确认
|
||||
|
||||
- MCP 服务可信。
|
||||
- 明确它是否能读文件、写文件、执行命令或访问第三方网络。
|
||||
- 确定接入方式:stdio、HTTP、SSE。
|
||||
|
||||
### 步骤
|
||||
|
||||
1. 在外部 MCP 页面新增服务。
|
||||
2. 如果是 stdio,填写命令、参数、工作目录和环境变量。
|
||||
3. 如果是 HTTP/SSE,填写 URL 和认证信息。
|
||||
4. 启动服务。
|
||||
5. 查看 `/api/external-mcp/stats`。
|
||||
6. 检查工具列表是否出现。
|
||||
7. 用低风险参数执行一次工具。
|
||||
8. 把高风险工具排除在全局免审批白名单之外。
|
||||
|
||||
### 验收
|
||||
|
||||
- MCP 状态为 running。
|
||||
- 工具 schema 可见。
|
||||
- Agent 能通过 `tool_search` 找到工具。
|
||||
- 工具执行记录出现在监控页。
|
||||
- 配置变更出现在审计页。
|
||||
|
||||
### 回滚
|
||||
|
||||
- 停止 MCP。
|
||||
- 删除外部 MCP 配置。
|
||||
- 从角色/白名单中移除相关工具。
|
||||
- 检查 Agent 当前任务是否仍持有旧上下文。
|
||||
|
||||
## Runbook 3:启用知识库并调优召回
|
||||
|
||||
适用:把内部安全知识、漏洞手册或测试方法接入 Agent。
|
||||
|
||||
### 步骤
|
||||
|
||||
1. 修改配置:
|
||||
|
||||
```yaml
|
||||
knowledge:
|
||||
enabled: true
|
||||
base_path: knowledge_base
|
||||
embedding:
|
||||
model: text-embedding-v4
|
||||
retrieval:
|
||||
top_k: 5
|
||||
similarity_threshold: 0.4
|
||||
```
|
||||
|
||||
2. 把 Markdown 放入 `knowledge_base/`。
|
||||
3. 在 Web 知识库页面执行扫描。
|
||||
4. 重建索引。
|
||||
5. 准备 5 到 10 个固定测试问题。
|
||||
6. 搜索并记录命中情况。
|
||||
7. 根据结果调 `threshold`、`top_k`、chunk 参数和文档标题。
|
||||
|
||||
### 验收
|
||||
|
||||
- `index-status` 显示索引完成。
|
||||
- 常见问题能命中正确文档。
|
||||
- Agent 在不确定时会先查知识库。
|
||||
- 检索日志能显示查询和命中文档。
|
||||
|
||||
### 常见回滚
|
||||
|
||||
- 关闭 `knowledge.enabled`。
|
||||
- 恢复旧的 `data/knowledge.db`。
|
||||
- 降低 `batch_size` 后重新索引。
|
||||
|
||||
## Runbook 4:一次授权 Web 测试标准流程
|
||||
|
||||
适用:对授权目标做 Web 安全测试。
|
||||
|
||||
### 步骤
|
||||
|
||||
1. 创建项目,记录授权范围。
|
||||
2. 新建对话,绑定项目。
|
||||
3. 选择最小角色,例如“信息收集”或“Web 应用扫描”。
|
||||
4. 明确目标、时间窗口、禁止动作。
|
||||
5. 先执行只读信息收集。
|
||||
6. 发现线索后写入项目事实。
|
||||
7. 对高风险验证请求使用 HITL。
|
||||
8. 确认漏洞后写入漏洞管理。
|
||||
9. 生成攻击链或报告材料。
|
||||
10. 清理上传文件、临时 workspace 和无用执行记录。
|
||||
|
||||
### 验收
|
||||
|
||||
- 每个漏洞都有证据、影响、复现和修复建议。
|
||||
- 高风险操作有 HITL 记录。
|
||||
- 项目事实能复现测试路径。
|
||||
- 报告不包含无关敏感数据。
|
||||
|
||||
## Runbook 5:C2 演练结束清理
|
||||
|
||||
适用:授权演练中启用了 C2。
|
||||
|
||||
### 步骤
|
||||
|
||||
1. 停止所有 listener。
|
||||
2. 列出 sessions,确认没有仍在线的授权会话。
|
||||
3. 导出必要 task 结果。
|
||||
4. 删除 payload 或移动到受控归档。
|
||||
5. 删除无用 task、event、file。
|
||||
6. 审计 C2 操作记录。
|
||||
7. 将关键结果写入项目事实或报告。
|
||||
8. 将 `c2.enabled` 改回 false,除非平台持续需要。
|
||||
|
||||
### 验收
|
||||
|
||||
- 无运行中 listener。
|
||||
- 无待处理 task。
|
||||
- payload 不再公开可下载。
|
||||
- 审计与报告能解释整个生命周期。
|
||||
|
||||
## Runbook 6:Agent 不调用工具
|
||||
|
||||
排查顺序:
|
||||
|
||||
1. 当前角色是否绑定了该工具。
|
||||
2. 工具是否在 `/api/config/tools` 中出现。
|
||||
3. `tool_search` 是否隐藏了该工具。
|
||||
4. 工具描述是否过短或命名不清。
|
||||
5. HITL 是否挂起。
|
||||
6. Agent 是否处于总结/结束阶段。
|
||||
7. 多代理子 Agent 是否有自己的工具限制。
|
||||
|
||||
修复方式:
|
||||
|
||||
- 把工具加入角色。
|
||||
- 优化 `short_description`。
|
||||
- 加入 `tool_search_always_visible_tools`。
|
||||
- 在提示词中明确什么时候使用。
|
||||
- 检查过程详情和监控记录。
|
||||
@@ -0,0 +1,140 @@
|
||||
# 安全加固指南
|
||||
|
||||
[English](../en-US/security-hardening.md)
|
||||
|
||||
本文给出 CyberStrikeAI 上线前和持续运行中的安全加固清单。
|
||||
|
||||
## 上线前必做
|
||||
|
||||
- 修改 `auth.password` 为长随机密码。
|
||||
- 使用 HTTPS,或放在可信反向代理之后。
|
||||
- 限制来源 IP、VPN 或堡垒机访问。
|
||||
- 开启 `audit.enabled`。
|
||||
- 不需要 C2 时设置 `c2.enabled: false`。
|
||||
- 不暴露独立 HTTP MCP,除非设置强认证和网络隔离。
|
||||
- 外部 MCP 只接可信服务。
|
||||
- 备份 `config.yaml`、`data/`、自定义资源目录。
|
||||
|
||||
## 反向代理建议
|
||||
|
||||
Nginx 基线:
|
||||
|
||||
```nginx
|
||||
client_max_body_size 200m;
|
||||
proxy_buffering off;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
```
|
||||
|
||||
建议额外加:
|
||||
|
||||
```nginx
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header Referrer-Policy no-referrer;
|
||||
add_header X-Frame-Options DENY;
|
||||
```
|
||||
|
||||
## HITL 白名单基线
|
||||
|
||||
推荐最小白名单:
|
||||
|
||||
```yaml
|
||||
hitl:
|
||||
tool_whitelist:
|
||||
- read_file
|
||||
- glob
|
||||
- grep
|
||||
- tool_search
|
||||
```
|
||||
|
||||
不要默认加入:
|
||||
|
||||
- `execute`
|
||||
- WebShell 写入/执行工具
|
||||
- C2 任务和 payload 工具
|
||||
- 外部 MCP 高风险工具
|
||||
- 删除、写入、上传、持久化相关工具
|
||||
|
||||
## 文件权限
|
||||
|
||||
建议:
|
||||
|
||||
```bash
|
||||
chmod 600 config.yaml
|
||||
chmod 700 data
|
||||
```
|
||||
|
||||
生产环境使用独立系统用户运行:
|
||||
|
||||
```text
|
||||
cyberstrike-ai:cyberstrike-ai
|
||||
```
|
||||
|
||||
避免 root 运行,除非明确需要绑定低端口或访问特殊资源。
|
||||
|
||||
## 外部 MCP 审查
|
||||
|
||||
接入前确认:
|
||||
|
||||
- 工具是否能执行命令。
|
||||
- 是否能读写本机文件。
|
||||
- 是否会把数据发往第三方。
|
||||
- 是否有自己的认证。
|
||||
- 是否会返回不可信网页或模型内容。
|
||||
- 是否需要容器隔离。
|
||||
|
||||
接入后:
|
||||
|
||||
- 高风险工具不进白名单。
|
||||
- 定期检查工具列表变化。
|
||||
- 审计配置变更。
|
||||
|
||||
## C2 和 WebShell
|
||||
|
||||
C2:
|
||||
|
||||
- 默认关闭。
|
||||
- 演练窗口临时开启。
|
||||
- Listener 端口与管理端口分离。
|
||||
- 结束后清理 payload、session、task、event。
|
||||
|
||||
WebShell:
|
||||
|
||||
- 只保存授权目标。
|
||||
- 使用清晰命名。
|
||||
- 写入/删除/执行必须审批。
|
||||
- 项目结束删除连接。
|
||||
|
||||
## 数据保留
|
||||
|
||||
建议:
|
||||
|
||||
- 审计:30-90 天。
|
||||
- 工具监控:90-180 天。
|
||||
- 上传附件:项目结束清理。
|
||||
- C2/WebShell 输出:只保留报告需要的证据。
|
||||
- 知识库:不放真实凭证和客户私密数据。
|
||||
|
||||
## 周期巡检
|
||||
|
||||
每周:
|
||||
|
||||
- 登录失败和异常 IP。
|
||||
- 配置变更。
|
||||
- 外部 MCP 增删改。
|
||||
- 长时间运行工具。
|
||||
- C2 是否被意外开启。
|
||||
- WebShell 连接是否过期。
|
||||
- 磁盘空间和数据库大小。
|
||||
|
||||
每个项目结束:
|
||||
|
||||
- 清理临时 workspace。
|
||||
- 删除无用附件。
|
||||
- 归档必要证据。
|
||||
- 删除过期 WebShell/C2 资源。
|
||||
- 导出审计记录。
|
||||
@@ -0,0 +1,180 @@
|
||||
# 安全模型
|
||||
|
||||
CyberStrikeAI 面向授权安全测试场景,内置命令执行、MCP 工具、WebShell、C2、批量任务和多代理编排等能力。部署者必须把它当作高权限安全工具管理,而不是普通聊天应用。
|
||||
|
||||
## 信任边界
|
||||
|
||||
主要边界:
|
||||
|
||||
- Web 登录用户:可以发起对话、调用工具、修改配置、管理 WebShell/C2/知识库。
|
||||
- Agent:根据角色、工具列表、HITL 策略调用内置或外部工具。
|
||||
- MCP 工具:可能访问本机文件、执行命令、调用外部服务或操作目标系统。
|
||||
- 外部 MCP:由第三方进程或远端服务提供,需单独信任。
|
||||
- 机器人入口:企业微信、钉钉、飞书等回调入口不走 Web 登录,但有平台验签和速率限制。
|
||||
|
||||
如果一个账号可以登录 Web,就应视为拥有该 CyberStrikeAI 实例的操作权限。
|
||||
|
||||
## 认证与会话
|
||||
|
||||
`auth.password` 是 Web 登录密码。建议:
|
||||
|
||||
- 首次部署立即修改默认密码。
|
||||
- 使用长随机密码,并限制分享范围。
|
||||
- 将服务放在内网、VPN、堡垒机或反向代理认证后面。
|
||||
- 生产环境开启 HTTPS,避免明文传输 Cookie。
|
||||
- 结合反向代理限制来源 IP。
|
||||
|
||||
登录态有效期由 `auth.session_duration_hours` 控制。
|
||||
|
||||
## 工具执行风险
|
||||
|
||||
工具来源包括:
|
||||
|
||||
- 内置安全执行工具。
|
||||
- `tools/` 下的 YAML 命令工具。
|
||||
- Eino Skills 文件系统工具,如 `read_file`、`write_file`、`edit_file`、`execute`。
|
||||
- 外部 MCP 暴露的工具。
|
||||
- C2 和 WebShell 相关 MCP 工具。
|
||||
|
||||
风险控制建议:
|
||||
|
||||
- 只启用当前任务需要的工具。
|
||||
- 高风险命令工具不要加入全局白名单。
|
||||
- 给角色绑定最小工具集合。
|
||||
- 对 destructive、持久化、横向移动、凭证操作保持人工审批。
|
||||
- 外部 MCP 尽量使用本地可信进程,远端 MCP 必须有认证和网络隔离。
|
||||
|
||||
## HITL
|
||||
|
||||
HITL 是工具调用前的审批层。常见模式:
|
||||
|
||||
- `human`:人工审批。
|
||||
- `audit_agent`:审计 Agent 自动审批。
|
||||
- `review_edit`:审计 Agent 可改参后放行。
|
||||
|
||||
建议策略:
|
||||
|
||||
- 新环境默认人工审批。
|
||||
- 只把只读、低风险、稳定工具加入白名单。
|
||||
- 扫描类工具按目标范围配置角色和提示词约束。
|
||||
- 写入、删除、执行 payload、C2、WebShell、账号改动等操作必须谨慎审批。
|
||||
|
||||
详见 [HITL 最佳实践](hitl-best-practices.md)。
|
||||
|
||||
## 审计
|
||||
|
||||
平台审计由 `audit` 配置控制,记录登录、配置、资源管理等平台操作。它不记录完整对话正文,也不等同于取证日志。
|
||||
|
||||
工具执行记录由监控模块维护,保留时间由 `monitor.retention_days` 控制。
|
||||
|
||||
建议:
|
||||
|
||||
- 开启 `audit.enabled`。
|
||||
- 定期导出审计日志。
|
||||
- 配置合理保留期。
|
||||
- 对失败登录、配置变更、C2/WebShell 操作重点复核。
|
||||
|
||||
## C2 风险
|
||||
|
||||
内置 C2 会启动监听器、生成 payload、接收会话并执行任务。仅在明确授权的靶场、内网演练或红队环境中启用。
|
||||
|
||||
建议:
|
||||
|
||||
- 不使用时设置 `c2.enabled: false`。
|
||||
- 不在公网暴露 C2 监听端口,除非有明确授权和隔离。
|
||||
- 对 payload 文件、回连地址、任务输出进行访问控制。
|
||||
- C2 任务建议走 HITL。
|
||||
|
||||
## WebShell 风险
|
||||
|
||||
WebShell 管理允许对已登记连接执行命令和文件操作。建议:
|
||||
|
||||
- 只添加授权目标。
|
||||
- 给连接使用清晰名称、标签和备注。
|
||||
- 不在共享环境保存真实生产 WebShell。
|
||||
- AI 使用 WebShell 前确认目标和命令。
|
||||
- 清理失效或不再授权的连接。
|
||||
|
||||
## 数据与隐私
|
||||
|
||||
本地会保存:
|
||||
|
||||
- 对话和消息:`data/conversations.db`
|
||||
- 知识库索引:`data/knowledge.db`
|
||||
- WebShell、C2、漏洞、项目、任务等业务数据。
|
||||
- 上传附件:`chat_uploads/`
|
||||
|
||||
建议:
|
||||
|
||||
- 限制文件权限。
|
||||
- 备份加密。
|
||||
- 不上传无授权的敏感数据。
|
||||
- 清理不再需要的会话、附件、C2 输出和审计日志。
|
||||
|
||||
## 生产基线
|
||||
|
||||
最低建议:
|
||||
|
||||
- 强密码 + HTTPS + 内网访问。
|
||||
- `audit.enabled: true`。
|
||||
- `mcp.auth_header_value` 设置随机值。
|
||||
- 不需要时关闭 `c2.enabled`。
|
||||
- 外部 MCP 最小化启用。
|
||||
- 高风险工具不进白名单。
|
||||
- 定期备份和更新。
|
||||
|
||||
## 真实威胁模型
|
||||
|
||||
| 威胁 | 攻击路径 | 影响 | 防护点 |
|
||||
| --- | --- | --- | --- |
|
||||
| Web 密码泄露 | 登录管理面,调用终端/WebShell/C2 | 完整接管平台能力 | 强密码、HTTPS、内网、反向代理认证、审计 |
|
||||
| Prompt Injection | 目标页面或文档诱导 Agent 调高权限工具 | 越权执行工具或泄露数据 | 角色边界、HITL、工具最小化、知识库来源标注 |
|
||||
| 外部 MCP 恶意 | MCP 服务返回误导描述或执行副作用 | 本机或目标系统受影响 | 只接入可信 MCP、独立运行用户、网络隔离 |
|
||||
| 工具 YAML 被篡改 | 改写命令模板或参数 | Agent 调用时执行恶意命令 | 文件权限、代码审查、工具白名单 |
|
||||
| C2 滥用 | 生成 payload 或下发任务到非授权目标 | 法律和业务风险 | 默认关闭、审批、事件保留、网络隔离 |
|
||||
| WebShell 误操作 | AI 或用户在生产目标执行破坏命令 | 业务中断或数据损坏 | 连接命名、人工确认、只读优先、删除过期连接 |
|
||||
| 数据库泄露 | 复制 `data/*.db` 或上传目录 | 对话、目标、漏洞、连接信息泄露 | 文件权限、加密备份、最小保留 |
|
||||
|
||||
## 授权边界写法
|
||||
|
||||
每个高风险角色都应把授权边界写进提示词,而不是只依赖用户口头说明。示例:
|
||||
|
||||
```text
|
||||
你只能在用户明确给出的目标范围内行动。若需要执行写入、删除、爆破、持久化、凭证访问、C2、WebShell 或横向移动相关操作,必须先说明目的、影响、目标和回滚方式,并等待 HITL 审批。
|
||||
```
|
||||
|
||||
这段话不能代替技术控制,但能降低 Agent 在模糊任务中扩张行为边界的概率。
|
||||
|
||||
## HITL 不是万能保险
|
||||
|
||||
HITL 的风险在于审批者看到的是“工具名 + 参数 + 上下文摘要”,不是完整现实世界影响。下面几类情况要特别保守:
|
||||
|
||||
- 参数看似只读,但工具本身会触发大量请求或写缓存。
|
||||
- 命令通过 `bash -c`、脚本、base64 包装隐藏真实动作。
|
||||
- 外部 MCP 工具描述不可信。
|
||||
- WebShell 目标名称模糊,无法确认是否生产环境。
|
||||
- C2 payload 生成和分发链路不在平台内。
|
||||
|
||||
审计 Agent 适合筛掉普通低风险请求,不适合替代人类批准破坏性动作。
|
||||
|
||||
## 数据最小化原则
|
||||
|
||||
不要把这些内容长期留在平台里:
|
||||
|
||||
- 真实客户凭证。
|
||||
- 未脱敏报告。
|
||||
- 生产数据库导出。
|
||||
- 长期有效 Cookie。
|
||||
- 无关目标的扫描输出。
|
||||
- 已结束项目的 WebShell/C2 会话。
|
||||
|
||||
建议按项目结束流程清理:附件、WebShell 连接、C2 payload、临时 workspace、长输出工具记录。
|
||||
|
||||
## 源码锚点
|
||||
|
||||
- 认证会话:`internal/security/auth_manager.go`
|
||||
- 认证中间件:`internal/security/auth_middleware.go`
|
||||
- 限流:`internal/security/ratelimit.go`
|
||||
- Shell 执行:`internal/security/executor.go`
|
||||
- HITL 执行:`internal/handler/hitl_execution.go`
|
||||
- 审计服务:`internal/audit/service.go`
|
||||
@@ -0,0 +1,180 @@
|
||||
# Skills 指南
|
||||
|
||||
Skills 用于给 Agent 提供可按需加载的专题能力、流程说明、模板和参考资料。它适合承载稳定方法论,而不是一次性任务输入。
|
||||
|
||||
## 目录结构
|
||||
|
||||
默认目录:
|
||||
|
||||
```yaml
|
||||
skills_dir: skills
|
||||
```
|
||||
|
||||
推荐结构:
|
||||
|
||||
```text
|
||||
skills/
|
||||
api-security-testing/
|
||||
SKILL.md
|
||||
ssrf-testing/
|
||||
SKILL.md
|
||||
cyberstrike-eino-demo/
|
||||
SKILL.md
|
||||
REFERENCE.md
|
||||
assets/
|
||||
```
|
||||
|
||||
每个 Skill 至少包含 `SKILL.md`。
|
||||
|
||||
## SKILL.md
|
||||
|
||||
`SKILL.md` 使用 YAML front matter:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: ssrf-testing
|
||||
description: SSRF 漏洞识别、验证、绕过和修复建议流程
|
||||
---
|
||||
|
||||
# SSRF Testing
|
||||
|
||||
当任务涉及服务端请求伪造、URL 回调、云元数据访问或内网探测时使用本技能。
|
||||
```
|
||||
|
||||
`description` 很重要,Agent 会根据它判断何时加载。
|
||||
|
||||
## 渐进式披露
|
||||
|
||||
Eino Skills 支持按需加载。配置:
|
||||
|
||||
```yaml
|
||||
multi_agent:
|
||||
eino_skills:
|
||||
disable: false
|
||||
filesystem_tools: true
|
||||
skill_tool_name: skill
|
||||
```
|
||||
|
||||
Agent 初始只看到技能名称和描述,真正需要时再调用 `skill` 读取详情,减少上下文占用。
|
||||
|
||||
## 适合写成 Skill 的内容
|
||||
|
||||
- 某类漏洞测试流程。
|
||||
- 安全审计 checklist。
|
||||
- 报告模板。
|
||||
- 工具组合方法。
|
||||
- 内部规范。
|
||||
- 常见误报判断。
|
||||
|
||||
不适合:
|
||||
|
||||
- 临时目标信息。
|
||||
- API Key、密码、Cookie。
|
||||
- 经常变化的扫描结果。
|
||||
- 大量无结构原始日志。
|
||||
|
||||
## 附属文件
|
||||
|
||||
Skill 可以带附属文件,如 `REFERENCE.md`、模板、字典或示例。`SKILL.md` 中应说明何时读取这些文件。
|
||||
|
||||
建议:
|
||||
|
||||
- 主文件保持短而清晰。
|
||||
- 参考资料按主题拆分。
|
||||
- 大文件只在必要时读取。
|
||||
|
||||
## 与角色绑定
|
||||
|
||||
角色可以提示 Agent 使用某类 Skill;Skill 也可以通过页面管理和角色形成绑定关系。建议:
|
||||
|
||||
- 通用技能保持不绑定,按描述自动触发。
|
||||
- 高风险技能绑定到专用角色。
|
||||
- 同类技能不要描述过度重叠。
|
||||
|
||||
## 开发建议
|
||||
|
||||
Skill 内容结构:
|
||||
|
||||
1. 触发场景。
|
||||
2. 目标和边界。
|
||||
3. 操作步骤。
|
||||
4. 工具建议。
|
||||
5. 输出格式。
|
||||
6. 风险和禁止事项。
|
||||
7. 参考资料。
|
||||
|
||||
写法要让 Agent 能执行,而不是只给人阅读。
|
||||
|
||||
## 排错
|
||||
|
||||
Skill 没被使用:
|
||||
|
||||
- `description` 过窄或过模糊。
|
||||
- 任务没有触发关键词。
|
||||
- `multi_agent.eino_skills.disable: true`。
|
||||
- Skill 文件 front matter 格式错误。
|
||||
|
||||
Skill 读取太多:
|
||||
|
||||
- 拆分附属文件。
|
||||
- 在 `SKILL.md` 中明确“只有在需要 X 时读取 Y”。
|
||||
- 删除重复内容。
|
||||
|
||||
## Skill 设计深水区
|
||||
|
||||
Skill 的核心价值不是“让 Agent 知道一个概念”,而是让 Agent 在正确时机拿到一套可执行的程序。写 Skill 时要特别关注触发条件和退出条件。
|
||||
|
||||
推荐结构:
|
||||
|
||||
```markdown
|
||||
## When to use
|
||||
明确触发场景。
|
||||
|
||||
## Preconditions
|
||||
需要用户提供什么、目标必须满足什么。
|
||||
|
||||
## Procedure
|
||||
按步骤执行,每步说明工具、输入和判断标准。
|
||||
|
||||
## Stop conditions
|
||||
什么情况下停止、升级审批或转人工。
|
||||
|
||||
## Output
|
||||
最终结果格式。
|
||||
```
|
||||
|
||||
## 反模式
|
||||
|
||||
| 反模式 | 后果 | 改法 |
|
||||
| --- | --- | --- |
|
||||
| 描述过泛:`用于安全测试` | 几乎所有任务都触发 | 写具体漏洞、场景、信号 |
|
||||
| 内容像百科 | Agent 不知道下一步做什么 | 改成流程和决策树 |
|
||||
| 把敏感配置写进 Skill | 泄露和误用 | 用运行时配置或用户输入 |
|
||||
| 一个 Skill 装所有内容 | 读取成本高,召回混乱 | 按漏洞/任务拆分 |
|
||||
| 没有停止条件 | Agent 可能持续扩大范围 | 写明何时停止和审批 |
|
||||
|
||||
## Skill 与知识库的区别
|
||||
|
||||
- Skill:指导 Agent 怎么做,强调流程。
|
||||
- 知识库:提供事实、案例和参考,强调检索。
|
||||
|
||||
例如 SSRF:
|
||||
|
||||
- Skill 写“如何测试 SSRF、如何判定、何时停止”。
|
||||
- 知识库写“云厂商 metadata 地址、历史绕过、修复方案”。
|
||||
|
||||
## 本地文件工具风险
|
||||
|
||||
`filesystem_tools: true` 会暴露读写和执行能力。它对开发和自动化很有用,但也是安全边界。生产环境建议:
|
||||
|
||||
- 配合 `workspace_root_dir` 限制工作目录。
|
||||
- 对写入和执行动作使用 HITL。
|
||||
- 不把 `execute` 加入全局白名单。
|
||||
- Skill 中明确禁止读写授权范围外文件。
|
||||
|
||||
## 源码锚点
|
||||
|
||||
- Skill 包校验:`internal/skillpackage/validate.go`
|
||||
- Skill 服务:`internal/skillpackage/service.go`
|
||||
- Eino Skills 接入:`internal/multiagent/eino_skills.go`
|
||||
- Skills Handler:`internal/handler/skills.go`
|
||||
@@ -0,0 +1,191 @@
|
||||
# 测试指南
|
||||
|
||||
CyberStrikeAI 的测试包括 Go 单测、配置验证、API 手测、MCP 工具验证和前端冒烟测试。
|
||||
|
||||
## Go 单测
|
||||
|
||||
运行全部内部测试:
|
||||
|
||||
```bash
|
||||
go test ./internal/...
|
||||
```
|
||||
|
||||
运行指定包:
|
||||
|
||||
```bash
|
||||
go test ./internal/workflow
|
||||
go test ./internal/multiagent
|
||||
go test ./internal/handler
|
||||
```
|
||||
|
||||
常见重点包:
|
||||
|
||||
- `internal/security`
|
||||
- `internal/mcp`
|
||||
- `internal/multiagent`
|
||||
- `internal/workflow`
|
||||
- `internal/knowledge`
|
||||
- `internal/project`
|
||||
- `internal/handler`
|
||||
- `internal/c2`
|
||||
|
||||
## 构建测试
|
||||
|
||||
```bash
|
||||
go build -o cyberstrike-ai ./cmd/server
|
||||
```
|
||||
|
||||
构建通过不代表功能正确,但能发现入口、依赖和静态类型问题。
|
||||
|
||||
## 配置验证
|
||||
|
||||
启动前检查:
|
||||
|
||||
- YAML 缩进。
|
||||
- 模型配置。
|
||||
- 数据库路径可写。
|
||||
- `tools_dir`、`roles_dir`、`skills_dir`、`agents_dir` 是否存在。
|
||||
- HTTPS 证书路径是否正确。
|
||||
|
||||
启动后在 Web 设置页测试:
|
||||
|
||||
- OpenAI 兼容模型。
|
||||
- 视觉模型。
|
||||
- 工具列表。
|
||||
- 外部 MCP 状态。
|
||||
|
||||
## API 手测
|
||||
|
||||
访问:
|
||||
|
||||
```text
|
||||
/api-docs
|
||||
```
|
||||
|
||||
重点验证:
|
||||
|
||||
- 登录。
|
||||
- `/api/eino-agent/stream`。
|
||||
- `/api/config`。
|
||||
- `/api/config/tools`。
|
||||
- `/api/knowledge/search`。
|
||||
- `/api/monitor`。
|
||||
|
||||
流式接口经过反向代理时要验证输出是否实时。
|
||||
|
||||
## 工具测试
|
||||
|
||||
新增或修改 `tools/*.yaml` 后:
|
||||
|
||||
- 在工具列表中确认 schema。
|
||||
- 用低风险参数执行。
|
||||
- 检查错误输出是否可读。
|
||||
- 检查超时是否生效。
|
||||
- 检查 HITL 是否按预期拦截。
|
||||
|
||||
不要用生产目标测试新工具。
|
||||
|
||||
## MCP 测试
|
||||
|
||||
外部 MCP:
|
||||
|
||||
- stdio:先在终端独立运行命令。
|
||||
- HTTP/SSE:用 curl 检查连通性。
|
||||
- Web 页面启动后检查 `/api/external-mcp/stats`。
|
||||
- 在对话中确认工具是否可被 `tool_search` 找到。
|
||||
|
||||
## 知识库测试
|
||||
|
||||
步骤:
|
||||
|
||||
1. 放入小型 Markdown 文档。
|
||||
2. 扫描知识库。
|
||||
3. 重建索引。
|
||||
4. 搜索文档中的关键词和同义表达。
|
||||
5. 查看检索日志。
|
||||
|
||||
如果使用真实 embedding API,注意配额和速率限制。
|
||||
|
||||
## 前端冒烟
|
||||
|
||||
修改前端后至少验证:
|
||||
|
||||
- 登录和退出。
|
||||
- 侧边栏对话列表。
|
||||
- 新建对话和流式回复。
|
||||
- 设置页面保存。
|
||||
- 相关业务页面增删改查。
|
||||
- 中英文切换。
|
||||
- 浏览器控制台无明显错误。
|
||||
|
||||
## 高风险模块测试
|
||||
|
||||
C2、WebShell、终端、批量任务只能在授权测试环境验证。测试前确认:
|
||||
|
||||
- 目标是本机、靶机或演练环境。
|
||||
- 命令无破坏性。
|
||||
- HITL 策略符合预期。
|
||||
- 测试后清理会话、payload、上传文件和任务结果。
|
||||
|
||||
## 测试金字塔
|
||||
|
||||
建议测试分层:
|
||||
|
||||
| 层级 | 目标 | 示例 |
|
||||
| --- | --- | --- |
|
||||
| 单元测试 | 纯逻辑正确 | 表达式、chunk、脱敏、超时格式 |
|
||||
| Handler 测试 | HTTP 行为 | 参数校验、状态码、权限 |
|
||||
| 集成测试 | 多模块协作 | 外部 MCP、知识库索引、HITL |
|
||||
| 冒烟测试 | 用户路径可用 | 登录、对话、工具、设置 |
|
||||
| 授权靶场测试 | 高风险能力安全 | C2、WebShell、终端 |
|
||||
|
||||
不要用端到端手测代替单元测试,也不要用单元测试代替高风险靶场验证。
|
||||
|
||||
## 回归测试重点
|
||||
|
||||
修改这些模块时必须扩大测试范围:
|
||||
|
||||
- `internal/handler/config.go`:测模型、知识库、MCP、C2、机器人配置应用。
|
||||
- `internal/multiagent/`:测流式、工具调用、摘要、重试、HITL。
|
||||
- `internal/security/`:测认证、Shell、超时、无输出。
|
||||
- `internal/database/`:测旧数据兼容。
|
||||
- `web/static/js/chat.js`:测对话、过程详情、攻击链、分组。
|
||||
|
||||
## 测试数据管理
|
||||
|
||||
不要用真实客户数据做测试。建议准备:
|
||||
|
||||
- 小型 Markdown 知识库样例。
|
||||
- 本地假 MCP Server。
|
||||
- 本地可控 HTTP 目标。
|
||||
- 无害 WebShell 模拟端。
|
||||
- 临时 SQLite 数据库。
|
||||
|
||||
测试完成后删除临时数据库和上传文件,避免污染开发环境。
|
||||
|
||||
## 失败用例比成功用例更重要
|
||||
|
||||
至少覆盖:
|
||||
|
||||
- 模型 API 401/429/500。
|
||||
- MCP 进程启动失败。
|
||||
- 工具超时。
|
||||
- HITL 拒绝。
|
||||
- 知识库索引中断。
|
||||
- 数据库不可写。
|
||||
- WebShell 目标返回非 200。
|
||||
- C2 关闭时访问接口。
|
||||
|
||||
这些才是用户真实会遇到的问题。
|
||||
|
||||
## 源码锚点
|
||||
|
||||
已有测试集中在:
|
||||
|
||||
- `internal/handler/*_test.go`
|
||||
- `internal/multiagent/*_test.go`
|
||||
- `internal/workflow/*_test.go`
|
||||
- `internal/knowledge/*_test.go`
|
||||
- `internal/security/*_test.go`
|
||||
- `internal/mcp/*_test.go`
|
||||
- `internal/c2/*_test.go`
|
||||
@@ -0,0 +1,224 @@
|
||||
# 排错指南
|
||||
|
||||
本文按现象列出常见问题。优先查看服务日志、浏览器控制台和 `/api-docs` 中的接口响应。
|
||||
|
||||
## 无法访问页面
|
||||
|
||||
检查:
|
||||
|
||||
- 服务是否启动。
|
||||
- 端口是否被占用。
|
||||
- 配置中是否启用 HTTPS。
|
||||
- 访问协议是否正确。
|
||||
|
||||
默认配置常见地址:
|
||||
|
||||
```text
|
||||
https://127.0.0.1:8080/
|
||||
```
|
||||
|
||||
如果使用自签证书,浏览器会提示不受信任,需要手动继续访问。
|
||||
|
||||
## 登录失败
|
||||
|
||||
检查:
|
||||
|
||||
- `config.yaml` 中的 `auth.password`。
|
||||
- 是否修改后未重启或未应用配置。
|
||||
- 浏览器 Cookie 是否异常,可尝试无痕窗口。
|
||||
- 审计日志中是否有登录失败节流。
|
||||
|
||||
生产环境忘记密码时,需要在服务器上修改 `config.yaml` 并重启服务。
|
||||
|
||||
## 模型无响应
|
||||
|
||||
检查:
|
||||
|
||||
- `openai.base_url` 是否包含正确路径,如 `/v1`。
|
||||
- `openai.api_key` 是否有效。
|
||||
- `openai.model` 是否存在。
|
||||
- 服务商是否支持当前 `reasoning` 字段。
|
||||
|
||||
可在系统设置中使用模型测试。若网关报 400,先尝试:
|
||||
|
||||
```yaml
|
||||
openai:
|
||||
reasoning:
|
||||
mode: off
|
||||
```
|
||||
|
||||
## 流式输出中断
|
||||
|
||||
常见原因:
|
||||
|
||||
- 反向代理缓冲 SSE。
|
||||
- 模型网关超时。
|
||||
- 浏览器网络断开。
|
||||
- 上下文过大。
|
||||
|
||||
Nginx 需要:
|
||||
|
||||
```nginx
|
||||
proxy_buffering off;
|
||||
proxy_http_version 1.1;
|
||||
```
|
||||
|
||||
## 工具执行失败
|
||||
|
||||
检查:
|
||||
|
||||
- 工具命令是否已安装到 PATH。
|
||||
- `tools/*.yaml` 参数 schema 是否正确。
|
||||
- 是否被 HITL 拒绝。
|
||||
- 是否超过 `agent.tool_timeout_minutes`。
|
||||
- Shell 长时间无输出是否触发 `shell_no_output_timeout_seconds`。
|
||||
|
||||
工具配置可参考 `tools/README.md`。
|
||||
|
||||
## MCP 连不上
|
||||
|
||||
内置 MCP:
|
||||
|
||||
- 检查 `mcp.enabled`。
|
||||
- 检查 `mcp.port`。
|
||||
- 检查 `auth_header` 和 `auth_header_value`。
|
||||
|
||||
外部 MCP:
|
||||
|
||||
- stdio:检查命令路径、工作目录、环境变量。
|
||||
- HTTP/SSE:检查 URL、认证、网络连通性。
|
||||
- 查看 `/api/external-mcp/stats`。
|
||||
|
||||
## 知识库不可用
|
||||
|
||||
检查:
|
||||
|
||||
- `knowledge.enabled: true`。
|
||||
- embedding 配置是否正确。
|
||||
- 是否已经扫描并重建索引。
|
||||
- `data/knowledge.db` 是否可写。
|
||||
- 嵌入服务是否 429 或超时。
|
||||
|
||||
如果索引大量失败,降低:
|
||||
|
||||
```yaml
|
||||
knowledge:
|
||||
indexing:
|
||||
batch_size: 5
|
||||
rate_limit_delay_ms: 600
|
||||
```
|
||||
|
||||
## 机器人没有回复
|
||||
|
||||
检查:
|
||||
|
||||
- 对应平台 `robots.<platform>.enabled`。
|
||||
- 平台回调 URL 是否指向 `/api/robot/...`。
|
||||
- Token、secret、verify_token 是否一致。
|
||||
- 服务器是否可被平台访问。
|
||||
- 群聊是否需要 @ 机器人。
|
||||
|
||||
详细步骤见 [机器人使用说明](robot.md)。
|
||||
|
||||
## C2 监听器启动失败
|
||||
|
||||
检查:
|
||||
|
||||
- `c2.enabled`。
|
||||
- 端口是否被占用。
|
||||
- 防火墙或安全组。
|
||||
- 是否需要管理员权限绑定低端口。
|
||||
|
||||
关闭 C2 后 `/api/c2/*` 返回 503 是预期行为。
|
||||
|
||||
## WebShell 命令乱码
|
||||
|
||||
处理:
|
||||
|
||||
- 确认目标系统编码。
|
||||
- 尝试更短命令。
|
||||
- 使用 base64 包装输出。
|
||||
- Windows 目标检查代码页。
|
||||
|
||||
## 数据库锁或写入失败
|
||||
|
||||
检查:
|
||||
|
||||
- `data/` 是否可写。
|
||||
- 是否多个实例共用同一个 SQLite 文件。
|
||||
- 磁盘是否满。
|
||||
- 是否异常复制了 WAL/SHM 文件。
|
||||
|
||||
生产环境不要让多个进程同时写同一份 SQLite 数据库。
|
||||
|
||||
## 前端页面异常
|
||||
|
||||
检查:
|
||||
|
||||
- 浏览器控制台错误。
|
||||
- 静态资源是否加载成功。
|
||||
- 修改前端后是否刷新缓存。
|
||||
- i18n key 是否缺失。
|
||||
|
||||
接口异常时打开 `/api-docs` 对照请求体。
|
||||
|
||||
## 诊断顺序
|
||||
|
||||
遇到问题时不要直接改配置,先定位层级:
|
||||
|
||||
1. 进程:服务是否还在,日志是否有 panic。
|
||||
2. 网络:端口、HTTPS、反向代理、浏览器控制台。
|
||||
3. 认证:`/api/auth/validate` 是否 200。
|
||||
4. 配置:`/api/config` 是否能读,应用后是否报错。
|
||||
5. 模型:模型测试是否通过。
|
||||
6. 工具:工具列表和单个 schema 是否正常。
|
||||
7. 数据库:`data/` 是否可写,有无锁。
|
||||
8. 业务模块:知识库、MCP、C2、WebShell 分别测最小动作。
|
||||
|
||||
先定位层级,再改参数。否则容易把一个代理问题误判成模型问题。
|
||||
|
||||
## 最小诊断命令
|
||||
|
||||
```bash
|
||||
# 进程和端口
|
||||
lsof -i :8080
|
||||
|
||||
# 本机 HTTPS 是否通
|
||||
curl -k -I https://127.0.0.1:8080/
|
||||
|
||||
# 静态资源是否通
|
||||
curl -k -I https://127.0.0.1:8080/static/logo.png
|
||||
|
||||
# 查看数据库文件
|
||||
ls -lh data/
|
||||
```
|
||||
|
||||
如果经过 Nginx,再分别测代理地址和回源地址,确认问题在哪一层。
|
||||
|
||||
## 常见误判
|
||||
|
||||
- “模型坏了”:实际是 HITL 挂起等待审批。
|
||||
- “工具没加载”:实际是 tool_search 隐藏了大部分工具。
|
||||
- “知识库没效果”:实际是索引没重建或 risk_type 过滤过窄。
|
||||
- “C2 接口坏了”:实际是 `c2.enabled: false`,返回 503 是正常保护。
|
||||
- “配置保存了但没生效”:实际是监听端口/TLS 需要重启。
|
||||
- “机器人不回复”:实际是平台侧没有正确配置回调 URL 或验签参数。
|
||||
|
||||
## 故障报告模板
|
||||
|
||||
提交问题时建议附:
|
||||
|
||||
```text
|
||||
版本/提交:
|
||||
启动方式:
|
||||
访问方式:http/https/反向代理:
|
||||
相关配置段:
|
||||
复现步骤:
|
||||
预期结果:
|
||||
实际结果:
|
||||
服务端日志:
|
||||
浏览器控制台:
|
||||
相关接口响应:
|
||||
```
|
||||
|
||||
有了这些信息,定位速度通常会快很多。
|
||||
@@ -0,0 +1,176 @@
|
||||
# WebShell 管理
|
||||
|
||||
WebShell 管理用于保存授权目标的 WebShell 连接,并通过 Web 页面或 Agent 工具执行命令、文件操作和上下文分析。
|
||||
|
||||
## 基本流程
|
||||
|
||||
1. 在 WebShell 页面新增连接。
|
||||
2. 填写名称、URL、密码或请求参数。
|
||||
3. 测试连接。
|
||||
4. 执行命令或文件操作。
|
||||
5. 在对话中选择 WebShell 连接,让 AI 基于该连接辅助排查。
|
||||
|
||||
连接数据保存在 SQLite 中。
|
||||
|
||||
## 接口
|
||||
|
||||
主要 API:
|
||||
|
||||
- `GET /api/webshell/connections`
|
||||
- `POST /api/webshell/connections`
|
||||
- `PUT /api/webshell/connections/:id`
|
||||
- `DELETE /api/webshell/connections/:id`
|
||||
- `GET /api/webshell/connections/:id/state`
|
||||
- `PUT /api/webshell/connections/:id/state`
|
||||
- `POST /api/webshell/exec`
|
||||
- `POST /api/webshell/file`
|
||||
- `GET /api/webshell/connections/:id/ai-history`
|
||||
- `GET /api/webshell/connections/:id/ai-conversations`
|
||||
|
||||
## MCP 工具
|
||||
|
||||
系统会注册 WebShell MCP 工具,例如:
|
||||
|
||||
- `webshell_exec`:在连接上执行命令。
|
||||
- `webshell_file_list`:列目录。
|
||||
- `webshell_file_read`:读取文件。
|
||||
- `webshell_file_write`:写文件。
|
||||
- WebShell 连接管理工具。
|
||||
|
||||
Agent 使用这些工具时需要 `connection_id`。前端通常会把当前选中的连接注入上下文。
|
||||
|
||||
## 命令执行
|
||||
|
||||
执行命令前确认:
|
||||
|
||||
- 当前连接属于授权目标。
|
||||
- 命令不会破坏业务。
|
||||
- 输出中可能包含敏感信息。
|
||||
- 长命令和交互式命令不适合 WebShell 通道。
|
||||
|
||||
建议先执行只读命令确认环境:
|
||||
|
||||
```bash
|
||||
whoami
|
||||
pwd
|
||||
uname -a
|
||||
id
|
||||
```
|
||||
|
||||
Windows 目标可用:
|
||||
|
||||
```cmd
|
||||
whoami
|
||||
cd
|
||||
ver
|
||||
ipconfig
|
||||
```
|
||||
|
||||
## 文件操作
|
||||
|
||||
文件操作包括列目录、读取、写入。建议:
|
||||
|
||||
- 写入前先备份原文件。
|
||||
- 不在生产目标写入未经确认的脚本或二进制。
|
||||
- 大文件优先通过专用下载/上传通道处理。
|
||||
- 注意目标编码和换行符。
|
||||
|
||||
## AI 辅助
|
||||
|
||||
AI 可以帮助:
|
||||
|
||||
- 识别操作系统和当前权限。
|
||||
- 规划只读枚举步骤。
|
||||
- 分析命令输出。
|
||||
- 汇总风险和修复建议。
|
||||
|
||||
不建议让 AI 自动执行:
|
||||
|
||||
- 删除文件。
|
||||
- 修改业务配置。
|
||||
- 持久化。
|
||||
- 凭证抓取。
|
||||
- 大范围扫描内网。
|
||||
|
||||
这些操作应由人工确认,并配合 HITL。
|
||||
|
||||
## 安全建议
|
||||
|
||||
- 仅保存授权目标连接。
|
||||
- 给连接命名时包含项目、环境、目标。
|
||||
- 演练结束后删除连接。
|
||||
- 不把 WebShell 写入工具加入全局免审批白名单。
|
||||
- 重要输出及时纳入项目事实或报告,随后清理敏感原始数据。
|
||||
|
||||
## 排错
|
||||
|
||||
连接失败:
|
||||
|
||||
- URL 不可达。
|
||||
- 参数名或密码错误。
|
||||
- 目标 WAF 拦截。
|
||||
- 代理或 TLS 配置异常。
|
||||
|
||||
命令乱码:
|
||||
|
||||
- 检查目标系统编码。
|
||||
- 尝试切换命令输出编码或使用 base64 包装。
|
||||
|
||||
AI 找不到连接:
|
||||
|
||||
- 确认前端已选中 WebShell 连接。
|
||||
- 确认连接未被删除。
|
||||
- 检查 `connection_id` 是否正确。
|
||||
|
||||
## 操作分层
|
||||
|
||||
WebShell 操作建议分成四层,不同层级使用不同审批策略:
|
||||
|
||||
| 层级 | 操作 | 风险 | 建议 |
|
||||
| --- | --- | --- | --- |
|
||||
| 识别 | `whoami`、`pwd`、系统版本 | 低 | 可自动 |
|
||||
| 枚举 | 目录、进程、环境变量 | 中 | 限定路径和命令 |
|
||||
| 读取 | 配置、日志、源码 | 中高 | 人工确认敏感性 |
|
||||
| 写入/执行 | 写文件、运行脚本、删除 | 高 | 人工审批,说明回滚 |
|
||||
|
||||
不要把“WebShell 已经拿到了”理解成“后续操作都低风险”。WebShell 通常位于业务系统内部,误操作成本很高。
|
||||
|
||||
## 连接命名规范
|
||||
|
||||
建议命名:
|
||||
|
||||
```text
|
||||
<项目>-<环境>-<目标>-<权限>-<日期>
|
||||
```
|
||||
|
||||
示例:
|
||||
|
||||
```text
|
||||
acme-staging-web01-www-20260707
|
||||
```
|
||||
|
||||
糟糕命名:
|
||||
|
||||
```text
|
||||
test
|
||||
shell1
|
||||
客户机器
|
||||
```
|
||||
|
||||
AI 和人类审批都依赖上下文,连接名称含糊会直接放大误操作概率。
|
||||
|
||||
## AI 使用约束模板
|
||||
|
||||
给 WebShell 相关角色加一段约束:
|
||||
|
||||
```text
|
||||
使用 WebShell 前先确认 connection_id、目标名称、当前目录和权限。默认只执行只读命令。任何写入、删除、上传、权限修改、持久化、凭证读取、内网探测都必须先给出目的、影响和回滚方式,并等待审批。
|
||||
```
|
||||
|
||||
## 源码锚点
|
||||
|
||||
- Handler:`internal/handler/webshell.go`
|
||||
- 连接上下文:`internal/handler/webshell_context.go`
|
||||
- 探测逻辑:`internal/handler/webshell_probe.go`
|
||||
- OS/编码处理测试:`internal/handler/webshell_os_test.go`、`internal/handler/webshell_encoding_test.go`
|
||||
- MCP 工具注册:`internal/app/app.go` 中 `registerWebshellTools`
|
||||
@@ -0,0 +1,553 @@
|
||||
# CyberStrikeAI 图编排使用说明
|
||||
|
||||
[English](../en-US/workflow-graph.md)
|
||||
|
||||
本文档说明 **图编排(Graph Orchestration)** 的完整使用方式:如何在画布上搭建流程、配置各类型节点、在节点之间传递数据,以及如何将流程绑定到角色并自动运行。
|
||||
|
||||
---
|
||||
|
||||
## 一、在哪里使用图编排
|
||||
|
||||
1. 登录 CyberStrikeAI Web 端
|
||||
2. 左侧导航进入 **图编排**
|
||||
3. 在左侧列表选择已有流程,或新建流程
|
||||
4. 在中央画布拖拽、连线、配置节点
|
||||
5. 填写流程 **ID**、**名称**、**描述** 后点击 **保存**
|
||||
|
||||
保存后的流程可在 **角色管理** 中绑定到某个角色。绑定后,用户与该角色对话时会按流程图自动执行(`workflow_policy: auto`)。
|
||||
|
||||
---
|
||||
|
||||
## 二、画布基本操作
|
||||
|
||||
| 操作 | 说明 |
|
||||
|------|------|
|
||||
| 添加节点 | 点击画布上方节点类型按钮(开始、工具、Agent、条件、审批、输出、结束) |
|
||||
| 连线 | 点击 **连线**,依次点击源节点和目标节点;再次点击 **连线** 退出连线模式 |
|
||||
| 选中元素 | 单击节点或连线,右侧显示 **节点属性** |
|
||||
| 删除选中 | 点击 **删除选中** 删除当前节点或连线 |
|
||||
| 自动布局 | 点击 **自动布局** 整理节点位置 |
|
||||
| 试运行 | 点击 **试运行** 使用安全 dry-run 验证数据流;工具、Agent、审批不会真实执行 |
|
||||
| 删除流程 | 点击 **删除** 删除整个流程定义 |
|
||||
|
||||
**硬性规则:** 每个流程至少包含 **1 个开始节点** 和 **1 个输出节点**;开始节点不能有入边,输出 / 结束节点不能有出边。保存时前端和后端都会执行严格校验。
|
||||
|
||||
---
|
||||
|
||||
## 三、执行模型(先理解再配置)
|
||||
|
||||
图编排按 **有向图** 执行,引擎从 **开始** 节点出发,沿连线依次运行下游节点。
|
||||
|
||||
每次运行会维护一份内部状态,模板变量 `{{...}}` 从这里取值:
|
||||
|
||||
| 内部状态 | 模板前缀 | 含义 |
|
||||
|----------|----------|------|
|
||||
| `inputs` | `{{inputs.xxx}}` | 流程启动时的输入(用户消息、会话 ID 等) |
|
||||
| `lastOutput` | `{{previous.xxx}}` | **上一个刚执行完** 的节点的输出 |
|
||||
| `outputs` | `{{outputs.xxx}}` | 全局 **命名变量池**(由节点的「输出变量名」写入) |
|
||||
| `nodeOutputs` | `{{节点ID.xxx}}` | 指定节点 ID 的完整输出对象 |
|
||||
| `metrics` | 运行详情中查看 | 节点耗时、工具调用数、可收集到的 token / cost 等指标 |
|
||||
|
||||
### 3.1 `previous` 是什么?
|
||||
|
||||
`{{previous.output}}` 表示 **紧邻的上一个执行节点** 的 `output` 字段。
|
||||
|
||||
- 每执行完一个节点,引擎都会更新 `lastOutput`
|
||||
- **不是**「画布上画线的上游」,而是 **实际执行顺序上的上一步**
|
||||
|
||||
示例:
|
||||
|
||||
```text
|
||||
开始 → Agent A → Agent B
|
||||
```
|
||||
|
||||
Agent B 的 `{{previous.output}}` = Agent A 的输出。
|
||||
|
||||
但若中间有条件节点:
|
||||
|
||||
```text
|
||||
开始 → Agent A → 条件 → Agent B
|
||||
```
|
||||
|
||||
Agent B 的 `{{previous.output}}` = **条件节点** 的输出(`true` / `false`),**不是** Agent A 的结果。
|
||||
|
||||
如果一个节点有 **多个上游节点** 同时连入,`previous` 会先按该节点的 **汇聚策略** 生成:
|
||||
|
||||
| 汇聚策略 | 含义 | 适合场景 |
|
||||
|----------|------|----------|
|
||||
| `all_merge` | 合并所有上游输出,`previous.output` 为数组 | 默认推荐,综合多路结果 |
|
||||
| `last_by_canvas` | 按画布顺序取最后一个上游输出 | 明确只采用一路结果 |
|
||||
| `first_non_empty` | 取第一个非空输出 | 多路兜底 |
|
||||
| `fail_fast` | 任一上游失败则中止当前节点 | 关键链路、审批前置、安全检查 |
|
||||
|
||||
### 3.2 `outputs` 是什么?
|
||||
|
||||
`outputs` 是引擎在运行过程中维护的 **命名变量注册表**。
|
||||
|
||||
当 Agent、工具、输出 等节点配置了 **输出变量名**(字段 `output_key`)后,节点执行成功会把结果写入:
|
||||
|
||||
```text
|
||||
outputs["你填的变量名"] = 节点输出内容
|
||||
```
|
||||
|
||||
之后 **任意下游节点** 都可以通过 `{{outputs.变量名}}` 引用,不要求两个节点直接相连。
|
||||
|
||||
示例:
|
||||
|
||||
- Agent A 的 **输出变量名** 填 `agent_result1`
|
||||
- Agent B 的 **输入来源** 填 `{{outputs.agent_result1}}`
|
||||
|
||||
即使 A 和 B 之间隔着条件节点,B 仍能拿到 A 的输出。
|
||||
|
||||
### 3.3 什么时候用 `previous`,什么时候用 `outputs`?
|
||||
|
||||
| 场景 | 推荐写法 |
|
||||
|------|----------|
|
||||
| 两个节点 **直连**,只取上一步结果 | `{{previous.output}}` |
|
||||
| 中间有其他节点(条件、工具、审批等) | `{{outputs.变量名}}` |
|
||||
| 需要引用 **更早** 的某个节点结果 | `{{outputs.变量名}}` 或 `{{节点ID.output}}` |
|
||||
| 条件判断要基于某 Agent 的输出 | `{{outputs.变量名}} != ""` |
|
||||
| 读取用户最初输入 | `{{inputs.message}}` |
|
||||
|
||||
**记忆口诀:**
|
||||
|
||||
- `previous` = 上一步(链式、紧邻)
|
||||
- `outputs` = 按名字取(跨节点、可回溯)
|
||||
|
||||
---
|
||||
|
||||
## 四、模板语法
|
||||
|
||||
### 4.1 基本格式
|
||||
|
||||
```text
|
||||
{{变量路径}}
|
||||
```
|
||||
|
||||
支持字母、数字、下划线、点、连字符,例如:
|
||||
|
||||
```text
|
||||
{{previous.output}}
|
||||
{{outputs.agent_result1}}
|
||||
{{inputs.message}}
|
||||
{{inputs.conversationId}}
|
||||
{{previous.matched}}
|
||||
{{node-abc123.output}}
|
||||
```
|
||||
|
||||
### 4.2 可用路径一览
|
||||
|
||||
| 路径 | 说明 |
|
||||
|------|------|
|
||||
| `{{inputs.message}}` | 用户消息(开始节点输入) |
|
||||
| `{{inputs.conversationId}}` | 会话 ID |
|
||||
| `{{inputs.projectId}}` | 项目 ID |
|
||||
| `{{previous.output}}` | 上一节点主输出 |
|
||||
| `{{previous.matched}}` | 上一条件节点的匹配结果(`true` / `false`) |
|
||||
| `{{outputs.变量名}}` | 某节点注册过的命名输出 |
|
||||
| `{{节点ID.output}}` | 指定节点 ID 的 `output` 字段 |
|
||||
| `{{previous.kind}}` | 上一节点输出类型,如 `agent` / `tool` / `condition` |
|
||||
| `{{previous.status}}` | 上一节点状态,如 `completed` / `failed` / `simulated` |
|
||||
|
||||
节点输出会保留兼容字段(如 `output`、`matched`),同时带有结构化字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "agent",
|
||||
"node_id": "node-2",
|
||||
"node_type": "agent",
|
||||
"status": "completed",
|
||||
"output": "..."
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 条件表达式
|
||||
|
||||
条件节点和连线条件支持比较、文本匹配、正则、逻辑组合与安全 JSONPath/JQ 路径读取:
|
||||
|
||||
```text
|
||||
{{outputs.agent_result1}} != ""
|
||||
{{previous.output}} == "ok"
|
||||
{{outputs.count}} >= 100
|
||||
{{previous.output}} contains "success"
|
||||
{{previous.output}} matches "^ok"
|
||||
{{outputs.risk_score}} >= 8 && {{previous.output}} != ""
|
||||
jsonpath({{previous.output}}, "$.status") == "ok"
|
||||
jq({{outputs.scan}}, ".severity") == "high"
|
||||
```
|
||||
|
||||
规则:
|
||||
|
||||
- 支持 `==`、`!=`、`>`、`>=`、`<`、`<=`
|
||||
- 支持 `contains` 子串匹配与 `matches` 正则匹配
|
||||
- 支持简单 `&&` / `||`
|
||||
- 支持 `jsonpath(value, "$.path")` 与 `jq(value, ".path")` 的**安全路径子集**,仅做字段读取,不执行任意脚本
|
||||
- 比较两侧会自动去掉首尾空格和引号
|
||||
- 无比较符时,非空且不为 `false` / `0` / `null` 视为真
|
||||
- 保存时会静态校验表达式格式、JSONPath/JQ 路径和正则语法
|
||||
|
||||
### 4.4 嵌套字段绑定
|
||||
|
||||
节点的字段绑定除 `output`、`message` 等普通字段外,也支持 JSONPath/JQ 风格路径:
|
||||
|
||||
| 绑定配置 | 含义 |
|
||||
|----------|------|
|
||||
| `from=previous, field=$.status` | 从上一节点输出对象读取 `status` |
|
||||
| `from=outputs, field=$.scan.severity` | 从命名输出中读取嵌套字段 |
|
||||
| `from=node-1, field=.output.items[0]` | 从指定节点输出读取数组元素 |
|
||||
|
||||
---
|
||||
|
||||
## 五、节点类型与配置
|
||||
|
||||
### 5.1 开始(start)
|
||||
|
||||
流程入口,将用户输入注入 `inputs`。
|
||||
|
||||
| 字段 | 说明 | 默认值 |
|
||||
|------|------|--------|
|
||||
| 输入变量 | 逗号分隔的输入键名 | `message, conversationId, projectId` |
|
||||
|
||||
开始节点输出包含:`output`、`message`、`conversationId`、`projectId`。
|
||||
|
||||
### 5.2 Agent(agent)
|
||||
|
||||
调用大模型 Agent 处理任务,支持多种运行模式。
|
||||
|
||||
| 字段 | 说明 | 默认值 |
|
||||
|------|------|--------|
|
||||
| Agent 模式 | `eino_single` / `deep` / `plan_execute` / `supervisor` | `eino_single` |
|
||||
| 输入来源 | 上游数据的模板表达式 | `{{previous.output}}` |
|
||||
| 节点指令 | 本节点要完成的任务描述 | 空 |
|
||||
| 输出变量名 | 写入 `outputs` 的键名 | `agent_result` |
|
||||
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
|
||||
|
||||
**消息拼装规则:**
|
||||
|
||||
- 仅填 **节点指令**:直接把指令发给 Agent
|
||||
- 仅填 **输入来源**:生成「请基于上游节点输出继续处理:…」
|
||||
- 两者都填:合并为「上游输入 + 节点指令」
|
||||
|
||||
Agent 节点执行后:
|
||||
|
||||
- `previous.output` 更新为本节点响应文本
|
||||
- 若配置了 **输出变量名**,同时写入 `outputs[输出变量名]`
|
||||
- Agent 子图在 Eino 中拆为 `prepare → execute → finalize`,便于 trace 与后续局部 checkpoint
|
||||
|
||||
### 5.3 工具(tool)
|
||||
|
||||
调用已启用的 MCP 工具。
|
||||
|
||||
| 字段 | 说明 | 默认值 |
|
||||
|------|------|--------|
|
||||
| MCP 工具 | 工具名称(必填) | — |
|
||||
| 参数模板 | JSON,支持 `{{...}}` 模板 | `{}` |
|
||||
| 超时秒数 | 可选 | 空 |
|
||||
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
|
||||
|
||||
示例参数模板:
|
||||
|
||||
```json
|
||||
{"target": "{{inputs.message}}", "port": "443"}
|
||||
```
|
||||
|
||||
若配置了 **输出变量名**,工具返回结果会写入 `outputs`。
|
||||
|
||||
### 5.4 条件(condition)
|
||||
|
||||
根据表达式计算分支,输出 `matched`(`true` / `false`)。
|
||||
|
||||
| 字段 | 说明 | 默认值 |
|
||||
|------|------|--------|
|
||||
| 条件表达式 | 支持 `{{...}}` 与 `==` / `!=` | `{{previous.output}} != ""` |
|
||||
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
|
||||
|
||||
**分支规则:**
|
||||
|
||||
- 从条件节点连出的 **第一条线** 默认为 **「是」** 分支(`matched == true`)
|
||||
- **第二条线** 默认为 **「否」** 分支(`matched == false`)
|
||||
- 连线标签可写 `是` / `否`(或 `yes` / `no`、`true` / `false`)辅助识别
|
||||
- 第三条及以后的出边需在 **连线条件** 中自定义表达式
|
||||
|
||||
连线条件示例(选中连线后在右侧配置):
|
||||
|
||||
```text
|
||||
{{previous.matched}} == "true"
|
||||
{{previous.matched}} == "false"
|
||||
```
|
||||
|
||||
### 5.5 审批(hitl)
|
||||
|
||||
人工确认检查点。流程运行到该节点前会通过 Eino interrupt/checkpoint 暂停,等待 API 或监控面板审批后恢复。
|
||||
|
||||
| 字段 | 说明 | 默认值 |
|
||||
|------|------|--------|
|
||||
| 审批提示 | 支持模板 | `请审批该步骤是否继续执行` |
|
||||
| 提示字段绑定 | 留空审批提示时,从绑定字段读取说明 | `previous.output` |
|
||||
| 审批方 | `human` / `audit_agent` | `human` |
|
||||
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
|
||||
|
||||
HITL 等待信息会记录:
|
||||
|
||||
- `checkpointId`
|
||||
- interrupt `beforeNodes`
|
||||
- resume target / address / path
|
||||
- resume payload schema(`approved`、`comment`)
|
||||
|
||||
### 5.6 输出(output)
|
||||
|
||||
将流程最终结果写入 `outputs`,供结束摘要和对话展示使用。
|
||||
|
||||
| 字段 | 说明 | 默认值 |
|
||||
|------|------|--------|
|
||||
| 输出变量名 | 必填,最终结果的键名 | `result` |
|
||||
| 变量来源 | 模板表达式,决定写入的值 | `{{previous.output}}` |
|
||||
| 固定输出值 | 可选,填写后覆盖变量来源 | 空 |
|
||||
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
|
||||
|
||||
**注意:** 输出节点是流程的「出口」,不应再有出边。
|
||||
|
||||
### 5.7 结束(end)
|
||||
|
||||
可选节点,用于生成结束摘要模板(角色绑定流程中较少单独使用)。
|
||||
|
||||
| 字段 | 说明 | 默认值 |
|
||||
|------|------|--------|
|
||||
| 结束摘要模板 | 支持 `{{outputs.xxx}}` | `{{outputs.result}}` |
|
||||
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
|
||||
|
||||
---
|
||||
|
||||
## 六、连线配置
|
||||
|
||||
选中 **连线** 后,右侧可配置 **连线条件**。
|
||||
|
||||
| 场景 | 示例 |
|
||||
|------|------|
|
||||
| 普通节点后的过滤 | `{{previous.output}} == "ok"` |
|
||||
| 条件节点「是」分支 | `{{previous.matched}} == "true"` |
|
||||
| 条件节点「否」分支 | `{{previous.matched}} == "false"` |
|
||||
|
||||
若不填连线条件:
|
||||
|
||||
- 非条件节点:连线始终放行
|
||||
- 条件节点:按出边顺序自动分配是/否分支
|
||||
|
||||
---
|
||||
|
||||
## 七、完整示例:跨条件节点传递 Agent 输出
|
||||
|
||||
### 7.1 流程结构
|
||||
|
||||
```text
|
||||
开始 → Agent(生成初始值)→ 条件 → Agent(加工)→ 输出
|
||||
↘ 否 → 输出
|
||||
```
|
||||
|
||||
### 7.2 节点配置
|
||||
|
||||
**Agent 1(第一个 Agent)**
|
||||
|
||||
| 字段 | 值 |
|
||||
|------|-----|
|
||||
| 节点指令 | 只输出 `123333333` |
|
||||
| 输出变量名 | `agent_result1` |
|
||||
|
||||
**条件**
|
||||
|
||||
| 字段 | 值 |
|
||||
|------|-----|
|
||||
| 条件表达式 | `{{outputs.agent_result1}} != ""` |
|
||||
|
||||
**Agent 2(第二个 Agent)**
|
||||
|
||||
| 字段 | 值 |
|
||||
|------|-----|
|
||||
| 输入来源 | `{{outputs.agent_result1}}` |
|
||||
| 节点指令 | 在输入基础上加 100,然后输出 |
|
||||
| 输出变量名 | `agent_result` |
|
||||
|
||||
**输出**
|
||||
|
||||
| 字段 | 值 |
|
||||
|------|-----|
|
||||
| 输出变量名 | `result` |
|
||||
| 变量来源 | `{{outputs.agent_result}}` |
|
||||
|
||||
### 7.3 常见错误
|
||||
|
||||
| 错误配置 | 原因 |
|
||||
|----------|------|
|
||||
| Agent 2 输入来源写 `{{previous.output}}` | `previous` 指向条件节点,得到的是 `true`/`false`,不是 Agent 1 的文本 |
|
||||
| 未给 Agent 1 填输出变量名 | `outputs.agent_result1` 不存在,下游取到空值 |
|
||||
| 条件表达式写 `{{previous.output}}` | 判断的是开始节点或上一节点的输出,而非 Agent 1 的命名变量 |
|
||||
|
||||
---
|
||||
|
||||
## 八、绑定角色并运行
|
||||
|
||||
### 8.1 在角色管理中绑定
|
||||
|
||||
1. 进入 **角色管理**,编辑或新建角色
|
||||
2. 选择 **工作流 / 图编排** 绑定的流程 ID
|
||||
3. 策略设为 `auto`(默认:有 `workflow_id` 时自动执行)
|
||||
4. 保存角色
|
||||
|
||||
也可在角色 YAML 中直接配置:
|
||||
|
||||
```yaml
|
||||
name: 工作流测试
|
||||
workflow_id: "1233"
|
||||
workflow_version: latest
|
||||
workflow_policy: auto
|
||||
```
|
||||
|
||||
### 8.2 运行效果
|
||||
|
||||
用户选择该角色并发送消息后:
|
||||
|
||||
1. 引擎加载对应 `graph_json` 并按图执行
|
||||
2. 对话页可看到 `workflow_start`、`workflow_node_start`、Agent 推理等进度事件
|
||||
3. 流程结束后返回摘要,列出 `outputs` 中所有命名输出
|
||||
|
||||
若未配置输出节点或条件未命中,`outputs` 可能为空,摘要会提示检查输出节点与分支。
|
||||
|
||||
---
|
||||
|
||||
## 九、调试、试运行与复盘
|
||||
|
||||
### 9.1 安全试运行(dry-run)
|
||||
|
||||
画布工具栏点击 **试运行**,输入一条测试消息即可模拟执行流程。
|
||||
|
||||
dry-run 的安全边界:
|
||||
|
||||
- `start` / `condition` / `output` / `end` 会按真实逻辑计算
|
||||
- `tool` 不会真实调用 MCP,只返回 `[dry-run] tool call skipped`
|
||||
- `agent` 不会真实调用模型,只返回 `[dry-run] agent execution skipped`
|
||||
- `hitl` 不会暂停,只模拟通过
|
||||
|
||||
相关 API:
|
||||
|
||||
```http
|
||||
POST /api/workflows/dry-run
|
||||
```
|
||||
|
||||
请求体:
|
||||
|
||||
```json
|
||||
{
|
||||
"graph": { "nodes": [], "edges": [], "config": {} },
|
||||
"inputs": { "message": "ping" }
|
||||
}
|
||||
```
|
||||
|
||||
响应包含:
|
||||
|
||||
- `outputs`
|
||||
- `nodeOutputs`
|
||||
- `trace`
|
||||
- `metrics`
|
||||
- `replayScript`
|
||||
|
||||
### 9.2 运行详情与 replay
|
||||
|
||||
运行后可查询完整节点执行轨迹:
|
||||
|
||||
```http
|
||||
GET /api/workflows/runs/{runId}
|
||||
```
|
||||
|
||||
返回 `run` 与 `nodeRuns`,每个节点记录包含:
|
||||
|
||||
- input 快照
|
||||
- output 快照
|
||||
- status / error
|
||||
- started_at / finished_at
|
||||
- `duration_ms`
|
||||
|
||||
复盘接口:
|
||||
|
||||
```http
|
||||
GET /api/workflows/runs/{runId}/replay
|
||||
```
|
||||
|
||||
该接口只根据已保存的 `nodeRuns` 生成步骤,不会重新执行工具或 Agent。
|
||||
|
||||
### 9.3 指标(metrics)
|
||||
|
||||
工作流会尽量累计:
|
||||
|
||||
- `node_count`
|
||||
- `duration_ms`
|
||||
- `tool_call_count`
|
||||
- Agent progress 中可收集到的 `prompt_tokens` / `completion_tokens` / `total_tokens` / `cost`
|
||||
|
||||
token 与成本是否存在取决于底层模型/Agent 事件是否上报 usage。
|
||||
|
||||
---
|
||||
|
||||
## 十、保存前校验规则
|
||||
|
||||
保存时系统会自动检查:
|
||||
|
||||
| 规则 | 说明 |
|
||||
|------|------|
|
||||
| 必须有开始节点 | 至少 1 个 `start` |
|
||||
| 必须有输出节点 | 至少 1 个 `output`,且填写输出变量名 |
|
||||
| 连线合法 | 源/目标节点存在,不能自环 |
|
||||
| 开始节点无入边 | 开始节点不能被指向 |
|
||||
| 输出 / 结束节点无出边 | 输出 / 结束节点后不应再连线 |
|
||||
| 非开始节点必须有入边 | 避免孤岛节点 |
|
||||
| 非输出 / 结束节点必须有出边 | 避免执行到死路 |
|
||||
| 无环路 | Workflow 编排必须是 DAG |
|
||||
| 可达性 | 所有节点必须能从开始节点到达,并能最终到达 output/end |
|
||||
| 工具节点 | 必须选择 MCP 工具;参数 JSON 必须合法;超时必须为正整数 |
|
||||
| Agent 节点 | 必须填写节点指令或输入绑定;必须填写输出变量名 |
|
||||
| 条件节点 | 必须填写表达式;需要 1~2 条出边;分支必须标记是/否且不能重复 |
|
||||
| 连线条件 | 表达式、正则、JSONPath/JQ 路径必须通过静态校验 |
|
||||
| 汇聚策略 | 必须是 `all_merge` / `last_by_canvas` / `first_non_empty` / `fail_fast` |
|
||||
|
||||
---
|
||||
|
||||
## 十一、排错指南
|
||||
|
||||
| 现象 | 可能原因 | 处理建议 |
|
||||
|------|----------|----------|
|
||||
| 下游拿到空值 | 上游未配置输出变量名 | 给上游 Agent/工具填 **输出变量名**,下游用 `{{outputs.xxx}}` |
|
||||
| 下游拿到 `true`/`false` | 误用 `{{previous.output}}`,上一步是条件节点 | 改用 `{{outputs.xxx}}` |
|
||||
| 条件总走「否」 | 表达式与真实输出格式不一致 | 检查 Agent 输出是否带引号、换行;用 `!= ""` 先验证 |
|
||||
| 流程无最终输出 | 未命中输出节点所在分支 | 检查条件分支连线;确保至少一条路径到达 **输出** 节点 |
|
||||
| 角色对话未跑流程 | 角色未绑定或未启用 | 确认 `workflow_id`、`workflow_policy: auto`、流程 `enabled: true` |
|
||||
| 工具节点失败 | 参数 JSON 不合法或工具未启用 | 检查参数模板;在 MCP 中启用对应工具 |
|
||||
| 保存失败提示分支非法 | 条件节点出边未标记是/否或重复 | 选中连线,设置条件分支为 `true` 或 `false` |
|
||||
| 多上游结果不符合预期 | 汇聚策略不合适 | 根据场景改为 `all_merge` / `first_non_empty` / `last_by_canvas` / `fail_fast` |
|
||||
| 嵌套字段取不到 | JSONPath/JQ 路径不符合安全子集 | 使用 `$.a.b[0]` 或 `.a.b[0]`,不要用通配符/递归/表达式 |
|
||||
|
||||
---
|
||||
|
||||
## 十二、最佳实践
|
||||
|
||||
1. **命名规范**:为每个需要被引用的节点设置有意义的输出变量名,如 `scan_result`、`parsed_targets`,避免都叫 `agent_result`。
|
||||
2. **跨节点传参优先用 `outputs`**:只要中间可能插入条件、工具、审批节点,就应用命名变量。
|
||||
3. **`previous` 仅用于直连**:A → B 且无中间节点时,`{{previous.output}}` 最简洁。
|
||||
4. **条件判断引用源数据**:判断 Agent 输出时用 `{{outputs.xxx}}`,不要用 `{{previous.output}}`(除非条件紧跟在目标 Agent 之后)。
|
||||
5. **每条路径都要有出口**:确保「是」「否」分支最终都能到达 **输出** 节点(或你期望的终点)。
|
||||
6. **多上游节点显式选择汇聚策略**:综合结果用 `all_merge`,兜底用 `first_non_empty`,关键链路用 `fail_fast`。
|
||||
7. **嵌套 JSON 用 JSONPath/JQ 安全路径**:例如 `jsonpath({{previous.output}}, "$.status") == "ok"`。
|
||||
8. **保存前先 dry-run**:用简单消息验证数据传递和分支,再绑定角色真实执行。
|
||||
|
||||
---
|
||||
|
||||
## 十三、相关代码位置(开发者参考)
|
||||
|
||||
| 模块 | 路径 |
|
||||
|------|------|
|
||||
| 执行引擎 | `internal/workflow/runner.go` |
|
||||
| Eino 编译 / checkpoint / HITL | `internal/workflow/eino_compile.go` |
|
||||
| 图校验 | `internal/workflow/validation.go` |
|
||||
| 表达式 / JSONPath / 汇聚 | `internal/workflow/expression.go`、`jsonpath.go`、`join.go` |
|
||||
| dry-run / replay 数据 | `internal/workflow/dry_run.go`、`internal/handler/workflow_run.go` |
|
||||
| 画布前端 | `web/static/js/workflows.js` |
|
||||
| 流程 API | `internal/handler/workflow.go` |
|
||||
| 角色绑定 | `internal/config/config.go`(`workflow_id` 字段) |
|
||||
Reference in New Issue
Block a user