4. 创建第一个Web ACL

Web ACL 是 AWS WAF 的核心容器,它决定了“哪些请求被检查、按什么顺序检查、不匹配时放行还是拦截”。本节以给一个公网 ALB 加防护为例,走完从创建到验证的完整闭环。示例中 ALB 的 ARN 为 arn:aws:elasticloadbalancing:ap-northeast-1:111122223333:loadbalancer/app/web-alb/50dc6c495c0c9188,Web ACL 名称 prod-web-acl,区域 ap-northeast-1,这些均为教学示例值,实际使用时替换为自己的资源标识。

先理解三个决定行为的关键点

默认动作(Default Action)是 Web ACL 的兜底策略:当请求没有命中任何一条规则,或命中的规则动作为 Allow/Count 时,最终由默认动作裁决。默认动作只有 Allow 和 Block 两种,没有 Count。因此“默认 Allow + 规则 Block 恶意流量”是白名单式放行思路,“默认 Block + 规则 Allow 可信流量”是更严格的零信任思路。生产环境通常先用默认 Allow,避免误拦正常用户。

规则优先级(Priority)是数字,越小越先评估,且同一 Web ACL 内不可重复。AWS WAF 按优先级从小到大逐条匹配,一旦某条规则命中且其动作为 Allow 或 Block,评估即终止并返回该结果;若动作为 Count,则只记录指标和日志,继续评估后续规则。这意味着“先放行可信 IP、再拦截恶意 IP”与“先拦截、再放行”会得到完全不同的结果,优先级顺序本身就是策略的一部分。

关联资源(Associated Resources)决定 Web ACL 生效范围。区域级 Web ACL 可关联同区域的 ALB、API Gateway REST API、AppSync、Cognito 用户池等;CloudFront 必须使用 us-east-1 的全局(CLOUDFRONT)作用域 Web ACL。一个 Web ACL 可关联多个资源,但一个资源同一时刻只能关联一个 Web ACL。

Web ACL 创建 → 优先级评估 → 关联 → 验证 创建方式 控制台 选资源类型 → 命名 → 默认动作 添加规则 → 设优先级 → 创建 CLI / API create-web-acl 提交 JSON 再 associate-web-acl 关联 规则优先级评估(数字小者先) Priority 0:Allow 可信办公 IP 命中 → 放行并终止评估 Priority 1:AWS 托管规则(Count) 仅记录,继续向下评估 Priority 2:Block 恶意 IP 集 命中 → 拦截并终止评估 Priority 3:限速规则 Rate-based 超阈值 → Block 未命中任何规则 → 执行默认动作(Allow / Block) 关联资源 ALB(区域级) ap-northeast-1 CloudFront(全局) 必须 us-east-1 作用域 API Gateway / AppSync 同区域关联 验证流程 Sampled requests 看命中规则与动作 CloudWatch 指标 Allowed / Blocked 计数 curl 实测 403 即被拦截

控制台创建:适合首次搭建与可视化核对

进入 WAF 控制台,选择 Create web ACL。第一步填写名称 prod-web-acl、描述、资源类型选 Regional resources(因为目标是 ALB),区域选 ap-northeast-1。第二步设置默认动作,示例选 Allow,即未命中规则的请求放行。第三步添加规则:先加一条 IP set 规则放行公司出口 IP,再加 AWS 托管规则组 AWSManagedRulesCommonRuleSet,最后加一条基于 IP 的 Block 规则。每条规则都要指定 Priority,控制台会按你添加的顺序给出默认值,但必须手动确认不重复。第四步选择要关联的 ALB,创建后立即生效。

CLI 创建:适合自动化与版本化

CLI 方式把 Web ACL 定义写成 JSON,便于纳入代码仓库。先创建 IP set,再创建 Web ACL,最后关联资源。以下命令为示例,需替换 ARN 与区域。

# 1. 创建放行用的 IP set(区域级)
aws wafv2 create-ip-set \
  --name allow-office-ips \
  --scope REGIONAL \
  --region ap-northeast-1 \
  --ip-address-version IPV4 \
  --addresses 203.0.113.0/24 198.51.100.7/32

# 2. 创建 Web ACL,默认动作 Allow
aws wafv2 create-web-acl \
  --name prod-web-acl \
  --scope REGIONAL \
  --region ap-northeast-1 \
  --default-action Allow={} \
  --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=prod-web-acl \
  --rules file://rules.json

# 3. 关联到 ALB
aws wafv2 associate-web-acl \
  --web-acl-arn arn:aws:wafv2:ap-northeast-1:111122223333:regional/webacl/prod-web-acl/xxxx \
  --resource-arn arn:aws:elasticloadbalancing:ap-northeast-1:111122223333:loadbalancer/app/web-alb/50dc6c495c0c9188 \
  --region ap-northeast-1

其中 rules.json 的关键结构如下,注意 Priority 与 Action 的对应关系:

{
  "Name": "allow-office",
  "Priority": 0,
  "Statement": {
    "IPSetReferenceStatement": {
      "ARN": "arn:aws:wafv2:ap-northeast-1:111122223333:regional/ipset/allow-office-ips/xxxx"
    }
  },
  "Action": { "Allow": {} },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "allow-office"
  }
}
CLI 创建时若忘记设置 SampledRequestsEnabled,后续在控制台看不到采样请求,排障会非常被动。建议所有规则都开启采样与 CloudWatch 指标。

优先级与默认动作的配合逻辑

把上面的规则按优先级串起来看:Priority 0 的 Allow 规则命中公司 IP 后直接放行,不再评估后续规则;Priority 1 的托管规则设为 Count,只记录不拦截,用于观察误报;Priority 2 的 Block 规则命中恶意 IP 集时拦截;Priority 3 的限速规则在 5 分钟内同一 IP 超过 2000 次请求时拦截。若请求全部未命中,则落到默认动作 Allow。这套组合的意图是“可信放行、可疑观察、恶意拦截、异常限速”,而不是简单地把所有规则都设成 Block。

关联资源与验证

关联完成后,验证分三层。第一层看 Sampled requests:在 Web ACL 详情页能看到最近请求的源 IP、URI、命中规则和最终动作,确认 Allow 规则是否真的命中了办公 IP。第二层看 CloudWatch 指标:AllowedRequests 与 BlockedRequests 应随流量变化,若 Blocked 突然飙升,说明规则可能误伤。第三层做 实测:用 curl 从非白名单 IP 访问,若返回 403 且采样中显示命中 Block 规则,说明拦截链路生效;从白名单 IP 访问应正常返回 200。

# 从非白名单环境测试,预期被拦截
curl -i https://demo.example.com/login
# HTTP/2 403  → 说明 Block 规则或默认动作生效

# 查看当前 Web ACL 关联了哪些资源
aws wafv2 list-resources-for-web-acl \
  --web-acl-arn arn:aws:wafv2:ap-northeast-1:111122223333:regional/webacl/prod-web-acl/xxxx \
  --region ap-northeast-1
修改规则后需要等待数十秒到数分钟才在全球边缘生效。验证时不要刚保存就立刻下结论,建议观察 1~2 分钟采样数据再判断。另外,删除 Web ACL 前必须先解除所有资源关联,否则 delete-web-acl 会报错。