sergioemancinas/ngn-sip-attack-detect-defend
GitHub: sergioemancinas/ngn-sip-attack-detect-defend
一个可复现的 SIP/VoIP 攻击-检测-防御测试平台,使用无泄漏 ML 评估协议对多种检测方案进行客观基准比较并驱动自动化响应。
Stars: 1 | Forks: 0
# NGN SIP 攻击-检测-防御
[](LICENSE)


[](https://github.com/sergioemancinas/ngn-sip-attack-detect-defend/actions/workflows/ci.yml)
## 演示
https://github.com/user-attachments/assets/f62fe960-1003-4489-b81f-ba241d3acd41
3 分钟演示流程:通过 Suricata 和 Wazuh 检测实时入口流量、ML 分诊、自动化响应和可观测性。
*注:* 显示的源 IP 是在暴露边缘捕获的真实蜜罐遥测数据;有关数据溯源详情,请参阅[结果](#results)。
这是一个可复现的 SIP 攻击-检测-防御测试平台及客观的评估研究。它针对真实的 SIP 核心(Kamailio、Asterisk、rtpengine)生成带标签的攻击流量,并在无泄漏协议下比较三种检测分支(Suricata 特征签名、Wazuh 关联分析和 XGBoost 分类器):按源 IP 分组的交叉验证,包含 bootstrap 置信区间,并如实报告负面结果。
检测结果通过 Kamailio 主动响应和分级 Shuffle SOAR 工作流驱动经过审计的自动化响应。其中包含一个咨询性 LLM 分诊阶段,并作为受延迟限制的方案进行报告。所有证据都会汇入 ClickHouse,并可在 Grafana 和 Next.js dashboard 中查看。本代码库是 accompanying IEEE 论文的配套产出物。
## 目录
- [演示](#demo)
- [安全态势](#security-posture)
- [架构](#architecture)
- [ML 分诊](#ml-triage)
- [结果](#results)
- [快速开始](#quick-start)
- [服务与访问](#services-and-access)
- [持续集成](#continuous-integration)
- [代码库布局](#repository-layout)
- [部署](#deployment)
- [已知局限性](#known-limitations)
- [文档](#documentation)
- [伦理](#ethics)
- [许可证](#license)
## 安全态势
- 没有特权容器。每个服务都运行在 `no-new-privileges` 和 `cap_drop: ALL` 下,仅重新添加其所需的能力。
- 容器基础镜像由摘要锁定,GitHub Actions 由 commit SHA 锁定;Dependabot 负责追踪基础镜像、pip、npm 和 Actions。
- 代码库中无密钥。配置信息来自 `.env`(从 `.env.example` 占位符复制而来),并且 CI 会运行阻断式的 Gitleaks 扫描。
- CI 工作流以最低权限运行(`contents: read`);OpenSSF Scorecard 工作流和发布的 SBOM 用于追踪供应链安全态势。
## 架构
```
flowchart LR
Attacker(["Attacker
sippts · SIPp · scapy"]):::atk subgraph CORE["SIP core"] direction TB Kamailio["Kamailio SBC
PIKE rate-limit · NGN-SEC xlog · ban_table"] Asterisk["Asterisk PBX"] Rtpengine["rtpengine
media relay"] Postgres[("PostgreSQL
+ pgvector")] end subgraph DETECT["Detect"] direction TB Suricata["Suricata IDS"] Heplify["heplify
HEP agent"] Homer["Homer
HEP store + UI"] HepBridge["hep-bridge"] end subgraph EVID["Evidence & observe"] direction TB Vector["Vector"] ClickHouse[("ClickHouse
evidence store")] Grafana["Grafana"] Prometheus["Prometheus"] end subgraph TRIAGE["ML triage"] direction TB Stage1["Stage 1
XGBoost + IsolationForest"] Stage2["Stage 2
Ollama LLM
RAG-grounded · advisory"] end Wazuh["Wazuh SIEM
SIP rules 100100-100134"] subgraph RESP["Respond"] direction TB Autoban["autoban
deterministic"] Shuffle["Shuffle SOAR
graded policy"] Relay["kamcmd-relay"] end subgraph IDP["Identity & proxy"] direction TB Caddy["Caddy
TLS reverse proxy"] Keycloak["Keycloak
OIDC SSO"] Dashboard["Next.js dashboard"] end %% SIP / data path (solid) Attacker --> Kamailio Kamailio --> Asterisk --> Rtpengine Kamailio --- Postgres Kamailio --> Suricata Kamailio -->|siptrace HEP| Heplify --> Homer Homer -->|poll| HepBridge Suricata & HepBridge --> Vector --> ClickHouse ClickHouse -->|SIP rules| Wazuh ClickHouse --> Stage1 --> Stage2 Stage1 -->|verdict rules 100150/100151| Wazuh Wazuh --> Autoban & Shuffle Shuffle --> Relay Shuffle -->|enrich| ClickHouse %% Defend loop + observe / auth (dotted) Autoban & Relay -.->|ban_table| Kamailio Postgres -.->|RAG grounding| Stage2 ClickHouse -.-> Grafana Prometheus -.-> Grafana ClickHouse -.-> Dashboard Keycloak -.->|OIDC SSO| Caddy Caddy -.->|TLS| Grafana & Dashboard classDef atk fill:#fde,stroke:#c33,color:#900; ``` 虚线边缘代表闭环防御循环:确定性的 `autoban` 和分级的 Shuffle 路径都会通过共享的 `ban_table` 将封禁策略强制执行回 Kamailio SBC。 该技术栈被组织为多个功能组,共享同一个 ClickHouse 证据存储:SIP 核心;检测(Suricata 以及 Homer/HEP 捕获);证据与可观测性(Vector、ClickHouse、Grafana、Prometheus);ML 分诊(Stage-1 评分器、Stage-2 Ollama);响应(autoban、Shuffle、kamcmd-relay);以及身份与代理(Keycloak、Caddy、dashboard)。Wazuh 在各功能组之间进行关联,并驱动主动响应。 ## ML 分诊 ``` flowchart LR CH[("ClickHouse
suricata_alerts · sip_events · attack_labels")] S1["Stage 1 — XGBoost
per-source-IP 5-min features"] W["Wazuh
verdict rules 100150/151"] S2["Stage 2 — Ollama LLM
advisory triage"] RAG[("pgvector RAG corpus")] LV[("ClickHouse llm_verdicts")] CH --> S1 --> W --> S2 --> LV RAG --> S2 ``` Stage-1 XGBoost 对每个源 IP 的行为进行评分;Wazuh 将高可信度的判定转化为警报;Stage-2 Ollama 添加基于 RAG 的咨询性分诊,该分诊绝不会覆盖 Stage-1 的结果。详见 [`ml/README.md`](ml/README.md)。 ## 结果  - Stage-1 检测,无泄漏协议。采用按源 IP 分组的 `StratifiedGroupKFold` 并结合 bootstrap 95% 置信区间,XGBoost 的二分类 F1 达到了 **0.75 [0.68, 0.81]**,ROC-AUC 为 0.947。Isolation Forest 的得分要低得多(二分类 F1 为 0.38)。早期的 0.988 数据来源于基于窗口的 `StratifiedKFold`,这使得完整的攻击活动在各折叠之间发生了泄漏。详见 [`docs/results/RESULTS_stage1_grouped.md`](docs/results/RESULTS_stage1_grouped.md)。 - C1 HEP 响应级别特征。加入响应码特征(相比仅有的 16 个请求特征,增加到了 31 个)使 macro F1 提升了 **+0.013**(从 0.582 提升至 0.595),二分类 OOF F1 提升了 **+0.015**(从 0.918 提升至 0.933)。详见 [`ml/results/RESULTS_c1_hep.md`](ml/results/RESULTS_c1_hep.md)。 - Stage-2 LLM 分诊仅作为建议,绝不会覆盖 Stage-1 的检测结果。在基准测试的 `qwen2.5:3b`(因其受限于 CPU 延迟而被选中;默认发布版本为 `7b-instruct`)上,相比于简单的 `attack_score >= 0.6` 阈值,它未能带来任何可测量的假阳性降低,并且语法层面的提示注入防线被 43% 的对抗性语料库绕过。这两项结果均如实报告,并未通过调参掩盖。
来自校园 VM 的端到端防御证据。上图:Grafana 攻击证据看板将真实情况与检测结果连接起来,包含来自 484 个唯一攻击者地址的 1940 万条 Suricata 警报、359 条 attack_labels 数据行、触发频率最高的特征签名,以及 MITRE 技术透视。下图:实时 ban_audit 数据行记录了每次执行决策的源地址、动作和时间戳。
来自暴露 SIP 边缘的证据。上图:实时 Kamailio 日志显示了在其 SIP URI 中携带 SQL 注入 payload 的 REGISTER 请求,以及被拒绝的访问源在入口处被丢弃。中图:sip_events 数据行显示了伪造的 FreePBX 和 Polycom 用户代理及 SIPVicious friendly-scanner,其中一个正在拨打高费率号码。下图:Suricata 标记了欺诈性 INVITE,ban_audit 记录了相关的封禁操作,其中两个是由 Stage-1 ML 判定触发的。
## 快速开始
需要 Docker(Engine 26+),并且 VM 需要有约 18 GiB 的可用空间。在 macOS 上,Colima 是经过测试的运行时。
```
git clone
cd ngn-sip-attack-detect-defend
cp .env.example .env
make up-all # base, IDS, Keycloak, Wazuh, Homer, observability
make ml-up && make ml-pull # ML ring plus the models (about 4.7 GB)
make soar-up # Shuffle SOAR and the ban relay
make bootstrap # one idempotent pass: indexer OIDC, log collectors, SSO clients, SOAR provisioning
make e2e # drive labeled attack traffic and assert every ring produced evidence
```
`make bootstrap` 和 `make e2e` 可以安全地重复运行。主机端口通过 `DEV_BIND_IP` 绑定到回环地址(`127.0.0.1`)。请在浏览器中使用 `localhost` 访问,以便 OIDC 状态 cookie 能够在 Keycloak 重定向后保留。
## 服务与访问
每个服务的角色、回环 URL 和登录详细信息,以及七个预配置的 Grafana dashboard(D1-D7)记录在 [`docs/SERVICES.md`](docs/SERVICES.md) 中。默认情况下,所有服务都绑定到回环地址;此处列出的凭据为本地实验环境的默认值,在任何非回环网络暴露之前必须进行轮换。
## 持续集成
CI 是一道硬性关卡:损坏的提交会导致流水线失败,质量任务中不存在 `allow_failure` 设置。GitHub Actions(`.github/workflows/`)会运行 shell/YAML/Dockerfile lint、为每个 Compose 文件执行 `docker compose config`、Kamailio 配置检查、`ml/tests` 套件以及可观测性冒烟测试,并在未通过时阻断流程。容器构建会执行 Trivy CRITICAL/HIGH 检查关卡,而 Gitleaks 密钥扫描将单独进行阻断。
## 代码库布局
```
.
├── attacks/ # Attack scripts by phase (01_recon ... 06_tollfraud)
├── caddy/ # Caddy HTTPS reverse-proxy config
├── dashboard/ # Next.js stack dashboard
├── docs/ # Architecture, threat model, runbooks, results, provenance
├── identity/keycloak/ # Keycloak realm and OIDC client configuration
├── ids/suricata/ # Suricata rules and config
├── infra/ # Per-service Dockerfiles and runtime config
│ ├── clickhouse/ # ClickHouse: DDL and init for the evidence store
│ ├── kamailio/ asterisk/ … # SIP core services
│ └── postgres/ # Subscriber DB + pgvector
├── observability/ # Metrics and log pipeline
│ ├── vector/ # Vector: log/alert shipper into ClickHouse
│ ├── grafana/ # Provisioned dashboards D1-D7
│ └── prometheus/ hep-bridge/ # Metrics scrape + HEP bridge
├── ml/ # Stage 1, Stage 2, eval harness, C1 experiment, tests
├── scripts/ # Bootstrap, provisioning, and E2E verification helpers
├── siem/wazuh/ # Wazuh decoders, rules, integrations, active response
├── soar/ # Shuffle workflow and the kamcmd ban relay
├── docker-compose*.yml # Compose files split by ring and optional service
└── Makefile # up-all, bootstrap, e2e, and per-tier targets
```
ClickHouse 的配置位于 `infra/clickhouse/`,Vector 的配置位于
`observability/vector/`;两者均作为 Compose 服务运行(有关如何
实时查询它们,请参阅上文的 `Components` 表格)。
## 部署
Docker Compose 是经过验证的路径;其他目标属于处于不同成熟度的脚手架,
每个都标明了其实际状态:
| 路径 | 位置 | 状态 |
|---|---|---|
| Docker Compose + Makefile | `docker-compose*.yml`, `Makefile` | 在全新机器上端到端**已验证**(`make up-all` / `make e2e`)。 |
| Kubernetes (Helm) | `helm/ngn-sip/` | **设计已验证**:lint 检查通过且 `kubeconform -strict` 校验通过,并注释了当前可部署与仅作设计参考的层级划分。未进行端到端实例化。详见 [`docs/05_kubernetes_migration.md`](docs/05_kubernetes_migration.md)。 |
| VM 环境配置 (OpenTofu) | `terraform/proxmox/` | **骨架**:Proxmox 参考网络的资源模型与路线图。仅进行了语法检查;未实际应用到集群中。 |
| VM 配置管理 (Ansible) | `ansible/` | **骨架**:playbook 结构与基线加固任务。仅进行 `--check`/语法检查;无真实密钥或完整的服务配置。 |
请使用 Compose 运行该技术栈。Helm chart 和 VM 骨架用于记录相同的
架构如何映射到集群和裸机 VM;请将它们视为设计意图,
而非开箱即用的部署方案。
## 已知局限性
以下内容如实报告,而非系统缺陷(有关 Stage-2 的注意事项详见[结果](#results)):
- 注入和欺诈类别拥有的标记组太少,无法得出稳定的单类 F1 值。
- Wazuh 规则 100151(Stage-1 高可信度 ML 判定)已针对 SOC 可见的 level-10 警报启用。破坏性的主动响应被刻意限制在外部专用的 `kamailio-autoban` 路径上,而不是在原生直接绑定到该规则;有关各分类的具体考量,请参阅 [`siem/wazuh/rules/ml_rules.xml`](siem/wazuh/rules/ml_rules.xml) 中的规则头部说明。
## 文档
- 威胁模型(STRIDE 和 DFD):[`docs/02_threat_model.md`](docs/02_threat_model.md)
- 评估方法(无泄漏的按源 IP 分组协议):[`docs/06_evaluation_methodology.md`](docs/06_evaluation_methodology.md)
- 互联网暴露加固清单:[`docs/INTERNET_EXPOSURE.md`](docs/INTERNET_EXPOSURE.md)
- 数据溯源与发布产出物:[`docs/DATA_PROVENANCE.md`](docs/DATA_PROVENANCE.md)
- SSO 架构与 OAuth 加固:[`docs/sso/keycloak_architecture.md`](docs/sso/keycloak_architecture.md),[`docs/security/oauth_hardening_checklist.md`](docs/security/oauth_hardening_checklist.md)
- SOAR 操作手册:[`docs/09_soar_runbook.md`](docs/09_soar_runbook.md)
## 伦理
本项目仅限于授权的实验基础设施、合成身份及合成攻击流量。不包含任何生产系统、第三方网络或未经授权的目标。详见 [`docs/ethics_authorisation.md`](docs/ethics_authorisation.md)。
## 许可证
MIT License(详见 [LICENSE](LICENSE))。
sippts · SIPp · scapy"]):::atk subgraph CORE["SIP core"] direction TB Kamailio["Kamailio SBC
PIKE rate-limit · NGN-SEC xlog · ban_table"] Asterisk["Asterisk PBX"] Rtpengine["rtpengine
media relay"] Postgres[("PostgreSQL
+ pgvector")] end subgraph DETECT["Detect"] direction TB Suricata["Suricata IDS"] Heplify["heplify
HEP agent"] Homer["Homer
HEP store + UI"] HepBridge["hep-bridge"] end subgraph EVID["Evidence & observe"] direction TB Vector["Vector"] ClickHouse[("ClickHouse
evidence store")] Grafana["Grafana"] Prometheus["Prometheus"] end subgraph TRIAGE["ML triage"] direction TB Stage1["Stage 1
XGBoost + IsolationForest"] Stage2["Stage 2
Ollama LLM
RAG-grounded · advisory"] end Wazuh["Wazuh SIEM
SIP rules 100100-100134"] subgraph RESP["Respond"] direction TB Autoban["autoban
deterministic"] Shuffle["Shuffle SOAR
graded policy"] Relay["kamcmd-relay"] end subgraph IDP["Identity & proxy"] direction TB Caddy["Caddy
TLS reverse proxy"] Keycloak["Keycloak
OIDC SSO"] Dashboard["Next.js dashboard"] end %% SIP / data path (solid) Attacker --> Kamailio Kamailio --> Asterisk --> Rtpengine Kamailio --- Postgres Kamailio --> Suricata Kamailio -->|siptrace HEP| Heplify --> Homer Homer -->|poll| HepBridge Suricata & HepBridge --> Vector --> ClickHouse ClickHouse -->|SIP rules| Wazuh ClickHouse --> Stage1 --> Stage2 Stage1 -->|verdict rules 100150/100151| Wazuh Wazuh --> Autoban & Shuffle Shuffle --> Relay Shuffle -->|enrich| ClickHouse %% Defend loop + observe / auth (dotted) Autoban & Relay -.->|ban_table| Kamailio Postgres -.->|RAG grounding| Stage2 ClickHouse -.-> Grafana Prometheus -.-> Grafana ClickHouse -.-> Dashboard Keycloak -.->|OIDC SSO| Caddy Caddy -.->|TLS| Grafana & Dashboard classDef atk fill:#fde,stroke:#c33,color:#900; ``` 虚线边缘代表闭环防御循环:确定性的 `autoban` 和分级的 Shuffle 路径都会通过共享的 `ban_table` 将封禁策略强制执行回 Kamailio SBC。 该技术栈被组织为多个功能组,共享同一个 ClickHouse 证据存储:SIP 核心;检测(Suricata 以及 Homer/HEP 捕获);证据与可观测性(Vector、ClickHouse、Grafana、Prometheus);ML 分诊(Stage-1 评分器、Stage-2 Ollama);响应(autoban、Shuffle、kamcmd-relay);以及身份与代理(Keycloak、Caddy、dashboard)。Wazuh 在各功能组之间进行关联,并驱动主动响应。 ## ML 分诊 ``` flowchart LR CH[("ClickHouse
suricata_alerts · sip_events · attack_labels")] S1["Stage 1 — XGBoost
per-source-IP 5-min features"] W["Wazuh
verdict rules 100150/151"] S2["Stage 2 — Ollama LLM
advisory triage"] RAG[("pgvector RAG corpus")] LV[("ClickHouse llm_verdicts")] CH --> S1 --> W --> S2 --> LV RAG --> S2 ``` Stage-1 XGBoost 对每个源 IP 的行为进行评分;Wazuh 将高可信度的判定转化为警报;Stage-2 Ollama 添加基于 RAG 的咨询性分诊,该分诊绝不会覆盖 Stage-1 的结果。详见 [`ml/README.md`](ml/README.md)。 ## 结果  - Stage-1 检测,无泄漏协议。采用按源 IP 分组的 `StratifiedGroupKFold` 并结合 bootstrap 95% 置信区间,XGBoost 的二分类 F1 达到了 **0.75 [0.68, 0.81]**,ROC-AUC 为 0.947。Isolation Forest 的得分要低得多(二分类 F1 为 0.38)。早期的 0.988 数据来源于基于窗口的 `StratifiedKFold`,这使得完整的攻击活动在各折叠之间发生了泄漏。详见 [`docs/results/RESULTS_stage1_grouped.md`](docs/results/RESULTS_stage1_grouped.md)。 - C1 HEP 响应级别特征。加入响应码特征(相比仅有的 16 个请求特征,增加到了 31 个)使 macro F1 提升了 **+0.013**(从 0.582 提升至 0.595),二分类 OOF F1 提升了 **+0.015**(从 0.918 提升至 0.933)。详见 [`ml/results/RESULTS_c1_hep.md`](ml/results/RESULTS_c1_hep.md)。 - Stage-2 LLM 分诊仅作为建议,绝不会覆盖 Stage-1 的检测结果。在基准测试的 `qwen2.5:3b`(因其受限于 CPU 延迟而被选中;默认发布版本为 `7b-instruct`)上,相比于简单的 `attack_score >= 0.6` 阈值,它未能带来任何可测量的假阳性降低,并且语法层面的提示注入防线被 43% 的对抗性语料库绕过。这两项结果均如实报告,并未通过调参掩盖。
来自校园 VM 的端到端防御证据。上图:Grafana 攻击证据看板将真实情况与检测结果连接起来,包含来自 484 个唯一攻击者地址的 1940 万条 Suricata 警报、359 条 attack_labels 数据行、触发频率最高的特征签名,以及 MITRE 技术透视。下图:实时 ban_audit 数据行记录了每次执行决策的源地址、动作和时间戳。
来自暴露 SIP 边缘的证据。上图:实时 Kamailio 日志显示了在其 SIP URI 中携带 SQL 注入 payload 的 REGISTER 请求,以及被拒绝的访问源在入口处被丢弃。中图:sip_events 数据行显示了伪造的 FreePBX 和 Polycom 用户代理及 SIPVicious friendly-scanner,其中一个正在拨打高费率号码。下图:Suricata 标记了欺诈性 INVITE,ban_audit 记录了相关的封禁操作,其中两个是由 Stage-1 ML 判定触发的。
## 快速开始
需要 Docker(Engine 26+),并且 VM 需要有约 18 GiB 的可用空间。在 macOS 上,Colima 是经过测试的运行时。
```
git clone 标签:AI风险缓解, Metaprompt, 测试用例, 自动化攻击, 自定义请求头, 请求拦截, 逆向工具