skip to content

In an AWS VPC, how do security groups and network ACLs differ in what they attach to, what a rule can express, and how return traffic is treated?

level: juniorimportance: must knowfreq 85%

answer

  1. two filters, two attachment points
  2. one keeps state, one does not
  3. allow-only versus numbered allow and deny
  4. the reply needs its own rule

basics

~20 s

Security groups attach to network interfaces, are allow-only and stateful, so return traffic is automatically permitted. Network ACLs attach to subnets, allow or deny in numbered order, and are stateless, so every direction needs an explicit rule.

solid answer

~50 s

AWS gives you two independent packet filters in a VPC. A **security group** is attached to an elastic network interface — so effectively to an instance, task, Lambda ENI or load balancer — and holds only *allow* rules; there is no deny, and there is no ordering, because every rule in every attached group is evaluated and traffic passes if any of them matches. It is **stateful**: if a request is allowed in, the reply is allowed back out regardless of the outbound rules. A **network ACL** is attached to a subnet, so it filters everything entering or leaving that subnet. Its rules are numbered, evaluated lowest number first, first match wins, and they can be `deny` as well as `allow`. It is **stateless**: the reply to an allowed request is a brand-new packet that must match a rule in the opposite direction. Both must permit a packet for it to pass.

go deeper

for a junior

Be ready to state the four-part contrast cleanly: interface versus subnet, allow-only versus allow and deny, unordered versus numbered, stateful versus stateless. Say plainly that both have to permit a packet.

for a middle

Explain the mechanics: all attached security groups evaluate as one allow set, NACL rules stop at the first numeric match before falling to the implicit deny, and a stateless filter re-checks the reply as a fresh packet.

for a senior

Show that you know which one production actually uses. Expect to justify leaving NACLs wide open and doing real segmentation in security groups, and to name the case that flips it — a subnet-wide explicit deny.

for a principal

Own the ownership question: security groups belong with the workload and its team, NACLs are a platform-level guardrail. Be ready to argue where each control lives so that two teams are not fighting over one subnet's rules.

## Two filters, two attachment points Inside a VPC, a packet on its way to an instance is checked by two mechanisms that look superficially alike and behave very differently. A **security group** is attached to an *elastic network interface* (ENI). An ENI is the virtual NIC that AWS gives to an EC2 instance, an ECS task with `awsvpc` networking, a Lambda function configured for VPC access, an RDS instance, an interface VPC endpoint or a load balancer node. So a security group is an instance-level filter: two instances in the same subnet can have completely different security groups and completely different reachability. A **network ACL** (NACL) is attached to a *subnet*. Every ENI in that subnet is behind the same NACL, and every packet crossing the subnet boundary in either direction is evaluated against it. A subnet is associated with exactly one NACL at a time; one NACL can be associated with many subnets. Both must permit a packet. They are AND-ed, not layered as an override: a NACL `allow` does not rescue traffic the security group never permitted, and a permissive security group does not rescue traffic a NACL denies. ## What a rule can say Security-group rules are **allow-only**. There is no `deny` action — the absence of a matching allow rule *is* the denial. There is also no rule ordering: all rules across all security groups attached to the ENI are evaluated as a set, and the traffic passes if any of them matches. Because of this, attaching a second security group can only ever widen access, never narrow it. A rule's source (inbound) or destination (outbound) can be a CIDR block, a managed prefix list, or another security group. NACL rules are **numbered** — you assign the number yourself — and carry an explicit `allow` or `deny`. Evaluation walks the rules in ascending numeric order and stops at the first match; anything unmatched falls through to the untouchable final `*` rule, which denies. This ordering is why people leave gaps between rule numbers (100, 200, 300) so a rule can be inserted later without renumbering. The source or destination of a NACL rule is a CIDR block only — a NACL cannot reference a security group. ## Stateful versus stateless: the part interviews hinge on A security group **tracks connections**. When an inbound rule admits a TCP connection, the reply packets are permitted back out no matter what the outbound rules say, and vice versa for connections the instance originates. This is why the very common configuration — restrictive inbound rules plus the default "allow all outbound" rule — works fine, and why removing the outbound rule does not break inbound-initiated traffic. A NACL tracks nothing. Each packet is evaluated on its own against the rules for the direction it is moving. The reply to a request you allowed inbound is a separate outbound packet, and it will be dropped unless an outbound rule matches it. Because a reply travels *from* the service port *to* the client's randomly chosen ephemeral port, the outbound rule that permits it is written over the ephemeral port range, not over the service port. Getting that wrong is the single most common way a hand-written NACL breaks connectivity. ## The defaults A VPC ships with a **default security group** whose inbound rule allows traffic from resources that have that same security group attached, and whose outbound rule allows all traffic. A security group you create yourself starts with **no inbound rules** and an allow-all outbound rule. The **default network ACL** that comes with a VPC allows all inbound and all outbound traffic — it is deliberately transparent, so that people who never touch NACLs are only ever filtered by security groups. A NACL you create yourself starts with **only** the implicit `*` deny in both directions, so associating a fresh custom NACL with a live subnet blackholes it instantly. ``` # custom NACL, inbound 100 allow tcp 443 0.0.0.0/0 * deny all 0.0.0.0/0 ``` ## Why AWS ships both The security group is the workhorse: it follows the workload rather than its location, it composes safely, and its statefulness means you write half as many rules. The NACL is a coarse subnet-wide guardrail with the one capability security groups lack — an explicit `deny`, which lets a platform team block a CIDR range across a subnet without touching any application's rules. Most production VPCs leave NACLs wide open and do all real work in security groups.

  • If I attach a second security group to an instance, can that make the instance less reachable than it was?
    No. Security-group rules are allow-only and unordered, and all groups attached to the ENI are evaluated as one set — traffic passes if any rule in any of them matches. Adding a group can only widen access. Narrowing means removing rules from the groups already attached, or putting a deny in the subnet's network ACL.
  • Which filter would you reach for to block a single abusive IP range from an entire subnet, and why?
    The network ACL, because it is the only one of the two that has an explicit deny action and it applies subnet-wide. A security group cannot express "everyone except this range" — you would have to enumerate allowed CIDRs across every group. A NACL deny rule with a low rule number short-circuits before the permissive allow rules below it.
  • You create a new network ACL and associate it with a running subnet. What happens immediately?
    All traffic stops. A custom network ACL is created with only the implicit final rule, which denies everything in both directions, so the subnet blackholes until you add rules. The default NACL created alongside a VPC is the opposite — it allows all traffic in both directions.

saying these in an interview costs you the question

  • Claiming security groups support deny rules
  • Saying network ACL rules are evaluated top to bottom by creation order
  • Thinking a permissive network ACL can override a missing security-group allow
  • Saying security groups attach to subnets and NACLs to instances
  • Assuming return traffic is automatic on both filters

context