Metadata-Version: 2.4
Name: fengyun-agent-task
Version: 0.3.3
Summary: CncertAgent local WSS log cache, offline analysis, submission, and API adapter toolkit.
Author: Fengyun-AI-Agent
License-Expression: MIT
Keywords: fengyun,security,logs,mongodb,wss
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: System :: Logging
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.31.0
Requires-Dist: websocket-client>=1.7.0
Requires-Dist: pycryptodome>=3.23.0
Requires-Dist: hyperscan>=0.7.0
Requires-Dist: pymongo>=4.10.0
Provides-Extra: transfer
Requires-Dist: zstandard<1,>=0.23.0; extra == "transfer"
Requires-Dist: Brotli<2,>=1.1.0; extra == "transfer"
Provides-Extra: publish
Requires-Dist: build>=1.2.2; extra == "publish"
Requires-Dist: twine>=5.1.1; extra == "publish"
Dynamic: license-file

# CncertAgent

CncertAgent 是面向安全日志接收、单告警研判、攻击链关联、专家复核和比赛结果
提交的 Python/Vue 工具。运行数据统一保存在 MongoDB `cncert` 数据库的四个
集合中，JSONL 仅作为原始日志和成功提交结果的本地备份。

## 架构

```text
WSS / JSONL
    │
    ▼
logs ──单告警分析──> label / entities
  │      ├─ judge（默认）
  │      └─ expert-first（专家命中直接赋值，未命中再 judge）
  │
  ├─攻击链分析 association（默认）──> chain_id + attack_chains
  └─攻击链分析 expert ─────────────> 按专家链生成 attack_chains
  │
  └──前端专家标注双写 expert_annotations 与人工字段

告警/攻击链分析 ──逐条增量写 final_results outbox
submit ──────────读取统一 outbox──> 比赛服务
```

MongoDB 使用四个业务集合：

- `logs`：原始日志以及自动/专家研判字段。
- `expert_annotations`：单日志专家标注和专家攻击链。
- `attack_chains`：自动分析生成的核心攻击链 payload。
- `final_results`：统一的最终 payload 和提交状态，不按 Judge/专家区分。

`expert_annotations` 不保存 payload，也不直接生成提交结果。

单告警分析按批量 bulk write 保存，攻击链分析保存时增量写入 `final_results`。`submit` 只读取统一
outbox 并发送，不读取或区分结果来自 Judge、关联规则还是专家记录。

完整字段说明见
[MONGODB_SCHEMA.md](src/fengyun_ai_agent/MONGODB_SCHEMA.md)，完整业务说明见
[PROJECT_KNOWLEDGE.md](PROJECT_KNOWLEDGE.md)。

## 比赛环境通过 PyPI 安装

PyPI 包只包含 `src/fengyun_ai_agent` 分析框架、规则数据（包括该目录内的
`.jsonl`）和命令行工具，不包含
`frontend`、`backend_py`、测试数据或本地运行结果：

```bash
python -m pip install fengyun-agent-task
fengyun-task --help
```

需要共享目录高压缩加密归档功能时安装可选依赖：

```bash
python -m pip install "fengyun-agent-task[transfer]"
fengyun-transfer --help
```

## 源码开发安装

```powershell
python -m pip install -e .
fengyun-task --help
```

配置 MongoDB。连接密码不要写入源码或提交到 Git：

```powershell
$env:MONGODB_URI = "mongodb://<user>:<password>@<host>:<port>/?authSource=admin"
$env:MONGODB_DATABASE = "cncert"
fengyun-task init-db
```

Linux：

```bash
export MONGODB_URI='mongodb://<user>:<password>@<host>:<port>/?authSource=admin'
export MONGODB_DATABASE='cncert'
fengyun-task init-db
```

比赛环境只需设置统一环境变量，MongoDB 和模型服务会同时切换到生产配置：

```bash
export PRODUCTION=1  # 也兼容 production=1
fengyun-task init-db
fengyun-task pipeline
```

生产 MongoDB 默认对应比赛 Docker 配置：`127.0.0.1:27017`、用户 `admin`、
认证库 `admin`。生产模型默认切换到 `http://127.0.0.1:8100/v1` 的
`qwen3-8B`；可通过
`LLM_INTERNAL_BASE_URL` 和 `LLM_INTERNAL_MODEL` 覆盖。Mongo 运行在其它主机时，
使用 `MONGODB_PRODUCTION_HOST`、`MONGODB_PRODUCTION_PORT`，或直接设置
`MONGODB_PRODUCTION_URI`。显式 `MONGODB_URI`、`LLM_BASE_URL` 始终优先。

