maxias13/snort_3_validator
GitHub: maxias13/snort_3_validator
面向 Snort 3 规则的生产级静态与动态验证及优化工具,帮助安全团队在编写、迁移和上线规则时发现错误并提升匹配性能。
Stars: 0 | Forks: 0
# snort_3_validator
生产级 **静态 + 动态验证器与优化器**,专为 Snort 3 规则设计。
一个基于 Claude Code / OpenCode 的 skill,立足于 的官方 Snort 3 规则参考。它延续了其前身 [`snort_2_validator`](https://github.com/maxias13/snort_2_validator) 的设计,并增加了 Snort 3 专有的检查(sticky buffers、service 规则、已移除的 Snort 2 语法)。
## 功能介绍
给定任何包含 Snort 3 规则的文件——无论是内置(来自 Talos / OISF 的 `*.rules`)**还是**本地的——`snort_3_validator` 都会:
1. **解析**每条规则(括号平衡、多行、`# …` 和 `/* … */` 注释)。
2. **验证**25 项静态检查(`S001`..`S025`),涵盖结构、规范性、弃用项以及 Snort 3 专有限制。
3. **优化**:输出 10 项可操作的启发式建议(`O001`..`O010`),并附带用于标记高开销规则的数字**成本评分**。
4. **动态验证**:如果 Snort 3 二进制文件可用,则通过 `snort -T -c ` 执行验证(若不可用则平滑回退)。
5. 将结果渲染为 **text / JSON / HTML** 格式。
适用对象:规则作者、从 Snort 2 迁移到 Snort 3 的安全工程师、审计客户规则包的 MSSP,以及强制执行规则质量标准的 CI 门禁。
## 安装
```
git clone https://github.com/maxias13/snort_3_validator.git
cd snort_3_validator
python3 scripts/snort3val.py --help
```
要求 Python ≥ 3.10。无需第三方包。可选:在 `$PATH` 中提供 `snort` 3 二进制文件以进行动态检查。
要作为 Claude / OpenCode skill 安装,请将此目录复制到 `~/.claude/skills/snort_3_validator/`(或您项目的 `.claude/skills/` 目录中)。
## CLI
```
snort3val {validate|optimize|dynamic|all} [options]
```
选项:
| Flag | 描述 |
|------|-------------|
| `--format {text,json,html}` | 输出格式(默认:`text`) |
| `--out PATH` | 写入文件而非标准输出 |
| `--classtypes PATH` | 自定义 `classification.config` 以扩展内置的 classtype 集合 |
| `--snort-bin PATH` | `snort` 二进制文件的路径(仅限动态检查) |
| `--config PATH` | `snort.lua` 的路径(仅限动态检查) |
退出代码:`0` 正常,`1` 警告/错误,`2` 解析失败 / I/O 错误。
### 示例
```
# Static validation
python3 scripts/snort3val.py validate my.rules
# 仅 Optimization suggestions,JSON 输出到文件
python3 scripts/snort3val.py optimize my.rules --format json --out report.json
# All checks + dynamic verification (需要 snort binary)
python3 scripts/snort3val.py all my.rules --snort-bin /usr/local/bin/snort \
--config /etc/snort/snort.lua
# Self-tests
python3 scripts/snort3val.py all examples/good.rules # → 0 findings
python3 scripts/snort3val.py all examples/bad.rules # → matches examples/expected_output.txt
```
## 检查矩阵
### 静态验证 (`scripts/validator.py`)
| ID | 严重度 | 检查项 | Snort 3 参考 |
|----|----------|-------|-------------------|
| S001 | error | 头部解析失败 / 不支持的动作 | `rules/headers` |
| S002 | error | 规则缺少必需的 `sid` | `rules/options/general/sid` |
| S003 | warn | 规则缺少 `rev` | `rules/options/general/rev` |
| S004 | warn | 规则缺少 `msg` | `rules/options/general/msg` |
| S005 | warn | 规则缺少 `classtype` | `rules/options/general/classtype` |
| S006 | error | sid 不是数字或 < 1 | `rules/options/general/sid` |
| S007 | warn | 文件内存在重复的 `sid` | `rules/options/general/sid` |
| S008 | warn | 规则没有 `content`/`pcre`/`regex` | `rules/options/payload` |
| S009 | info | `pcre`/`regex` 出现在 `content` 之前(违反低成本优先原则) | `rules/options/payload/pcre` |
| S010 | warn | 包含多个 `content`,却没有 `fast_pattern` | `rules/options/payload/fast_pattern` |
| S011 | warn | `fast_pattern` 内容少于 4 字节 | `rules/options/payload/fast_pattern` |
| S012 | error | `nocase` 和精确大小写修饰符同时存在产生冲突 | `rules/options/payload/content` |
| S013 | error | 存在 `distance`/`within`/`offset`/`depth` 却没有锚点 | `rules/options/payload` |
| S014 | warn | `nocase` 放置在任何 `content` 之前 | `rules/options/payload/content` |
| S015 | error | 已移除/弃用的规则选项(`uricontent`、`threshold`、`rem`、`activates`、`activated_by`、`logto`、`metadata: rule-flushing`) | `rules/migrating` |
| S016 | error | 未知的 classtype | `rules/options/general/classtype` |
| S017 | warn | TCP 规则缺少 `flow` | `rules/options/non-payload/flow` |
| S018 | info | 在仅限 `to_client` 的端口上使用 `flow:to_server,established`(反之亦然) | `rules/options/non-payload/flow` |
| S019 | info | 带有弱内容的 `any/any` 头部 —— 开销大 | `rules/headers` |
| S020 | error | `pcre` 值的格式不是 `/.../flags` | `rules/options/payload/pcre` |
| S021 | error | `pcre` 使用了 Snort 2 专有的标志 `UIPHDMCKSYBO` | `rules/migrating` |
| S022 | warn | 服务规则缺少 `service:` 或 `metadata: service ;` | `rules/headers` |
| S023 | error | 服务规则头部中存在未知服务 | `rules/headers` |
| S024 | warn | 尾随的 sticky buffer 后面没有 content/pcre/regex | `rules/options/payload` |
| S025 | info | 在经典头部规则中使用了 `file_data` | `rules/options/payload/file_data` |
### 优化 (`scripts/optimizer.py`)
| ID | 严重度 | 启发式建议 |
|----|----------|-----------|
| O001 | warn | 使用 `fast_pattern;` 标记最长且唯一的内容 |
| O002 | info | 将 `content:` 移至 `pcre:` 之前(低成本优先) |
| O003 | info | 为 TCP 添加 `flow:established,...` |
| O004 | info | 将 `any/any` 头部限制为 `$HOME_NET` / 特定端口 |
| O005 | info | 服务端口上的经典 TCP 规则 → 改写为服务规则 + sticky buffer |
| O006 | info | 用更长的字符串替换短的十六进制 `fast_pattern` |
| O007 | info | 缺少显式 `service:` 的服务规则 —— 绑定它 |
| O008 | info | 没有字符串锚点的 `pcre` —— 添加 `content:` 以利用 fast-pattern |
| O009 | warn | 移除 Snort 2 专用的 pcre 标志,使用 sticky buffer |
| O010 | warn | 规则成本评分 ≥ 15 —— 被标记为高开销 |
**成本评分公式**(参见 `references/best_practices.md`):
```
10*has_pcre + 6*invalid_pcre_flag + 5*no_fast_pattern + 5*classic_any
+ 4*no_flow + 4*no_service + 4*raw_content_in_service
+ 3*short_fp + 2*content_after_pcre + 1*no_classtype
```
## 强制执行的 Snort 3 专有特性
- **8 种动作**:`alert`、`block`、`drop`、`log`、`pass`、`react`、`reject`、`rewrite`。
- **33 个 sticky buffers**:`http_uri`、`http_header`、`http_method`、`file_data`、`pkt_data`、`tls_sni`、`dce_iface` 等。Sticky buffer 必须位于其作用域的 `content:` 之前(`S013`、`S024`)。
- **服务规则 (Service rules)**:`alert http (...)`、`alert smtp (...)` 等。需要显式的 `service:;`(`S022`、`O007`)。
- **移除的 PCRE 缓冲区标志**:`UIPHDMCKSYBO` 在 Snort 3 中无效 —— 缓冲区选择现在通过 sticky buffers 进行(`S021`、`O009`)。
- **已移除的选项**被标记为错误:`uricontent`、`rem`、`activates`/`activated_by`、`threshold` 规则选项、`sdrop` 动作、`logto`、`metadata: rule-flushing`(`S015`)。
完整的迁移检查清单请参见 `references/deprecations_vs_snort2.md`。
## 目录结构
```
snort_3_validator/
├── SKILL.md # Skill frontmatter + workflow
├── README.md # This file
├── scripts/
│ ├── snort3val.py # CLI entry
│ ├── parser.py # Tolerant rule parser
│ ├── validator.py # S001..S025
│ ├── optimizer.py # O001..O010 + cost score
│ ├── dynamic.py # `snort -T` wrapper
│ └── report.py # text/json/html renderers
├── references/
│ ├── rule_grammar.md # Snort 3 BNF & header model
│ ├── rule_options_spec.md # Option-by-option contract
│ ├── sticky_buffers.md # 33-entry sticky buffer table
│ ├── deprecations_vs_snort2.md # Snort 2 → 3 migration map
│ └── best_practices.md # Cost-score philosophy
└── examples/
├── good.rules # 5 idiomatic rules — passes 0/0/0
├── bad.rules # 15 rules covering every check
└── expected_output.txt # Reproducible CLI output for bad.rules
```
## 交叉引用 (docs.snort.org)
- — 头部语法
- — `sid`、`rev`、`msg`、`classtype`、`metadata`
- — `content`、`pcre`、`regex`、sticky buffers
- — `flow` 语义
- — Snort 2 → 3 差异
## 许可证
根据 MIT(代码)和 CC-BY-4.0(文档)双许可证授权。详见仓库。
标签:AMSI绕过, MSSP, NDR, PB级数据处理, Python, Snort3, Talos, 云安全监控, 入侵检测系统, 动态检测, 威胁检测, 安全工程, 安全数据湖, 安全运维, 无后门, 网络安全, 规则优化, 规则解析, 规则验证器, 配置检查, 防御规避检测, 隐私保护, 静态分析