Back to posts
May 23, 2026
6 min read

AWS Network ACL: The Stateless “Fence” Protecting Your Subnet

You’re running an e-commerce system on AWS. Your DevOps team discovers a suspicious IP from overseas continuously scanning ports on EC2 instances in your private subnet. Security Groups have already blocked unnecessary ports — but you want to completely block that IP, preventing it from reaching any instance in the subnet.

The problem: Security Groups only have Allow rules, no Deny. You simply cannot write a rule that says “block IP 1.2.3.4”.

This is where NACL (Network Access Control List) comes in. NACL lets you write Deny rules to stop traffic right at the subnet gateway — before it ever reaches any instance inside.

This post will explain what NACL is, how it differs from Security Groups, and a critical concept that many newcomers overlook: Ephemeral Ports.


1. What is NACL?

NACL (Network Access Control List) is a virtual firewall that operates at the subnet level. If you think of a VPC as a city district and subnets as neighborhoods, then NACL is the fence surrounding each neighborhood — controlling who can enter (Inbound) and who can leave (Outbound).

Key characteristics:


2. How Do NACL Rules Work?

NACL uses a numbered rule system to decide which traffic is allowed and which is denied. This mechanism is fundamentally different from Security Groups.

How it works:

Example:

Rule #TypeProtocolPort RangeSourceAction
100HTTPSTCP4430.0.0.0/0ALLOW
200HTTPSTCP44310.0.0.10/32DENY
*AllAllAll0.0.0.0/0DENY

In this example, IP 10.0.0.10 sends an HTTPS request to the subnet. NACL evaluates top to bottom:

  1. Rule #100: source 0.0.0.0/0 (all IPs) matches first, so the traffic is ALLOWED.
  2. Rule #200 is never evaluated because rule #100 already matched.

If you want to block IP 10.0.0.10 while still allowing HTTPS for all other IPs, you need to swap the order: place the DENY rule at a lower number than the ALLOW rule.

Rule #TypeProtocolPort RangeSourceAction
100HTTPSTCP44310.0.0.10/32DENY
200HTTPSTCP4430.0.0.0/0ALLOW
*AllAllAll0.0.0.0/0DENY

Now IP 10.0.0.10 gets blocked at rule #100, while all other IPs are allowed at rule #200.

AWS recommends adding rules in increments of 100 (100, 200, 300…) so you can easily insert new rules in between later. For example, if you need to add a rule between #100 and #200, you can use #150.


3. Why Do We Need NACL When Security Groups Already Exist?

Many people wonder: Security Groups (SG) already control traffic, so isn’t NACL redundant? The answer is no — because they protect at two different layers and complement each other.

Comparison

FeatureSecurity Group (SG)Network ACL (NACL)
LevelInstance Level (attached to ENI)Subnet Level (attached to subnet)
StateStateful — auto-allows responseStateless — must allow both directions
Rule typesAllow onlyBoth Allow and Deny
Rule evaluationAll rules merged togetherEvaluated by rule number (first match)
Default behaviorDeny all inbound, Allow all outboundDefault NACL: Allow all
Primary use caseAllow specific apps to accessBlock specific IPs/CIDRs at subnet level

Stateful vs Stateless — The Key Difference

This is the most important distinction to understand:

Defense in Depth

In security, the Defense in Depth principle recommends never relying on a single layer of protection. NACL and SG form two complementary defense layers:

  1. Layer 1 — NACL (Subnet boundary): blocks bad traffic right at the subnet gateway, before it reaches any instance. Example: blocking an IP that is launching a DDoS attack.
  2. Layer 2 — Security Group (Instance boundary): controls exactly which traffic each instance can receive. Example: only allowing the ALB to send traffic to EC2 on port 8080.

If someone bypasses NACL (because you haven’t added a block rule yet), Security Group is still the last line of defense.


4. Ephemeral Ports — Why NACL Must Allow Them

This is the part that many AWS beginners overlook, but it is critical when configuring NACL.

What Are Ephemeral Ports?

When two devices communicate over a network, they need to use ports. For example, when you access an HTTPS website, your browser connects to port 443 (a defined port) on the web server. But the browser also needs a port on the client side to receive the response — this port is randomly chosen by the operating system from a temporary range called Ephemeral Ports.

Ephemeral port ranges differ by operating system:

Operating SystemEphemeral Port Range
IANA & Windows 10+49152 – 65535
Many Linux Kernels32768 – 60999

Concrete Example

In the diagram above, a Client (IP 11.22.33.44) accesses a Web Server (IP 55.66.77.88) over HTTPS:

Why Must NACL Allow Ephemeral Ports?

Recall the stateless nature of NACL:

Correct NACL outbound rules configuration:

Rule #TypeProtocolPort RangeDestinationAction
100CustomTCP1024 – 655350.0.0.0/0ALLOW
*AllAllAll0.0.0.0/0DENY

The port range 1024 – 65535 covers the ephemeral port range of both Windows and Linux, ensuring response traffic is always permitted.

This is one of the most common mistakes when configuring NACL: allowing inbound but forgetting to allow outbound for ephemeral ports. The result is that requests reach the server, the server processes them, but responses cannot make it back to the client.


Conclusion

NACL and Security Group are not alternatives to each other — they are two complementary defense layers in VPC architecture:

Related