doctena-org/octorules-bunny
GitHub: doctena-org/octorules-bunny
这是一个用于通过YAML格式以「基础设施即代码」方式管理Bunny.net Shield WAF规则、速率限制及安全配置的Python提供程序。
Stars: 1 | Forks: 0
# octorules-bunny
[Octorules](https://github.com/doctena-org/octorules) 的 Bunny.net Shield WAF 提供程序 — 以 YAML 格式管理 Bunny Shield 自定义 WAF 规则、速率限制、访问列表、边缘规则、托管规则覆盖、拉取区域安全以及 Bot/DDoS 配置。
## 安装
```
pip install octorules-bunny
```
这将安装 octorules(核心)和 octorules-bunny。该提供程序会被自动发现 — 配置中不需要 `class:`。
## 配置
```
# config.yaml
providers:
bunny:
api_key: env/BUNNY_API_KEY
rules:
directory: ./rules
zones:
my-blog:
sources:
- rules
api-backend:
sources:
- rules
```
每个区域名称映射到一个 Bunny Pull Zone 名称。提供程序在运行时将 Pull Zone 名称解析为 Shield Zone ID。`env/` 前缀在运行时从环境变量中解析值。提供程序部分下的所有键都作为关键字参数转发给提供程序构造函数(octodns 风格的透传)。
### 身份验证
将 `BUNNY_API_KEY` 设置为您的 Bunny.net 账户 API 密钥(可在 https://dash.bunny.net 的 Account Settings 下找到)。该密钥是账户范围的 — 一个密钥覆盖所有 Pull Zone。
### 提供程序设置
以下所有设置均位于提供程序部分下(例如 `providers.bunny`)。
| 键 | 默认值 | 描述 |
|-----|---------|-------------|
| `api_key` | `BUNNY_API_KEY` 环境变量 | Bunny.net API 密钥 |
| `timeout` | `30` | API 超时时间(秒) |
| `max_retries` | `2` | API 重试次数(在 429/5xx 时重试) |
| `max_workers` | `1` | 用于多区域操作的并行工作线程数 |
| `plan` | *(无)* | Bunny 账户层级(`free` 或 `advanced`),用于感知层级的 lint 规则 (BN501)。 |
安全阈值在 `safety:` 下配置(由框架拥有,不转发给提供程序):
| 键 | 默认值 | 描述 |
|-----|---------|-------------|
| `safety.delete_threshold` | `30.0` | 可删除规则的最大百分比 |
| `safety.update_threshold` | `30.0` | 可更新规则的最大百分比 |
| `safety.min_existing` | `3` | 阈值生效前的最小规则数 |
## 支持的功能
| 功能 | 状态 |
|---------|--------|
| 阶段规则(4 个阶段) | 支持 |
| 边缘规则(重定向、标头、强制 SSL、阻止) | 支持 |
| Pull Zone 安全(已阻止的 IP/国家/引用来源、Token 认证、CORS) | 支持 |
| 托管 WAF 规则覆盖 | 支持 |
| Shield 配置(Bot/DDoS) | 支持 |
| 区域发现 (`list_zones`) | 支持 |
| 审计 IP 提取 (`octorules audit`) | 支持 |
| 自定义规则集 | 不支持(Bunny API 限制) |
| 列表 | 不支持(请改用访问列表阶段) |
## 区域文件示例
```
# rules/my-cdn.yaml
---
bunny_waf_custom_rules:
- ref: Block SQLi
action: block
severity: error
description: Detect SQL injection in request body
conditions:
- variable: request_body
operator: detect_sqli
transformations:
- lowercase
- url_decode
- ref: Block bad bots
action: challenge
severity: warning
description: Challenge requests from known bot user agents
conditions:
- variable: request_headers
variable_value: User-Agent
operator: rx
value: "(curl|wget|python-requests)"
transformations:
- lowercase
- ref: Block admin from CN
action: block
severity: error
description: Block access to admin panel from China
conditions:
- variable: request_uri
operator: begins_with
value: /admin
- variable: geo
variable_value: COUNTRY_CODE
operator: str_eq
value: CN
bunny_waf_rate_limit_rules:
- ref: API rate limit
action: block
description: Rate limit API endpoints
request_count: 100
timeframe: 1m
block_time: 5m
counter_key_type: ip
conditions:
- variable: request_uri
operator: begins_with
value: /api/
bunny_waf_access_list_rules:
- ref: "42"
type: country
action: block
enabled: true
content: |
CN
RU
- ref: "43"
type: ip
action: allow
enabled: true
content: |
203.0.113.0/24
bunny_waf_managed_rules:
disabled:
- "941100"
- "942100"
log_only:
- "930100"
bunny_shield_config:
bot_detection:
execution_mode: block
request_integrity_sensitivity: medium
ip_sensitivity: medium
fingerprint_sensitivity: high
complex_fingerprinting: true
ddos:
shield_sensitivity: medium
execution_mode: block
challenge_window: 300
```
## 阶段
| 阶段 | YAML 键 | 描述 |
|-------|----------|-------------|
| 自定义 WAF | `bunny_waf_custom_rules` | 具有条件、运算符和操作的自定义 WAF 规则 |
| 速率限制 | `bunny_waf_rate_limit_rules` | 具有阈值和阻止时间的速率限制规则 |
| 访问列表 | `bunny_waf_access_list_rules` | IP/CIDR/ASN/国家/组织/JA4 阻止/允许列表 |
| 边缘规则 | `bunny_edge_rules` | CDN 级别的边缘规则(重定向、标头操作、强制 SSL、阻止) |
## 非阶段部分
| YAML 键 | 描述 |
|----------|-------------|
| `bunny_waf_managed_rules` | 禁用或仅记录单个托管 WAF 规则 |
| `bunny_shield_config` | Bot 检测和 DDoS 防护配置 |
| `bunny_pullzone_security` | Pull Zone 安全:已阻止的 IP/国家/引用来源、Token 认证、CORS |
## 操作
| 操作 | API 值 | 描述 |
|--------|:---------:|-------------|
| `block` | 1 | 阻止请求 |
| `log` | 2 | 仅记录(不执行) |
| `challenge` | 3 | JavaScript 工作量证明挑战 |
| `allow` | 4 | 显式允许请求 |
| `bypass` | 5 | 绕过所有后续 WAF 处理 |
## 运算符
| 运算符 | API 值 | 描述 |
|----------|:---------:|-------------|
| `begins_with` | 0 | 字符串前缀匹配 |
| `ends_with` | 1 | 字符串后缀匹配 |
| `contains` | 2 | 子字符串匹配 |
| `contains_word` | 3 | 单词级匹配 |
| `str_match` | 4 | 区分大小写的精确匹配 |
| `eq` | 5 | 整数相等 |
| `ge` | 6 | 大于或等于 |
| `gt` | 7 | 大于 |
| `le` | 8 | 小于或等于 |
| `lt` | 9 | 小于 |
| `within` | 12 | 子字符串包含 |
| `rx` | 14 | 正则表达式 |
| `str_eq` | 15 | 不区分大小写的精确匹配 |
| `detect_sqli` | 17 | SQL 注入检测(无需值) |
| `detect_xss` | 18 | XSS 检测(无需值) |
## 变量
| 变量 | API 值 | 子值? | 描述 |
|----------|:---------:|:----------:|-------------|
| `request_uri` | 0 | 否 | 请求 URI |
| `request_uri_raw` | 1 | 否 | 原始请求 URI |
| `args` | 2 | 可选 | 所有参数 |
| `args_combined_size` | 3 | 否 | 参数总大小 |
| `args_get` | 4 | 可选 | GET 参数 |
| `args_post` | 6 | 可选 | POST 参数 |
| `geo` | 9 | **必需** | 地理数据 (COUNTRY_CODE, ASN, CITY, CONTINENT, LATITUDE, LONGITUDE) |
| `remote_addr` | 10 | 否 | 客户端 IP 地址 |
| `query_string` | 11 | 否 | 查询字符串 |
| `request_body` | 13 | 否 | 请求体 |
| `request_cookies` | 15 | **必需** | Cookie(将 cookie 名称指定为 variable_value) |
| `request_headers` | 18 | **必需** | 标头(将标头名称指定为 variable_value) |
| `request_method` | 20 | 否 | HTTP 方法 |
| `response_status` | 24 | 否 | 响应状态码 |
| `fingerprint` | 25 | 否 | 客户端指纹 |
有关 26 个变量的完整列表,请参阅 `octorules_bunny/_enums.py`。
## 规则名称约束
自定义 WAF 和速率限制规则名称(`ref`)必须匹配 `[a-zA-Z0-9 ]+`(仅限字母数字字符和空格)。不允许连字符、下划线或特殊字符。这是 Bunny 强制执行的 API 约束。
访问列表 `ref` 值是 API 分配的数字 ID。在 Bunny 仪表板中初始创建后,使用 `octorules dump` 发现 ID。
## 同步行为
Bunny Shield 不支持原子批量规则替换。提供程序使用差异与协调策略:
1. **修补** 现有规则(ref 同时存在于旧规则和新规则中)
2. **添加** 新规则(ref 仅在所需的 YAML 中)
3. **移除** 过时规则(ref 仅在当前 API 状态中)
此顺序确保区域在同步期间永远不会拥有比预期*更少*的规则。
## 计划限制
| 计划 | 自定义 WAF 规则 | 速率限制 | 访问列表 |
|------|:----------------:|:-----------:|:------------:|
| Free | 0 | 2 | 仅托管 |
| Advanced ($9.50/mo) | 10 | 10 | 自定义 + 托管 |
| Enterprise | 无限制 | 无限制 | 完整 |
## Linting
55 条带有 `BN` 前缀的 lint 规则在同步之前离线验证您的规则。完整参考请参阅 [docs/lint.md](docs/lint.md)。
```
octorules lint
```
## 已知限制
- **非原子同步**:Bunny Shield 没有批量替换 API。`octorules sync` 使用差异与协调(修补现有、添加新、移除过时)— 每个更改的规则进行三次单独的 API 调用。同步中途失败会使区域处于中间状态;重新运行同步将收敛。
- **规则名称约束**:Bunny 仅允许字母数字字符和空格 — 连字符、下划线和特殊字符会被 API 拒绝。
- **无自定义规则集或列表**:Bunny Shield 没有相当于 AWS Rule Groups 或 Cloudflare Lists 的功能。请使用访问列表阶段进行 IP/CIDR/ASN/国家阻止。
- **访问列表条目是独立的**:每个访问列表条目都是一个单独的 API 对象;没有批量创建/删除。大型变更集同步会进行许多 API 调用。
- **计划层级限制**:Free 计划无法创建自定义 WAF 规则,且仅限于 2 条速率限制规则。Linter 会警告这些限制 (BN501)。在提供程序配置中设置 `plan: advanced` 以仅对照 Advanced 层级限制进行检查。
## 开发
```
python -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest tests/ -v
```
Pre-commit hook:
```
ln -sf ../../scripts/hooks/pre-commit .git/hooks/pre-commit
```
## 许可证
Apache-2.0
标签:API集成, AppImage, Bot防护, Bunny.net, CDN安全, DDoS防护, DevSecOps, Octorules, Pull Zone, Python, Streamlit, WAF, Web应用防火墙, YAML, 上游代理, 可观测性, 安全库, 安全策略, 提示词设计, 无后门, 网络安全, 自动化运维, 访问控制, 边缘规则, 逆向工具, 隐私保护