📅 第14天 | AWS NACL — AWS 中的子网级安全 🔐
发布: (2025年12月13日 GMT+8 01:56)
4 min read
原文: Dev.to
Source: Dev.to
概览
- 子网级防火墙 – 关联到子网,而不是单个 EC2 实例。
- 无状态 – 入站和出站规则独立评估;必须显式允许返回流量。
- 支持 ALLOW 和 DENY 规则 – 规则顺序很重要(数字最小的规则先被评估)。
- 默认 NACL – 允许所有流量。
- 自定义 NACL – 除非显式允许,否则默认拒绝所有流量。
关键特性
| 功能 | 描述 |
|---|---|
| 防护层级 | 保护公共子网和私有子网(例如 Web 服务器、数据库、EKS 节点)。 |
| 无状态过滤 | 双向通信需要匹配的入站和出站规则。 |
| 规则类型 | 可以同时存在 ALLOW 和 DENY 条目。 |
| 规则优先级 | 按规则编号升序处理(例如 100 → 101 → 102…)。 |
| 默认行为 | 默认 NACL 允许所有流量;自定义 NACL 从拒绝全部开始。 |
NACL 工作原理
- 关联 – NACL 与一个或多个子网关联。
- 无状态特性 – 如果在某端口允许入站流量,还必须为响应流量创建相应的出站规则。
- 规则评估 – 第一个匹配流量的规则(按规则编号)决定动作。
- 默认 vs. 自定义 – 默认 NACL 允许所有流量;自定义 NACL 必须显式允许所需流量,未匹配的流量将被隐式拒绝。
示例场景
公共子网
| 资源 | 允许的流量 |
|---|---|
| EC2 Web 服务器 | HTTP (80)、HTTPS (443)、SSH (22) |
| 应用负载均衡器 (ALB) | 同上 |
私有子网
| 资源 | 允许的流量 |
|---|---|
| 应用服务器 | 向数据库的内部流量 (3306) |
| 数据库 | 接受来自应用子网的 3306 端口流量 |
| EKS 工作节点 | 子网内节点间通信 |
| 注意 | 无直接互联网访问;所有入站/出站流量均经过过滤。 |
与安全组的比较
| 方面 | 安全组 | NACL |
|---|---|---|
| 作用范围 | 实例级别 | 子网级别 |
| 有状态性 | 有状态(返回流量自动允许) | 无状态(返回流量必须显式允许) |
| 规则类型 | 仅 ALLOW | ALLOW 和 DENY |
| 管理方式 | 对实例特定规则更简洁 | 适用于高层次的子网控制 |
示例规则集
| 规则号 | 方向 | 协议 | 端口范围 | 源/目的地 | 动作 |
|---|---|---|---|---|---|
| 100 | 入站 | TCP | 80 | 0.0.0.0/0 | ALLOW |
| 110 | 入站 | TCP | 443 | 0.0.0.0/0 | ALLOW |
| 120 | 入站 | TCP | 22 | 0.0.0.0/0 | ALLOW |
| 1000 | 出站 | ALL | ALL | 0.0.0.0/0 | ALLOW |
| * | * | * | * | * | DENY (隐式) |
提示: 根据你的环境调整
vpc_id、CIDR 块和规则编号。
Terraform 示例
resource "aws_network_acl" "public_nacl" {
vpc_id = aws_vpc.main.id
tags = {
Name = "public-nacl"
}
}
resource "aws_network_acl_rule" "allow_http_in" {
network_acl_id = aws_network_acl.public_nacl.id
rule_number = 100
egress = false
protocol = "6" # TCP
rule_action = "allow"
cidr_block = "0.0.0.0/0"
from_port = 80
to_port = 80
}
resource "aws_network_acl_rule" "allow_https_in" {
network_acl_id = aws_network_acl.public_nacl.id
rule_number = 110
egress = false
protocol = "6"
rule_action = "allow"
cidr_block = "0.0.0.0/0"
from_port = 443
to_port = 443
}
resource "aws_network_acl_rule" "allow_ssh_in" {
network_acl_id = aws_network_acl.public_nacl.id
rule_number = 120
egress = false
protocol = "6"
rule_action = "allow"
cidr_block = "0.0.0.0/0"
from_port = 22
to_port = 22
}
resource "aws_network_acl_rule" "allow_all_out" {
network_acl_id = aws_network_acl.public_nacl.id
rule_number = 1000
egress = true
protocol = "-1" # all protocols
rule_action = "allow"
cidr_block = "0.0.0.0/0"
from_port = 0
to_port = 0
}
参考资料与进一步阅读
- GitHub 仓库:
- Dev.to 博客文章:
- LinkedIn 文章:
- 简历(Google Drive):(可选)