## 主流程

一键处理 MongoDB 中全部待研判日志和待关联种子：

```bash
fengyun-task pipeline
```

需要先从一个或多个备份 JSONL 导入时，可重复指定 `--import-path`：

```bash
fengyun-task pipeline \
  --import-path data/raw_logs/first/waf.jsonl \
  --import-path data/raw_logs/first/hids.jsonl
```

`pipeline` 当前流程为“可选导入 → 单包研判直至清空 → 攻击链分析直至清空”。
IP 已在单包研判保存时写入日志内嵌 `correlation_ips` 多键索引，不存在独立的
IP 索引构建或 IP 建链步骤。源码目录仍可使用兼容入口 `python run_full_pipeline.py`。

接收日志：

```bash
python -m fengyun_ai_agent.cli receive --batch first
```

单告警分析：

```bash
python -m fengyun_ai_agent.cli analyze-alerts --limit 100
python -m fengyun_ai_agent.cli analyze-alerts --limit 100 --watch
```

攻击链关联：

```bash
# 全量数据或关联规则调整后可先重建实体和 correlation_ips
python -m fengyun_ai_agent.cli re-extract-entities --workers 64

# 从日志内嵌 correlation_ips 和其余声明式规则递归关联
python -m fengyun_ai_agent.cli analyze-chains --limit 1000
python -m fengyun_ai_agent.cli analyze-chains --limit 1000 --watch
```

关联规则以 `chain.md` 为业务基准，在 `chain_rules.py` 中声明。支持黑种子关联
黑/白/灰候选、AND/OR 复合条件、前后时间窗口和 UTC 事件时间。规则默认会把
被关联的白/灰日志提升为黑，并保存原始标签和说明，`reset-analysis --scope chains`
时可以恢复。攻击链会记录命中的规则 ID、入口日志和 `needs_review`；没有
RASP/WAF/Web/Auth/Mail/DB Audit 入口的链会标记为需要人工检视。
时间属于日志而不是实体：`eventTimeDay/Hour/Minute` 不再写入 `entities`，统一
保存为顶层 BSON Date 字段 `event_time_utc`，MongoDB 时间范围查询使用
`(log_source, event_time_utc)` 轻量索引。

非直接-IP关联会把实体规范化为 `correlation_entities` 精确匹配键，并通过单一
多键复合索引查询；直接IP关联的时间和目标资产范围保持不变。

默认执行 Judge 告警分析：

```bash
python -m fengyun_ai_agent.cli analyze-alerts --mode judge --watch
```

专家优先告警分析：

```bash
python -m fengyun_ai_agent.cli analyze-alerts --mode expert-first --watch
```

默认关联分析与专家攻击链分析：

```bash
python -m fengyun_ai_agent.cli analyze-chains --mode association --watch
python -m fengyun_ai_agent.cli analyze-chains --mode expert --watch
```

统一提交：

```bash
python -m fengyun_ai_agent.cli submit --watch
```

提交前预览：

```bash
python -m fengyun_ai_agent.cli submit --dry-run
```

`--dry-run` 不请求远端、不更新状态、不写成功提交 JSONL。
远端返回成功并写入 MongoDB `submitted` 后，即使本地成功 JSONL 备份失败，也不会
把结果改回失败或重复提交；程序只打印备份警告。

## 专家标注语义

- 前端人工标注只写 `label_human` 和 `description_human`。
- 自动研判只写 `label` 和 `description`。
- 专家攻击链写 `chain_id_human`；自动攻击链写 `chain_id`。
- 专家标注本身不生成提交结果；只有选择专家分析模式并完成分析后才写 outbox。
- 接收入库只保存原始字段和待研判状态，不提取实体，也不查询专家记录。
- 前端新增、修改或删除专家标注时，同时更新 `expert_annotations` 和 `logs` 的
  人工字段；`sync-expert-annotations` 保留为异常恢复和全量重建命令。
