简介
一个公网配送应用已经具备互联网路由、公网地址和 HTTP 安全组授权,但客户端 A 仍然无法读取它。子网的网络 ACL 允许请求的目的端口,却阻断客户端的返回端口。你将诊断并修复这条路径,观察规则优先级,最后恢复预置的初始配置。
请先完成 Connect Privately to S3 with a VPC Endpoint。本次全新环境独立提供应用、公有和私有子网、公网路由、地址、安全组及自定义 ACL,CLI 也已配置。保留这些资源和参考网络。只修改本实验讲解的自定义 ACL 规则,并在清理时删除临时拒绝规则。最终基线会有意重现初始故障,不会删除预置应用。
认证关联
本实验为以下考试主题提供基础练习。
- Cloud Practitioner (CLF-C02) · 任务 3.5:VPC 安全组与网络 ACL 的基本作用。
- Solutions Architect – Associate (SAA-C03) · 任务 1.2:基本子网安全控制与应用访问条件。
- CloudOps Engineer – Associate (SOA-C03) · 任务 5.3:通过 ACL 规则和响应端口诊断应用连接。
- Advanced Networking – Specialty (ANS-C01) · 任务 3.1:维护有序子网规则并检查真实返回路径的基础练习。
检查应用的子网边界
本步骤先定位应用,对比其路由、安全组和网络 ACL,再进行修改。
使用 Terminal,并在旁边打开 AWS View。公网应用的私有地址为 10.20.1.10;客户端 A 为 198.51.100.10,客户端 B 为 198.51.100.20。预置安全组只允许客户端 A 访问 TCP 80,未授权端口 8081。
cd /home/labex/project
根据 Name 标签选择 VPC。过滤器选择资源,query 提取 ID,$(...) 将结果保存供后续命令使用:
VPC_ID=$(aws ec2 describe-vpcs \
--filters Name=tag:Name,Values=application-network \
--query 'Vpcs[0].VpcId' \
--output text)
保存公网应用子网及其预置网卡的 ID:
SUBNET_ID=$(aws ec2 describe-subnets \
--filters "Name=vpc-id,Values=$VPC_ID" Name=tag:Name,Values=public-subnet \
--query 'Subnets[0].SubnetId' \
--output text)
ENI_ID=$(aws ec2 describe-network-interfaces \
--filters "Name=subnet-id,Values=$SUBNET_ID" \
--query 'NetworkInterfaces[0].NetworkInterfaceId' \
--output text)
读取私有地址、公网地址关联和已附加安全组:
aws ec2 describe-network-interfaces \
--network-interface-ids "$ENI_ID" \
--query 'NetworkInterfaces[].{Private:PrivateIpAddress,Public:Association.PublicIp,Groups:Groups}' \
--output json
读取与该子网关联的路由表:
aws ec2 describe-route-tables \
--filters "Name=association.subnet-id,Values=$SUBNET_ID" \
--query 'RouteTables[].{Routes:Routes,Associations:Associations}' \
--output json
公网地址已关联,活动的 0.0.0.0/0 路由指向互联网网关。保存并读取预置安全组:
GROUP_ID=$(aws ec2 describe-security-groups \
--filters "Name=vpc-id,Values=$VPC_ID" Name=group-name,Values=supplied-application \
--query 'SecurityGroups[0].GroupId' \
--output text)
aws ec2 describe-security-groups \
--group-ids "$GROUP_ID" \
--query 'SecurityGroups[].{Inbound:IpPermissions,Outbound:IpPermissionsEgress}' \
--output json
入站授权为来自 198.51.100.10/32 的 TCP 80,并具有预置的默认出站授权。保留这些规则。
网络 ACL 控制跨越子网边界的流量。每个子网只有一个 ACL,一个 ACL 可以服务多个子网。与有状态安全组不同,ACL 是无状态的:允许请求不会自动允许响应。选择与应用子网关联的 ACL:
ACL_ID=$(aws ec2 describe-network-acls \
--filters "Name=association.subnet-id,Values=$SUBNET_ID" \
--query 'NetworkAcls[0].NetworkAclId' \
--output text)
读取其身份、关联及独立的入站和出站条目:
aws ec2 describe-network-acls \
--network-acl-ids "$ACL_ID" \
--query 'NetworkAcls[].{ID:NetworkAclId,Default:IsDefault,Associations:Associations,Entries:Entries}' \
--output json
这是自定义 application-acl,不是默认 ACL。两个方向的规则 100 都允许客户端 A 的 TCP 目的端口 80。Egress: false 表示入站,true 表示出站;协议 6 是 TCP。未匹配流量最终被拒绝,该规则在 AWS View 中显示为 *,在 CLI 中显示为 32767。
在 AWS View 点击 Request application · client A:即使公网路由和安全组授权存在,结果仍为 Connection failed。Request application · client B 和 Request port 8081 也失败。保持此 Terminal 打开,以保留已保存的 ID。
修复客户端返回端口规则
本步骤替换错误的出站端口匹配,同时保留严格的客户端地址范围。
HTTP 请求从客户端选择的临时端口发往服务器端口 80;响应从服务器端口 80 发往该客户端端口。网络 ACL 在每个方向匹配数据包的目的端口,出站目的端口 80 规则不能放行这种响应。
临时端口范围由发起连接的客户端决定。本练习只向客户端 A 198.51.100.10/32 放行常见客户端范围 1024–65535;不要把它当作所有操作系统统一的默认值。替换现有出站规则 100;--egress 选择出站方向,--port-range 指定目的端口范围:
aws ec2 replace-network-acl-entry \
--network-acl-id "$ACL_ID" \
--rule-number 100 \
--protocol 6 \
--rule-action allow \
--egress \
--cidr-block 198.51.100.10/32 \
--port-range From=1024,To=65535
替换成功时没有输出。读取条目:
aws ec2 describe-network-acls \
--network-acl-ids "$ACL_ID" \
--query 'NetworkAcls[].Entries' \
--output json
入站规则 100 仍允许来自客户端 A 的 TCP 80。出站规则 100 现在允许发往同一客户端的目的端口 1024–65535。默认拒绝规则和子网关联保持原样。
在 AWS View 再次点击 Request application · client A。新请求成功返回 Application online,源地址为 198.51.100.10,目的端口为 80。Request application · client B 和 Request port 8081 仍失败。请求与响应现在都能跨越 ACL;此次修复没有扩大入站安全组或子网 ACL 对其他客户端的授权。

