zentinelproxy/zentinel-agent-zentinelsec
GitHub: zentinelproxy/zentinel-agent-zentinelsec
一个纯 Rust 实现的兼容 ModSecurity 的 WAF 代理,无需任何 C 依赖即可提供完整的 OWASP CRS 规则支持。
Stars: 4 | Forks: 1
# zentinel-agent-zentinelsec
一个用于 [Zentinel](https://github.com/zentinelproxy/zentinel) 反向代理的纯 Rust 兼容 ModSecurity 的 WAF agent。提供完整的 OWASP Core Rule Set (CRS) 支持,**零 C 语言依赖** - 无需 libmodsecurity。
## 功能
- **完整的 OWASP CRS 兼容性**:解析并执行 800+ 条 CRS 规则
- **纯 Rust 实现**:无 libmodsecurity 或 C 语言依赖
- **内置 SQLi/XSS 检测**:原生 `@detectSQLi` 和 `@detectXSS` 运算符
- **SecLang 支持**:加载标准 ModSecurity 规则文件
- **请求 Body 检查**:JSON、表单数据、XML 及所有内容类型
- **响应 Body 检查**:检测数据泄露(可选开启)
- **阻断或仅检测模式**:在阻断前进行监控
- **路径排除**:跳过对可信路径的检查
- **零安装烦恼**:只需 `cargo install`,无系统依赖
## 与其他 WAF Agent 的对比
| 功能 | ZentinelSec | ModSec | WAF |
|---------|-------------|--------|-----|
| 检测规则 | 800+ CRS 规则 | 800+ CRS 规则 | 285 条规则 |
| SecLang 支持 | 是 | 是 | 否 |
| 自定义规则 | 是 | 是 | 否 |
| @detectSQLi/@detectXSS | 是(纯 Rust) | 是(C 语言库) | 否 |
| 依赖项 | **纯 Rust** | libmodsecurity (C) | 纯 Rust |
| 二进制大小 | ~10MB | ~50MB | ~5MB |
| 安装方式 | `cargo install` | 需要 libmodsecurity | `cargo install` |
**ZentinelSec 结合了两者的优点**:具备像 ModSec 一样完整的 CRS 兼容性,同时拥有像 WAF 一样的零依赖安装体验。
## 安装说明
### 使用 Bundle(推荐)
```
# 仅安装此 agent
zentinel bundle install zentinelsec
# 或安装所有捆绑的 agents
zentinel bundle install
```
bundle 命令会为您的平台下载正确的二进制文件,并将其放置在标准位置。详情请参阅 [bundle 文档](https://zentinelproxy.io/docs/deployment/bundle/)。
### 使用 Cargo
```
cargo install zentinel-agent-zentinelsec
```
### 从源码构建
```
git clone https://github.com/zentinelproxy/zentinel-agent-zentinelsec
cd zentinel-agent-zentinelsec
cargo build --release
```
## 使用方法
```
zentinel-zentinelsec-agent \
--socket /var/run/zentinel/zentinelsec.sock \
--rules /etc/modsecurity/crs/crs-setup.conf \
--rules "/etc/modsecurity/crs/rules/*.conf"
```
### 命令行选项
| 选项 | 环境变量 | 描述 | 默认值 |
|--------|---------------------|-------------|---------|
| `--socket` | `AGENT_SOCKET` | Unix socket 路径 | `/tmp/zentinel-zentinelsec.sock` |
| `--rules` | `ZENTINELSEC_RULES` | 规则文件路径(支持通配符模式) | - |
| `--block-mode` | `ZENTINELSEC_BLOCK_MODE` | 阻断 或 仅检测 | `true` |
| `--exclude-paths` | `ZENTINELSEC_EXCLUDE_PATHS` | 要排除的路径(逗号分隔) | - |
| `--body-inspection` | `ZENTINELSEC_BODY_INSPECTION` | 启用请求 body 检查 | `true` |
| `--max-body-size` | `ZENTINELSEC_MAX_BODY_SIZE` | 检查的最大 body 大小(字节) | `1048576` (1MB) |
| `--response-inspection` | `ZENTINELSEC_RESPONSE_INSPECTION` | 启用响应 body 检查 | `false` |
| `--verbose`, `-v` | `ZENTINELSEC_VERBOSE` | 启用调试日志 | `false` |
## OWASP CRS 设置
### 下载 CRS
```
# 克隆 CRS repository
sudo mkdir -p /etc/modsecurity
sudo git clone https://github.com/coreruleset/coreruleset /etc/modsecurity/crs
# 复制示例配置
sudo cp /etc/modsecurity/crs/crs-setup.conf.example /etc/modsecurity/crs/crs-setup.conf
```
### 运行 CRS
```
zentinel-zentinelsec-agent \
--socket /var/run/zentinel/zentinelsec.sock \
--rules /etc/modsecurity/crs/crs-setup.conf \
--rules "/etc/modsecurity/crs/rules/*.conf"
```
## Zentinel 配置
```
agents {
agent "zentinelsec" {
type "custom"
transport "unix_socket" {
path "/var/run/zentinel/zentinelsec.sock"
}
events "request_headers" "request_body_chunk" "response_body_chunk"
timeout-ms 100
failure-mode "open"
}
}
routes {
route "all" {
matches { path-prefix "/" }
upstream "backend"
agents "zentinelsec"
}
}
```
## 偏执级别
在 `/etc/modsecurity/crs/crs-setup.conf` 中配置:
```
SecAction "id:900000,phase:1,pass,t:none,nolog,setvar:tx.blocking_paranoia_level=1"
```
| 级别 | 描述 | 使用场景 |
|-------|-------------|----------|
| 1 | 标准防护,误报率最低 | 生产环境 - 适用于大多数应用 |
| 2 | 提高防护,存在一些误报 | 安全敏感型应用 |
| 3 | 高防护,中等误报率 | 预发/测试环境,或经过调优后 |
| 4 | 最高防护,误报率高 | 安全研究 |
## 响应头
| Header | 描述 |
|--------|-------------|
| `X-WAF-Blocked` | 如果请求被阻断则为 `true` |
| `X-WAF-Rule` | 触发阻断的规则 ID |
| `X-WAF-Message` | 检测消息 |
| `X-WAF-Detected` | 检测消息(仅检测模式) |
## CRS 规则类别
| 文件匹配模式 | 防护内容 |
|--------------|------------|
| REQUEST-913-* | 扫描器检测 |
| REQUEST-920-* | 协议强制执行 |
| REQUEST-930-* | 本地文件包含 (LFI) |
| REQUEST-931-* | 远程文件包含 (RFI) |
| REQUEST-932-* | 远程代码执行 (RCE) |
| REQUEST-941-* | 跨站脚本攻击 (XSS) |
| REQUEST-942-* | SQL 注入 |
| REQUEST-943-* | 会话固定 |
| REQUEST-944-* | Java 攻击 |
| RESPONSE-950-* | 数据泄露 |
## Docker/Kubernetes
```
# 环境变量
env:
- name: AGENT_SOCKET
value: "/var/run/zentinel/zentinelsec.sock"
- name: ZENTINELSEC_RULES
value: "/etc/modsecurity/crs/crs-setup.conf,/etc/modsecurity/crs/rules/*.conf"
- name: ZENTINELSEC_BLOCK_MODE
value: "true"
- name: ZENTINELSEC_EXCLUDE_PATHS
value: "/health,/metrics"
```
## 编写自定义规则
使用 SecLang 语法创建自定义规则:
```
# /etc/modsecurity/custom-rules.conf
# 阻止带有特定 user-agent 的请求
SecRule REQUEST_HEADERS:User-Agent "@contains badbot" \
"id:100001,phase:1,deny,status:403,msg:'Bad bot detected'"
# 检测响应中的敏感数据
SecRule RESPONSE_BODY "@rx \b\d{3}-\d{2}-\d{4}\b" \
"id:100002,phase:4,deny,status:500,msg:'SSN detected in response'"
```
加载自定义规则:
```
zentinel-zentinelsec-agent \
--rules /etc/modsecurity/crs/crs-setup.conf \
--rules "/etc/modsecurity/crs/rules/*.conf" \
--rules /etc/modsecurity/custom-rules.conf
```
## 开发
```
# 以 debug logging 运行
RUST_LOG=debug cargo run -- --socket /tmp/test.sock --rules ./test-rules.conf
# 运行测试
cargo test
# 构建 release binary
cargo build --release
```
## 架构
ZentinelSec 使用 [zentinel-modsec](https://github.com/zentinelproxy/zentinel-modsec),这是一个纯 Rust 编写的 libmodsecurity 重新实现:
- **Parser**:用于 SecRule、SecAction、SecMarker 指令的完整 SecLang parser
- **变量**:REQUEST_URI、ARGS、REQUEST_HEADERS、TX collections 等
- **运算符**:包含 @rx、@pm、@detectSQLi、@detectXSS 在内的 37+ 个运算符
- **Transformations**:35+ 个 transformations(urlDecode、base64Decode、lowercase 等)
- **引擎**:带有规则链和异常评分的 5 阶段事务处理
## 相关 Agent
| Agent | 使用场景 |
|-------|----------|
| **[ModSec](/agents/modsec/)** | 基于 C 语言的 libmodsecurity(如果您需要最大的兼容性) |
| **[WAF](/agents/waf/)** | 轻量级,约 20 条规则(如果您需要最低的开销) |
| **[AI Gateway](/agents/ai-gateway/)** | 特定于 AI/LLM 的安全控制 |
## 许可证
Apache-2.0
标签:ModSecurity, OWASP CRS, Rust, WAF, Web安全, 反向代理, 可视化界面, 子域名突变, 网络流量审计, 蓝队分析, 请求拦截, 通知系统