sanidhya-chamoli/AI-integrated-SIEM
GitHub: sanidhya-chamoli/AI-integrated-SIEM
一个基于 Wazuh 和 Ollama 本地 LLM 的 AI 增强 SIEM 原型,通过自动分析和丰富安全告警来减轻 SOC L1 分析师的告警疲劳问题。
Stars: 0 | Forks: 0
# AI 增强的 SIEM





## 目录
1. [这是什么](#what-this-is)
2. [解决什么问题](#the-problem-its-solving)
3. [实际功能](#what-it-actually-does)
4. [架构](#architecture)
5. [仓库结构](#repository-structure)
6. [Pipeline 工作原理](#how-the-pipeline-works)
7. [前置条件](#prerequisites)
8. [安装](#installation)
9. [配置](#configuration)
10. [运行说明](#running-it)
11. [仪表板](#the-dashboard)
12. [批处理与演示模式](#batch-and-demo-mode)
13. [测试](#testing)
14. [安全设计](#security-design)
15. [示例输出](#example-output)
16. [坦诚的局限性](#honest-limitations)
17. [未来展望](#where-this-could-go-next)
18. [学术背景](#academic-context)
19. [作者](#author)
20. [许可证](#license)
## 这是什么
这最初是一个网络安全 B.Tech 项目,后来演变成了一个我真正引以为豪的作品:一个可用的 pipeline,它通过 [Ollama](https://ollama.com/) 将 [Wazuh](https://wazuh.com/) 连接到本地运行的 LLM,并利用它将原始的高严重性告警转化为分析师可以真正采取行动的信息。
它不是一个商业产品,也不是一个可以直接替代 SOC 的方案。它是一个实验室原型,旨在回答一个真实的问题:
根据构建和运行它的经验,答案是可以的——但我尝试在整个 README 中坦诚地说明一些真实的注意事项。
## 解决什么问题
如果你使用过 SIEM,你就知道原始告警是什么样子的。类似于这样:
```
Rule: 5710 | Level: 12 | Agent: windows-endpoint | 192.168.1.45 | Jan 15 14:32:07 sshd[2341]: ...
```
就是这样。凌晨 3 点值班的分析师收到这个告警后,仍然需要:
1. 记住或查阅规则 5710 到底是什么意思。
2. 弄清楚这个特定的事件是真正的威胁,还是仅仅是噪音。
3. 决定哪些系统面临风险,以及需要以多快的速度进行响应。
4. 找到相关的补救步骤,这通常需要翻阅自从入职以来就没再看过的操作手册。
把这个过程乘以每晚一百个告警,你就会明白什么是告警疲劳——分析师开始忽略这些警告,从而错过了真正的安全事件。
这个项目在 Wazuh 和分析师之间增加了一个步骤。一个 Python 进程监控 `alerts.json`,捕获高严重性事件,通过结构化的 prompt 将它们发送到本地 LLM,并将结果与原始告警一起存储——包括对发生的事情、面临的风险以及如何处理的通俗英文解释。
LLM 的输出是一个**初步辅助**,而不是最终定论。最终决策仍然由分析师做出。其目标是省去查找和拼凑上下文的工作,以便分析师能更快地做出决策。
## 实际功能
| 功能 | 详情 |
|---|---|
| 实时追踪 `alerts.json` | 字节偏移跟踪;能干净利落地处理部分写入和文件轮转 |
| 按 Wazuh 规则严重性过滤 | 默认:level ≥ 10;可在 `config.yaml` 中修改 |
| 发送告警到本地 LLM | 通过 HTTP POST 发送到 Ollama;要求返回结构化的 JSON |
| 结构化丰富输出 | 每次输出包含三个字段:`explanation`、`impact`、`remediation` |
| Ollama 宕机时的优雅降级 | 基于规则感知的启发式数据丰富;保证 pipeline 继续运行 |
| SHA-256 告警指纹识别 | 基于 rule ID + source IP + raw log 的去重——不使用 MD5 |
| JSONL 审计跟踪 | 仅追加;每个丰富后的告警占一行 |
| Markdown 报告 | `reports/` 目录下每个告警生成一个 `.md` 文件;写入前对内容进行转义处理 |
| Flask 仪表板 | 每次加载页面时读取完整的 JSONL 文件;确保跨重启后计数依然准确 |
| 通知路由 | 支持 SMTP / Slack / Teams,可按 rule ID 或 Wazuh group 进行路由 |
| 通过环境变量传递密钥 | `config.yaml` 中无需存储任何敏感信息 |
| 批处理模式 | 支持传入 JSONL 文件,而无需实时 Wazuh 实例 |
| 演示就绪检查 | `--demo-status` 会在演示前告诉你 Wazuh 和 Ollama 是否均可连通 |
| 回归测试套件 | 使用 `pytest` 覆盖指纹识别、过滤、SSRF 防护等功能 |
## 架构
### 数据流
```
flowchart TD
WA[Windows Endpoint\nWazuh Agent]
KL[Kali Linux\nAttack Simulation]
WZ[Wazuh All-in-One\nUbuntu — alerts.json]
MW[middleware.py\nTail → Filter → Enrich]
DISC[Discarded\nlevel < 10]
OL[Ollama\nLocal LLM inference]
FB[Rule-aware Fallback\nif Ollama unreachable]
RL[report_logger.py]
JSONL[enriched_alerts.jsonl]
MD[reports/*.md]
NT[notifier.py\nSMTP / Slack / Teams]
DB[Flask Dashboard\ndashboard.py]
KL -->|generates events on| WA
WA -->|Wazuh agent telemetry| WZ
WZ -->|file tail| MW
MW -->|level < threshold| DISC
MW -->|level ≥ 10| OL
OL -->|unreachable| FB
OL -->|enriched JSON| RL
FB --> RL
RL --> JSONL
RL --> MD
MW --> NT
JSONL --> DB
MD --> DB
```
### 实验室环境配置
三个虚拟机,全部位于仅主机网络上。下面的 IP 只是演示 `config.yaml` 中的配置——逻辑中没有任何硬编码。
```
┌──────────────────────────────────────────────────────┐
│ Lab Network (VMware / VirtualBox host-only) │
│ │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ Ubuntu 22.04 │ │ Kali Linux │ │
│ │ 10.99.85.19 │ │ 10.99.85.71 │ │
│ │ │ │ │ │
│ │ • Wazuh 4.x │ │ • Ollama + model │ │
│ │ • Python middleware │ │ • Attack tooling │ │
│ │ • Flask dashboard │ │ (nmap, hydra …) │ │
│ └──────────┬───────────┘ └──────────────────────┘ │
│ │ Wazuh agent (port 1514) │
│ ┌──────────▼───────────┐ │
│ │ Windows 10/11 │ │
│ │ Monitored endpoint │ │
│ └──────────────────────┘ │
└──────────────────────────────────────────────────────┘
```
刻意将 Ollama 运行在 Kali 虚拟机上——这样可以避免 Wazuh 服务器承担 LLM 推理的负担,它本身的工作已经够多了。如果你的配置不同,只需将 `ollama.base_url` 指向 Ollama 运行的位置即可。
## 仓库结构
```
SIEM/
├── src/
│ ├── main.py # Entry point — --config, --batch, --demo-status
│ ├── middleware.py # The core loop: tail, filter, enrich, dispatch
│ ├── ollama_service.py # Talks to Ollama, builds prompts, parses responses
│ ├── models.py # Alert and EnrichedAlert dataclasses
│ ├── notifier.py # Sends to SMTP / Slack / Teams
│ ├── report_logger.py # Writes JSONL and Markdown reports
│ ├── dashboard.py # Flask dashboard
│ ├── config_loader.py # Loads config.yaml, applies env var overrides
│ ├── config.yaml # All runtime settings — don't commit real secrets
│ └── install.sh # Sets up a systemd service on Ubuntu
│
├── reports/ # Where enriched reports land (git-ignored)
├── tests/
│ └── test_core_hardening.py # The regression suite
│
├── wazuh-training-set.jsonl # Sample alerts for batch/demo mode
├── requirements.txt
├── .gitignore
└── README.md
```
## Pipeline 工作原理
### 摄取告警
`middleware.py` 通过跟踪文件的字节偏移量来 tail `alerts.json。有三点可能会破坏简单实现的问题得到了明确处理:
**部分行写入。** Wazuh 写入的是以换行符分隔的 JSON,但 `read()` 并不保证你能读取到完整的一行。Tailer 会缓冲传入的字节,直到看到换行符才开始尝试解析。
**文件轮转。** 当 Wazuh 轮转告警文件时,inode 会发生改变。Tailer 会捕获这一情况,并从新文件的开头重新打开,而不是继续读取过期的文件句柄。
**格式错误的 JSON。** 错误的行会被记录并跳过。它不会导致循环崩溃或丢弃随后的告警。
### 严重性过滤
Wazuh 级别从 0 到 15。中间件会丢弃低于配置阈值(默认:10)的任何内容。按照 Wazuh 惯例,10-11 级为“高”,12-14 级为“严重”,15 级保留给 Wazuh 的内部事件。如果你想捕获更多(或更少)的告警,请在 `config.yaml` 中调整 `severity_threshold`。
### LLM 丰富
`ollama_service.py` 会构建一个 prompt,其中包含 rule ID、描述、agent 名称、source IP 以及原始日志片段。模型被要求返回一个刚好包含三个键的 JSON 对象。如果返回的内容格式错误,调用会重试一次——如果再次失败,就会触发降级操作。
降级操作会根据 Wazuh 的规则组(`syscheck`、`authentication_failed`、`web` 等)生成确定的响应。它虽然不如真正的 LLM 响应有用,但它对自己的来源非常诚实:JSONL 记录会标记 `"fallback": true`,这样你就可以随时区分哪些输出来自模型,哪些来自降级操作。
### 指纹识别
早期版本使用 MD5 对告警进行去重,但由于输入集有限(仅包含 rule ID 和时间戳),很容易发生冲突——来自不同 source IP 但具有相同 rule ID 的两个告警会被视为重复。现在的指纹使用 SHA-256 算法,基于 rule ID、source IP、完整的原始日志字符串和分钟级时间戳生成。来源不同,记录就不同。
### 持久化
在 `report_logger.py` 中,每个丰富后的告警会执行两项操作:
1. 作为单行 JSON 追加到 `enriched_alerts.jsonl` 中。这是权威记录——它是仪表板读取的内容,也是你会交给任何进行事件分析的人员的内容。
2. 在 `reports/` 中生成属于自己的 Markdown 文件。所有用户可控的字符串在写入前都会经过转义函数处理,因此无论原始日志包含什么内容,输出都能干净地渲染。
### 通知
`notifier.py` 会根据 `config.yaml` 中的路由表检查每个丰富后的告警。你可以按 rule ID 或 Wazuh group 将告警路由到 SMTP、Slack 或 Teams 的任意组合。如果没有匹配项,则不会发送任何内容——这里没有“发送所有内容”的兜底机制,否则很快就会变得极为嘈杂。SMTP 密码在日志调用发生之前,就已经在日志输出中被掩码处理了。
## 前置条件
| 依赖 | 备注 |
|---|---|
| Python 3.9+ | 在 3.10 和 3.11 上测试过 |
| Wazuh 4.x | Ubuntu 上的 All-in-One 部署;需要正在写入 `alerts.json` |
| Ollama | 任何近期版本;必须能从中间件主机通过 HTTP 访问 |
| LLM 模型 | 追求更好的输出选择 `llama3`;如果硬件受限可选择 `tinyllama` |
| Wazuh agent | 安装在你正在监控的 endpoint 上 |
中间件不需要 root 权限。它需要对 `alerts.json` 的读取权限(默认属主为 `ossec`)以及对 `reports/` 的写入权限。
## 安装
### 1. 克隆仓库
```
git clone https://github.com/vinayak-sriv/SIEM.git
cd SIEM
```
### 2. 安装 Python 依赖
```
python3 -m pip install -r requirements.txt
```
### 3. 设置 Wazuh
按照 Ubuntu 的 [Wazuh All-in-One 快速入门指南](https://documentation.wazuh.com/current/quickstart.html) 进行操作。一旦运行起来,检查告警是否正在被写入:
```
sudo tail -f /var/ossec/logs/alerts/alerts.json
```
如果中间件用户无法读取该文件,请将他们添加到 `ossec` 组:
```
sudo usermod -aG ossec $USER
# 注销并重新登录,然后检查:
ls -la /var/ossec/logs/alerts/alerts.json
```
### 4. 安装 Ollama 并拉取模型
```
# 安装 Ollama
curl -fsSL https://ollama.com/install.sh | sh
# 拉取模型 — llama3 提供更好的输出,tinyllama 在有限硬件上运行更快
ollama pull llama3
ollama pull tinyllama # optional lighter alternative
# 在进行其他任何操作之前,请确保 API 正在响应
curl http://localhost:11434/api/tags
```
### 5. (可选)作为 systemd 服务运行
```
sudo bash src/install.sh
sudo systemctl status siem-middleware
```
## 配置
所有配置都在 `src/config.yaml` 中:
```
wazuh:
alerts_file: /var/ossec/logs/alerts/alerts.json
severity_threshold: 10 # Wazuh rule level 0–15; 10 is a reasonable starting point
ollama:
base_url: http://127.0.0.1:11434 # Override with OLLAMA_URL
model: tinyllama # Override with OLLAMA_MODEL
timeout: 60
reports:
output_dir: ./reports
jsonl_file: ./reports/enriched_alerts.jsonl
dashboard:
host: 127.0.0.1 # Keep this local; don't expose to 0.0.0.0 without a proxy and auth
port: 5000
token: "" # Set via SIEM_DASHBOARD_TOKEN
notifications:
smtp:
host: smtp.gmail.com
port: 587
user: ""
password: "" # Set via SMTP_PASSWORD — please don't commit a real password here
recipients: []
slack:
webhook_url: "" # Set via SLACK_WEBHOOK; must start with https://
teams:
webhook_url: "" # Set via TEAMS_WEBHOOK; must start with https://
routing:
rules: []
# Examples:
# - match: {rule_id: 5710}
# channel: slack
# - match: {group: authentication_failed}
# channel: smtp
```
### 将密钥排除在配置文件之外
配置中的任何字段都可以通过环境变量进行覆盖。使用 `.env` 文件(不要提交到仓库)或 secrets manager:
```
export OLLAMA_URL=http://10.99.85.71:11434
export OLLAMA_MODEL=llama3
export SEVERITY_LEVEL=10
export SMTP_PASSWORD=your-app-password
export SLACK_WEBHOOK=https://hooks.slack.com/services/T.../B.../...
export TEAMS_WEBHOOK=https://outlook.office.com/webhook/...
export SIEM_DASHBOARD_TOKEN=local-dev-token
```
## 运行说明
### 首先检查所有服务是否可连通
在演示或在全新机器上首次运行之前,此命令会检查 `alerts.json` 是否可读以及 Ollama 是否正在响应:
```
python3 src/main.py --config src/config.yaml --demo-status
```
它不止一次让我避免了在投影仪前面对令人尴尬的沉默。
### 启动中间件
```
python3 src/main.py --config src/config.yaml
```
这会阻塞并持续追踪告警文件,直到你按下 `Ctrl+C` 停止它。如果你安装了 systemd 服务,请使用该服务来实现持久化运行。
### 启动仪表板
在另一个单独的终端中:
```
python3 src/dashboard.py --config src/config.yaml --reports ./reports
```
然后打开 `http://127.0.0.1:5000`。
## 仪表板
Flask 仪表板特意设计得简单且只读。它在每次加载页面时读取 `enriched_alerts.jsonl`,并显示:
- 按时间倒序排列的丰富后告警信息流——包括 rule ID、严重级别、source IP、agent 名称以及 LLM 的解释。
- 严重性分布计数,该数据是基于完整的 JSONL 文件计算得出,而非依赖内存中的状态,因此即使你重启了中间件,统计结果也能保持准确。
- 指向每个告警独立 Markdown 报告的链接。
有一点需要注意:**仪表板没有任何身份验证**。它是一个本地检查工具。请将其绑定保持在 `127.0.0.1`。如果你需要通过网络访问,请在前面部署带有基础认证的 nginx 或 Caddy。
## 批处理与演示模式
如果你没有运行实时的 Wazuh 实例——也许你正在做演示、测试更改,或者只是在笔记本电脑上对此进行评估——批处理模式允许你针对静态的 JSONL 文件运行完整的 pipeline:
```
python3 src/main.py --batch wazuh-training-set.jsonl --config src/config.yaml
```
`wazuh-training-set.jsonl` 包含在仓库中。它是精心挑选的、具有代表性的高严重性 Wazuh 告警集合——足以正确展示数据丰富功能,而无需真正发起一次暴力破解攻击。输出会存放在同一个 `reports/` 目录中,并且仪表板对其的渲染效果与实时模式完全相同。
添加此模式是专门为了让这个项目能够在院系评审中进行演示,而不会出现那种“抱歉,让我先把这个 Kali 机器跑起来”的尴尬场面。
## 测试
```
python3 -m pytest tests/ -v
```
`tests_core_hardening.py` 中的测试套件是伴随着安全加固工作一起编写的,而不是事后补充。以下是它涵盖的内容:
| 测试领域 | 检查内容 |
|---|---|
| SHA-256 指纹识别 | 具有相同 rule ID 但 source IP 不同的两个告警会产生不同的指纹 |
| 指纹稳定性 | 同一个告警始终产生相同的指纹 |
| 抗碰撞性 | 仅在日志内容上有所不同的告警不会发生碰撞 |
| 格式错误的 JSON | 错误的行不会引发异常或中断循环;下一个有效的行将正常处理 |
| SSRF 防护 | 在发出任何请求之前,私网范围或环回地址的 Ollama URL 会被拒绝 |
| Webhook 验证 | 非 HTTPS 的 webhook URL 在启动时会被拒绝 |
| 严重性过滤 | 低于阈值的告警永远不会到达丰富处理阶段 |
| Markdown 转义 | 用户可控的字符串在报告输出中会被转义 |
| 仪表板计数准确性 | 告警计数反映的是完整的 JSONL 文件,而不仅仅是内存中的内容 |
运行这些测试不需要启动 Ollama。任何涉及 `ollama_service.py` 的测试,要么使用降级路径,要么对 HTTP 调用进行了 patch 处理。
## 安全设计
### 对范围保持坦诚
这是一个实验室原型。下面提到的控制措施都是真实且经过测试的。但是,该系统尚未经过审计,如果不进行额外的加固,它还不能直接用于生产环境的 SOC。如果你要在真实环境中使用它,请将其视为一个起点,而不是最终产品。
### 已实现的功能
| 控制措施 | 做了什么及其原因 |
|---|---|
| **数据本地性** | 所有 LLM 推理都通过本地的 Ollama 实例进行。告警内容永远不会接触到外部 API。 |
| **SHA-256 指纹识别** | 旧的基于 MD5 的方法使用了狭窄的输入集(rule ID + 时间戳),会将来自不同 source IP 的告警合并为同一个指纹。通过基于 rule ID + source IP + 完整原始日志 + 截断时间戳的 SHA-256 解决了这个问题。 |
| **针对 Ollama URL 的 SSRF 防护** | `config_loader.py` 会在发出任何请求之前,根据 RFC 1918 私有地址范围和环回地址验证 `ollama.base_url`。这可以防止中间件被用作探测其他内部服务的跳板。如果你在分离网络实验室中的单独主机上运行 Ollama,`config_loader.py` 中有一个标志可以禁用此检查——代码中已有相关文档说明。 |
| **强制 Webhook 使用 HTTPS** | Slack 和 Teams 的 URL 必须以 `https://` 开头。HTTP URL 在配置加载阶段就会被拒绝——如果你的 webhook token 以明文传输,它就已经被破解了。 |
| **SMTP 凭据掩码** | SMTP 密码在被传递给任何日志语句之前就会被替换为 `***`。原始值永远不会被写入日志中。 |
| **通过环境变量传递密钥** | `config.yaml` 中的任何敏感字段都不需要填入真实值。所有内容都在运行时从环境变量中解析,因此你可以直接使用 secrets manager,而无需修改任何代码。 |
| **日志文件轮转** | `RotatingFileHandler` 限制了日志文件的大小。如果没有这个机制,连续运行几周就会塞满磁盘。 |
| **部分行缓冲** | 永远不会对不完整的行调用 `json.loads()`。Tailer 会等待换行符的出现。 |
| **Markdown 转义** | LLM 输出和来自告警的字符串在写入前都会被转义。精心构造的日志行中的反引号注入不会破坏报告的渲染。 |
### 未受保护的内容——你有必要了解
**仪表板没有登录功能。** 默认情况下,它绑定在 `127.0.0.1` 上。如果在没有配置带有身份验证的反向代理的情况下,千万不要将 5000 端口暴露在网络接口上。
**`config.yaml` 的文件权限至关重要。** 如果该文件包含 webhook URL,任何能够读取该文件的人都可以触发向你的 Slack 或 Teams 频道发送通知。请运行 `chmod 600 src/config.yaml`。
**Ollama 默认没有访问控制。** 任何能够访问 Ollama 主机 11434 端口的人,都可以消耗你的计算资源来提交推理请求。请设置防火墙,仅允许中间件主机访问。
**Prompt 注入是一个真实的攻击面。** Wazuh 告警中精心构造的日志行可能会影响 LLM 输出的内容。Markdown 转义可以防止渲染错误,但它并不能净化响应的语义内容。依然需要分析师进行人工审核——在没有人工干预的情况下,不要根据 LLM 的输出自动执行操作。
## 示例输出
以下是 SSH 暴力破解规则触发后,丰富后的告警示例:
### JSONL 记录
```
{
"fingerprint": "a3f7c2d19e84b1056d2c7f3a...",
"timestamp": "2025-01-15T14:32:07Z",
"rule_id": 5710,
"rule_level": 12,
"description": "SSHD brute force attack",
"source_ip": "192.168.1.45",
"agent": "windows-endpoint",
"enrichment": {
"explanation": "Rule 5710 fires when Wazuh detects more than 8 failed SSH authentication attempts from a single source within a short window. The volume here — 12 failures in 40 seconds from 192.168.1.45 — is consistent with an automated credential-stuffing tool rather than a user mistyping a password.",
"impact": "If any of the attempted credentials are valid, the attacker gains an interactive shell under the compromised account. From there: direct filesystem access, lateral movement via SSH agent forwarding or stored keys, and a persistent foothold if they append to ~/.ssh/authorized_keys.",
"remediation": "1. Block 192.168.1.45 at the perimeter firewall and on-host via iptables/ufw. 2. Check /var/log/auth.log for any successful authentications from this IP. 3. Review ~/.ssh/authorized_keys on targeted accounts. 4. If compromise is suspected, lock the account (passwd -l) and rotate credentials. 5. Enforce key-only SSH auth (PasswordAuthentication no in sshd_config) and restart sshd."
},
"fallback": false
}
```
### Markdown 报告头部
```
# 告警 — Rule 5710,Level 12
| Field | Value |
|-------------|-----------------------------|
| Timestamp | 2025-01-15T14:32:07Z |
| Source IP | 192.168.1.45 |
| Agent | windows-endpoint |
| Fingerprint | a3f7c2d19e84b105... |
| Fallback | No |
## 解释
Rule 5710 fires when Wazuh detects more than 8 failed SSH authentication attempts…
## 影响
If any of the attempted credentials are valid, the attacker gains an interactive shell…
## 修复
1. Block 192.168.1.45 at the perimeter firewall…
```
## 坦诚的局限性
我宁愿坦率地说明它的不足之处,也不愿让你在演示过程中自己发现。
**丰富质量严重依赖于模型。** `tinyllama`(11 亿参数)速度很快且能返回有效的 JSON,但其分析往往停留在表面。`llama3`(80 亿参数)则有显著的提升。但两者都没有针对 Wazuh 数据进行过 fine-tuning,因此对于不常见的 rule ID,其解释可能含糊不清。在对丰富输出采取行动之前,务必由分析师进行审查。
**没有告警关联。** 每个告警都是独立丰富的。Pipeline 没有记忆,没有会话重建,也没有“这三个告警组合在一起意味着什么”的概念。一次暴力破解、一次成功的登录和一次权限提升,将作为三个独立且互不相关的记录出现。真正的 SOC 工具会将这些点连接起来。
**去重窗口是分钟级别的。** 一次持续 10 分钟、产生 500 个相同告警的暴力破解会产生十条记录(每过一分钟边界产生一条),而不是一条。这并不理想,但这是为了防止错过真正不同的事件而做出的刻意权衡。
**仪表板未进行身份验证。** 如果这让你感到担忧——如果你考虑将其用于本地以外的任何用途,你应该感到担忧——这并不是一个难以解决的问题。使用 Flask-Login 或简单的 token 中间件就可以解决。
**高告警量会导致积压。** 数据丰富的吞吐量受限于 Ollama 的推理延迟。这里没有背压机制,因此大量涌入的高严重性告警会形成队列。在测试实验室中,这从来不是问题,但这一点值得注意。
**降级处理的内容显然只是降级。** 当 Ollama 无法访问时,降级操作会根据 Wazuh 规则组生成一些内容。如果该组未被识别,则输出是一个通用的占位符。它比直接崩溃要好,但仪表板能明确看出哪些记录是真正的丰富输出,哪些是降级输出。
## 未来展望
如果这个项目将来不止于实验室阶段,以下几个方向似乎值得追求:
**告警关联**是目前缺失的最具影响力的部分。为每个 agent 维护一个近期告警的滑动窗口,并寻找匹配已知攻击模式(侦察 -> 凭据攻击 -> 横向移动)的序列,将使数据丰富的实用性大幅提升。
**MITRE ATT&CK 标记** 是相对容易实现的目标——Wazuh 的规则元数据中已经包含了映射到 ATT&CK 技术的组名。将这些标签添加到 JSONL 记录中,将使输出更自然地集成到威胁情报工作流中。
**Wazuh REST API 摄取**将取代文件追踪(file-tail)方式,并消除对 `ossec` 组权限的依赖。它还将支持多管理器部署,而这在文件追踪方式中从根本上是不可能的。
**模型评估框架** 将允许你通过多个 Ollama 模型运行批处理数据集,并系统地比较丰富的深度、JSON 解析成功率,以及模型产生规则解释幻觉的频率。这种基准测试将使模型选择成为一个数据驱动的决策。
**LLM prompt 之前的 IP 信誉查询**——向 AbuseIPDB 或 VirusTotal 查询 source IP,并将信誉评分包含在上下文中——可能会显著提高影响和补救建议输出的质量。
## 学术背景
这是我在 **University of Petroleum and Energy Studies (UPES), Dehradun** 完成的网络安全 B.Tech 项目。目标是构建真实的东西——一个涉及 SIEM 部署、日志分析、LLM 集成和安全系统编程的可用系统——而不是模拟,也不是一个仅用幻灯片描述系统*将要*做什么的空壳。
实验室从零开始搭建:在 Ubuntu 上部署 Wazuh All-in-One,在 Windows endpoint 上安装 Wazuh agent,从 Kali Linux 发起攻击模拟,并在本地运行 LLM 推理,从而不依赖于任何付费 API 或外部服务。`wazuh-training-set.jsonl`、`--batch` 模式和 `--demo-status` 命令是后来专门添加的,以便在不需要主动运行攻击模拟的情况下,就可以在教职员审查中演示该项目。
## 作者
**Sanidhya Chamoli**
网络安全 B.Tech,UPES Dehradun
sanidhyachamoli06@gmail.com
## 许可证
学术项目。作者保留所有权利。
如果要在研究或教育中重用,请提交 issue 或通过 GitHub 联系。
*Wazuh · Ollama · Python · Flask*
标签:AI风险缓解, DLL 劫持, Wazuh, 告警分析, 大语言模型, 安全规则引擎, 安全运营, 扫描框架, 逆向工具