iodesk/VibesWAF
GitHub: iodesk/VibesWAF
一个用于学习和实验的个人反向代理与 WAF 项目,通过四阶段请求 pipeline 结合多维度评分机制实现流量拦截、验证和放行决策。
Stars: 0 | Forks: 0
# VibesWAF
一个为个人使用和实验而构建的反向代理和 WAF。未经过生产环境强化,也未经过实战检验:这只是一个为了从内部了解 WAF 工作原理而进行的项目。

使用 Go 构建。使用 [Coraza](https://github.com/corazawaf/coraza) + OWASP CRS 作为托管规则,PostgreSQL 存储配置,ClickHouse 存储日志,Redis 存储状态。
## 功能说明
部署在您的应用前端(位于 OpenResty/nginx 之后),将每个请求通过一个包含 4 个阶段的 pipeline,并做出决定:拦截、验证或放行。所有请求都会经过此流程。
```
Request -> Phase 1 (Hard Rules) -> Phase 2 (Scoring) -> Phase 3 (Decision) -> Phase 4 (Response)
```
## Pipeline
### 阶段 1:硬性规则(确定性,提前退出)
按顺序执行。如果任何一个 handler 做出了决定(拦截/验证),pipeline 会立即停止。
```
ChallengeValidator -> IPAccess -> Flood -> RateLimit -> Cache -> Custom Rules
```
- **ChallengeValidator**:验证 `ok` cookie(包含 IP + UA + 时间戳 + 信任级别的 HMAC-SHA256)。如果有效,该请求会将信任级别带入阶段 2。
- **IPAccess**:基于 CIDR 或单一 IP 实现针对每个应用的允许/拦截/验证。匹配即为最终决定。
- **Flood**:具有可配置惩罚周期的 256 分片内存检测器。处理基本、攻击和错误泛洪配置。
- **RateLimit**:基于 IP+UA 的令牌桶算法。热路径(hot path)上不依赖 Redis。
- **Cache**:针对重复的请求指纹重放缓存的决策。
- **Custom Rules**:基于表达式的规则(IP、路径、UA、标头、地理位置、ASN)。支持 `skip` 操作以绕过特定的阶段 2 模块。
如果阶段 1 的任何 handler 做出了最终决定,阶段 2 和阶段 3 将被跳过,pipeline 直接跳转到阶段 4。
### 阶段 2:评分(累积)
所有 handler 都会运行。每个 handler 会为五个独立的类别贡献分数:
```
IPReputation -> BotDetection -> WAFEngine -> ProtocolAnomaly -> TrustedHistory -> StableSession -> Trust
```
| 类别 | 数据源 | 典型信号 |
|---|---|---|
| `ip_reputation` | MaxMind, Spamhaus, 手动录入 | 数据中心 IP,已知恶意 ASN |
| `bot_detection` | UA 分析,标头一致性,时间 | 缺失 Sec-Fetch,机器人 UA 模式,突发速率 |
| `waf_anomaly` | Coraza + OWASP CRS | SQLi、XSS、LFI、RCE 规则匹配 |
| `protocol_anomaly` | HTTP 标头分析,JA4 指纹 | GET 请求带有 Content-Type,TE/CL 冲突,旧版 TLS + 浏览器 UA |
| `trust` | 验证结果,历史记录,已知良性机器人 | 已验证用户的负分(减分) |
在所有 handler 运行完毕后,每个类别的分数会被限制在其 `max_score` 内,并乘以其配置的乘数。可以在仪表板中禁用相应类别(分数重置为 0)。
### 阶段 3:决策
只有一条规则:总分决定结果。
```
score >= block_threshold -> block
score >= challenge_threshold -> challenge
score < challenge_threshold -> allow
```
所有的阈值、权重、上限和乘数都存储在 PostgreSQL 中,并通过原子指针交换(atomic pointer swap)保留在内存中。没有任何内容是硬编码的。
### 阶段 4:响应
- **Block**:返回 403 页面,附带原因和 Ray ID。
- **Challenge**:返回滑动验证页面(见下文)。
- **Allow**:代理至上游(upstream)。
## Challenge 系统
当请求达到验证阈值时,客户端会收到一个滑动验证页面。该滑块会收集原始的鼠标轨迹数据(每个采样点的坐标位置 + 时间),并将其发送到后端。
服务器会验证以下三项内容:
1. **位置**:滑块位置在服务器生成目标位置的容差范围(4 个百分点)内。
2. **持续时间**:总交互时间 >= 1.5 秒。
3. **轨迹分析**:原始鼠标路径会根据以下七项指标进行评分:
| 指标 | 人类 | 机器人 |
|---|---|---|
| 速度方差 | 不规则 | 均匀 |
| 平直度 | 0.85..0.98 | ~1.0 |
| Y 轴抖动 | 存在 | 呈直线 |
| 方向改变 | >= 1 次 X 轴反转 | 无 |
| 时间方差 | 间隔多变 | 间隔恒定 |
| 加速度方差 | 分阶段(加速、匀速、减速) | 平稳 |
| 微停顿 | 释放前存在 | 无 |
轨迹得分(70%)+ 浏览器信号得分(30%)组合成一个置信度值(0.0..1.0),该值映射为相应的信任级别:
| 信任级别 | 置信度 | 分数扣减 |
|---|---|---|
| 0 | 0.00..0.39 | 0(已解开但可疑) |
| 1 | 0.40..0.59 | -5 |
| 2 | 0.60..0.79 | -10 |
| 3 | 0.80..1.00 | -15 |
该信任级别会嵌入到 `ok` cookie 中(受 HMAC 保护),并在下一次请求中作为负分应用。高置信度的人类验证成功可以使处于边缘状态的请求不再触发验证阈值。
每次验证最多尝试 3 次。验证存储具有可配置的 TTL。验证解开请求会按 IP 进行速率限制。
## 信任历史
具有 N 个连续干净请求(无拦截或验证)的 IP 会累积信任扣减分数。阈值(N)和扣减值均可在仪表板中进行配置。存储在 Redis 中,TTL 为 24 小时。
## 配置
DB -> 预加载 -> 内存 -> 运行时,通过原子交换实现。后台每 10 秒刷新一次。请求路径上零数据库查询。
## 日志记录
无论决策如何,所有请求都会被记录。日志记录属于副作用:它通过缓冲 channel 和批量处理 worker 完成。请求 handler 从不等待日志写入。目的地:ClickHouse。
每个日志条目都包含完整的 pipeline 跟踪记录(各阶段分数、原因、乘数、最终分数)。
## 技术栈
| 组件 | 作用 |
|---|---|
| Go | 核心代理 + pipeline |
| OpenResty (nginx + Lua) | TLS 终结,JA4 指纹,动态 SSL |
| Coraza + OWASP CRS | 托管 WAF 规则 |
| PostgreSQL | 配置存储,数据库迁移 |
| ClickHouse | 请求日志 + 分析 |
| Redis | 速率限制状态,验证存储,信任历史 |
| React + Vite | 仪表板前端 |
| MaxMind GeoIP2 | 地理位置查询 + 数据中心检测 |
## 仪表板
用于管理所有配置的 Web UI:
- **Applications**:域名,上游,负载均衡,针对应用的覆盖配置,可信代理。
- **Security Rules**:基于表达式的自定义规则(IP、路径、UA、标头、地理位置、ASN),支持拦截/验证/放行/记录/跳过操作。
- **Rate Limiter**:泛洪配置(基本、攻击、错误)以及基于每个应用的令牌桶速率限制。
- **Bot Detector**:基于每个规则的 UA/referer 得分,机器人 IP 范围,信任级别阈值。
- **WAF Engine**:Coraza 偏执级别,异常阈值,允许的方法,已禁用的规则,自定义 SecRules。
- **IP Reputation**:手动配置 IP 和 ASN 评分。
- **Scoring Engine**:基于类别的乘数,最高分上限,启用/禁用开关,拦截和验证阈值。
- **Logs**:请求日志查看器,包含原始的 JSON pipeline 跟踪记录。
- **Analytics**:流量图表,威胁分类,分数分布。
## 环境要求
- Go 1.25+
- PostgreSQL 14+
- ClickHouse
- Redis
- OpenResty(用于 TLS 终结和 JA4 指纹)
## 设置
```
cp .env.example .env
# 编辑 .env
# 运行 migrations(默认自动运行,设置 AUTO_MIGRATE=false 以跳过)
./wafer
```
前端:
```
cd frontend
cp .env.example .env
npm install
npm run build
```
有关 nginx 配置、systemd 服务和 ACME 脚本,请参阅 `config/`。
## 注意事项
- 个人项目。不提供任何保证,也没有 SLA。
- 测试覆盖率不完整。
- 部分功能默认前端部署了 OpenResty(JA4 标头,动态 SSL)。
- 并非为多租户(multi-tenant)设计。
标签:AppImage, Go, rizin, Ruby工具, WAF, Web应用防火墙, 反向代理, 搜索引擎查询, 日志审计, 流量拦截, 测试用例, 自动化攻击, 防护系统