Architecting secure network perimeters in Amazon Web Services (AWS) Virtual Private Cloud (VPC) environments requires enforcing defense-in-depth across software-defined networking (SDN) layers. Within an AWS VPC, traffic filtering is delivered through two distinct perimeter controls: Security Groups (SGs) and Network Access Control Lists (NACLs).
While both controls filter IP traffic within an AWS VPC, their operational models are fundamentally distinct: Security Groups are stateful virtual firewalls bound directly to Elastic Network Interfaces (ENIs), whereas Network ACLs are stateless packet filters evaluated at the subnet boundary. Misunderstanding how statefulness and rule evaluation differ between these layers is a primary cause of broken cloud communications and unintended network exposure.
AWS VPC Architectural Comparison Matrix
Understanding the technical distinctions between AWS Security Groups and Network ACLs:
| Operational Property | AWS Security Groups (SG) | AWS Network Access Control Lists (NACL) |
|---|---|---|
| Bound Infrastructure Level | Elastic Network Interface (ENI) | Subnet boundary (applies to all ENIs in subnet) |
| State Tracking Mechanics | Stateful: Return traffic is automatically tracked and allowed. | Stateless: Return traffic must be explicitly permitted by rule. |
| Rule Permissibility | Allow rules only (implicit default deny). | Supports both explicit Allow and Deny rules. |
| Rule Evaluation Order | All rules are evaluated concurrently before making an allow decision. | Rules evaluated sequentially in ascending numeric order (e.g., 100, 200). |
| Default Posture (Custom Created) | Denies all inbound traffic; allows all outbound traffic. | Denies all inbound and outbound traffic until rules are added. |
| Primary Defensive Role | Instance / container microsegmentation. | Coarse subnet boundary barrier and CIDR blocking. |
The Mechanics of Stateful Filtering (AWS Security Groups)
In AWS VPC, a Security Group functions as a stateful virtual firewall at the hypervisor layer immediately adjacent to an EC2 instance's Elastic Network Interface (ENI). Powered by the AWS Nitro System or hypervisor-level connection tracking, Security Groups maintain state tables in memory:
- Automatic Return Flow: If an inbound packet matches an allowed rule (e.g., TCP port 443 from
0.0.0.0/0), the hypervisor records the flow in its state table. When the instance sends the outbound HTTP response back to the client, the hypervisor recognizes the active session and automatically permits the outbound packet, regardless of outbound Security Group rules. - Outbound Originated Traffic: Conversely, if an EC2 instance initiates an outbound connection (e.g., querying an external API on port 443), the inbound response from that external server is automatically permitted back into the instance without requiring an inbound rule.
- Security Group Referencing: Within an AWS VPC, Security Groups can reference other Security Groups as source or destination targets (e.g., allowing port 3306 on a database ENI only from the
sg-appserversidentifier), enabling robust microsegmentation that adapts dynamically without hardcoding private IP addresses.
The Mechanics of Stateless Filtering (AWS NACLs) & Ephemeral Ports
Unlike Security Groups, AWS Network ACLs operate at the subnet boundary and are completely stateless: they do not maintain connection tracking tables. Every individual packet entering or leaving the subnet is evaluated in isolation against the numbered rule list.
The Ephemeral Return Port Dynamic: When an external client initiates a connection to a web server on port 443, the client allocates a random high-numbered ephemeral port to identify the socket locally. While an inbound NACL rule permits destination port 443 into the subnet, the web server's return response packets destined for the client's ephemeral port will be dropped at the subnet boundary unless an outbound NACL rule explicitly permits return traffic to those ephemeral ports.
Understanding Ephemeral Port Ranges in AWS
Ephemeral port allocations vary based on the client operating system and AWS service:
- Linux Kernels: Typically use ports
32768–60999(governed by/proc/sys/net/ipv4/ip_local_port_range). - Windows Server & Modern Windows: Allocate from
49152–65535(adhering to IANA standards). - AWS Services & Older Systems: AWS NAT Gateways, Elastic Load Balancers, and legacy systems can utilize the broad range of
1024–65535.
While configuring outbound NACL rules to allow 1024–65535 is commonly used as a broad compatibility range to accommodate diverse Internet clients and AWS managed services, tightly governed VPC designs can scope outbound ephemeral ranges more narrowly when traffic sources are standardized.
Example Production AWS NACL Rule Set for a Public Web Subnet
To operate a public web tier safely behind a custom AWS NACL, administrators configure explicit bidirectional rules:
| Rule # | Direction | Protocol | Port Range | Source / Destination | Action & Operational Function |
|---|---|---|---|---|---|
100 |
Inbound | TCP | 443 |
0.0.0.0/0 |
ALLOW: Inbound HTTPS requests from clients. |
110 |
Inbound | TCP | 1024-65535 |
0.0.0.0/0 |
ALLOW: Inbound return responses for outbound requests initiated by the server (e.g., OS updates). |
* |
Inbound | ALL | ALL | 0.0.0.0/0 |
DENY: Implicit default catch-all drop. |
100 |
Outbound | TCP | 1024-65535 |
0.0.0.0/0 |
ALLOW: Outbound return responses sent to clients' ephemeral ports. |
110 |
Outbound | TCP | 443 |
0.0.0.0/0 |
ALLOW: Outbound HTTPS calls initiated by the server (e.g., AWS API calls, package repos). |
* |
Outbound | ALL | ALL | 0.0.0.0/0 |
DENY: Implicit default catch-all drop. |
Evaluation Sequence: The AWS VPC Packet Flow
When an inbound packet arrives at an AWS VPC destined for an EC2 instance, the AWS SDN fabric processes traffic through a two-stage sequential evaluation:
- Subnet Ingress (NACL Evaluation): The packet crosses the subnet boundary. AWS evaluates the packet against the subnet's Inbound NACL rules in ascending numerical order. If the lowest-numbered matching rule specifies
DENY, the packet is immediately dropped at the boundary. If the matching rule isALLOW, the packet enters the subnet. - Instance Ingress (Security Group Evaluation): The packet reaches the ENI. AWS evaluates all Inbound Security Group rules attached to that ENI concurrently. If any rule permits the traffic, the packet passes into the operating system.
Comparison Note: Microsoft Azure Network Security Groups (NSGs)
It is important not to confuse the AWS dual-layer model with Microsoft Azure's networking architecture. Azure does NOT feature a separate stateless subnet-level NACL construct. Instead, Azure utilizes Network Security Groups (NSGs), which are stateful packet filters with priority-based rules (e.g., 100 to 4096). In Azure, NSGs can be associated at the subnet level, network interface (NIC) level, or both, but in all cases, Azure NSG rules are stateful—return traffic is automatically permitted by the underlying Azure Virtual Filtering Platform (VFP) without requiring manual ephemeral port configuration.
AWS Enterprise Design Best Practices
- Security Groups as Primary Control: Use Security Groups for primary microsegmentation and application tiering. Leverage Security Group referencing rather than hardcoding static IPs to maintain elastic scalability.
- NACLs for Coarse Subnet Ingress/Egress Guardrails: Use NACLs primarily for explicit
DENYrules—such as blocking known malicious CIDRs, dropping unencrypted protocols across sensitive subnets, or isolating database subnets from unauthorized subnets. - Leave Default NACLs Intact for General Subnets: The AWS default NACL allows all inbound and outbound traffic. Unless specific subnet-wide blocking is required, relying primarily on Security Groups avoids accidental ephemeral port blackholing.