示例:入站规则 100 允许客户端 A 的 TCP 80,出站规则 100 允许发往该客户端响应目的端口 1024–65535。两个方向均显示末尾默认拒绝,真实请求返回 Application online。你的环境中的资源 ID 可能不同。
观察较小编号的拒绝规则
本步骤有意在入站允许规则前插入匹配的拒绝规则,观察规则顺序如何影响访问。
每个方向的网络 ACL 规则都从最小编号开始评估。第一个匹配规则决定结果,后续规则不再评估。添加临时入站规则 90,拒绝客户端 A 的 TCP 80。--ingress 明确选择入站方向;创建规则 90 不会覆盖规则 100:
aws ec2 create-network-acl-entry \
--network-acl-id "$ACL_ID" \
--rule-number 90 \
--protocol 6 \
--rule-action deny \
--ingress \
--cidr-block 198.51.100.10/32 \
--port-range From=80,To=80
读取条目:
aws ec2 describe-network-acls \
--network-acl-ids "$ACL_ID" \
--query 'NetworkAcls[].Entries' \
--output json
入站拒绝 90 在入站允许 100 之前匹配。出站 100 仍放行客户端返回端口,安全组也仍允许客户端 A 的 HTTP。两者都不能覆盖更早匹配的 ACL 拒绝。
AWS View 显示入站规则 90 后,点击 Request application · client A,新请求会失败。客户端 B 和端口 8081 仍被阻断。先前成功的响应只是历史结果,修改规则后必须重新请求。保留规则 90 以完成本步骤检查,再在下一步删除它。
删除临时拒绝并重新检查访问
本步骤只删除较早的拒绝规则,验证修复后的返回路径仍然有效。
删除入站规则 90。方向很重要,因为入站和出站规则编号彼此独立:
aws ec2 delete-network-acl-entry --network-acl-id "$ACL_ID" --rule-number 90 --ingress
再次读取条目:
aws ec2 describe-network-acls \
--network-acl-ids "$ACL_ID" \
--query 'NetworkAcls[].Entries' \
--output json
规则 90 已不存在。入站 100 允许客户端 A 的 TCP 80,出站 100 允许客户端返回端口,未匹配流量仍被拒绝。保持 ACL 与原子网的关联,保留安全组、公网路由和地址。
在 AWS View 发起新的 Request application · client A,会成功返回 Application online。Request application · client B 和 Request port 8081 仍失败。有状态安全组允许已放行请求的响应,但无状态子网 ACL 仍需要两个方向的授权;删除较早拒绝规则后,这个独立边界恢复通行。
恢复预置的初始 ACL 配置
本步骤撤销返回端口修改,确认没有临时拒绝规则,保留所有预置资源。
将出站规则 100 恢复为预置的目的端口 80。该清理有意恢复初始故障,这不是 HTTP 响应路径正常工作时推荐使用的规则:
aws ec2 replace-network-acl-entry \
--network-acl-id "$ACL_ID" \
--rule-number 100 \
--protocol 6 \
--rule-action allow \
--egress \
--cidr-block 198.51.100.10/32 \
--port-range From=80,To=80
读取该 VPC 完整 ACL 清单及关联。不要仅凭可删除的标签证明清理完成:
aws ec2 describe-network-acls \
--filters "Name=vpc-id,Values=$VPC_ID" \
--query 'NetworkAcls[].{ID:NetworkAclId,Default:IsDefault,Associations:Associations,Entries:Entries}' \
--output json
临时规则 90 必须不存在。预置自定义 ACL 仍属于公网应用子网。两个方向的规则 100 都匹配客户端 A 的 TCP 目的端口 80,末尾拒绝规则完整保留。私有子网仍使用默认 ACL。不要删除或替换预置 ACL、子网、应用、安全组、网关或公网地址。
读取原安全组,确认规则已保留:
aws ec2 describe-security-groups \
--group-ids "$GROUP_ID" \
--query 'SecurityGroups[].{Inbound:IpPermissions,Outbound:IpPermissionsEgress}' \
--output json
在 AWS View 发起新的 Request application · client A,它会因返回端口不再被放行而再次失败。客户端 B 和端口 8081 仍被阻断。API 失败或应用网络不可用不能证明清理成功;认证后的资源清单查询必须成功,实际配置的路径也必须产生上述结果。
运行本步骤的完成检查。
总结
你定位了公网应用的子网 ACL,并诊断出缺失的响应端口范围。替换出站规则后,客户端 A 恢复真实 HTTP 访问,其他来源和端口仍被阻断。较小编号的入站拒绝随后展示了首次匹配的规则顺序;删除该规则后访问恢复。
你保留了预置安全组、路由、地址和子网关联,删除了临时拒绝,并恢复原始 ACL 基线。



