Networking 6 min read
NACLs
What Problem It Solves
Security Groups protect individual resources, but sometimes you need a blanket rule at the subnet boundary itself — e.g. explicitly blocking a known-bad IP range for every resource in a subnet, regardless of its security group. A Network ACL (NACL) solves this: it’s a stateless firewall attached to a subnet that evaluates numbered rules in order, and unlike security groups, it supports explicit deny rules.
Global | Regional | AZ Scope
- A NACL is created inside a VPC (regional) but is associated with one or more subnets — its actual effect is at the subnet (AZ) level.
- Every subnet is associated with exactly one NACL at a time; a NACL can be associated with multiple subnets.
- Every VPC has a default NACL that allows all inbound and outbound traffic, associated automatically with any subnet you don’t explicitly assign elsewhere.
graph TD
Internet(("Internet")) --> NACL["NACL: rule 100 allow 443, rule 200 deny 1.2.3.0/24, * deny all"]
NACL --> SG["Security Group (stateful, allow-only)"]
SG --> EC2["EC2 Instance"]
classDef nacl fill:#fde8e8,stroke:#dc2626,stroke-width:3px,color:#7f1d1d
Cost
NACLs are free — no charge for creating them, associating them with subnets, or the number of rules within default quotas.
Exam Tips
- NACLs are stateless: if you allow inbound port 443, you must also explicitly allow the outbound ephemeral port range (typically 1024–65535) for return traffic — nothing is automatic, unlike Security Groups.
- Rules are evaluated in numbered order, lowest number first, and processing stops at the first match — order matters, unlike Security Groups where all rules are combined.
- NACLs support explicit allow and explicit deny rules — the only mechanism in a VPC that can outright block specific traffic (e.g. a known-malicious CIDR) regardless of security group settings.
- The default (implicit) final rule on every NACL is
* deny all— anything not matched by an earlier rule is dropped. - Typical exam pairing: use a Security Group for normal application-level access control, and reach for a NACL only when you need a coarse, subnet-wide explicit block.