介绍
一个 Web 应用需要阻止内部导出路径,同时保持健康检查可用。你将附加路径规则,测试请求能否到达后端,并在清理前更新规则。
请先完成 在 LabEx 上开始学习 AWS 和 为报告读取者授予最小权限。本实验的全新 VM 提供应用和独立的 REST API 阶段,不需要之前的 API 或网络资源。
相关认证考点
本实验为以下认证考点提供动手练习。
- Cloud Practitioner (CLF-C02) · 任务 2.4: WAF Web ACL 关联与请求过滤规则。
- Solutions Architect – Associate (SAA-C03) · 任务 1.2: WAF Web ACL 关联与请求过滤规则。
- Security – Specialty (SCS-C03) · 任务 3.1: 基础练习:WAF Web ACL 关联与请求过滤规则。
- Solutions Architect – Professional (SAP-C02) · 任务 2.3: 基础练习:WAF Web ACL 关联与请求过滤规则。
创建 Regional Web ACL
本步骤中,你将在 Web 访问控制列表(Web ACL) 内定义 AWS WAF 请求规则。WAF 会在请求到达应用之前检查请求。提供的 REST API 有一个命名阶段,可以关联 Regional Web ACL;这个入口不同于 API/Cognito 课程中使用的 HTTP API。
在 Terminal 旁打开 AWS View,对比规则、阶段关联和每个请求是否到达后端。保留无关的参考 Web ACL 和阶段。
规则由匹配条件和操作组成。当没有规则匹配时,会应用默认操作。我们将阻止 /internal/,并允许其他路径。
进入项目目录,确认准备好的操作员身份。提供的 stage-arn.txt 包含应用阶段 ARN,不是凭证。命令替换会保存该值,供稍后关联时使用。
cd /home/labex/project
aws sts get-caller-identity --query Arn --output text
STAGE_ARN=$(cat stage-arn.txt)
预期看到 labex-sec05-operator。在关联任何 Web ACL 之前,模拟的内部导出请求会到达后端。curl 发出实际 HTTP 请求;-sS 隐藏进度输出但保留连接错误,-w 打印响应状态。
curl -sS -w '\nHTTP %{http_code}\n' http://127.0.0.1:8090/internal/export
预期看到 HTTP 200 和模拟的后端响应。使用带引号的 here-document 写入规则文件:<<'EOF' 和 EOF 之间的行会原样写入 JSON 文件。UriPath 选择路径,STARTS_WITH 匹配前缀,NONE 表示不进行转换。数字较小的优先级先执行;此 ACL 只有一条优先级为零的规则。可见性设置关闭可选的请求采样和指标,以便专注于本练习。将相同设置保存到 visibility.json,供 ACL 本身及后续更新使用。
cat > rules-internal.json <<'EOF'
[{
"Name": "block-private-export",
"Priority": 0,
"Action": {"Block": {}},
"Statement": {"ByteMatchStatement": {
"SearchString": "/internal/",
"FieldToMatch": {"UriPath": {}},
"PositionalConstraint": "STARTS_WITH",
"TextTransformations": [{"Priority": 0, "Type": "NONE"}]
}},
"VisibilityConfig": {"SampledRequestsEnabled": false, "CloudWatchMetricsEnabled": false, "MetricName": "labex-sec05-owned-export"}
}]
EOF
创建默认操作为 Allow 的 Regional ACL。--cli-binary-format raw-in-base64-out 告诉 AWS CLI v2 将 SearchString 解释为字面输入字节,而不是要求 base64 字符串。file:// 加载规则文档;--query 只选择生成的 ACL ID。
cat > visibility.json <<'EOF'
{
"SampledRequestsEnabled": false,
"CloudWatchMetricsEnabled": false,
"MetricName": "labex-sec05-owned-export"
}
EOF
ACL_ID=$(aws wafv2 create-web-acl \
--name labex-sec05-owned-export \
--scope REGIONAL \
--default-action Allow={} \
--visibility-config file://visibility.json \
--rules file://rules-internal.json \
--cli-binary-format raw-in-base64-out \
--query Summary.Id \
--output text)
ACL_ARN=$(aws wafv2 get-web-acl \
--name labex-sec05-owned-export \
--scope REGIONAL \
--id "$ACL_ID" \
--query WebACL.ARN \
--output text)
aws wafv2 get-web-acl \
--name labex-sec05-owned-export \
--scope REGIONAL \
--id "$ACL_ID" \
--query 'WebACL.{Name:Name,Default:DefaultAction,Rules:Rules[].Name}'
预期看到你创建的 ACL、默认操作 Allow 和 block-private-export。创建策略不会将它附加到端点。AWS View 此时应仍显示没有目标关联。
关联 ACL 并测试实际请求
本步骤中,你将把策略连接到提供的 REST API 阶段,并对比公开请求与匹配规则的导出请求。阶段标识已部署的 API 环境;关联会将 ACL 应用于该阶段的请求。

关联的 Web ACL 会在内部路径请求到达后端之前拒绝它。
只将你的 ACL 关联到提供的目标 ARN。无关的参考阶段已经有自己的参考 ACL;不要替换它。
aws wafv2 associate-web-acl --web-acl-arn "$ACL_ARN" --resource-arn "$STAGE_ARN"
aws wafv2 get-web-acl-for-resource \
--resource-arn "$STAGE_ARN" \
--query WebACL.Name \
--output text
预期看到 labex-sec05-owned-export。先测试不匹配 /internal/ 的公开健康检查路径,再测试内部导出路径。
curl -sS -w '\nHTTP %{http_code}\n' http://127.0.0.1:8090/health
curl -sS -w '\nHTTP %{http_code}\n' http://127.0.0.1:8090/internal/export
预期健康检查返回 HTTP 200,导出请求返回 HTTP 403 并包含 block-private-export。Block 决定会在后端执行前返回响应。AWS View 必须将健康检查请求显示为 Executed,将被阻止的请求显示为 Not reached。仅有原生关联还不够;这些实际 HTTP 结果才能证明规则生效。

更新规则并观察实时行为
本步骤中,你将把保护范围移到 admin 前缀,并在不重启应用的情况下观察行为变化。更新 Web ACL 会替换规则列表。它的锁定令牌(lock token)用于防止覆盖并发更改;在更新前立即从当前原生配置中获取它,并保存在变量中。
替换之前文件中的 URI 前缀,创建新规则文档。sed 转换文本,> 写入新文件,同时保留原始规则文档。
sed 's|/internal/|/admin/|' rules-internal.json > rules-admin.json
LOCK_TOKEN=$(aws wafv2 get-web-acl \
--name labex-sec05-owned-export \
--scope REGIONAL \
--id "$ACL_ID" \
--query LockToken \
--output text)
aws wafv2 update-web-acl \
--name labex-sec05-owned-export \
--scope REGIONAL \
--id "$ACL_ID" \
--lock-token "$LOCK_TOKEN" \
--default-action Allow={} \
--visibility-config file://visibility.json \
--rules file://rules-admin.json \
--cli-binary-format raw-in-base64-out \
--query NextLockToken \
--output text
返回的锁定令牌标识新的 ACL 修订版本;它不是身份验证凭证。现在,原先的 internal 前缀应通过默认 Allow 操作,而 admin 导出请求应被阻止。
curl -sS -w '\nHTTP %{http_code}\n' http://127.0.0.1:8090/internal/export
curl -sS -w '\nHTTP %{http_code}\n' http://127.0.0.1:8090/admin/export
预期依次看到 HTTP 200 和 HTTP 403。AWS View 应显示新的 /admin/ 前缀、之前被阻止的 internal 请求,以及当前允许的 internal 请求和被阻止的 admin 请求。请求使用当前原生规则;无需重启 VM 或应用。在这个针对特定功能的环境中,不支持的策略类型会拒绝请求,因此只使用这里教授的语句。

解除关联并只删除自己创建的 ACL
本步骤中,你将移除策略,并确认应用恢复普通路由。先完成前面的功能检查。解除关联会移除该阶段上的规则执行;随后删除 ACL 会移除你创建的策略资源。
从目标阶段解除你的 Web ACL 关联,并通过成功的原生查询检查关联情况。预期关联为空,而不是把身份验证错误当作删除证据。
aws wafv2 disassociate-web-acl --resource-arn "$STAGE_ARN"
aws wafv2 get-web-acl-for-resource --resource-arn "$STAGE_ARN" --query WebACL
之前被阻止的 admin 导出请求现在应再次到达提供的后端。
curl -sS -w '\nHTTP %{http_code}\n' http://127.0.0.1:8090/admin/export
预期看到 HTTP 200。获取当前锁定令牌,只删除你创建的 ACL,然后成功列出剩余 ACL。你创建的名称必须不存在,而 labex-sec05-reference 必须保留。
LOCK_TOKEN=$(aws wafv2 get-web-acl \
--name labex-sec05-owned-export \
--scope REGIONAL \
--id "$ACL_ID" \
--query LockToken \
--output text)
aws wafv2 delete-web-acl \
--name labex-sec05-owned-export \
--scope REGIONAL \
--id "$ACL_ID" \
--lock-token "$LOCK_TOKEN"
aws wafv2 list-web-acls --scope REGIONAL --query 'WebACLs[].Name'
完整保留两个提供的 API 阶段和参考 ACL。移除本地规则与可见性文档,然后在移除临时 CLI 配置档之前运行本步骤的验证。
rm -f rules-internal.json rules-admin.json visibility.json
rm -f /home/labex/.aws/credentials /home/labex/.aws/config
unset STAGE_ARN ACL_ID ACL_ARN LOCK_TOKEN
总结
你创建了 Regional Web ACL,将它关联到 REST API 阶段,并测试了实际 HTTP 请求的允许和阻止行为。匹配规则的请求在到达后端之前被阻止,而健康检查请求继续正常运行。更新 URI 前缀改变了实时路由;解除关联后端点恢复访问。你只删除自己创建的 ACL,并保留提供的阶段和参考策略。



