Stop 07 · Identity & SecurityTopics · 7/10

Security Groups vs Network ACLs

Part of the Cloud Computing Roadmap

In short

Two firewalls guard your VPC and they think very differently. Mix up which one remembers traffic and you'll spend an evening wondering why replies never come back.

Security groups are stateful and apply at the instance level; network ACLs are stateless and apply at the subnet level — using both together provides defense in depth for network access control.

The blob character walks through a mall security frame while a shopkeeper waves from inside.

Think of it like this

Mall gate and shop door

The mall's main gate frisks everyone going in and checks bags again going out, with no memory of you. The shopkeeper inside remembers you walked in, so you just walk back out. NACL at the gate, security group at the shop.

Watch it happen

Two firewalls, two personalities

Security group

  • Attached to each instance or ENI
  • Stateful: replies allowed automatically
  • Allow rules only, all evaluated

Network ACL

  • Attached to a whole subnet
  • Stateless: return traffic needs its own rule
  • Allow and Deny, checked in number order

Use security groups as your main tool. Add NACLs for broad subnet-wide blocks, like denying a bad IP range.

The big ideas

What you need to know

Stateful remembers

If a security group allows inbound 443, the reply goes out even with no outbound rule. It tracks the connection.

Stateless forgets

A NACL checks each packet alone. Allow inbound 443 and you must also allow outbound ephemeral ports 1024-65535 for replies.

Reference other groups

A DB security group can allow 5432 only from the app's security group ID, instead of IP addresses.

NACL rule order

NACL rules run lowest number first and stop at the first match. Put specific Deny rules before broad Allows.

See it in code

Walk through the code

bash
1# DB only accepts Postgres from the app tier's security group2aws ec2 authorize-security-group-ingress \3  --group-id sg-db1234 --protocol tcp --port 5432 \4  --source-group sg-app56785 6# Subnet-wide block of a bad range, checked before other rules7aws ec2 create-network-acl-entry --network-acl-id acl-0abc \8  --ingress --rule-number 90 --protocol -1 \9  --cidr-block 203.0.113.0/24 --rule-action deny

1/2Stateful and specific: only instances in sg-app5678 can reach the DB on 5432.

203.0.113.0/24 is a documentation range used for examples. Swap in a real range only when you have a reason.

Save yourself the pain

Common mistakes

Oops

Adding a NACL inbound allow for 443 and nothing outbound, then wondering why pages hang.

Do this instead

NACLs are stateless. Allow outbound ephemeral ports too, or leave NACLs at the default allow-all.

Oops

Opening SSH port 22 to 0.0.0.0/0 "just to test".

Do this instead

Allow 22 from your own IP only, or skip SSH and use Session Manager instead.

Your mission

Break it, then fix it

~40 min

Quick check

A security group allows inbound TCP 443 and has no outbound rules. Do HTTPS responses reach the client?

Go deeper

  1. 1Configure both a security group and a network ACL for the same resource and compare their rules.
  2. 2Learn why 'stateful' means a security group automatically allows return traffic, but an ACL doesn't.
  3. 3Practice reasoning about which layer to use for a specific access control requirement.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge