dev-huihui/detectionRule
GitHub: dev-huihui/detectionRule
一个结合 Spring Boot 与 Python 的检测规则管理平台,支持 Snort/Suricata/YARA 规则的语法校验、结构化解析及基于 Elasticsearch 的相似度检测。
Stars: 0 | Forks: 0
# detectionRule
这是一个将 **Python** 处理模块连接到用于存储和管理检测规则(Detection Rule)的 **Spring Boot(Java)** 应用程序的项目。
在保存规则的逻辑中,执行以下 3 个操作。
1. **语法检查** — 检测规则(Snort/Suricata/YARA)的有效性验证
2. **嵌入、索引和相似度检查** — 基于 Elasticsearch 的向量索引和相似(重复)规则检测
3. **规则解析** — Snort 头部/选项,YARA meta/strings/condition 结构分解
繁重的处理(加载 embedding 模型、Elasticsearch 通信、规则解析)由 **Python** 承担,数据存储和编排由 **Java(Spring Boot)** 承担。
## 架构
```
HTTP (REST)
Client ───────────────────────▶ Spring Boot (Java)
├─ Controller / Service
├─ DetectionRuleRepository (저장) ← 데이터 저장은 Java
└─ PythonExecutor
│ ProcessBuilder
│ stdin(JSON) → stdout(JSON)
▼
Python 스크립트 (python/)
├─ syntax_check.py (모듈 1, snort/yara)
├─ snort_parser.py (모듈 3)
├─ yara_parser.py (모듈 3-b)
├─ embedding_index.py (모듈 2, ES 색인)
└─ similarity_search.py (모듈 2, ES kNN)
│
▼
Elasticsearch (dense_vector / kNN)
```
### Java ↔ Python 通信协议
`PythonExecutor` 使用 `ProcessBuilder` 执行脚本并交换 JSON。
- **请求**:将 1 个 JSON 对象传递给脚本的 **stdin**
- **响应**:脚本将 1 个 JSON 对象输出到 **stdout**
- 成功:`{"ok": true, "data": { ... }}`(退出码 0)
- 失败:`{"ok": false, "error": {"type": "...", "message": "..."}}`(退出码 1)
- 供人类阅读的日志/模型加载消息发送至 **stderr**(防止污染 stdout)
Java 端的失败响应将被转换为 `PythonExecutionException`,并映射为 HTTP `502`。
## 环境要求
| 组件 | 版本/备注 |
|-----------|-----------|
| **JDK** | **21 或更高版本**(Spring Boot 4.x 要求) |
| Maven | 使用项目内置的 `mvnw` |
| **Python** | **3.9 或更高版本** |
| Elasticsearch | 8.x(使用模块 2 时。若没有,规则会保存,但索引/相似度检查将自动跳过) |
## 项目结构
```
detectionRule/
├── pom.xml
├── mvnw / mvnw.cmd
├── README.md
│
├── python/ # Python 처리 모듈 (실제 작업 수행)
│ ├── requirements.txt
│ ├── .env.example # Elasticsearch/임베딩 환경변수 예시
│ ├── common/
│ │ ├── io.py # stdin/stdout JSON 통신 규약 래퍼
│ │ ├── snort.py # Snort 규칙 파서 (공용)
│ │ ├── yara_rules.py # YARA 규칙 파서/구조 검사기 (공용)
│ │ ├── embedding.py # 임베딩 제공자 (모델 미설치 시 hash 폴백)
│ │ └── es.py # Elasticsearch 클라이언트/인덱스 헬퍼
│ ├── syntax_check.py # 모듈 1: 문법 검사 (snort/suricata/yara)
│ ├── snort_parser.py # 모듈 3: Snort 파싱
│ ├── yara_parser.py # 모듈 3-b: YARA 파싱
│ ├── embedding_index.py # 모듈 2-a: 임베딩 + ES 색인
│ └── similarity_search.py # 모듈 2-b: ES kNN 유사도 검색
│
└── src/main/java/com/api/detectionrule/
├── DetectionRuleApplication.java
├── ServletInitializer.java
├── config/
│ └── JacksonConfig.java # ObjectMapper 빈 (통신/응답 직렬화)
├── python/ # Python 연동 계층
│ ├── PythonProperties.java # python.* 설정
│ ├── PythonScript.java # 호출 가능한 스크립트 목록(enum)
│ ├── PythonExecutor.java # ProcessBuilder 실행 + JSON 통신
│ └── PythonExecutionException.java
├── domain/
│ └── DetectionRule.java # 저장 도메인
├── repository/
│ ├── DetectionRuleRepository.java # 저장소 추상화 (JPA 등으로 교체 가능)
│ └── InMemoryDetectionRuleRepository.java # 기본 인메모리 구현
├── service/
│ ├── SyntaxCheckService.java # 모듈 1 위임
│ ├── SnortParseService.java # 모듈 3 위임
│ ├── YaraParseService.java # 모듈 3-b 위임
│ ├── EmbeddingService.java # 모듈 2 위임 (index / findSimilar)
│ ├── DetectionRuleService.java # 저장 오케스트레이션
│ ├── InvalidRuleException.java
│ └── RuleNotFoundException.java
├── controller/
│ ├── DetectionRuleController.java
│ └── GlobalExceptionHandler.java
└── dto/ # 요청/응답 레코드
├── CreateRuleRequest.java
├── ContentRequest.java
├── SimilarityRequest.java
├── SyntaxCheckResult.java
├── SnortParseResult.java
├── SimilaritySearchResult.java
├── IndexResult.java
└── RuleResponse.java
```
## 安装与运行
### 1) Python 环境
```
cd python
python -m venv .venv
# Windows
.venv\Scripts\activate
# Linux/mac
# source .venv/bin/activate
pip install -r requirements.txt
```
### 2) Elasticsearch(使用模块 2 时)
参考 `python/.env.example` 配置环境变量。例如:
```
export ES_HOST=http://localhost:9200
export ES_INDEX=detection-rules
```
即使没有 Elasticsearch,应用程序也能正常运行,仅会自动跳过索引/相似度检查步骤。
### 3) 运行应用程序
```
$env:JAVA_HOME="C:\Program Files\Java\jdk-21.0.2"
.\mvnw.cmd spring-boot:run
```
更改端口:
```
.\mvnw.cmd "-Dspring-boot.run.arguments=--server.port=8090" spring-boot:run
```
构建(WAR):
```
.\mvnw.cmd clean package
```
## 配置(`application.properties`)
| 键 | 默认值 | 说明 |
|----|--------|------|
| `python.executable` | `python` | Python 可执行文件(可指定 venv 路径) |
| `python.scripts-dir` | `python` | Python 脚本目录(相对于项目根目录) |
| `python.timeout-seconds` | `120` | 脚本执行超时时间(考虑到首次加载 embedding 模型) |
| `server.port` | `8080` | 服务器端口 |
Python 脚本端的 Elasticsearch/嵌入配置通过 **环境变量** 注入(参考 `python/.env.example`)。
## REST API
基础路径:`/api/rules`
| Method | Path | 说明 |
|--------|------|------|
| `POST` | `/api/rules` | 注册规则(语法检查 -> 解析 -> 相似度 -> 保存 -> 索引) |
| `GET` | `/api/rules` | 查询全部 |
| `GET` | `/api/rules/{id}` | 查询单条 |
| `DELETE` | `/api/rules/{id}` | 删除 |
| `POST` | `/api/rules/syntax-check` | 仅执行语法检查(模块 1,ruleType:snort/suricata/yara) |
| `POST` | `/api/rules/parse` | 仅执行规则解析(模块 3,ruleType:默认为 snort / yara) |
| `POST` | `/api/rules/similar` | 仅执行相似规则搜索(模块 2) |
### 规则注册流程(`POST /api/rules`)
```
1. 문법 검사 (syntax_check.py) ── 실패 시 저장하지 않고 422 반환
2. 규칙 파싱 ── snort: sid/msg 추출 (snort_parser.py)
yara: 규칙 이름/meta.description 추출 (yara_parser.py)
3. 유사 규칙 검색 (similarity) ── 중복 경고 (best-effort, ES 없으면 생략)
4. Java 저장소에 저장
5. 임베딩 + ES 색인 (embedding) ── best-effort, ES 없으면 생략
```
### 支持的规则类型
| ruleType | 语法检查 | 解析 | 备注 |
|----------|-----------|------|------|
| `snort` / `suricata` | 基于内置解析器(sid 必填,推荐填写 msg/rev) | 头部/选项结构化 | 默认值 |
| `yara` | 结构检查(condition 必填,检查重复名称和字符串引用一致性) | meta/strings/condition 结构化 | 安装 `yara-python` 后将增强为实际的编译检查 |
#### 示例
```
curl -X POST http://localhost:8080/api/rules \
-H "Content-Type: application/json" \
-d '{
"name": "HTTP GET probe",
"ruleType": "snort",
"content": "alert tcp $HOME_NET any -> $EXTERNAL_NET 80 (msg:\"web\"; sid:1000003; rev:1;)"
}'
```
成功响应(`201 Created`):
```
{
"id": "0cd0f42d-663f-45d8-b6a9-0ffe413e644e",
"name": "HTTP GET probe",
"ruleType": "snort",
"content": "alert tcp $HOME_NET any -> $EXTERNAL_NET 80 (msg:\"web\"; sid:1000003; rev:1;)",
"sid": 1000003,
"msg": "web",
"syntaxValid": true,
"createdAt": "2026-07-05T12:29:34.525843700Z",
"syntax": { "valid": true, "errors": [], "warnings": [], "ruleCount": 1 },
"similar": [],
"index": null
}
```
语法错误时(`422 Unprocessable Entity`):
```
{
"title": "Invalid detection rule",
"status": 422,
"detail": "탐지 규칙 문법 검사 실패",
"syntax": {
"valid": false,
"errors": [{ "line": 1, "message": "필수 옵션 'sid' 가 없습니다." }],
"warnings": [{ "line": 1, "message": "권장 옵션 'rev' 가 없습니다." }],
"ruleCount": 1
}
}
```
## 独立运行 Python 脚本
每个脚本都是接收 JSON 到 stdin 的独立可执行文件。这对于调试非常有用。
```
echo '{"content":"alert tcp any any -> any 80 (msg:\"t\"; sid:1; rev:1;)"}' \
| python python/syntax_check.py
echo '{"content":"alert tcp any any -> any 80 (msg:\"t\"; sid:1; rev:1;)"}' \
| python python/snort_parser.py
echo '{"content":"rule Foo { strings: $a = \"x\" condition: $a }","ruleType":"yara"}' \
| python python/syntax_check.py
echo '{"content":"rule Foo { strings: $a = \"x\" condition: $a }"}' \
| python python/yara_parser.py
```
## 扩展点
- **替换存储库**:保持 `DetectionRuleRepository` 接口不变,将
`InMemoryDetectionRuleRepository` 替换为 Spring Data JPA/JDBC 实现。
- **替换 embedding 模型**:替换 `python/common/embedding.py` 中的 `embed()` 实现
(通过环境变量 `EMBED_MODEL` 指定模型名称)。
- **扩展规则类型**:在 `syntax_check.py` 中添加新的 `ruleType` 分支
(snort 参考 `common/snort.py`,yara 参考 `common/yara_rules.py`)。
- **强化 YARA 检查**:只需 `pip install yara-python`,语法检查就会
自动切换为基于实际编译的检查(`checker: "yara-python"`)。
- **添加脚本**:在 `PythonScript` 枚举中添加项,并在 `python/` 目录下部署脚本。
## 备注(设计决策)
- **集成方式**:使用 `ProcessBuilder` 子进程(无需单独的服务器)。由于每次请求都会
执行脚本,因此每次都需要加载 embedding 模型,产生一定的开销。如果需要大规模/低延迟处理,请考虑
将 Python 转换为常驻服务(如 FastAPI 等)。
- **数据存储主体**:保存由 **Java** 负责,实际处理(1、2、3)由 **Python** 负责。
- **故障隔离**:embedding/ES 步骤以 best-effort 方式处理,外部依赖故障
不会阻止规则本身的保存。
标签:Elasticsearch, JS文件枚举, Python, Spring Boot, 向量检索, 域名枚举, 安全规则管理, 文本解析, 无后门, 逆向工具