内容
# FENGARDE
[](https://github.com/supermhel/fengarde/actions/workflows/ci.yml)
[](https://github.com/supermhel/fengarde/actions/workflows/codeql.yml)
[](https://securityscorecards.dev/viewer/?uri=github.com/supermhel/fengarde)
> 上方的徽章反映了在 `main` 分支上最近的实际运行结果,而不是承诺 —
> CI/CodeQL/Scorecard 均已至少运行一次,截至 2026-07-19(PR#2 合并后)。
> Scorecard 的发现推动了一次供应链固定(工作流 SHA、Docker 基础镜像摘要),使其得分从初始的约 54 个开放警报降至 19 个,所有这些都是可接受的政策级别的权衡(参见 `SSOT.md` §1),而不是未解决的漏洞。
**适用于欧洲工业中型企业的开源 SIEM — 将工厂和 IT 日志转换为 NIS2 事件通知草稿,具备 AI 预警功能,且永不离开您的网络。**
FENGARDE 从多个来源收集日志,将它们标准化为单一模式([OCSF](https://schema.ocsf.io/)),在滑动窗口上运行关联规则,并在一个仪表盘中显示警报。每个服务都是独立的,仅通过消息总线与其他服务通信,因此您可以扩展或替换任何部分而无需重写其他部分。
FENGARDE 有三点使其与普通的自托管 SIEM 不同:
- **原生 OCSF,而非 retrofit。** 从一开始,每个来源都标准化为相同的开放模式 — 仅需一次接入,保持可移植,无供应商日志格式锁定。
- **OpenSearch,而非 Elastic。** 存储引擎上没有许可限制 — 开源故事没有附加条款。
- **AI 预警功能永不离开您的网络。** 默认情况下使用本地 Ollama,并具备文档化的备用 stub — 您的警报数据永不会通过第三方 LLM API 发送。
v0.4 新增功能:针对特定来源的解析器包(MCP/AI 代理工具调用审计日志、工业 OPC UA 控制系统事件和 n8n 自动化平台日志),以及事件报告草稿钩子(NIS2/DORA 监管证据功能的开放部分;参见 [`contracts/reporting.md`](contracts/reporting.md))。
---
## 快速入门(10 分钟)
```sh
git clone https://github.com/supermhel/fengarde.git && cd fengarde
make preflight # 检测 vm.max_map_count、Docker RAM 和空闲端口
make demo # docker compose up — 真实的 SSH 暴力破解警报在 ~30-60 秒内出现在仪表盘中,无需手动干预
# 打开 http://localhost:8080
```
没有 Docker?整个检测管道可以在零基础设施下运行:`make e2e` 证明相同的 SSH 暴力破解 → 真实警报 → 等幂重放路径,无需 Redis/OpenSearch/Docker。
---
## 演示
观看 FENGARDE 将真实的 SSH 暴力破解突发转换为真实警报 — **无需任何基础设施**(无需 Docker、Redis、OpenSearch):
```sh
bash tools/demo.sh
```
这将 10 次来自一个 IP 的 SSH 登录失败事件输入整个管道(标准化 → 检测 → 预警 → 索引),显示暴力破解 **警报** 的产生,并重放事件以证明警报是 **幂等的**(去重,不重复)。
### 自己试试
```sh
# 零基础设施:SSH 暴力破解 -> 真实警报,在重放下幂等(无需 Docker)。
make e2e # 运行 demo_e2e.py(快速,无旁白)
bash tools/demo.sh # 相同的测试,带有横幅和故事旁白
# # Windows: powershell -File tools\demo.ps1
# 完整的实时堆栈(收集 -> 标准化 -> 检测 -> 索引 -> 仪表盘):
make up # docker compose up -d
# ...然后在以下地址打开 FENGARDE 警报控制台:
# http://localhost:8080
make down # 停止堆栈并删除卷
```
> 首次使用实时堆栈?在启动前运行 `make preflight` — 它检查 `vm.max_map_count`、Docker RAM 和空闲端口,并打印缺少内容的确切修复方法。参见 [预飞行](#%E9%A1%B5%E9%A3%98%E9%A3%9C-%E8%AF%BB%E5%90%8B%E5%89%8D%E6%82%A8%E5%90%8B%E5%90%8A%E5%90%8A%E5%90%8C%E5%90%8C)。
---
## 真实内容(v0.5.0 已发布 — v0.4.0/v0.5.0 标签在 `main` 上)
FENGARDE 配备了一个**可用的检测管道**。我们有意区分什么是真实的,什么是有计划的 — 这是一个安全工具,因此准确性比功能列表更重要。参见 [SSOT.md](SSOT.md) 以获取权威的、持续更新的状态 — 该表是一个快照,那个文件是真相来源。
| 功能 | 状态 | 备注 |
|---|---|---|
| **检测管道**(收集 → 标准化 → 检测 → 索引 → 仪表盘) | ✅ 已完成 | 自 v0.1 起端到端 |
| **解析器(16)** | ✅ 已完成 | Cisco ASA、Active Directory、VMware vSphere、Linux SSH、通用 syslog、Windows 事件日志(包括帐户更改 4720/4722/4726/4728/4732)、DB 审计(GRANT/REVOKE/ALTER)、MCP/AI 代理工具调用审计、OPC UA/OT 审计、n8n 自动化平台审计、DNS 查询日志、Kubernetes 审计、CEF(通用设备)、AWS CloudTrail、Sysmon(进程/网络/文件)、Modbus/TCP 协议异常检测器 — 所有 → OCSF |
| **检测规则(27)** | ✅ 已完成 | 暴力破解(每 IP 和无源/每目标主机)、端口扫描、横向移动、密码喷洒、特权组授予、非工作时间管理员、不可能旅行、银行 DB 特权提升、DC 大规模 VM 删除、代理凭证文件访问/工具调用突发/提示注入指示器/破坏性命令/出口非允许列表域、OT 维护外写入/新工程连接/配置更改/Modbus 未授权写入,n8n 新 webhook 暴露/工作流修改后非工作时间,DNS 数据泄露,特权容器创建,云根控制台登录,大规模 DB 对象读取,快速帐户创建/删除,信标(周期性基元) |
| **规则语法** | ✅ 已完成 | 布尔逻辑、比较运算符(`gt/gte/lt/lte/ne`)、允许列表抑制(`not_in`,CIDR + 精确)、时间(`outside_hours`)— 所有失败闭合输入无效 |
| **规则预过滤器** | ✅ 已完成 | 规则按 `class_uid` 等式选择分组;事件仅在候选规则下评估(修复 O(规则 × 事件)扫描) |
| **反休眠防护** | ✅ 已完成 | `tools/check_rule_producers.py` 在 CI 门户中证明每个规则的选择都是可满足的,由实际解析器发出的值 |
| **AI 预警**(本地 Ollama) | ✅ 已完成 | 通过 `OLLAMA_URL` 实现真正的本地 LLM 预警;降级为带有零基础设施的文档化直通存根 |
| **预警工作流** | ✅ 已完成 | 警报状态 + 分析师注释通过 WS-3 预警 API 持久保存,可在仪表盘中编辑;并发写入在两个层面上受到保护(进程内锁定 + OpenSearch 乐观并发) |
| **事件报告草稿钩子** | ✅ 已完成(v0.4) | `POST /alerts/{id}/report` 从警报事实中渲染通用 markdown 事件报告,始终标记为 `status: draft`,带有免责声明;监管内容后端是付费的可选附加组件(`contracts/reporting.md`) |
| **可选身份验证** | ✅ 已完成(v0.4) | 共享密钥 `FENGARDE_API_KEY` 在预警/库存 API 上,可选仪表盘基本身份验证,可选 Redis `AUTH` — 未设置(默认)保持完全开放,与 v0.1-v0.3 行为匹配 |
| **Syslog UDP 监听器**(WS-1) | ✅ 已完成 | 即时数据报 → `raw.events` |
| **多租户** | ✅ 已完成 | `tenant_id` 线程收集器 → 标准化 → 检测 → 索引;每租户 OpenSearch 索引,每租户规则启用;通过 `tools/test_multi_tenant_isolation.py` 证明隔离 |
| **基于角色的访问控制** | ✅ 已完成,可选 | 通过 `FENGARDE_RBAC_DB` 进行每用户帐户/角色/租户范围;会话 cookie,CSRF 保护,仪表盘登录 UI;未设置(默认)= 预 RBAC API 密钥仅行为,按字节不变 |
| **版本化 REST API** | ✅ 已完成 | `contracts/triage-api.yaml`(OpenAPI 3.1);每个路由在裸或 `/api/v1/...` 下均可访问;规范与代码漂移在 CI 中测试 |
| **外出警报 webhook** | ✅ 已完成,可选 | HMAC-SHA256 签名交付到操作员配置的 URL(`contracts/webhooks/*.yml`,空值);参见 `docs/webhooks.md` |
| **解析器/规则插件接口** | ✅ 已完成 | 外部 pip 包可以通过 Python 入口点提供解析器或规则包,无需分叉;参见 `docs/plugin-development.md` |
| **混沌测试交付** | ✅ 已完成 | `make chaos`:40 个场景,每个管道服务 SIGKILL 在重放中 — 零丢失,零重复警报(2026-07-18 运行) |
| **NIS2(DE)报告模板** | ✅ 已完成 | 确定性德语/英语 NIS2 Art. 23 / §32 BSIG 草稿,在报告钩子上添加(`?template=nis2`);每个实体特定事实都呈现为显式 `[分析师必须提供]` 占位符,永不捏造 |
| SNMP 解析器 | 🚧 计划中 | 延期 — [良好第一个问题](CONTRIBUTING.md) |
| NetFlow 解析器 | 🚧 计划中 | 延期(二进制格式) |
| 自定义 JSON 解析器 | 🚧 计划中 | 延期 |
> **无需 AI。** 管道在零基础设施和无 LLM 的情况下生成真实警报;Ollama 预警是一个可选层,在没有基础设施的情况下会降级为存根。
---
## 性能(`fengarde-bench`)
```sh
python tools/fengarde_bench.py --events 20000 --mixed
```
只需一个命令,任何人都可以复制 — 无需 Docker。2026-07-16 在 4 个 vCPU / 15 GB 沙盒主机(不是固定的参考 VPS,参见下面的免责声明)上测量:
| 指标 | 值 |
|---|---|
| 持续 EPS(5,000 事件,仅 `linux_ssh`) | ~12,950 events/sec |
| 持续 EPS(20,000 事件,混合 `ssh`/`asa`/`generic_syslog`) | ~13,750 events/sec |
| 峰值驻留内存(20,000 事件运行) | ~84 MB |
**在任何地方引用这些数字之前请阅读:** 这是一个 **零基础设施 CPU 绑定基线** — 一个进程,内存总线,`MemoryStore` — 测量 WS-2/WS-4/WS-3 的 Python 代码处理一批数据的速度。它不包括实际的 Redis 网络 I/O、OpenSearch 索引延迟和实时堆栈中的任何实际队列/背压行为。它 **不是** 一个“FENGARDE 在生产环境中处理 N 个事件/秒”的声明,并且没有 p50/p99 事件 → 警报延迟数字 — 批量处理没有现实的队列延迟来衡量;该数字仅在实时总线上才有意义。定义明确的参考框上的实时堆栈数字仍然是一个开放的 TODO(需要 Docker,而此存储库的当前 CI/开发环境不总是具有)。
---
## 先决条件
- **Docker Desktop**(或 Docker 引擎 + Compose v2),**≥ 4 GB RAM** 分配给 Docker。
- **操作系统:** Linux,macOS 或 **Windows via WSL2**。(演示堆栈运行 Linux 容器;预飞行和演示脚本是 POSIX `sh`。)
- **Python 3** — 仅当您想要运行合同测试或贡献解析器时需要。您 **不需要** Docker 来添加解析器(参见 [贡献](#%E8%B4%A1%E7%8C%AE))。
---
## ⚠️ 预飞行 — 在启动堆栈前请阅读
OpenSearch(存储引擎)**将无法启动**,在 Linux/WSL2 上使用默认内核设置。它需要提高 `vm.max_map_count` 限制。运行此命令 **一次** 每台机器(它在重启后重置):
```sh
sudo sysctl -w vm.max_map_count=262144
```
使其在重启后持续:
```sh
echo 'vm.max_map_count=262144' | sudo tee /etc/sysctl.d/99-fengarde.conf
```
> 在 **macOS with Docker Desktop** 上,这在 Docker VM 内处理,您可以通常跳过它。在 **Linux/WSL2** 上,这是必需的 — 如果没有它,您会得到一个 JVM 崩溃,而不是一个有用的错误。
`make preflight`(如下)为您检查这一点,并在缺少任何内容时打印确切的修复方法。
---
## 快速开始
```sh
# 1. 检查您的机器是否准备就绪(vm.max_map_count、Docker RAM、空闲端口)
make preflight
# 2. 启动完整的堆栈
make demo
```
`make demo` 运行预飞行检查,然后使用 Docker Compose 启动所有服务。所有服务都是长期运行的守护进程,具有 `/health` 端点和重启策略。
> **想在没有 Docker 的情况下查看 FENGARDE 工作?** 运行 **`make e2e`** — 一个零基础设施验收测试,将真实的 SSH 暴力破解突发输入整个管道,并显示警报从另一端输出(详见
> [如何查看警报](#%E5%A6%82%E4%BD%95%E6%9F%A5%E7%9B%96%E6%9C%AA%E6%8A%A1))。
>
> **诚实状态:** *in-stack* 实时馈送器和 *live* 仪表盘(直接从 OpenSearch 读取警报)是剩余的 DX2/DX4 项 — 参见
> [构建计划](docs/superpowers/specs/2026-06-27-fengarde-v0.1-build-plan.md)。自 v0.1 起,端到端检测逻辑已得到验证。
其他便捷目标:
```sh
make e2e # 零基础设施验收测试:SSH 暴力破解 -> 真实警报(无需 Docker)
make test # 运行完整的零基础设施合同测试套件(无需 Docker)
make up # 以分离模式启动堆栈(docker compose up -d)
make down # 停止堆栈并删除卷
```
---
## 端口
| 端口 | 服务 | 描述 |
|------|---------|------------|
| 6379 | `redis` (`siem-bus`) | 服务之间的消息总线 |
| 9200 | `opensearch` (`siem-store`) | 事件/警报存储 + 查询 API |
| 5601 | `dashboards` (`siem-dashboards`) | OpenSearch 仪表盘 |
| 8000 | `ws6-inventory` | 库存 API(IP/MAC 历史) |
| 8080 | `ws7-dashboard` | FENGARDE 警报控制台 |
| 5514/udp | `ws1-collectors` | 实时 syslog 收集(无身份验证 — 仅受信任的分段) |
| 8013 | `ws3-indexer` | 预警 API — **仅限内部使用**,仪表盘在容器之间代理到它;不发布到主机 |
`make preflight` 在您启动前检查已发布的端口是否空闲。
---
## 如何查看警报
v0.1 的验收测试是一个真实的 **暴力破解警报**,而非模拟数据:
1. **信号。** 60 秒内来自单个源 IP 的 10 个身份验证失败事件。FENGARDE 从 Linux SSH 的“密码失败”行或 Windows 的 `EventID 4625` 生成这些信息 — 两者都标准化为相同的 OCSF 身份验证事件(`class_uid: 3002`, `activity_id: 4`)。
2. **规则。** [`contracts/rules/common_bruteforce.yml`](contracts/rules/common_bruteforce.yml) 与这些事件匹配,按 `src_endpoint.ip` 分组,阈值为 10 且 `window_seconds: 60`。它是源无关的,因此在 SSH 或 AD 上都能触发相同的警报。
3. **警报。** 当来自一个 IP 的第 10 个失败事件在窗口内到达时,检测服务会发出一个警报,该警报流向索引器并进入仪表盘警报列表。
通过 **无需任何基础设施** 的方式查看 **整个管道** 生成警报:接受性测试将 10 个 SSH 登录失败事件注入并断言一个真实的暴力破解警报到达索引,并重放相同的事件以重用相同的警报 ID(幂等,无需至少一次交付双重警报):
```sh
make e2e # 或:python tools/demo_e2e.py
```
预期输出:
```
ALERT: Authentication brute-force from single source src=203.0.113.5 score=70 id=...
T7 OK: replay reused alert_id ... -> deduped (alerts count stayed 2)
[OK] FENGARDE v0.1 acceptance: SSH brute-force -> real alert in the index, idempotent under replay. Zero infra.
```
如果您更喜欢单元级检查,WS-4 检测合约测试断言规则在第 10 次尝试时触发:`cd services/ws4-detection && python test_contract.py`.
对于完整的 Docker 化堆栈(收集 → 标准化 → 检测 → 索引 → 仪表盘),运行 `make demo` 并在 <http://localhost:8080> 打开仪表盘。
---
## 架构
```
WS-1 Collectors ─raw.events─▶ WS-2 Normalization ─normalized.events─┬─▶ WS-3 Indexer ─▶ OpenSearch
(Cisco ASA / AD / (parsers → OCSF) ├─▶ WS-6 Inventory (IP/MAC)
VMware / Linux SSH) └─▶ WS-4 Detection ─scored.events─▶ WS-3
│ alerts ─▶ WS-3 / WS-7
└─ai.requests─▶ WS-5 AI (stub) ─▶ WS-3/WS-7
WS-7 Dashboard ◀── WS-6 API + alerts
```
服务之间**唯一**的耦合是消息总线。其他所有内容都是 `contracts/` 下的冻结合约。所有源格式的异质性都在边缘吸收(每个源一个解析器,在 WS-2 中);内部系统处理单个模式(OCSF)。
| WS | 服务 | 角色 | v0.1 状态 |
|----|---------|------|-------------|
| 1 | `services/ws1-collectors` | 收集日志 → `raw.events` | ✅ |
| 2 | `services/ws2-normalization` | 解析器 → 验证 OCSF 事件 | ✅(16 个解析器) |
| 3 | `services/ws3-indexer` | 路由 + OpenSearch 索引(幂等) | ✅ |
| 4 | `services/ws4-detection` | 关联规则 + 评分 + 窗口 | ✅(27 条规则) |
| 5 | `services/ws5-ai` | 预警 | ✅ 真实本地 LLM(Ollama)自 v0.2 起,存根备用 |
| 6 | `services/ws6-inventory` | IP/MAC 库存 API(SQLite) | ✅ |
| 7 | `services/ws7-dashboard` | 警报控制台 | ✅ |
有关当前状态和未来路线图的详细信息,请参阅 **[SSOT.md](SSOT.md)**(请先阅读)。有关历史设计背景: [v0.1 构建计划](docs/superpowers/specs/2026-06-27-fengarde-v0.1-build-plan.md) 和 [`docs/PHASE0_README.md`](docs/PHASE0_README.md).
## 评估和检测质量
“规则通过CI”和“规则在实际攻击流量中触发” 是不同的声明 — 本仓库将它们分开,而不是混淆 — 在 `eval/` 下的三个评估通道中:
| 命令 | 验证内容 | 需求 |
|---|---|---|
| `make attack-scorecard` | **声明**的 MITRE ATT&CK/ATT&CK-ICS/ATLAS 覆盖范围(规则的 `mitre:` 块声称的哪些技术)加上一个 **经验** 检查,即每个标记的规则实际上都通过实时检测引擎在其自己的真实生产者固定装置上触发 — 保持为两个不同的声明,永远不会合并为一个数字 | 零基础设施 |
| `make eval-detection` | 独立预言机重放:真实的 Windows 安全/Sysmon 攻击数据集(EVTX-ATTACK-SAMPLES,splunk/attack_data)通过实时管道输入,警报根据单独使用引擎自己的逻辑计算出的基准事实进行检查 — 这可以捕获单元测试无法捕获的错误,因为单元测试会镜像引擎自己的代码。有关数据集许可和设置的详细信息,请参见 [`eval/detection_accuracy/README.md`](eval/detection_accuracy/README.md)(两个数据集都是第三方提供的,不由我们提供;目标在不获取任何数据集的情况下可以跳过) | 需要单独获取真实数据集 |
| `make nis2-demo` | 端到端证明,真实警报成为结构上符合 NIS2 草案的警报(免责声明、草案状态、无虚构实体事实)— 与 `eval/report_generator/` 的测试框架在 CI 中运行的相同检查清单,涵盖 12 个合成场景 × 3 个阶段 × 2 种语言 | 零基础设施 |
这些都不是可选的附加功能 — `attack-scorecard` 和报告生成器评估都运行在 `run_all_tests.sh` 中;`eval-detection` 故意排除在零基础设施门控之外(始终跳过的目标在那里会产生噪音),但它是实际捕获暴力规则在 2026-07-21 审计过程中的真实假阴性的测试框架。
---
## 贡献
最快的贡献方式是 **添加解析器** — 而且你 **不需要** Docker 或 OpenSearch 即可做到。整个内部循环只需一条命令:
```sh
cd services/ws2-normalization && python test_contract.py
```
详见 **[CONTRIBUTING.md](CONTRIBUTING.md)** 了解贡献工作流程,**[docs/adding-a-parser.md](docs/adding-a-parser.md)** 了解逐步教程(复制 `linux_ssh.py`,进行三个小编辑,验证)。上述三个延迟解析器是明显的首个 PR — 或者通过 [规则请求模板](.github/ISSUE_TEMPLATE/rule_request.md) 提出新的检测规则。
监控 AI 代理/MCP 服务器?详见 **[docs/agent-monitoring.md](docs/agent-monitoring.md)**。想了解 FENGARDE 与 Wazuh/Elastic Security/Security Onion 的比较?详见 **[docs/vs.md](docs/vs.md)** — 一个诚实的比较,而不是销售推销。
---
## 安全
FENGARDE 服务设计用于 **本地主机 / Docker-Compose 网络**,**不适用于**互联网暴露。身份验证是 **可选** 的(`FENGARDE_API_KEY` 共享密钥、仪表板基本身份验证、Redis `AUTH` — 默认为关闭,与 v0.4 之前版本的行为一致,直到您选择启用)。真正的身份/RBAC 层(`FENGARDE_RBAC_DB` — SQLite 用户、scrypt 哈希、会话、角色、CSRF 保护写入、租户隔离)自 v0.5/M4 起存在,也默认为关闭(单进程会话存储,尚不支持高可用性 — 参见 SSOT.md §2)。检测引擎执行规则文件 — 因此请仅运行您信任的规则。需要从主机外部访问仪表板?详见 **[docs/deployment.md](docs/deployment.md)** 了解反向代理 TLS 示例。详见 **[SECURITY.md](SECURITY.md)** 了解完整的安全边界和漏洞报告方式。
---
## 开源核心 — 免费与付费
**本仓库永久免费开源,遵循 Apache-2.0 许可协议。** 其中所有内容 — 管道、每个解析器、每个检测规则、仪表板、分类 API、通用和 NIS2 报告模板 — 都是完整产品,而非阉割版试用。
有一个单独的、封闭的配套产品,**FENGARDE-Sec**,在私有仓库中开发:一个面向受监管部署的付费层(合法验证的报告内容和模型辅助合规工具)。它仅通过一个固定的、文档化的接口与本仓库连接 — [`contracts/reporting.md`](contracts/reporting.md) 中的报告后端接口(`REPORT_BACKEND=http`)。本仓库中的任何内容都不需要它、与它通信或在没有它的情况下功能下降。
实际上:功能永远不会从本仓库转移到付费层。新功能若符合接口约定,则在此开源;仅有受监管的合法内容层是付费的。
---
## 许可协议
FENGARDE 遵循 **Apache License 2.0** 许可协议。详见 [LICENSE](LICENSE)。
连接信息
猜你喜欢
暂无推荐服务器