bastian-red/mini-ids
GitHub: bastian-red/mini-ids
基于 Python + Scapy 的轻量级网络入侵检测系统,集成特征规则引擎、行为检测器、可选 ML 异常检测和实时 Web 仪表板,兼顾教学与实际防御场景。
Stars: 1 | Forks: 0
# mini-ids
一个使用 Python + Scapy 构建的轻量级网络入侵检测系统。它结合了 Snort-lite 特征规则引擎、三个行为检测器(端口扫描、暴力破解、DNS 隧道/外泄)以及一个可选的无监督 ML 异常检测器,所有这些都将数据汇入一个告警流水线,支持控制台/日志/webhook/邮件输出目标,并提供实时 Web 仪表板。
## 截图

## 功能
- **Snort-lite 规则引擎** (`rules/`):解析真实 Snort 规则语法的子集(`action proto src_ip src_port -> dst_ip dst_port (msg:"..."; flags:S; content:"..."; nocase; threshold: type threshold, track by_src, count 5, seconds 60; sid:1000001; severity:medium;)`),包括单条规则的 `threshold` 计数器和 `dsize` payload 大小匹配。内置 11 条规则,涵盖暴力破解阈值、NULL/FIN/XMAS 扫描特征、明文凭证、可疑扫描器 User-Agents 以及超大 ICMP payload。
- **行为检测器** (`detectors/`):基于单源不同端口的端口扫描检测,支持扫描类型分类(SYN/NULL/FIN/XMAS/ACK);针对敏感端口的滑动窗口暴力破解计数;以及 DNS 隧道/外泄检测(基于信息熵、子域名扇出、payload 洪泛)。
- **可选的 ML 异常检测器**:在每条流量的特征(持续时间、数据包/字节数、平均数据包大小、SYN 计数、flag 多样性)上运行 `IsolationForest` (scikit-learn),在合成的良性基线上进行训练,通过 `--enable-ml` 开启。
- **告警流水线** (`alerts/`):一个具有冷却/防刷机制的调度器,将告警分发到控制台、JSONL 日志、webhook (HTTP POST) 和 SMTP 邮件输出目标——每个输出目标均采用故障软处理,因此损坏的邮件服务器或不可达的 webhook 永远不会使引擎宕机。
- **实时仪表板** (`dashboard/`):Flask + Socket.IO,提供统计磁贴、按类型分类的告警图表、已加载的规则集以及实时告警流。
- **仅限实验室环境的攻击流量生成器** (`offensive/`):包含一个基于 Scapy 的 SYN 端口扫描器和一个重复连接尝试模拟器,用于证明检测器确实能捕获到威胁,受限于仅允许针对 loopback/RFC1918 地址的实验室环境检查。
## 架构
```
mini-ids/
├── mini_ids.py / cli.py # engine assembly + argparse CLI (sniff/replay/rules/stats/attack)
├── core/ # config dataclasses + PacketRecord/Flow/Alert data contracts
├── engine/ # capture (live + pcap), dissect, flow tracking, IDSEngine pipeline
├── rules/ # Snort-lite parser/matcher + builtin/default.rules
├── detectors/ # port_scan, brute_force, exfil, ml_anomaly
├── alerts/ # dispatcher + console/log/email/webhook sinks
├── storage/ # thread-safe SQLite store for alerts + flows
├── dashboard/ # Flask + Socket.IO live dashboard
├── offensive/ # lab-only traffic generators (+ guard.py safety check)
├── evals/ # seeded synthetic corpora + precision/recall gate
├── samples/ # offline no-root demo
└── tests/ # pytest gate suite (no root, no live network)
```
数据流:一个原始的 Scapy 数据包进入 `IDSEngine.process()`(来自 `engine.capture.LiveCapture` 或重放的 pcap),通过 `engine.dissect` 被规范化为 `PacketRecord`,更新 `FlowTable`,并依次与规则引擎以及每个行为/ML 检测器进行匹配。产生的任何 `Alert` 都会被写入 SQLite,移交给 `AlertDispatcher`(控制台/日志/邮件/webhook),并通过 Socket.IO 推送到仪表板——CLI 和 Web UI 背后运行的是同一个流水线。
## 安装
```
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt # or requirements.txt for a runtime-only install
bash scripts/install-hooks.sh # wires the pytest + gitleaks pre-commit gate
```
实时捕获需要主机上安装 `libpcap`,并且通常需要 root 权限或 `CAP_NET_RAW`(参见下方的权限表)。本项目中的其他操作均不需要提升权限。
## 用法
### 免 root 离线演示
```
python samples/demo_run.py
```
在整个流水线中重放合成的数据包流(一次端口扫描、一次 SSH 暴力破解突发、一次 DNS 隧道尝试以及常规流量)并打印每一条告警——这是零配置下见证 mini-ids 捕获威胁的最快方式。
### CLI
```
# 实时捕获 + 检测(需要 root/CAP_NET_RAW),包含 dashboard
sudo python cli.py sniff --iface lo --dashboard
# 重放 pcap 文件而非实时 interface
python cli.py replay samples/capture.pcap --dashboard
# 规则管理
python cli.py rules list --rules-dir rules/builtin
python cli.py rules validate --rules-dir rules/builtin
# 存储的 stats
python cli.py stats --db-path data/mini_ids.db
# 启用 ML 异常检测器(需要经过训练的 model - 参见下方的 Tests 和 evals)
sudo python cli.py sniff --iface lo --enable-ml
```
告警输出目标通过标志或环境变量进行配置:`--webhook-url` / `MINI_IDS_WEBHOOK_URL`,`--smtp-host` / `MINI_IDS_SMTP_HOST`(以及 `--smtp-user`、`--smtp-password`、`--email-from`、`--email-to`)。未配置的输出目标根本不会被注册——没有死连接,也没有启动错误。
### Web 仪表板
在 `sniff` 或 `replay` 命令后添加 `--dashboard`(默认地址为 `http://127.0.0.1:5000`),或者直接通过 `dashboard.app.DashboardApp` 独立运行。它显示总/高严重性告警计数、按类型分类的告警图表、已加载的规则集以及实时告警流。
### 权限
| 操作 | 需要 root/CAP_NET_RAW 吗? |
|---|---|
| `cli.py sniff`(实时捕获) | 是 |
| `cli.py replay`(pcap 重放) | 否 |
| `cli.py rules list/validate`、`cli.py stats` | 否 |
| `cli.py attack port-scan` / `attack brute-force` | 发送原始 SYN 数据包通常需要 root |
| 仪表板、评估、测试 | 否 |
## 检测规则与启发式算法
| 类别 | 机制 | 示例 |
|---|---|---|
| 特征 (rules/builtin/default.rules) | Snort-lite 逐包匹配 + 单规则阈值 | SSH/FTP/RDP 暴力破解阈值、NULL/FIN/XMAS 扫描 flag、明文 HTTP Basic Auth / FTP `PASS`、sqlmap/nikto User-Agents、超大 ICMP payload |
| 端口扫描 (`detectors/port_scan.py`) | 滑动窗口内每个源 IP 访问的不同目标端口,根据 TCP flag 模式进行分类 | SYN/NULL/FIN/XMAS/ACK 扫描 |
| 暴力破解 (`detectors/brute_force.py`) | 滑动窗口内对敏感端口的重复全新连接尝试(SYN,无 ACK) | SSH/FTP/RDP 密码猜测 |
| 数据外泄 (`detectors/exfil.py`) | 滑动窗口内的 DNS 查询信息熵、子域名扇出以及 payload-qtype 洪泛 | Base32/base64 DNS 隧道 |
| ML 异常 (`detectors/ml_anomaly.py`,可选开启) | 基于每条流量特征的 `IsolationForest` 对比合成的良性基线 | 上述规则均未预料到的流量形态 |
## 攻击实验室(仅限自有网络)
```
python cli.py attack port-scan --target-ip 127.0.0.1 --i-understand-lab
python cli.py attack brute-force --target-ip 127.0.0.1 --port 22 --attempts 8 --i-understand-lab
```
在一个终端运行 `cli.py sniff --iface lo --dashboard`,并在另一个终端运行任意攻击命令,即可观察 mini-ids 自身的规则和检测器如何在它自己生成的流量上被触发。每个攻击脚本都会首先调用 `offensive.guard.require_lab_target()`,除非您传入明确的授权 flag,否则它将拒绝非 loopback/非私有/非本地链路的目标。
## 测试与评估
```
pytest -q # gate suite: 111 tests, offline, no root, <4s
python -m evals.run_detection # periodic precision/recall eval against seeded synthetic corpora
```
当前评估指标(随机种子 1337):
| 类别 | 精确率 (Precision) | 召回率 (Recall) | F1 |
|---|---|---|---|
| 端口扫描 | 1.00 | 1.00 | 1.00 |
| 暴力破解 | 1.00 | 1.00 | 1.00 |
| 数据外泄 | 1.00 | 1.00 | 1.00 |
| ML 异常 | 0.94 | 1.00 | 0.97 |
ML 检测器的精确率(非 1.00)是一个真实的局限性,而不是刻意调优掩盖的结果:`IsolationForest` 的 `contamination` 参数在*训练*分布上设置了一个预期的异常率,因此恰好处于该分布尾部的预留良性流量可能仍会被标记。召回率保持在 1.00,是因为评估语料库中的异常流量形态(长达数小时的流量、数以万计的数据包)与良性基线相差好几个数量级。每次评估运行还会(重新)训练模型并将其持久化到 `storage/models/isolation_forest.joblib`,供 `--enable-ml` 在运行时加载。
`evals/corpus.py` 刻意包含了对抗性/真阴性案例,使得评估关卡具有实际意义而不是同义反复:例如未达到端口计数阈值的慢速端口扫描、合法的多服务客户端、良性的连接重试,以及绝对不能被误认为是编码 DNS 隧道标签的超长但真实的域名。
## 这展示了什么
蓝队流量分析(特征检测与行为检测,这与真实 Snort 在规则和预处理器之间做出的概念划分一致)、应用于安全领域的 ML(经过真实精确率/召回率检验门控验证的无监督异常检测器,而不仅仅是“能跑起来”),以及全栈工具链开发(一个在 CLI 和实时 Web 仪表板背后运行的、采用依赖注入且无需 root 即可测试的捕获/检测流水线)。
标签:Flask, Python, Scapy, 入侵检测系统, 安全数据湖, 安全规则引擎, 插件系统, 无后门, 红队行动, 网络安全, 逆向工具, 隐私保护