doctena-org/octorules-azure
GitHub: doctena-org/octorules-azure
这是一个 octorules 的 Azure 提供程序,支持通过统一的 YAML 声明式配置来管理 Azure Front Door 和 Application Gateway 的 WAF 自定义规则及策略。
Stars: 1 | Forks: 0
# octorules-azure
[octorules](https://github.com/doctena-org/octorules) 的 Azure WAF 提供程序 — 以 YAML 格式管理 Azure Web Application Firewall 自定义规则。
通过统一接口支持 **Azure Front Door WAF**(高级版/标准版)和 **Application Gateway WAF** (WAF_v2)。无论部署哪种 WAF 类型,用户编写的 YAML 都是一致的。
## 安装
```
pip install octorules-azure
```
这将安装 octorules(核心)和 octorules-azure。提供程序会被自动发现 — 配置中无需 `class:`。
## 配置
```
# config.yaml
providers:
azure:
subscription_id: env/AZURE_SUBSCRIPTION_ID
resource_group: rg-waf-production
waf_type: front_door # or "app_gateway"
timeout: 30 # API timeout in seconds
max_workers: 1 # parallel workers for multi-zone ops
rules:
directory: ./rules
zones:
api-gateway-waf-policy:
sources:
- rules
corporate-site-waf-policy:
sources:
- rules
```
每个区域名称映射到一个 Azure WAF 策略名称。提供程序在运行时解析策略名称。`env/` 前缀在运行时从环境变量中解析值。提供程序部分下的所有键都作为关键字参数转发给提供程序构造函数(octodns 风格的透传)。
### 提供程序设置
以下所有设置均位于提供程序部分下(例如 `providers.azure`)。
| 键 | 默认值 | 描述 |
|---|---|---|
| `subscription_id` | `AZURE_SUBSCRIPTION_ID` 环境变量 | Azure 订阅 ID(必需) |
| `resource_group` | `AZURE_RESOURCE_GROUP` 环境变量 | 包含 WAF 策略的资源组(必需) |
| `waf_type` | `front_door` / `AZURE_WAF_TYPE` 环境变量 | `"front_door"` 或 `"app_gateway"` |
| `timeout` | `30` | API 超时时间(秒) |
| `max_workers` | `1` | 用于多区域操作的并行工作线程数 |
### 身份验证
使用 [`DefaultAzureCredential`](https://learn.microsoft.com/en-us/python/api/azure-identity/azure.identity.defaultazurecredential) — 配置文件中不需要 token。常用选项:
- **服务主体** (CI/CD):`AZURE_TENANT_ID` + `AZURE_CLIENT_ID` + `AZURE_CLIENT_SECRET` 环境变量
- **托管标识** (Azure VM、ACI、App Service):将标识分配给资源,授予 WAF 参与者角色
- **Azure CLI**(本地开发):在运行 octorules 命令前运行 `az login`
- **证书**(自动化系统):`AZURE_TENANT_ID` + `AZURE_CLIENT_ID` + `AZURE_CLIENT_CERTIFICATE_PATH` 环境变量
服务主体或托管标识需要在包含 WAF 策略的资源组上拥有 **参与者** 或 **网络参与者** 角色。
安全阈值在 `safety:` 下配置(由框架拥有,不转发给提供程序):
| 键 | 默认值 | 描述 |
|---|---|---|
| `safety.delete_threshold` | `30.0` | 可删除规则的最大百分比 |
| `safety.update_threshold` | `30.0` | 可更新规则的最大百分比 |
| `safety.min_existing` | `3` | 阈值生效前的最小规则数 |
## 支持的功能
| 功能 | 状态 | Azure 概念 |
|---|---|---|
| 阶段规则(3 个阶段) | 支持 | 自定义规则、速率限制规则、托管规则 |
| 策略设置 | 支持 | WAF 模式、请求正文检查、文件上传限制 |
| 自定义规则集 | 不支持 | Azure 没有单独的规则组概念 |
| 列表 (IP Sets) | 不支持 | IP 内联在 `matchConditions` 中(每个条件最多 600 个) |
| 区域发现 (`list_zones`) | 支持 | 列出资源组中的 WAF 策略 |
| ETag 并发控制 | 支持 | 在 HTTP 412(并发更新冲突)时重试 |
## 阶段
| 阶段 | 规则类型 | 描述 |
|---|---|---|
| `azure_waf_custom_rules` | `MatchRule` | 标准 WAF 规则(IP 封禁、地理位置封禁、请求头检查等) |
| `azure_waf_rate_rules` | `RateLimitRule` | 带有阈值、持续时间和分组的速率限制规则 |
| `azure_waf_managed_rules` | 托管 | 带有覆盖和排除项的 OWASP DRS、机器人防护规则集 |
## 规则格式
相同的 YAML 格式适用于 Front Door 和 Application Gateway。适配器透明地转换 API 级别的差异(字段命名、SDK 模型)。
### 自定义规则
```
# rules/api-gateway-waf-policy.yaml
azure_waf_custom_rules:
# Block specific IP ranges
- ref: BlockBadIPs
priority: 1
action: Block
matchConditions:
- matchVariable: RemoteAddr
operator: IPMatch
matchValue:
- 192.168.1.0/24
- 10.0.0.0/8
# Block requests with suspicious user-agent
- ref: BlockBadUserAgents
priority: 2
action: Block
matchConditions:
- matchVariable: RequestHeader
selector: User-Agent
operator: Contains
matchValue:
- evilbot
- scanner
transforms:
- Lowercase
# Geo-block: allow only US and CA
- ref: GeoBlock
priority: 3
action: Block
matchConditions:
- matchVariable: RemoteAddr
operator: GeoMatch
negateCondition: true
matchValue:
- US
- CA
# Block requests matching a regex pattern
- ref: BlockAdminPaths
priority: 4
action: Block
matchConditions:
- matchVariable: RequestUri
operator: RegEx
matchValue:
- "^/admin/.*\\.php$"
transforms:
- Lowercase
```
### 速率限制规则
```
azure_waf_rate_rules:
# Rate limit API endpoints to 100 requests per minute per client IP
- ref: RateLimitAPI
priority: 100
action: Block
ruleType: RateLimitRule
rateLimitDurationInMinutes: 1
rateLimitThreshold: 100
groupBy:
- variableName: SocketAddr
matchConditions:
- matchVariable: RequestUri
operator: BeginsWith
matchValue:
- /api/
```
### 规则字段参考
| 字段 | 类型 | 必需 | 描述 |
|---|---|---|---|
| `ref` | string | 是 | 规则名称(字母、数字、下划线;最多 128 个字符) |
| `priority` | int | 是 | 评估顺序(正整数,越小越优先;必须在所有规则中唯一) |
| `action` | string | 是 | `Allow`、`Block`、`Log`、`Redirect`、`AnomalyScoring` 或 `JSChallenge` |
| `enabledState` | string | 否 | `Enabled`(默认)或 `Disabled` |
| `ruleType` | string | 否 | `MatchRule`(默认)或 `RateLimitRule` |
| `matchConditions` | list | 是 | 一个或多个条件(AND 关系);每条规则最多 10 个 |
| `rateLimitDurationInMinutes` | int | RateLimitRule | `1` 或 `5`(时间窗口) |
| `rateLimitThreshold` | int | RateLimitRule | 窗口内每个客户端的请求数(10 — 1,000,000) |
| `groupBy` | list | 否 | 速率限制分组:`SocketAddr`、`GeoLocation` 或 `None` |
### 匹配条件字段
| 字段 | 类型 | 描述 |
|---|---|---|
| `matchVariable` | string | 匹配对象:`RemoteAddr`、`SocketAddr`、`RequestMethod`、`QueryString`、`PostArgs`、`RequestUri`、`RequestHeader`、`RequestBody`、`Cookies` |
| `selector` | string | 请求头/Cookie/POST 参数名称(`RequestHeader`、`Cookies`、`PostArgs` 必需) |
| `operator` | string | `Any`、`IPMatch`、`GeoMatch`、`Equal`、`Contains`、`BeginsWith`、`EndsWith`、`RegEx`、`LessThan`、`GreaterThan`、`LessThanOrEqual`、`GreaterThanOrEqual`、`ServiceTagMatch` |
| `negateCondition` | bool | 反转匹配(默认:`false`) |
| `matchValue` | list | 要匹配的值(IPMatch 最多 600 个,字符串运算符最多 10 个) |
| `transforms` | list | 预处理:`Lowercase`、`Uppercase`、`Trim`、`UrlDecode`、`UrlEncode`、`RemoveNulls`、`HtmlEntityDecode` |
## WAF 类型差异
适配器模式透明地处理所有 API 差异。无论 `waf_type` 如何,用户编写的 YAML 都是一致的:
| 功能 | Front Door | Application Gateway |
|---|---|---|
| **范围** | 全局(边缘 CDN) | 区域(反向代理) |
| **传播** | 最长 45 分钟 | 秒到分钟 |
| **SDK** | `azure-mgmt-frontdoor` | `azure-mgmt-network` |
| **更新模型** | 异步 LRO (`begin_create_or_update`) | 同步 (`create_or_update`) |
| **额外操作** | Redirect、AnomalyScoring | -- |
| **额外转换** | -- | HtmlEntityDecode |
| **额外运算符** | ServiceTagMatch | -- |
| **匹配变量名称** | `RequestHeader`、`Cookies` | `RequestHeaders`、`RequestCookies`(由适配器映射) |
| **取反字段** | `negateCondition` | `negationConditon`(API 拼写错误;由适配器映射) |
## Linting
73 条带有 `AZ` 前缀的 lint 规则,涵盖结构、优先级、操作、匹配条件、速率限制、跨规则分析、最佳实践和托管规则集。完整参考及示例请参阅 [`docs/lint.md`](docs/lint.md)。
```
octorules lint --config config.yaml
```
## 已知限制
- **Front Door 传播延迟**:配置更改可能需要长达 45 分钟才能传播到全球所有边缘节点。请相应规划生产部署。
- **无 PATCH API**:Azure WAF 使用全策略 PUT。octorules 始终先获取当前策略并合并更改,但同步期间的外部并发修改可能会导致冲突(通过 ETag 重试缓解)。
- **无自定义规则集或列表**:Azure WAF 没有相当于 AWS 规则组或 IP Sets 的概念。IP 地址内联在 `matchConditions` 中(每个条件最多 600 个,所有规则中总共 60,000 个)。
- **Regex 限制**:每个策略最多 5 条使用 `RegEx` 运算符的自定义规则。
- **优先级必须全局唯一**:规则优先级必须在策略中的所有自定义规则中唯一(MatchRule 和 RateLimitRule 合并),而不仅仅是在某个阶段内。
## 开发
```
python -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest tests/ -v
.venv/bin/ruff check octorules_azure/ tests/
.venv/bin/ruff format --check octorules_azure/ tests/
```
Pre-commit 钩子:
```
ln -sf ../../scripts/hooks/pre-commit .git/hooks/pre-commit
```
## License
Apache-2.0
标签:AppImage, Application Gateway, Azure, Azure Front Door, Azure WAF Policy, octorules, Python, WAF, Web应用防火墙, YAML, 安全库, 无后门, 网络安全, 自定义规则, 逆向工具, 隐私保护