┌─────────────────────────────────────────┐
Internet │ Mini-WAF 处理链路 │
│ │
┌──────┐ :49888 │ ┌──────────┐ ┌─────────┐ ┌────────┐ │ ┌─────────────┐
│ 用户 │ ──────────▶ │ │ IP 过滤 │─▶│ 规则引擎 │─▶│ 路由 │ │──▶ │ 后端服务 A │
└──────┘ │ │ 黑白名单 │ │SQLi/XSS │ │域名+路径│ │ └─────────────┘
│ │ 国家阻断 │ │ 正则匹配 │ │ 精准匹配 │ │ ┌─────────────┐
┌──────┐ :49777 │ └──────────┘ └─────────┘ └────────┘ │──▶ │ 后端服务 B │
│ 管理 │ ──────────▶ │ 管理控制台 │ └─────────────┘
└──────┘ └─────────────────────────────────────────┘
| 模块 | 能力 |
|---|---|
| 反向代理 | 域名 + 路径前缀双维度路由,同端口保护多个域名 |
| 攻击拦截 | 内置 SQL 注入、XSS、目录穿越规则,支持自定义正则热重载 |
| IP 管控 | 黑白名单、GeoIP 国家级封锁,O(1) 内存匹配 |
| 限流熔断 | 滑动窗口限速 + 惩罚分机制,自动封禁异常 IP |
| Nginx 管理 | 可视化编辑配置,保存后自动 reload,无需 SSH |
| 实时监控 | 访问日志、攻击日志、QPS 大盘、地理位置溯源 |
| 负载均衡 | Round-Robin 轮询多上游节点,自动健康检查剔除 |
| SSL 证书管理 | ACME 自动申请(Let's Encrypt / ZeroSSL)、独立 DNS 凭证列表、通配符证书、到期进度监控与自动续签 |
bash <(curl -sSL https://raw.githubusercontent.com/LYX9527/mini-waf/master/install/install.sh)需要已安装 Docker 和 Docker Compose。脚本会自动生成随机密钥、配置端口、启动全部服务。
# 1. 下载配置文件
mkdir -p /opt/mini-waf && cd /opt/mini-waf
curl -sSL -o docker-compose.yml \
https://raw.githubusercontent.com/LYX9527/mini-waf/master/docker/docker-compose.yml
# 2. 修改密码(强烈建议)
# 编辑 docker-compose.yml 中的数据库密码和 JWT_SECRET
# 3. 启动
docker compose up -d安装完成后访问管理控制台:http://<服务器IP>:49777
| 端口 | 容器内端口 | 用途 |
|---|---|---|
49888 |
48080 |
WAF 代理入口,所有保护流量从此进入 |
49777 |
8081 |
管理控制台,建议通过防火墙限制访问 |
在管理控制台 → 站点管理 中添加路由条目:
| 字段 | 示例 | 说明 |
|---|---|---|
| 路径前缀 | / 或 /api |
请求路径匹配前缀 |
| 域名限制 | api.example.com 或 *.example.com |
可选,不填则匹配所有域名 |
| 目标地址 | 127.0.0.1:3000 |
内网服务地址 (host:port) |
多域名路由示例:
api.example.com / → 127.0.0.1:3000 # API 服务
web.example.com / → 127.0.0.1:8080 # 前端服务
(任意域名) /admin → 127.0.0.1:9090 # 通配路由
推荐通过 Nginx 将公网 80/443 流量转入 WAF:
# 在管理控制台 → Nginx 管理 中添加此配置
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://mini-waf:48080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}保存后 WAF 会自动下发配置并 reload Nginx,无需 SSH 操作。
管理控制台 → 安全规则 支持:
- 内置规则:SQL 注入、XSS、目录穿越
- 自定义关键字匹配(包含/精确/正则三种模式)
- 匹配目标:URL、请求头、请求体、User-Agent
- 热重载:添加规则立即生效,无需重启
管理控制台 → SSL 证书管理 包含三个模块:
- X.509 到期时间解析与进度条展示
- 单证书独立自动续签开关
- 一键生成 Nginx SSL 配置模板
- 手动上传 PEM 证书(支持商业 CA、ZeroSSL 等)
支持配置多个 ACME 账号(邮箱 + CA 服务器):
| CA 服务器 | 说明 |
|---|---|
| Let's Encrypt 正式版 | 生产环境使用 |
| Let's Encrypt 测试版 | 调试时不消耗配额 |
| ZeroSSL | 备用 CA |
| DNS 提供商 | 所需凭证 | 支持通配符 |
|---|---|---|
| Cloudflare | CF_DNS_API_TOKEN + CF_ZONE_API_TOKEN |
✅ |
| DNSPod | DP_Id + DP_Key |
✅ |
| 阿里云 | Ali_Key + Ali_Secret |
✅ |
| Hurricane Electric | HE_Username |
✅ |
| 无(HTTP-01) | 不需要凭证,需要 80 端口 | ❌ 不支持 |
申请证书
├─ 选择 ACME 账号 ← 注册到哪个 CA
├─ 选择 DNS 凭证 (可空) ← 空 = HTTP-01,不支持通配符
├─ 填写域名
└─ 开启通配符 (需 DNS 凭证)
mini-waf/
├── src/
│ ├── main.rs # 入口:初始化状态、加载规则、启动监听
│ ├── state.rs # 全局共享状态(路由表、规则、计数器)
│ ├── proxy/
│ │ ├── handler.rs # 请求处理主链路(五阶段过滤)
│ │ ├── router.rs # 路由匹配(Host + 路径前缀,优先级排序)
│ │ └── response.rs # 统一响应构建(错误页、重定向)
│ └── api/
│ ├── routes.rs # 站点路由 CRUD API
│ ├── nginx.rs # Nginx 配置管理 API
│ ├── ssl.rs # SSL 证书 / ACME 账号 / DNS 凭证 API
│ ├── logs.rs # 日志查询 API
│ └── ...
├── admin_frontend/ # React + Ant Design 管理控制台
├── migrations/ # sqlx 数据库迁移文件
│ ├── ...ssl_tables.sql # ssl_certs / acme_config 表
│ ├── ...acme_accounts.sql # ACME 账号多账号支持
│ └── ...dns_credentials.sql # DNS 凭证独立列表
├── docker/
│ └── docker-compose.yml # 完整编排:WAF + Nginx + MySQL
├── install/
│ └── install.sh # 一键安装脚本
└── site/ # 项目主页
后端 前端
───────────────────── ──────────────────────
Rust (1.75+) React 18
├─ Tokio (异步运行时) ├─ Ant Design 5
├─ Hyper (HTTP 协议栈) ├─ TypeScript
├─ Axum (管理 API) └─ Vite
├─ sqlx (MySQL 驱动)
├─ moka (内存缓存) 基础设施
├─ maxminddb (GeoIP) ──────────────────────
└─ regex (规则引擎) Docker + Docker Compose
MySQL 8.0
Nginx Alpine
| 变量 | 默认值 | 说明 |
|---|---|---|
DATABASE_URL |
— | MySQL 连接字符串 |
JWT_SECRET |
— | JWT 签名密钥(必须修改) |
RUST_LOG |
info |
日志级别 (error/warn/info/debug) |
TZ |
Asia/Shanghai |
容器时区 |
MMDB_PATH |
./data/GeoLite2-City.mmdb |
GeoIP 数据库路径(可选) |
下载 GeoLite2-City.mmdb 并挂载到容器,即可启用国家/城市归属地查询和国家封锁功能:
# 下载(需要 MaxMind 免费账号)
# https://www.maxmind.com/en/geolite2/signup
mkdir -p /opt/mini-waf/data
cp GeoLite2-City.mmdb /opt/mini-waf/data/
docker compose restart mini-wafQ: 如何只允许特定 IP 访问管理控制台?
# UFW 示例:只允许 1.2.3.4 访问 49777
ufw allow from 1.2.3.4 to any port 49777
ufw deny 49777Q: 如何通过 SSH 隧道安全访问控制台?
ssh -L 18080:127.0.0.1:49777 user@your-server
# 然后访问 http://localhost:18080Q: 如何更新到最新版本?
cd /opt/mini-waf
docker compose pull
docker compose up -dQ: Nginx 管理提示无法连接 Docker Socket?
确认 docker-compose.yml 中 mini-waf 服务已挂载:
volumes:
- /var/run/docker.sock:/var/run/docker.sock# 后端
cargo sqlx prepare # 更新 sqlx 查询缓存(需要本地 MySQL)
cargo build --release
# 前端
cd admin_frontend
npm install
npm run build # 构建产物输出到 dist/
# Docker 镜像
docker build -t mini-waf .MIT · 由 Rust 社区工具链强力驱动