aws-samples/sample-aws-waf-dynamic-labels
GitHub: aws-samples/sample-aws-waf-dynamic-labels
该项目演示了 AWS WAF 动态标签插值功能,通过 `${awswaf:}` 语法在请求标头、响应正文和响应标头中内联解析标签值,避免为每个标签编写硬编码规则。
Stars: 3 | Forks: 1
# AWS WAF 动态标签插值
## 什么是动态标签插值?
AWS WAF 标签在评估时对请求进行分类 —— Bot Control 识别机器人类别、信号强度和机器人名称;Account Takeover Prevention 标记凭证撞库;您自己的规则应用自定义标签。直到现在,对这些标签采取行动需要静态的一对一映射:每个标签值对应一条规则,并在标头和响应正文中使用硬编码的字符串。
动态标签插值引入了 `${namespace:}` 语法,可以内联解析标签值。无需编写数百条规则将每个机器人类别映射到特定的标头值,只需一条包含 `${awswaf:managed:aws:bot-control:bot:category:}` 的规则,即可解析为请求所携带的任何标签 —— `scraping`、`search_engine`、`advertising` 等。
### 插值适用的场景
| 表面 | 示例 |
| --------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| **自定义请求标头** | `"value": "${awswaf:managed:aws:bot-control:bot:category:}"` — 将解析后的标签转发至您的源站 |
| **自定义响应正文** | `"Content": "Your IP: ${awswaf:ip:}"` — 在拦截/质询页面中嵌入值 |
| **自定义响应标头** | `"Value": "/verify?ip=${awswaf:ip:}&rid=${awswaf:request_id:}"` — 带有请求上下文的动态重定向 |
### 解析行为
- **单个标签**:解析为最终值(例如 `scraping`)
- **多个标签**:逗号分隔的列表(例如 `non_browser_user_agent,automated_browser`)
- **无匹配**:空字符串
### 合成标签
从请求上下文中解析的内置值:`${awswaf:ip:}`、`${awswaf:request_id:}`、`${awswaf:ja3:}`、`${awswaf:ja4:}`。
## 演示用例
此 CDK 项目部署了一个包含 Bot Control V5(定向、计数模式)的 WAF WebACL,以及基于路径的规则来演示每种插值表面。Lambda Function URL 会将所有请求标头以 JSON 格式回显,以便您检查解析后的值。
| 优先级 | 规则 | 演示内容 |
| -------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| 50 | `challenge-root` | 在 `/` 上发起质询以生成 WAF token(启用指纹/token ID) |
| 100 | `bot-control` | Bot Control V5 在计数模式下定向 —— 为下游规则生成标签 |
| 150 | `classify-tier` | **自定义标签**:匹配 `x-api-key` 标头,并通过 `ruleLabels` 应用 `app:tier:enterprise` |
| 160 | `forward-tier` | **自定义标签插值**:将 `${app:tier:}` 解析到 `x-customer-tier` 标头中 |
| 300 | `block-with-custom-page` | **响应正文插值**:在拦截页面中使用 `${awswaf:ip:}` 和 `${awswaf:request_id:}` |
| 400 | `verify-redirect` | **响应标头插值**:在 302 `Location` 标头中使用 `${awswaf:ip:}` 和 `${awswaf:request_id:}` |
| 500 | `app-signalling` | **请求标头插值**:转发 6 个命名空间(类别、名称、信号、指纹、token ID、客户端 IP) |
| 700 | `cache-segmentation` | **请求标头 + CloudFront 缓存键**:`${awswaf:managed:aws:bot-control:bot:category:}` 驱动缓存分段 |
## 部署
```
cd demo
npm install
cdk bootstrap --region us-east-1 # if not already bootstrapped
cdk deploy
```
部署到 **us-east-1**(CloudFront 范围的 WAF 必需)。
## 测试
### 应用信令 (`/app-signalling/`)
```
curl -s https:///app-signalling/ | jq .wafHeaders
```
Bot Control 标签解析为以下标头:`x-waf-bot-category`、`x-waf-bot-name`、`x-waf-bot-signals`、`x-waf-fingerprint`、`x-waf-token-id`、`x-waf-client-ip`。
### 自定义标签(任何带有 `x-api-key` 标头的路径)
```
curl -s -H "x-api-key: pk_enterprise_12345" https:///app-signalling/ | jq .wafHeaders
```
`x-customer-tier` 解析为 `enterprise`。
### 自定义拦截页面 (`/block-page/`)
```
curl -v https:///block-page/
```
返回 403 以及包含插值后的 IP 和 WAF 请求 ID 的 HTML 正文。
### 验证重定向 (`/verify`)
```
curl -v https:///verify
```
返回 302 以及 `Location: /verify?ip=&rid=`。
### 缓存分段 (`/cache-segment/`)
```
curl -s https:///cache-segment/page | jq .wafHeaders
```
CloudFront 将解析后的 `x-waf-bot-category` 标头包含在缓存键中,从而根据机器人分类生成单独的缓存条目。
### 浏览器对比 curl
首先在浏览器中打开 `/` —— Challenge 规则会生成 WAF token cookie。后续请求将包含该 token,从而填充指纹和 token ID 标头。使用 curl 时,Bot Control 仍会生成 `bot:category` 标签,但依赖于 token 的值不会被填充。
## 清理
```
cdk destroy
```
## 安全
有关更多信息,请参阅 [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications)。
## 许可证
本库根据 MIT-0 许可证授权。请参阅 LICENSE 文件。
标签:AppImage, AWS, CDK, DPI, WAF, Web应用防火墙, 流量管控, 自动化攻击