- 一条日志最多属于一条专家攻击链；加入新专家链时会自动从旧专家链移除。
- `analyze-chains --mode expert` 会把专家链物化到 `attack_chains`，供统一提交。

## 数据恢复

每次启动 WSS 接收必须指定业务批次，例如 `--batch first`。连接异常重连仍写入
同一批次；收到 `stream_finished` 后进程退出，下一批重新启动并传入新标识。
不同业务批次使用不同目录，同一批次的日志按来源保存。例如第一批位于
`raw_logs/first/`，其中包含 `waf.jsonl`、`hids.jsonl` 和 `unknown.jsonl` 等文件。
随后所有日志统一写入 MongoDB `logs` 集合。
分类文件每行就是原始日志对象，不再额外包装成 `{"log": {...}}`，以减少文件
体积。正常 WSS `log_batch` 不重复保存完整消息；只有异常帧和接收错误会
进入 `raw_logs/first/raw_receive_errors.jsonl`。回灌文件每行必须直接是日志对象，
不接受旧的 `{"log": {...}}` 外层包装。
MongoDB 临时失败时可从任一分类文件回灌：

```bash
python -m fengyun_ai_agent.cli import-raw-logs \
  --path src/fengyun_ai_agent/data/raw_logs/first/waf.jsonl \
  --batch-size 10000
```

重复导入按日志 `id` upsert，不覆盖已有自动研判、专家标注或攻击链字段。
`unknown.jsonl` 仅保留为原始备份，回灌时会跳过未知日志类型。

## 管理界面

后端：

```powershell
$env:PYTHONPATH = "src"
python backend_py/app.py
```

前端：

```powershell
cd frontend
npm install
npm run dev
```

界面会分别显示自动研判、专家标注、自动攻击链和专家攻击链。攻击链详情默认
以实体关系图展示：种子告警单独作为起始顶点，下游日志按“日志类型 + 父实体
类型/值 + 关系 + 当前实体类型/值”聚合，每条日志只属于一个顶点；同类型日志
使用不同关联关系时会拆成不同顶点。边展示相等、包含或归属关系，也可以切换回
分页日志表格。

## 单包标签规律挖掘

包内 [label_pattern_mining.ipynb](src/fengyun_ai_agent/notebooks/label_pattern_mining.ipynb)
会从 MongoDB 流式
统计每个日志类型下所有实体和原始 `data` 字段值的黑白分布，筛选高频、高置信度
规律，并导出与规律不一致的疑似误报/漏报日志。统计只读 Mongo，不修改标签。

从 PyPI 安装后导出并打开包内 Notebook：

```bash
python -m pip install "fengyun-agent-task[analysis]"
export production=1
fengyun-task export-label-pattern-notebook
jupyter lab label_pattern_mining.ipynb
```

源码环境也可以直接打开
`src/fengyun_ai_agent/notebooks/label_pattern_mining.ipynb`。

默认使用关联提升前的单包标签，并把聚合结果写入
`result/label_patterns/label_pattern_stats.sqlite3`，规律和疑似日志分别导出为 CSV。

## 共享目录安全归档

`src/fengyun_ai_agent/transfer` 提供 FYSEC1：把多个文件或目录合并为单一 tar
数据流，使用 Zstandard 或 LZMA2 高压缩后执行 AES-256-GCM 认证加密。文件名和内容均位于
密文内，接收端只在认证成功后安全解包。固定结构原始日志可使用 FYLOGB2
`secure-jsonl-pack`，执行 11 类日志专用二进制列式编码、可逆跨字段推导，并可选择
Zstandard 22、LZMA2 extreme 或实验性逐列自适应压缩；在
加密前逐文件执行原始 SHA256 回环验证，以进一步减少最终传输体积。

源码环境安装传输专用依赖：

```powershell
python -m pip install -r src/fengyun_ai_agent/transfer/requirements.txt -i <可用PyPI镜像>
```

完整流程和现场参数见
[transfer/README.md](src/fengyun_ai_agent/transfer/README.md)。

## 一键构建并发布到 PyPI

Windows 下可直接使用仓库根目录的一键脚本。首次把新 token 配置到用户目录
`~/.pypirc` 后，以后不需要再设置环境变量：

```powershell
.\publish.ps1 -Version 0.2.8
```

只检查、不上传：

```powershell
.\publish.ps1 -Version 0.2.8 -CheckOnly
```

