Flmelody/open-website-defender
GitHub: Flmelody/open-website-defender
自托管轻量级 WAF,单一二进制部署,配合 Nginx auth_request 为内网应用提供统一认证、威胁检测和多层访问控制。
Stars: 5 | Forks: 1
# Website Defender
[中文文档](README-zh.md)
一个 **自托管**、**轻量级**、**简单** 的 WAF (Web Application Firewall) —— 单一二进制文件,几分钟即可完成部署。
`Website Defender` 为暴露在公共网络上的网站提供统一认证、智能威胁检测和多层访问控制。无需安装代理,无需云订阅 —— 只需在 Nginx 前放置一个二进制文件。

企业通常部署许多内部应用,例如 `Gitlab`、`Jenkins`、`Prometheus`、`Nexus`、`Nacos` 等。当这些服务被暴露时,可能会面临以下安全风险:
- 缺乏统一认证
- 暴力破解攻击
- 开源版本中的漏洞
`Website Defender` 通过提供具有认证和访问控制策略的自托管安全网关来解决这些问题 —— 您现有的应用程序**无需更改任何代码**。
## 架构
`Website Defender` 旨在使用 `auth_request` 模块与 **Nginx** 协同工作。它充当认证提供者,在 Nginx 将请求转发到您的实际应用程序之前验证请求。
```
graph LR
User[User/Browser] --> Nginx
Nginx -->|1. Check Auth| Defender[Website Defender]
Defender -->|2. Allow/Deny| Nginx
Nginx -->|3. Proxy if Allowed| App[Internal App]
```
## 功能特性
### 认证与访问控制
- **JWT Token 认证**:通过 `Defender-Authorization` 标头颁发,支持可配置令牌过期时间的安全登录。
- **基于 Cookie 的认证**:支持 `flmelody.token` cookie,实现无缝的浏览器会话。
- **Git Token 认证**:通过可配置的 HTTP 标头(默认为 `Defender-Git-Token`)进行机器访问,格式为 `username:token`。
- **License Token 认证**:通过可配置的 HTTP 标头(默认为 `Defender-License`)进行 API 访问,令牌在存储前经过 SHA-256 哈希处理。
- **IP 白名单**:允许特定 IP 或 CIDR 范围(例如 `192.168.1.0/24`)绕过认证。
- **IP 黑名单**:通过精确匹配或 CIDR 范围阻止恶意 IP。支持带有自动过期和可选备注的临时封禁。
- **授权域名**:集中管理受保护的域名。作为 IP 白名单域名绑定和用户访问控制的数据源。
- **授权域名访问控制**:使用逗号分隔的模式(例如 `gitea.com, *.internal.org`)限制用户访问特定的授权域名。空的授权域名授予无限制访问权限。管理员用户绕过授权域名检查。域名从 `X-Forwarded-Host` 标头确定,回退到 `Host`。
**认证验证流程:**
```
IP Blacklist → IP Whitelist (+ Authorized Domain Check) → JWT Token (+ Authorized Domain Check) → Git Token (+ Authorized Domain Check) → License Token → Deny
```
### 授权域名访问控制
授权域名实现了多租户访问控制,允许不同的用户访问同一 Defender 实例背后的不同受保护服务。
**工作原理:**
1. 当请求到达 `/auth` 时,Defender 从 `X-Forwarded-Host` 读取域名(回退到 `Host` 标头)
2. 在 token/git-token 认证成功后,将根据请求的域名检查用户的授权域名
3. 如果域名与任何授权域名模式不匹配,则返回 `403 Forbidden`
**授权域名模式:**
| Pattern | Matches | Does Not Match |
|---------|---------|----------------|
| `gitea.com` | `gitea.com` | `gitlab.com`, `sub.gitea.com` |
| `*.example.com` | `app.example.com`, `dev.example.com` | `example.com` |
| `gitea.com, *.internal.org` | `gitea.com`, `app.internal.org` | `gitlab.com` |
| *(empty)* | Everything (unrestricted) | - |
**规则:**
- **空的授权域名** = 无限制访问(与现有用户向后兼容)
- **管理员用户** 无论其配置如何,始终绕过授权域名检查
- 匹配**不区分大小写**
- 匹配前去除端口(`gitea.com:3000` 匹配 `gitea.com`)
**Nginx 配置:**
要将域名信息传递给 Defender,请将 Nginx 配置为通过 `X-Forwarded-Host` 转发 `Host` 标头:
```
server {
server_name gitea.example.com;
location / {
auth_request /auth;
# Pass the original host to Defender for authorized domain checking
proxy_pass http://gitea-backend;
}
location = /auth {
internal;
proxy_pass http://127.0.0.1:9999/wall/auth;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Original-URI $request_uri;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
}
```
### Web Application Firewall (WAF)
基于正则表达式的请求过滤,检查 URL 路径、查询字符串、User-Agent 和请求体(最大 10KB)。每条规则支持 `block`(返回 403)或 `log`(允许但记录)操作。
**9 条内置规则:**
| Category | Rule | Description |
|----------|------|-------------|
| SQL Injection | Union Select | Detects `UNION SELECT` based attacks |
| SQL Injection | Common Patterns | Detects `; DROP`, `; ALTER`, `; DELETE`, etc. |
| SQL Injection | Boolean Injection | Detects `' OR 1=1` style bypass |
| SQL Injection | Comment Injection | Detects `' --` and `/* */` comment abuse |
| XSS | Script Tag | Detects `