Security Group 是有状态的,NACL 是无状态的 - 这一差异背后的设计决策
解析 Security Group 通过连接追踪实现有状态运作的机制、NACL 无状态的原因、临时端口的陷阱、两者组合的纵深防御设计模式。
有状态与无状态的区别
Security Group 是有状态防火墙。入站规则允许的请求的响应,无论出站规则如何都会自动允许。反之,出站规则允许的请求的响应,无论入站规则如何也会自动允许。NACL (Network Access Control List) 是无状态防火墙。入站和出站规则独立评估。即使是入站允许的请求的响应,如果出站规则未明确允许也会被阻止。这种差异源于实现层面的根本不同。Security Group 维护连接追踪 (Connection Tracking) 表,记录每个连接的状态 (源 IP、目标 IP、端口、协议)。响应数据包到达时与连接追踪表比对,属于已有连接的数据包自动允许。NACL 不持有连接追踪表,独立评估每个数据包。
为什么存在两种防火墙
看起来 Security Group 就够了,但 NACL 存在的原因是纵深防御 (Defense in Depth) 原则。Security Group 在实例级别 (ENI 级别) 运作,NACL 在子网级别运作。这两个层在不同级别提供防御。Security Group 被入侵时 (例如拥有 IAM 权限的攻击者修改了 Security Group 规则),NACL 作为备份发挥作用。NACL 应用于整个子网,即使个别实例的 Security Group 被修改,NACL 规则仍维持防御。另一个原因是需要明确的 Deny。Security Group 只能定义允许规则,不能定义拒绝规则。要明确阻止特定 IP 地址的访问,Security Group 无法实现。NACL 可以定义允许和拒绝规则,按规则编号顺序评估,因此可以明确阻止特定 IP 地址。
NACL 临时端口的陷阱
NACL 无状态导致的最常见配置错误是临时端口 (Ephemeral Port) 的允许遗漏。客户端连接服务器时,客户端的源端口使用操作系统动态分配的临时端口。Linux 为 32768~60999,Windows 为 49152~65535。即使 NACL 出站规则允许了 HTTP (端口 80),响应会返回到客户端的临时端口。如果 NACL 入站规则未允许临时端口范围,响应会被阻止。Security Group 不会出现这个问题。因为是有状态的,出站允许的请求的响应自动允许。使用 NACL 时,通常在入站和出站都允许临时端口范围 (1024~65535)。如果对这么宽的范围允许有顾虑,可以用 Security Group 进行细粒度控制,NACL 仅做子网级别的粗粒度控制。
Security Group 连接追踪的详细机制
Security Group 的连接追踪分为被追踪的连接和不被追踪的连接。当入站和出站都设置了允许所有流量 (0.0.0.0/0) 的规则时,不进行连接追踪。因为不需要追踪。此时没有连接追踪的开销,性能提升。连接追踪表有大小上限。默认每个 ENI 最多保持 65,535 个追踪连接。达到上限时无法建立新连接。处理大量短命连接的工作负载 (如负载均衡器后面的实例) 需要注意连接追踪表耗尽。可通过 CloudWatch 指标 ConnTrackAllowanceExceeded 监控连接追踪表耗尽。连接追踪的超时时间为 TCP 已建立连接 5 天、UDP 180 秒、ICMP 30 秒。超时的连接从表中删除。
实践性纵深防御设计模式
介绍 Security Group 和 NACL 组合的实践设计模式。公有子网的 ALB,Security Group 入站允许 HTTP/HTTPS (0.0.0.0/0),NACL 保持默认 (全部允许)。ALB 是公开服务,无需用 NACL 限制。私有子网的应用服务器,Security Group 入站仅允许来自 ALB 的 Security Group,NACL 入站仅允许 ALB 子网的 CIDR。Security Group 仅允许来自 ALB 的流量,NACL 在子网级别提供备份防御。数据库子网,Security Group 入站仅允许来自应用服务器的 Security Group,NACL 入站仅允许应用子网的 CIDR。检测到特定 IP 地址的攻击时,可用 NACL 的拒绝规则立即阻止。Security Group 的变更是逐实例的,但 NACL 的变更立即应用于整个子网,适合紧急响应。要系统学习网络安全设计,可参考相关专业书籍 (Amazon)。