出方向明明开了,为什么还是不通
一句话总结
安全组会记住状态(stateful),而 NACL 不会记住状态(stateless)。 其余所有差异都源于这一点。
为什么需要了解这一点
如果只在安全组中开放入站 80 端口,响应会自动发出。因为安全组会记住 请求曾经进入,并自动允许该请求的响应通过。
NACL 则不同。它不会记住进入的流量,所以响应的出站流量也必须 另行允许。而且响应会通过临时端口(1024~65535)发出,因此必须在 出站规则中开放这个范围。
如果不了解这一点,就可能花上几个小时排查“入站已经开放,为什么收不到响应”。
并排比较
| 安全组 | 网络 ACL | |
|---|---|---|
| 作用对象 | 实例(ENI) | 整个子网 |
| 状态 | 保存 — 自动允许响应 | 不保存 — 两个方向都需分别设置 |
| 规则 | 仅允许 | 允许 + 拒绝 |
| 评估方式 | 查看所有规则,只要有一条允许即可通过 | 按编号顺序,采用第一条匹配规则 |
| 默认值 | 阻止全部入站,允许全部出站 | 默认全部允许 |
| 数量 | 每个实例可应用多个 | 每个子网一个 |
NACL 顺序规则造成的陷阱
번호 타입 동작
100 전체 ALLOW
200 TCP 22 DENY ← 절대 적용되지 않는다
因为编号 100 的规则已经允许并结束了评估,所以永远不会查看编号 200 的规则。 它不像安全组那样“拒绝优先”。规则会从较小的编号开始,在第一条匹配 规则处结束。
因此,NACL 规则编号通常按 100、200、300 这样留出间隔来设置,以便日后 在它们之间插入新规则。
安全组的强大功能——组引用
可以在安全组规则的来源中指定另一个安全组。
DB 보안그룹 인바운드:
5432 ← sg-app (앱 서버 보안그룹)
关键在于这里没有使用 IP。无论应用服务器有多少台,是否因自动扩缩容而 增减,或 IP 是否发生变化,都不需要修改规则。这是按角色编写规则, 也是云环境中最实用的模式之一。
如何分工使用
实际工作中通常会这样安排。
- 以安全组为主。它粒度细、支持组引用,也更不容易出错。
- NACL 仅用作覆盖整个子网的宽泛护栏。例如:阻止特定恶意 IP 网段,或彻底封锁数据子网向互联网发出的流量。
如果试图用 NACL 进行精细控制,很快就会因临时端口和顺序规则而陷入混乱。
五种常见错误
- 向
0.0.0.0/0开放 22 端口(SSH)——扫描器几分钟内就能发现。 - 完全开放出站——遭到入侵后会成为数据外泄通道。
- 没有在 NACL 中开放临时端口出站,导致响应被阻止。
- 把 NACL 规则编号连续设为 1、2、3,日后没有位置可插入新规则。
- 不写安全组说明(description),六个月后无人知道规则存在的原因。
第 5 点带来的麻烦出人意料地大。因为无法判断能否删除,规则会不断累积。
实际工作中的表现
- 入站正常但收不到响应 → 检查 NACL 出站临时端口。
- 自动扩缩容后无法连接 DB → 规则使用了 IP,应改用组引用。
- 安全组增加到 40 个 → 缺少整理标准,应强制填写说明。
如何防止规则不断增加
前面举了安全组增加到 40 个的例子。这不是懒惰造成的,而是结构上没有留下删除依据的问题。只要一开始规定好几条规则,就不会走到这种状态。
用格式强制约束名称和说明。 如果从名称就能读出它属于哪个服务的哪种角色,并且每条规则的说明都写明开放原因和需要保留到何时,六个月后仍然可以判断是否删除。说明为空时,最好在检查阶段就阻止创建。
按角色编写,不按地址编写。 使用组引用后,规则数量便与资源数量无关。相反,一旦开始使用 IP,服务器每增加一台,规则就会增加;服务器消失后,规则却会留下。如果某天该地址由其他人使用,还会意外开放访问权限,这也是 IP 规则的风险。
为临时开放项注明到期时间。 为了调查问题而短暂开放权限的情况总会发生。只要规定在说明中写上日期,日后就可以用机器筛选出已经过期的规则。
定期检查是否真的在使用。 启用流日志后,可以知道实际流量曾通过哪些规则。几个月内一次都没用过的允许规则,就是删除候选项。
而且,不手动修改规则是这一切的前提。在控制台中匆忙开放的规则不在代码里,可能在下一次部署时消失,也可能反过来与代码不一致而继续存在。无论哪一种,最终都会导致后来无人能够回答“这条规则为什么在这里”。
接下来要了解什么
私有资源访问外部的三条路径,以及各自的代价。