hello-urvesh/HELK
GitHub: hello-urvesh/HELK
HELK-modern 是一个基于 Kafka、Vector、Elasticsearch 9 和 Sigma 的开源威胁狩猎实验室,提供从日志接入到检测告警的一站式检测即代码环境。
Stars: 0 | Forks: 0
# 🦌 HELK-modern
### 一个现代化的开源威胁狩猎实验室 — 基于 2026 年组件重建
[](https://github.com/hello-urvesh/HELK/actions/workflows/ci.yml)
[](LICENSE)
[](CONTRIBUTING.md)
[](#)







*只需一条命令即可启动完整的检测与狩猎技术栈。接入 Windows 日志,
以代码形式编写检测规则,并实时捕捉行为模式。*
这是 Hunting ELK 概念的现代化重构版本:一个开源的威胁狩猎实验室,配备流式接入流水线、检测即代码(detection-as-code)循环以及 notebook 分析层 — 全部基于当前的组件版本运行。
```
Windows / WEF ──Winlogbeat──▶ Kafka 4.3 (KRaft) ──▶ Vector ──▶ Elasticsearch 9.4
│ │
▼ ▼
Flink SQL Kibana 9.4 (detection
(streaming) engine) ◀── pySigma
│
JupyterLab + PySpark (analytics)
```
与原版 HELK 的主要不同之处:Kafka 运行于 KRaft 模式(无需 ZooKeeper),Vector 替代了 Logstash,Flink SQL 替代了 KSQL,Kibana 的免费检测引擎加上 Sigma-to-Kibana 流水线替代了 Elastalert,并且 eland/ES|QL 在很大程度上替代了 ES-Hadoop 桥接器。
## ✅ 已构建功能(目前已可用)
- [x] **核心接入流水线** — Winlogbeat → Kafka (KRaft) → Vector → Elasticsearch
- [x] **搜索与仪表盘** — Kibana 9.4 及其免费检测引擎
- [x] **检测即代码** — 通过 pySigma 转换 Sigma 规则并推送至 Kibana
- [x] **流式检测** — 可选的 Flink SQL 层,用于有状态的实时模式检测
- [x] **Index 映射与保留** — ECS 风格的模板 + ILM 策略(rollover/delete)
- [x] **Notebook 分析** — JupyterLab 启动 notebook,通过 ES|QL 查询 ES
- [x] **一键启动** — 带有 `core` / `streaming` / `analytics` 配置文件的 Docker Compose
- [x] **安全的首次运行** — 预检密钥验证、有序启动、健康检查
- [x] **CI** — 每次推送时执行 lint + 真实的端到端冒烟测试
- [x] **开源治理** — Apache-2.0 协议、贡献指南、安全策略与模板
## 🔜 路线图(尚未构建)
- [ ] **数据集接入入口** — 批量重放脚本 + 字段标准化,使得公开的
攻击数据集(Mordor / Security-Datasets,EVTX 样本)能够直接使用
- [ ] **狩猎快速入门指南** — 下载数据集 → 重放 → 检测 → 调优 → 重新测试的循环
- [ ] **Sigma 规则库** — 从单一示例规则扩展为精心挑选的入门级规则集
- [ ] **EVTX 转换路径** — 详细的 `.evtx` → JSON 接入说明
- [ ] **TLS / 安全加固** — 针对本地实验室之外的部署
- [ ] **带标签的发布** — 版本化的 `v0.x` 里程碑
## 环境要求
- Docker Engine + Compose **v2**(`docker compose`,而不是旧版的
`docker-compose` v1 — `name:` 键和配置文件需要 v2 支持)
- `core` 配置文件:约 6 GB 内存。所有配置文件:建议 16 GB 以上。
- Linux 主机需要设置 `vm.max_map_count=262144`:
`sudo sysctl -w vm.max_map_count=262144`(将其添加到 `/etc/sysctl.conf` 以永久生效)
## 快速开始
```
cp .env.example .env # then edit the secrets (see notes below)
./scripts/preflight.sh # validates your .env before starting
docker compose --profile core up -d
```
每个服务都存在于 `core` 配置文件中,因此**每个** compose 命令都需要
加上 `--profile core` — 包括 `up`、`down`、`stop`、`restart`、`logs`、`ps`。为了避免
重复输入该标志,可以在每个 shell 中设置一次:
```
export COMPOSE_PROFILES=core # then plain `docker compose up -d` etc. work
```
等待健康检查通过(ES 和 Kibana 都变为 `healthy` 状态),然后访问
Kibana(参见访问说明),并使用 `.env` 中的密码以 `elastic` 身份登录。
可选层:
```
docker compose --profile core --profile streaming up -d --build # + Flink (UI :8081)
docker compose --profile core --profile analytics up -d # + JupyterLab (:8888)
```
### `.env` 注意事项
- **`KIBANA_ENCRYPTION_KEY` 必须至少为 32 个字符** — 否则 Kibana 将拒绝
启动(致命的配置验证错误)。
- 为 `ELASTIC_PASSWORD`、`KIBANA_PASSWORD` 和
`JUPYTER_TOKEN` 使用**独立且高强度**的值。不要在三者之间重复使用同一个密钥。
- `KAFKA_EXTERNAL_HOST` 是你的 Windows 日志转发器用来访问
Kafka `:29092` 端口的地址。请将其设置为主机可访问的 IP/主机名。
## 访问用户界面
对外发布的端口(`9200`、`5601`、`29092`、`8081`、`8888`)绑定到 `0.0.0.0`。
在云虚拟机上,这意味着它们可以从互联网访问。**不要在仅仅使用基本认证的情况下让
Elasticsearch 和 Kibana 暴露在公网中。** 对于单人使用的实验室,
根本不要发布这些端口 — 直接从你的工作站通过 SSH 隧道访问它们:
```
ssh -L 5601:localhost:5601 -L 9200:localhost:9200 user@YOUR_VM_IP
# 然后浏览至 http://localhost:5601
```
如果必须直接暴露端口,请使用云防火墙 / `ufw` 规则将它们限制为你自己的 IP,并将 TLS 视为前提条件(此处尚未配置)。
## 验证流水线
```
./scripts/send_test_event.sh
sleep 5
source .env
curl -s -u elastic:${ELASTIC_PASSWORD} \
'http://localhost:9200/logs-windows-*/_search?q=test-host&size=1&pretty'
```
出现 `"total":{"value":1 ...}` 结果意味着整条链路能够正常工作:
Kafka → Vector → Elasticsearch。`kafka-init` 服务会预先创建
`winlogbeat` topic,Vector 会等待它创建完成,因此这在首次运行时就能成功,无需手动创建 topic 或重启。
要在 Kibana 中查看:**Discover** → 创建一个 index pattern 为
`logs-windows-*` 且 timestamp field 为 `@timestamp` 的 data view。
## Index 映射与保留策略
默认情况下,Elasticsearch 会动态映射传入的字段,并且永远不会删除旧的
索引。对于真实的日志量,请应用提供的 index template(稳定的 ECS 风格
映射,将 `command_line` 设为 `wildcard` 字段以支持前导通配符狩猎)以及
ILM 策略(在 25 GB / 7 天时滚动,30 天后删除):
```
source .env
./scripts/apply-es-template.sh
```
模板更改仅影响*新的*后端索引。如果 `logs-windows-default`
数据流已经存在,请将其滚动,以便新数据使用新模板:
```
curl -u elastic:${ELASTIC_PASSWORD} -X POST 'http://localhost:9200/logs-windows-default/_rollover'
```
请在 `config/elasticsearch/ilm-policy.json` 中调整保留策略,并在
`config/elasticsearch/index-template.json` 中调整映射。
## 流式检测(可选)
`streaming` 配置文件添加了一个 Flink SQL 层,用于执行批处理查询难以表达的、有状态的低延迟
检测(进程生成突发、信标活动、事件序列)。这是一个面向检测工程师的高级层 — 核心
Kibana + Sigma 路径仍然是主要的检测平面。请参阅
[`flink/README.md`](flink/README.md) 了解何时使用它、展示作业的运行原理,以及如何编写你自己的作业。
## 检测即代码
Sigma 规则位于 `detections/sigma/rules/` 中。转换并将其推送到 Kibana 的
检测引擎:
```
pip install pysigma pysigma-backend-elasticsearch requests
python scripts/sigma_to_kibana.py --password "$ELASTIC_PASSWORD" detections/sigma/rules/
```
示例规则(编码的 PowerShell,T1059.001)会在 `send_test_event.sh` 发送的合成事件上触发,
从而提供一个完整的端到端测试:
事件 → Kafka → Vector → ES → 检测告警。
## 接入真实日志
在 Windows 端点或 WEF 收集器上安装 Winlogbeat,修改
`config/ingest/winlogbeat.reference.yml`(将 Kafka 主机设置为
`KAFKA_EXTERNAL_HOST:29092`),事件就会流入 `winlogbeat` topic。
## 布局
```
docker-compose.yml profiles: core / streaming / analytics
scripts/setup.sh one-shot: sets the kibana_system password
scripts/create-topic.sh one-shot: creates the winlogbeat Kafka topic
scripts/preflight.sh validates .env before startup
scripts/apply-es-template.sh applies the index template + ILM policy
scripts/sigma_to_kibana.py Sigma → Lucene → Kibana detection API
scripts/send_test_event.sh end-to-end pipeline smoke test
scripts/send_burst.sh generates a burst to trigger the Flink job
scripts/flink-submit.sh submits a Flink SQL job to the cluster
config/vector/vector.yaml Kafka → normalize → ES data stream
config/elasticsearch/ index template + ILM policy
config/ingest/ reference shipper config for endpoints
detections/sigma/rules/ Sigma rules (detection-as-code source of truth)
flink/ streaming layer: Dockerfile, job, and guide
notebooks/ JupyterLab hunting notebooks
```
## 服务启动顺序
compose 文件编码了依赖关系,因此干净的 `up` 首次即可正常运行:
1. `elasticsearch` → healthy
2. `setup` 设置 `kibana_system` 密码,然后以状态码 0 退出
3. `kibana` 在 `setup` 完成后启动
4. `kafka` → healthy,随后 `kafka-init` 创建 `winlogbeat` topic 并以状态码 0 退出
5. `vector` 仅在 ES 变为 healthy 状态**且** topic 存在后才启动
在 `docker compose ps -a` 中 `setup` 和 `kafka-init` 显示为 `Exited (0)` 是
正确的 — 它们是一次性任务。标签:Elasticsearch, Kafka, SonarQube插件, 安全, 安全实验室, 检测即代码, 版权保护, 超时处理, 越狱测试, 软件成分分析, 逆向工具