4. 安全组与网络 ACL 的纵深防御
在 AWS 的 VPC 网络隔离体系中,安全组(Security Group,SG)与网络 ACL(Network ACL,NACL)是两道作用层级不同、过滤机制也不同的防线。理解它们的关键,不是记住“一个在实例上、一个在子网上”,而是先分清有状态与无状态这两种过滤模型,再据此设计规则、排查误配置并建立审计方法。
一、有状态与无状态:两种过滤模型的本质差异
安全组是有状态的。当一条入站规则允许某个连接进入实例时,该连接的回程流量会被自动放行,无需再写一条出站规则。反过来,出站规则允许发起的连接,其响应流量也会自动返回。安全组只支持允许规则,不支持显式拒绝,默认拒绝所有未匹配流量。它绑定在弹性网卡(ENI)上,因此可以精确到单个实例或接口。
网络 ACL 是无状态的。它作用在子网边界,对每个数据包独立判断,不记忆连接状态。这意味着:如果允许 10.0.1.0/24 访问子网内实例的 443 端口,那么实例返回给 10.0.1.0/24 的响应流量,必须在出站规则中单独放行。NACL 同时支持允许和拒绝规则,按规则编号从小到大依次匹配,一旦命中即停止,因此规则顺序至关重要。默认 NACL 允许所有进出流量,而自定义 NACL 默认拒绝所有流量。
这两者的差异直接决定了规则设计思路:安全组关注“谁可以访问我”,NACL 关注“子网边界上哪些包可以通过”。
二、规则设计:从最小权限到可维护性
安全组规则设计应遵循最小权限原则。一个常见的生产实践是:Web 层安全组只允许来自 ALB 安全组的 443 端口,而不是写 0.0.0.0/0。AWS 支持在安全组规则中引用另一个安全组 ID 作为源,这样即使后端实例 IP 变化,规则依然有效,且天然形成层级引用关系。例如:
Web-SG 入站:TCP 443 ← ALB-SG
App-SG 入站:TCP 8080 ← Web-SG
DB-SG 入站:TCP 3306 ← App-SG
这种“安全组链”比按 CIDR 写死 IP 更安全、更易维护。出站规则同样应收紧,例如数据库安全组只允许出站到备份存储或监控端点,而不是默认全放行。
NACL 规则设计则要特别注意临时端口范围。客户端发起连接时,源端口通常是 1024–65535 之间的临时端口。如果 NACL 出站只允许 443,那么服务器返回给客户端的响应包(目标端口是客户端的临时端口)就会被拒绝。因此,NACL 出站规则通常需要放行 1024–65535 到 0.0.0.0/0,或者根据实际客户端范围精确限定。规则编号建议以 100、200、300 递增,预留插入空间;拒绝规则放在允许规则之前才能生效。
三、常见误配置与排障思路
实际运维中,以下几类误配置最为高频:
- NACL 只放行入站、忘记出站回程:表现为连接建立后立即超时或无法返回数据。排查时先看 NACL 出站是否覆盖临时端口范围。
- 安全组出站被收紧后未放行必要目标:例如实例需要访问 S3 网关端点或 NAT 网关,但出站规则未放行对应端口,导致软件更新、日志上传失败。
- NACL 规则顺序错误:把拒绝规则编号设得比允许规则大,导致拒绝规则永远不生效;或把宽泛允许规则放在前面,使后面的精细拒绝形同虚设。
- 安全组引用错误:跨 VPC 或跨账户引用安全组时,若未正确配置 VPC 对等连接或 RAM 共享,规则看似存在但实际不生效。
- 默认 NACL 与自定义 NACL 混用:新建子网若未关联自定义 NACL,会使用默认 NACL 的全放行规则,形成隐性敞口。
四、审计方法:让规则可查、可证、可收敛
审计的目标是回答三个问题:当前有哪些规则、这些规则是否必要、是否存在过度放行。可落地的做法包括:
- 定期导出规则清单:使用
aws ec2 describe-security-groups和aws ec2 describe-network-acls导出 JSON,转换为表格后逐条评审。重点关注 0.0.0.0/0 入站、0.0.0.0/0 出站、以及未使用的安全组。 - 启用 VPC Flow Logs:将日志发送到 CloudWatch Logs 或 S3,通过 Athena 查询被拒绝的流量,判断是误配置还是攻击探测。
- 使用 AWS Config 规则:例如
restricted-ssh、restricted-common-ports、vpc-sg-open-only-to-authorized-ports,自动检测并标记不合规的安全组。 - 建立规则变更审批:安全组和 NACL 的修改应纳入变更管理,结合 CloudTrail 记录
AuthorizeSecurityGroupIngress、CreateNetworkAclEntry等事件,追溯谁在何时放行了什么。 - 定期清理未使用规则:结合 Flow Logs 统计规则命中次数,对长期零命中的规则进行复核,确认是否可删除或收紧。
总结来说,安全组与 NACL 构成的是“实例级有状态过滤 + 子网级无状态过滤”的双层结构。安全组负责精细的、面向连接的最小权限控制;NACL 负责子网边界的粗粒度兜底和显式拒绝。只有同时理解有状态与无状态的差异,才能在设计时避免回程遗漏,在排障时快速定位过滤层,在审计时发现过度放行,让纵深防御真正生效。