macOS/Linux 使用：

```bash
chmod +x publish.sh
./publish.sh --version 0.2.8
```

只检查、不上传：

```bash
./publish.sh --version 0.2.8 --check-only
```

发布依赖只需安装一次：

```powershell
python -m pip install -e ".[publish]"
```

凭据必须放在环境变量或用户目录的 `.pypirc`，不要写入仓库。PowerShell 示例：

```powershell
$env:TWINE_USERNAME = "__token__"
$env:PYPI_API_TOKEN = "<PyPI API token>"
fengyun-publish --version 0.2.8
```

Linux：

```bash
export TWINE_USERNAME='__token__'
export PYPI_API_TOKEN='<PyPI API token>'
fengyun-publish --version 0.2.8
```

命令会依次运行单元测试、构建 wheel/sdist、执行 `twine check` 并上传。只构建和
校验、不上传：

```bash
fengyun-publish --version 0.2.8 --check-only
```

默认复用当前环境中由 `[publish]` 安装的构建依赖，避免构建时再次联网；如需使用
临时隔离构建环境，可额外传入 `--isolated-build`。

也可使用 `python -m fengyun_ai_agent.publish` 代替 `fengyun-publish`。

## 常用命令

| 命令 | 作用 |
|---|---|
| `init-db` | 创建四个集合和索引。 |
| `reset-db --yes` | 删除并重建四个集合，生产环境禁止误用。 |
| `reset-analysis --scope ... --yes` | 保留原始日志和专家数据，重置自动分析派生状态。 |
| `status` | 输出日志、专家记录和提交记录的分来源、攻击链及状态统计。 |
| `team-status` | 只读查询比赛服务端进度。 |
| `import-expert-annotations --path ...` | 从单个 JSON/JSONL 或整个目录导入专家告警和专家攻击链。 |
| `sync-expert-annotations` | 从专家记录全量重建日志人工字段。 |
| `receive` | 接收 WSS，写 JSONL 和 MongoDB。 |
| `import-sample-data` | 导入样例日志。 |
| `import-raw-logs` | 从原始 JSONL 回灌。 |
| `pipeline` | 可选导入 JSONL，并循环完成全部单包研判和攻击链分析。 |
| `analyze-alerts --mode ...` | 执行 Judge 或专家优先的单告警分析。 |
| `re-extract-entities` | 并发重建关联实体。 |
| `analyze-chains --mode ...` | 执行 chain.md 关联或专家攻击链分析。 |
| `submit` | 读取并提交统一 outbox。 |
| `show-log` | 查看单条原始日志。 |
| `show-chain` | 查看自动攻击链下的日志。 |
| `show-chain-trace <ID>` | 按日志ID或攻击链ID输出父子关系、规则、条件和实体的缩进树。 |
| `show-alert-detail <ID>` | 输出单告警原始结构、研判/专家标签及关联上下文。 |
| `export-chain-trace-notebook` | 导出攻击链文本展示与专家人工编辑 Notebook。 |
| `export-alert-statistics-notebook` | 导出各日志类型黑告警占比统计 Notebook。 |

## 测试阶段的数据结构调整

当前仍处于尝试阶段。只要日志字段、实体结构、索引结构或攻击链结构发生变化，
不做历史数据迁移和修复，统一清空 MongoDB 后从原始 JSONL 重新导入：

```bash
python -m fengyun_ai_agent.cli reset-db --yes
python -m fengyun_ai_agent.cli import-raw-logs --path <批次来源JSONL> --batch-size 10000
python -m fengyun_ai_agent.cli analyze-alerts --limit 100 --watch
python -m fengyun_ai_agent.cli analyze-chains --limit 1000 --watch
```

`reset-analysis` 仅保留给不改变数据结构的局部逻辑复算，不承担版本迁移。

参数详见 [usage_cli.md](usage_cli.md)。

## 规模建议

三百万日志可由单 MongoDB 副本集承载，但应保证：

- MongoDB 数据盘使用 SSD/NVMe；
- 保留项目创建的查询索引；
- `receive` 和分析进程使用批量写入；
- 监控工作集、慢查询、连接数和磁盘增长；
- 数据继续增长或写入并发明显增加时，再按 `id` 哈希或时间/来源规划分片；
- 不要在生产库执行 `reset-db --yes`。
