VPCSecurityNetworking

AWS Network ACLs: Subnet-Level Access Control for Defense in Depth

Vigilare Engineering

Platform Team · December 22, 2025 · 7 min read

Network Access Control Lists (NACLs) are AWS's subnet-level firewall. They operate differently from security groups in two important ways: they're stateless (return traffic must be explicitly allowed), and they support both allow and deny rules (security groups support only allow rules). These differences make NACLs suited for specific use cases that security groups don't handle well, but unsuitable as the primary access control mechanism for most traffic patterns.

Understanding when NACLs add genuine security value versus when they add complexity without benefit guides their appropriate use.

NACLs vs. Security Groups: Key Differences

Scope: Security groups apply to individual network interfaces; NACLs apply to all traffic entering or leaving a subnet. A NACL change affects every resource in the subnet simultaneously. A security group change affects only resources with that group attached.

Statefulness: Security groups are stateful — return traffic for an established connection is automatically permitted. NACLs are stateless — both the inbound request and the outbound response must be explicitly allowed. For TCP connections, the response typically uses an ephemeral port (1024-65535), so NACL outbound rules usually need to allow the entire ephemeral port range to permit response traffic.

Rule evaluation: Security groups evaluate all rules and allow if any rule matches. NACLs evaluate rules in order by rule number and stop at the first match. Rule ordering matters in NACLs — a deny rule at rule 100 blocks traffic even if an allow rule exists at rule 200 for the same source.

Allow vs. deny: Security groups can only allow traffic. NACLs can both allow and deny, enabling explicit blocking of specific source IPs or ranges.

When NACLs Add Value

Blocking specific IP addresses: If you identify an IP address actively attacking your infrastructure and want to block it network-wide across an entire subnet, a NACL deny rule is the right tool. Security groups can't block specific IPs (they only allow) — you'd need to add an allow rule for everything except the blocked IP, which is unwieldy. A NACL deny at rule 10 (before any allow rules) cleanly blocks the IP for all resources in the subnet.

Compliance-required subnet isolation: Some compliance frameworks require subnet-level controls independent of host-level controls. A NACL that restricts traffic between subnets satisfies a "network segmentation verified at subnet boundary" requirement even if security group rules provide the same restriction. The NACL serves as documented evidence of the network-level control.

Protection against security group misconfiguration: A NACL that denies direct SSH and RDP access from the internet to a private subnet provides a backstop against security group rules that accidentally open those ports. Even if a developer adds a dangerously permissive security group rule, the NACL blocks the traffic. This defense-in-depth approach is valuable for subnets containing sensitive infrastructure.

Default NACL and Rule Design

Every VPC has a default NACL that allows all inbound and outbound traffic. Custom NACLs have no rules by default (everything is denied) until you add allow rules. Most organizations use the default NACL for most subnets and add custom NACLs only for subnets with specific isolation requirements.

When creating custom NACLs for private subnets, the standard rule set:

  • Inbound rule 100: allow TCP 1024-65535 from 0.0.0.0/0 (response traffic to outbound connections)
  • Inbound rule 110: allow specific application ports from specific source CIDRs (e.g., port 5432 from your application subnet CIDR)
  • Inbound rule 200: deny port 22 from 0.0.0.0/0 (explicit block)
  • Inbound rule 32766: deny all (implicit deny, or explicit final deny)

The ephemeral port allowance in rule 100 is necessary for all outbound connections from the subnet to receive responses. Without this rule, all outbound connections from the subnet fail — instances can initiate connections but can't receive the response packets. This is the most common NACL misconfiguration.

NACLs in Multi-Tier Architectures

In a typical three-tier architecture (public subnet for load balancers, private subnet for application servers, isolated subnet for databases), NACLs at each subnet boundary can enforce the tier isolation:

Database subnet NACL: allow inbound only on the database port (5432, 3306, etc.) from the application subnet CIDR. Deny all other inbound traffic. Allow outbound response traffic (ephemeral ports) to the application subnet. This means that even if a security group on the database is misconfigured to allow connections from outside the application tier, the NACL blocks it.

Application subnet NACL: allow inbound on the application port from the public subnet CIDR. Allow outbound to the database subnet on the database port. Allow outbound HTTPS to 0.0.0.0/0 for external API calls and package downloads. This pattern creates clear documentation of the intended traffic flows between tiers.

Related Reading

FAQ

Should I use NACLs or security groups as my primary access control?

Security groups should be your primary access control mechanism. They're easier to maintain (stateful, so no ephemeral port management), apply per-resource rather than per-subnet, and support security group ID references that make rules self-documenting. Use NACLs as a supplemental layer for specific cases: IP blocking, compliance requirements for subnet-level controls, and defense-in-depth backstops for sensitive subnets.

Can a NACL block traffic that a security group allows?

Yes. NACLs are evaluated before security groups for inbound traffic and after security groups for outbound traffic. If a NACL denies inbound traffic, it never reaches the security group evaluation. A NACL deny overrides a security group allow for the same traffic. This is why using NACLs as a backstop for critical subnets works — the NACL block takes effect even if a security group misconfiguration would otherwise allow the traffic.

Do NACLs apply to traffic between instances in the same subnet?

No. NACLs evaluate traffic entering and leaving the subnet, not traffic that stays within the subnet. Two instances in the same subnet communicating with each other don't traverse the subnet boundary, so NACLs don't evaluate their traffic. Security groups do apply to this intra-subnet traffic — and by default, security groups only allow traffic explicitly permitted, so intra-subnet traffic between instances with different security groups is still controlled by those groups.

Protect your AWS accounts before it's too late

Vigilare monitors your AWS accounts for suspension risks — billing anomalies, IAM issues, GuardDuty findings, and more — and alerts you before AWS takes action.

Written by Vigilare Engineering

Platform Team