增加waf模块
This commit is contained in:
1 parent
fbccc5d909
commit
202f2804b2
22 files changed
+1097
-17
No files matched your search
+172
@@ -0,0 +1,172 @@
|
||||
# waf — Web 应用防火墙网关
|
||||
|
||||
基于 Go + [coraza](https://github.com/corazawaf/coraza) 的 WAF 网关,部署在 `gateway` 之前,终止 TLS 并按 SecLang 规则库匹配请求,未命中则转发到 gateway。
|
||||
|
||||
```
|
||||
客户端 ──HTTPS──▶ waf:443 (终止 TLS + coraza 规则匹配) ──明文 HTTP──▶ gateway:8443 (鉴权 + 反代)
|
||||
```
|
||||
|
||||
## 为什么是 Go
|
||||
|
||||
- `coraza-waf/coraza` 是 ModSecurity SecLang 的 Go 实现,100% 兼容 OWASP CRS v4
|
||||
- `net/http/httputil.ReverseProxy` 标准库反向代理,零第三方依赖
|
||||
- goroutine + net/http 吞吐量比 Python 高一个数量级
|
||||
- `go build` 出单二进制,`core/init.txt` 直接拉起
|
||||
|
||||
## 极客友好的规则系统
|
||||
|
||||
| 操作 | 命令 |
|
||||
|------|------|
|
||||
| 编辑规则 | `vim rules/local/custom.conf` |
|
||||
| 校验语法 | `./waf.bin -test rules/local/custom.conf` |
|
||||
| 列出所有规则 | `./waf.bin -list` |
|
||||
| 测试输入 | `./waf.bin -check "/?id=1' OR '1'='1"` |
|
||||
| 热加载(不重启) | `kill -HUP $(pgrep waf)` |
|
||||
| 临时禁用某文件 | `mv rules/local/x.conf x.conf.bak && kill -HUP $(pgrep waf)` |
|
||||
|
||||
### 规则文件组织
|
||||
|
||||
```
|
||||
rules/
|
||||
├── waf.conf # 主入口,Include 各子文件
|
||||
├── local/ # 本地自定义规则(ID 段 100000-199999)
|
||||
│ ├── custom.conf # 示例:SQL注入/XSS/路径遍历/命令注入/扫描器UA
|
||||
│ └── exceptions.conf # 误报白名单(SecRuleRemoveById / ctl:ruleRemoveById)
|
||||
└── crs/ # OWASP CRS(git clone,不入库,ID 段 900000-999999)
|
||||
```
|
||||
|
||||
### 规则 ID 分段
|
||||
|
||||
- `100000-199999` 本地自定义
|
||||
- `900000-999999` OWASP CRS
|
||||
|
||||
### 规则语法(SecLang)
|
||||
|
||||
```apache
|
||||
SecRule REQUEST_URI|ARGS "@rx (?i)union[\s/*]+select" \
|
||||
"id:100001,phase:1,deny,status:403,log,msg:'SQL injection: UNION SELECT'"
|
||||
```
|
||||
|
||||
字段说明:
|
||||
- `REQUEST_URI|ARGS` 匹配目标(URI / 参数 / Header / Cookie 等)
|
||||
- `@rx ...` 正则匹配(也支持 `@pm`、`@contains`、`@beginsWith` 等)
|
||||
- `phase:1` 请求头阶段 / `phase:2` 请求体阶段 / `phase:3` 响应头 / `phase:4` 响应体
|
||||
- `deny,status:403` 命中后动作
|
||||
- `msg` 命中日志描述
|
||||
|
||||
## 部署形态
|
||||
|
||||
WAF 必须终止 TLS 才能看到明文 body,因此证书需从 gateway 迁到 WAF:
|
||||
|
||||
1. 把 `gateway` 的 `full_chain.crt` / `server.key` 复制到 `waf/certs/`
|
||||
2. `gateway` 改为监听 `127.0.0.1:8443`,关闭 TLS(仅本机)
|
||||
3. `waf` 监听 `:443`,转发到 `http://127.0.0.1:8443`
|
||||
|
||||
## 配置
|
||||
|
||||
`config.yaml`:
|
||||
|
||||
```yaml
|
||||
listen: ":443"
|
||||
tls_cert: "./certs/full_chain.crt"
|
||||
tls_key: "./certs/server.key"
|
||||
upstream: "http://127.0.0.1:8443"
|
||||
rules_dir: "./rules"
|
||||
```
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
waf/
|
||||
├── main.go # 入口:服务模式 + CLI 子命令
|
||||
├── config.yaml # 配置
|
||||
├── go.mod
|
||||
├── internal/
|
||||
│ ├── engine/
|
||||
│ │ └── engine.go # coraza 封装:加载/热加载/列举/单测
|
||||
│ └── proxy/
|
||||
│ └── proxy.go # ReverseProxy + WAF 事务接入
|
||||
├── rules/
|
||||
│ ├── waf.conf
|
||||
│ └── local/
|
||||
│ ├── custom.conf
|
||||
│ └── exceptions.conf
|
||||
├── _set.sh # 编译
|
||||
├── _run.sh # 运行
|
||||
├── .gitignore
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
# 1. 安装 Go 1.21+
|
||||
brew install go # macOS
|
||||
# 或 sudo apt install golang-go # Debian/Ubuntu
|
||||
|
||||
# 2. 编译
|
||||
bash _set.sh
|
||||
|
||||
# 3. 准备证书
|
||||
mkdir certs && cp /path/to/full_chain.crt /path/to/server.key certs/
|
||||
|
||||
# 4. 运行
|
||||
bash _run.sh
|
||||
```
|
||||
|
||||
## 接入 core 自启动
|
||||
|
||||
在 `core/init.txt` 增加:
|
||||
|
||||
```
|
||||
bash /opt/micro_servers/waf/_run.sh
|
||||
```
|
||||
|
||||
并把 `gateway` 改为内部 HTTP 端口(不再监听 443)。
|
||||
|
||||
## 命中日志
|
||||
|
||||
命中规则时输出 JSON 一行,便于 `jq` 分析:
|
||||
|
||||
```json
|
||||
{"ts":"2026-07-25T10:00:00Z","action":"block","rule_id":100001,"ip":"1.2.3.4","method":"GET","path":"/","query":"id=1'+OR+'1'='1","ua":"curl/8.0","cost_ms":0}
|
||||
```
|
||||
|
||||
聚合统计:
|
||||
|
||||
```bash
|
||||
journalctl -u Nidus -o cat | grep '"action":"block"' | \
|
||||
jq -r '.rule_id' | sort | uniq -c | sort -rn
|
||||
```
|
||||
|
||||
## 启用 OWASP CRS(可选)
|
||||
|
||||
```bash
|
||||
cd rules
|
||||
git clone --depth 1 https://github.com/coreruleset/coreruleset.git crs
|
||||
```
|
||||
|
||||
在 `rules/waf.conf` 取消注释:
|
||||
|
||||
```apache
|
||||
Include crs/coraza.conf
|
||||
Include crs/rules/*.conf
|
||||
```
|
||||
|
||||
然后 `kill -HUP $(pgrep waf)`。
|
||||
|
||||
## 已知限制
|
||||
|
||||
- 请求体全量读入内存检测,10MB 上限(`SecRequestBodyLimit`)。大文件上传场景需调大或加白名单。
|
||||
- 响应体检测未启用(需缓冲整个响应,延迟成本高)。
|
||||
- 限流/黑白名单未实现,可后续作为 coraza 规则或独立中间件加。
|
||||
|
||||
## 依赖
|
||||
|
||||
- Go 1.21+
|
||||
- github.com/corazawaf/coraza/v3 v3.7.0
|
||||
- gopkg.in/yaml.v3
|
||||
|
||||
## 许可证
|
||||
|
||||
MIT License
|
||||
Reference in new issue
Block a user