corazawaf/coraza-spoa
GitHub: corazawaf/coraza-spoa
将 OWASP Coraza WAF 封装为 HAProxy SPOA 服务,通过 SPOE 协议实现高性能 Web 应用防火墙集成。
Stars: 153 | Forks: 36
Coraza SPOA - HAProxy Web Application Firewall
[](https://github.com/corazawaf/coraza-spoa/actions/workflows/lint.yaml)
[](https://github.com/corazawaf/coraza-spoa/actions/workflows/codeql.yaml)
Coraza SPOA 是一个系统守护进程,它将 Coraza Web 应用防火墙 (WAF) 作为 HAProxy 的后端服务。它使用 Go 语言编写,Coraza 支持 ModSecurity SecLang 规则集,并与 OWASP Core Rule Set v4 100% 兼容。
HAProxy 包含一个 [Stream Processing Offload Engine](https://www.haproxy.com/blog/extending-haproxy-with-the-stream-processing-offload-engine) [SPOE](https://raw.githubusercontent.com/haproxy/haproxy/master/doc/SPOE.txt),用于将请求处理卸载到 Stream Processing Offload Agent (SPOA)。Coraza SPOA 嵌入了 [Coraza Engine](https://github.com/corazawaf/coraza),加载规则集并过滤由 HAProxy 转发以进行检查的 HTTP 请求或应用程序响应。
## 编译
### 构建
命令 `go run mage.go build` 将编译源代码并在 `build/` 文件夹中生成可执行文件 `coraza-spoa`。
## 配置
## Coraza SPOA
示例配置文件是 [example/coraza-spoa.yaml](https://github.com/corazawaf/coraza-spoa/blob/main/example/coraza-spoa.yaml),你可以复制它并修改相关的配置信息。你可以通过运行以下命令来启动服务:
```
coraza-spoa -config /etc/coraza-spoa/coraza-spoa.yaml
```
## HAProxy SPOE
配置 HAProxy 以与 SPOA 交换消息。示例 SPOE 配置文件是 [coraza.cfg](https://github.com/corazawaf/coraza-spoa/blob/main/example/haproxy/coraza.cfg),你可以复制它并修改相关的配置信息。放置配置的默认目录是 `/etc/haproxy/coraza.cfg`。
```
# /etc/haproxy/coraza.cfg
spoe-agent coraza-agent
...
use-backend coraza-spoa
spoe-message coraza-req
args app=str(sample_app) id=unique-id src-ip=src ...
```
`config.yaml` 中的应用程序名称必须与 `app=` 名称匹配。
在 `use-backend` 中定义的后端必须匹配 `haproxy.cfg` 中的一个后端,该后端将请求定向到可通过 `127.0.0.1:9000` 访问的 SPOA 守护进程。
你可以使用一些 HAProxy 变量来代替硬编码的应用程序名称 `str(sample_app)`。例如,前端名称 `fe_name`。
## HAProxy
为 HAProxy 配置一个前端,其中包含一个 `filter` 语句,用于将请求转发到 SPOA 并根据返回的操作进行拒绝。同时添加一个后端部分,该部分在 `coraza.cfg` 中被 use-backend 引用。
```
# /etc/haproxy/haproxy.cfg
frontend web
filter spoe engine coraza config /etc/haproxy/coraza.cfg
...
http-request deny deny_status 403 hdr waf-block "request" if { var(txn.coraza.action) -m str deny }
...
backend coraza-spoa
mode tcp
option spop-check
server s1 127.0.0.1:9000 check
```
可以在 [example/haproxy/coraza.cfg](https://github.com/corazawaf/coraza-spoa/blob/main/example/haproxy/coraza.cfg) 中找到一个全面的 HAProxy 配置示例。
因为在 SPOE 配置文件 中,我们声明使用后端 [coraza-spoa](https://github.com/corazawaf/coraza-spoa/blob/main/example/haproxy/coraza.cfg#L13) 与服务进行通信,所以我们也需要在 [HAProxy 文件](https://github.com/corazawaf/coraza-spoa/blob/main/example/haproxy/haproxy.cfg#L50) 中定义它:
如果你打算从另一台机器访问 coraza-spoa 服务,请记住在 [contrib/coraza-spoa.service](https://github.com/corazawaf/coraza-spoa/blob/main/contrib/coraza-spoa.service) 中更改绑定网络指令。
## HAProxy 日志记录
为了直接从 HAProxy 日志全面了解 WAF 操作,你可以使用 Coraza-SPOA 代理导出的事务变量。
### 可用变量
代理在 `txn` 作用域中填充以下变量:
* **`txn.coraza.id`**:唯一的事务 ID。
* **`txn.coraza.status`**:由 WAF 确定的 HTTP 状态码(例如 403)。
* **`txn.coraza.anomaly_score`**:请求的总入站异常分数。
* **`txn.coraza.rules_hit`**:触发的攻击规则总数。
* **`txn.coraza.rule_ids`**:触发的规则 ID 列表(如果已启用),以逗号分隔。
* **`txn.coraza.error`**:如果事务失败,则包含与 SPOA 相关的错误。
### 示例日志格式
你可以将这些变量合并到 `haproxy.cfg` 的 `log-format` 指令中。
**1. 标准分数跟踪**
将其用于威胁级别和规则计数的一般监控:
```
log-format "%ci:%cp\ [%t]\ %ft\ %b/%s\ %Th/%Ti/%TR/%Tq/%Tw/%Tc/%Tr/%Tt\ %ST\ %B\ %CC\ %CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ %{+Q}r\ %[var(txn.coraza.id)]\ spoa-error:\ %[var(txn.coraza.error)]\ waf-hit:\ %[var(txn.coraza.status)]\ score:%[var(txn.coraza.anomaly_score)]\ rules_hit:%[var(txn.coraza.rules_hit)]"
```
**2. 扩展调试(带规则 ID)**
如果你需要准确识别触发了哪些规则以排查误报,请使用此选项。
```
spoe-message coraza-req
args app= ... exportRuleIDs=bool(true)
spoe-message coraza-res
args app= ... exportRuleIDs=bool(true)
.....
```
```
log-format "%ci:%cp\ [%t]\ %ft\ %b/%s\ %Th/%Ti/%TR/%Tq/%Tw/%Tc/%Tr/%Tt\ %ST\ %B\ %CC\ %CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ %{+Q}r\ %[var(txn.coraza.id)]\ spoa-error:\ %[var(txn.coraza.error)]\ waf-hit:\ %[var(txn.coraza.status)]\ rule_ids:\ %[var(txn.coraza.rule_ids)]\ rules-hit:\ %[var(txn.coraza.rules_hit)]"
```
### 自定义规则及 ID 范围分配
为了避免与 OWASP Core Rule Set (CRS) 冲突,并确保 SPOA 代理将准确的指标导出到 HAProxy(`rules_hit` 和 `rule_ids`),你必须严格遵守以下本地规则的规则 ID 范围:
* **基础设施及白名单 (ID: 100000 - 189999):** 此范围用于 IP 白名单、禁用特定 CRS 规则或调优(例如 GeoIP 限制)。SPOA 代理的攻击计数器会**有意忽略**此范围内的规则,以防止 HAProxy 指标中出现误报。
* **自定义攻击及加固规则 (ID: 190000 - 199999):** 此范围用于实际的安全阻断和自定义加固规则。此范围内的规则会受到主动监控。如果被触发,它们将增加 `rules_hit` 计数器,并且其 ID 将被导出到 `rule_ids` 变量中。
## Docker
- 构建 coraza-spoa 镜像 `cd ./example ; docker compose build`
- 运行 haproxy、coraza-spoa 和模拟服务器 `docker compose up`
- 执行一个被 WAF 阻断的请求:`curl http://localhost:8080/\?x\=/etc/passwd`标签:AppImage, Coraza, CoreRuleSet, EVTX分析, EVTX分析, Go, HAProxy, ModSecurity, Ruby工具, SPOA, SPOE, WAF, Web应用防火墙, 中间件, 云计算, 反向代理, 日志审计, 流量过滤, 网络安全, 规则引擎, 请求拦截, 防护软件, 隐私保护