TTechclick ⚡ XP 0% All lessons
AWS · VPC · Security Groups vs NACLsInteractive · L1 / L2 / L3

AWS Security Groups vs NACLs: — The Stateful/Stateless Difference That Trips Everyone

Your EC2 instance can be reached on the way IN but the reply never comes back — and every rule on screen looks correct. Nine times out of ten the culprit is a stateless NACL missing its ephemeral return-port rule. This lesson builds the mental model — NACL = building gate at the subnet, Security Group = apartment door at the instance — so you stop guessing and start reading the packet path.

📅 2026-06-11 · ⏱ 13 min · 3 live demos · 4 infographics · 🏷 10-Q assessment + AI Tutor inline

⚡ Quick Answer

AWS Security Groups vs NACLs for L1/L2 engineers and the SCS-C02 exam: stateful vs stateless, where each sits in the packet path, the ephemeral-port return-rule bug, SG-to-SG references and a web/app/db design.

🎯 By the end you will be able to

Read as:

Pick where you want to start

1

Two firewalls

NACL at the subnet gate, SG at the instance door.

2

Stateful vs stateless

Auto-return vs both-ways-explicit — and the ephemeral trap.

3

How they combine

Pass the NACL AND the SG; SG refs and NACL deny.

4

Designing it

Web/app/db tiers, the cheat-sheet, troubleshooting.

🧠 Warm-up — 3 questions, no score

Just notice which ones make you pause. We answer all three inside the lesson.

1. A Security Group allows inbound HTTPS on 443. A user connects. Do you also need a rule for the reply going back out?

Answered in Two firewalls.

2. Where does a Network ACL inspect traffic in the packet's journey?

Answered in How they combine.

3. Which control can you use to explicitly DENY a single malicious public IP for a whole subnet?

Answered in Stateful vs stateless.

Most engineers think…

Most engineers first meet Security Groups and NACLs and think they're "the same firewall, just one for instances and one for subnets — so pick whichever." They throw a rule into either and expect it to behave the same way.

Wrong — and this exact assumption is the bug that eats whole afternoons. A Security Group is stateful and allow-only: it remembers a connection, so the reply comes back automatically and there is no such thing as an SG deny rule. A NACL is stateless: it judges every packet on its own with no memory, so you must allow both directions explicitly — and forgetting the outbound ephemeral-port range (1024–65535) for return traffic is the single most common 'it connects but the reply hangs' failure in AWS networking. They are not interchangeable; they are two different machines that you stack on top of each other.

① The two firewalls in a VPC — subnet gate vs instance door

Meet Sneha, an L1 cloud engineer at Infosys. Her team runs a web app in a VPC on account 123456789012. A ticket lands: "users can't reach the new EC2 web server." Sneha opens the security settings and finds two different things that both look like firewalls — a Security Group and a Network ACL. Which one is blocking her? To answer that, she first has to know where each one sits.

Here is the mental model that makes everything else click. A NACL is the building gate: it guards the whole subnet, and every packet entering or leaving that subnet passes through it. A Security Group is the apartment door: it guards one specific instance (technically its ENI). A visitor must clear the building gate to even get into the compound, and then clear your apartment door to get into your flat. Clear the gate but fail at your door, and they're stuck in the corridor — which is exactly what a half-open ruleset feels like.

Put it in packet-path order. Traffic arriving from the internet gateway hits the subnet's NACL first (inbound), then the instance's Security Group (inbound), then finally the OS. On the way back out, the reply leaves the instance through the Security Group (outbound), then the NACL (outbound), then the subnet edge. So the NACL is the outer ring and the SG is the inner ring. Two rings, every packet, both directions — memorise that and half the 2 a.m. tickets explain themselves.

👉 So far: NACL = subnet building-gate (outer ring), SG = instance apartment-door (inner ring), and a packet crosses both. Next: see the exact order on a diagram, then meet the property that makes them behave so differently.
Figure 1 — Where each firewall sits in the packet path
A packet must clear the subnet's NACL gate before it ever reaches the instance's Security Group door A left-to-right packet path inside a VPC. From the internet gateway the packet enters the subnet through the Network ACL, which sits at the subnet boundary like a building gate. Only after passing the NACL does it reach the EC2 instance's Security Group, attached to the instance's elastic network interface like an apartment door, and then the operating system. The NACL is drawn as the outer ring at the subnet edge in blue; the Security Group is the inner ring at the instance in amber. Arrows show the reply leaving back out through the Security Group and then the NACL. Two rings: subnet NACL (outer) → instance Security Group (inner) Internetgateway203.0.113.50 Subnet 10.0.1.0/24 (the building) NACLbuilding gate EC2 web serveri-0ab12 · 10.0.1.20 SG ENI → OSapartment door 1· inbound 2· then SG reply leaves: SG out → NACL out Key ideaNACL = outerring (subnet)SG = innerring (instance) untrusted / deniedsubnet / NACL gateSG / decisionkey insightallowed
Follow one packet left-to-right: it crosses the subnet NACL (blue gate) before it ever reaches the instance's Security Group (amber door). The SG is the inner ring; the NACL is the outer ring. Both are checked, both directions.

The two firewalls, one tap each

Tap each card. These four facts are the foundation of every NACL/SG question you'll ever get.

🚪
Security Group
tap to flip

Attached to the ENI of one instance. Stateful, allow-only. So: the apartment door — the last check before the OS.

🏢
Network ACL
tap to flip

Attached to a whole subnet. Stateless, ALLOW + DENY. So: the building gate — every packet in or out of the subnet passes it.

🧭
Packet order
tap to flip

In: NACL then SG. Out: SG then NACL. So: NACL is the outer ring, SG the inner — both are checked.

🎯
Default counts
tap to flip

An instance gets at least 1 SG; a subnet always has exactly 1 NACL. So: you can't escape either — only configure them.

Daily-life analogy — your housing society gate vs your flat door

Think of a Mumbai housing society. The NACL is the society's main gate with the watchman and the gate-pass register: it screens everyone entering or leaving the whole compound, and it can keep a 'banned visitor' list (a DENY). Your Security Group is your own flat's door: even after a visitor clears the gate, they still have to be let in at your door. A delivery boy who clears the gate but stands outside your locked flat is exactly an 'inbound allowed at NACL, blocked at SG' situation — and you debug it by asking 'which barrier stopped them, the gate or my door?'

Quick check · Q1 of 10

Rahul at TCS sees a packet from the internet reach his subnet but never reach his EC2 instance. In packet-path terms, which barrier did it pass and which one stopped it?

Correct: a. Order on the way in is NACL first (subnet gate), then SG (instance door). If the packet reached the subnet but not the instance, it cleared the outer NACL ring and was stopped at the inner SG ring. If the NACL had stopped it, it would never have entered the subnet at all; and SG is always after NACL, not before.

Pause & Predict

Predict: a subnet has NO custom NACL associated and you never touched the default one. Does that mean traffic into the subnet is unfiltered, or is something still guarding it? Type your guess.

Answer: Something is still guarding it — there is no such thing as 'no NACL'. Every subnet is associated with exactly one NACL; if you don't attach a custom one, it uses the VPC's default NACL, which (out of the box) allows ALL inbound and ALL outbound. So traffic isn't blocked, but the subnet absolutely has a NACL — it's just permissive. The real filtering at that point is happening at the Security Group. This is why beginners think 'the NACL does nothing': the default one is wide open by design.

② Stateful vs stateless — and the ephemeral-port trap

This is the single most important idea in the lesson, and the one interviews probe hardest. A Security Group is stateful. When it allows your inbound HTTPS request on port 443, it remembers that connection, so the server's reply is automatically allowed straight back out — you never write a rule for the return traffic. And there is no 'deny' in a Security Group at all: every rule is an allow, and anything not explicitly allowed is implicitly denied.

A NACL is the opposite: stateless. It has no memory of the request, so when the reply tries to leave, the NACL judges it as a brand-new packet with no idea it's a response. That means you must write rules for both directions explicitly. NACLs also support ALLOW and DENY, and they evaluate rules in number order — lowest number first, and the first matching rule wins (then evaluation stops). Rule numbers run 1 to 32766 for the ones you create, with a final catch-all * rule that denies anything unmatched.

👉 So far: SG = stateful + allow-only (return is free); NACL = stateless + ALLOW/DENY + number-ordered (you pay for both directions). Next: the exact bug this difference creates — the ephemeral-port return range.

Here's the trap that catches everyone. When a client opens a connection to your server on port 443, the server's reply doesn't go back to port 443 — it goes back to a high, random ephemeral port the client picked. On a stateful Security Group that reply is auto-allowed, so you never think about it. But on a stateless NACL, if your outbound rules don't allow the ephemeral range, the reply is dropped — the request landed, the page just never loads. AWS's documented advice is to open outbound 1024–65535 on the NACL to cover all client types. The actual ranges vary: a Linux kernel uses 32768–60999, Windows Server 2008+ uses 49152–65535, and a NAT gateway or ELB uses the full 1024–65535 — which is why 1024–65535 is the safe blanket.

Figure 2 — Why the stateless NACL drops the reply
A stateful Security Group auto-allows the return packet; a stateless NACL silently drops it unless you open the ephemeral range outbound Two stacked scenarios for the same HTTPS request. In the top row, a stateful Security Group allows inbound on port 443 and the reply on the client's ephemeral port is automatically returned because the connection is remembered. In the bottom row, a stateless Network ACL allows inbound on 443 but has no outbound rule for the ephemeral port range, so the reply packet is dropped at the subnet boundary even though the request arrived. The fix is to add an outbound NACL allow rule for ports 1024 to 65535. Red marks the dropped reply; green marks the successful path. Same request, two firewalls — only one needs a return rule Stateful Security Group — return is free clientsrc port 51514 EC2 :443SG: allow 443 in request → dst 443 reply → dst 51514 · auto-allowed (stateful) Stateless NACL — you pay for the return trip clientsrc port 51514 NACL EC2 :443 request in: rule 100 allow 443 ✓ reply → dst 51514 · NO outbound rule → DROPPED ✗ Fix: add NACL outbound ALLOW TCP 1024–65535 → reply now passes untrusted / deniedsubnet / NACL gateSG / decisionkey insightallowed
Top (green) = Security Group: inbound 443 allowed, reply auto-returns, done. Bottom (red→fix) = NACL: inbound 443 is allowed but the OUTBOUND ephemeral range is missing, so the reply is dropped — add 1024-65535 outbound and it flows.

▶ Watch the reply die at a stateless NACL

A user in Bengaluru hits Sneha's web server on 443. The request gets in fine. Follow the reply on its way back out through the stateless NACL. Press Play for the healthy path, then Break it to see the failure.

① Request in203.0.113.50:5151410.0.1.20:443; NACL inbound rule 100 = allow 443 ✓
② SG inboundSecurity Group allows 443 from 0.0.0.0/0; packet reaches the web server
③ Reply out (SG)server replies 10.0.1.20:443203.0.113.50:51514; SG is stateful → auto-allowed ✓
④ Reply out (NACL)same reply hits NACL outbound; dst port 51514 — is it allowed? depends entirely on your outbound rules
Press Play to step through the healthy path. Then press Break it.
AWS CLI — add the missing NACL outbound ephemeral return rule
aws ec2 create-network-acl-entry \
  --network-acl-id acl-0a1b2c3d4e5f6a7b8 \
  --rule-number 200 \
  --protocol tcp \
  --port-range From=1024,To=65535 \
  --cidr-block 0.0.0.0/0 \
  --rule-action allow \
  --egress
Expected output
# (no output on success — create-network-acl-entry returns nothing)
# verify it landed:
$ aws ec2 describe-network-acls --network-acl-ids acl-0a1b2c3d4e5f6a7b8 \
    --query 'NetworkAcls[0].Entries[?Egress==`true`]'
[ { "RuleNumber": 200, "Protocol": "6", "RuleAction": "allow",
    "Egress": true, "CidrBlock": "0.0.0.0/0",
    "PortRange": { "From": 1024, "To": 65535 } } ]
Common mistake — "it connects but the reply hangs" after locking down a NACL

Symptom: you tightened a subnet's NACL, allowed inbound 443, and now curl https://server connects but just spins / times out — yet the Security Group is untouched and correct. Cause: the NACL is stateless and you only allowed the inbound; the server's reply goes to a high ephemeral port that your outbound NACL rules don't permit, so it's dropped. Fix: add an outbound ALLOW rule for TCP 1024–65535. Verify with VPC Flow Logs — you'll see the inbound packet ACCEPT and the outbound reply REJECT on the ephemeral port.

Quick check · Q2 of 10

Priya at HCL allows inbound 443 on a custom NACL but users still can't load the page (request arrives, reply never returns). Security Group is fine. What's the fix?

Correct: c. NACLs are stateless, so the reply (going to the client's high ephemeral port) needs its own explicit outbound allow — TCP 1024–65535 covers all client types. There is no 'stateful mode' toggle for a NACL; port 80 inbound is unrelated to an HTTPS reply; and deleting the NACL just falls back to the default NACL (and abandons your subnet-level controls), not a real fix.

Pause & Predict

Predict: you do the exact same lockdown on a Security Group instead of a NACL — allow inbound 443, leave outbound at the default. Does the reply get dropped this time? Type your guess.

Answer: No — and that's the whole point of stateful. A Security Group remembers the inbound connection it allowed, so the reply is automatically permitted regardless of the outbound rules. You never add an ephemeral return rule on an SG. The ephemeral-port headache exists ONLY on the stateless NACL. (In fact the default SG outbound rule allows all egress anyway, but even if it didn't, the stateful return would still work.)

③ How they combine — pass the NACL AND the SG

Now stack them. For a packet to reach your instance, it must be allowed by the NACL (subnet) AND the Security Group (instance) — both, not either. They're an AND gate, evaluated as the outer and inner rings we saw in section 1. This is genuine defense in depth: if someone fat-fingers an SG and opens SSH to 0.0.0.0/0, a NACL that denies port 22 at the subnet still blocks it. One mistake doesn't become a breach.

The Security Group has a power the NACL doesn't: it can reference another Security Group instead of an IP range. A rule like 'allow 8080 from sg-app' means 'allow traffic from any instance that carries the app-tier Security Group, whatever its IP is.' This is how you wire tier-to-tier trust that survives auto-scaling — new app servers come and go, their IPs change, but they all carry sg-app, so the rule keeps working. A NACL can only match CIDR ranges; it has no idea what an SG is.

👉 So far: NACL AND SG must both allow (defense in depth), and only the SG can reference another SG for tier-to-tier trust. Next: the defaults of each, and the rule of thumb for where DENY belongs vs where ALLOW belongs.

Know the defaults cold, because exam questions hinge on them. The default Security Group allows all inbound traffic from other instances in the same SG (a self-reference) and allows all outbound; a brand-new custom SG allows nothing inbound and all outbound. The default NACL allows all inbound and all outbound (rule 100 allow, then the * deny catch-all). But a brand-new custom NACL is the opposite — it denies everything in both directions until you add allow rules. So a fresh custom SG is 'deny-in/allow-out' while a fresh custom NACL is 'deny-all' — mix those up and you'll lock yourself out.

That gives the rule of thumb that experienced engineers live by. Allow-by-design belongs in Security Groups: they're stateful, instance-precise, and can reference SGs, so they're where you express 'the app tier may talk to the db tier.' Deny belongs in NACLs: an SG literally cannot deny, so when you need to block something — a known-bad public IP scanning your subnet, or a blanket 'no SSH from the internet to this whole tier' — you reach for a NACL DENY rule with a low rule number so it's evaluated first.

Figure 3 — The AND gate, SG references, and where DENY lives
A packet must pass both the NACL and the SG; SGs reference other SGs for tier trust; only the NACL can DENY a bad CIDR Three panels. Left panel shows an AND gate: a packet is allowed only if both the subnet NACL and the instance Security Group permit it. Centre panel shows a Security Group referencing another Security Group, so the app tier trusts the web tier by group membership rather than by IP address, which survives auto-scaling. Right panel shows a Network ACL with a low-numbered DENY rule that blocks a malicious public CIDR for the whole subnet, which a Security Group cannot do because it has no deny action. Amber marks the SG decision points, blue marks the NACL, red marks the denied attacker traffic. Combine them: AND gate · SG-to-SG trust · NACL deny 1 · Both must allow (AND) NACL allows? (subnet) AND SG allows? (instance) both yes → packet in ✓ either no → dropped ✗e.g. SG opens 22, NACL denies it 2 · SG references SG web tiersg-web app tiersg-app sg-app rule: allow 8080 from sg-web survives auto-scalingnew web box = new IP,same sg-web → still trustedno IP rule to update A NACL can't do this —it only matches CIDR ranges 3 · DENY lives in the NACL attacker 198.51.100.7scanning the subnet NACL rule 10: DENY198.51.100.7/32 (low # = first) blocked for whole subnet ✗SG has no deny action at all first matching rule wins, then stop untrusted / deniedsubnet / NACL gateSG / decisionkey insightallowed
Left: a packet must clear BOTH rings (AND gate). Centre: the SG-to-SG reference lets the app tier trust the web tier by SG, not IP. Right: a NACL DENY at a low rule number blocks a bad CIDR for the whole subnet — something an SG can't do.
AWS CLI — reference one Security Group from another (web tier → app tier)
# allow the app tier (sg-app) to accept 8080 only from the web tier (sg-web)
aws ec2 authorize-security-group-ingress \
  --group-id sg-0app1111appapp11 \
  --protocol tcp --port 8080 \
  --source-group sg-0web2222webweb22
Expected output
{
  "Return": true,
  "SecurityGroupRules": [
    { "SecurityGroupRuleId": "sgr-0c0ffee1234567890",
      "GroupId": "sg-0app1111appapp11", "IsEgress": false,
      "IpProtocol": "tcp", "FromPort": 8080, "ToPort": 8080,
      "ReferencedGroupInfo": { "GroupId": "sg-0web2222webweb22" } }
  ]
}
Prove a packet actually passed both layers, not just one

Don't guess which layer blocked it — read VPC Flow Logs. Each line ends in ACCEPT or REJECT. A flow log shows whether the packet reached the ENI at all (if it's missing entirely, the NACL likely dropped it at the subnet) and whether the reply went out. Console path: VPC Console → Your VPCs → (select VPC) → Flow logs → Create flow log, then read them in CloudWatch Logs. The combination 'inbound ACCEPT, outbound REJECT on a high port' is the fingerprint of the stateless-NACL ephemeral bug.

Quick check · Q3 of 10

Aditya at Wipro must block one specific malicious IP (203.0.113.66) from reaching an entire subnet of app servers. Which control does the job, and why not the other?

Correct: b. Only a NACL can DENY, and it applies to the whole subnet — perfect for blocking a bad CIDR. Give it a low rule number so it's evaluated before any allow. A Security Group literally cannot express 'deny'; every SG rule is an allow, so there's no SG deny rule to write. The controls are not interchangeable here.

Pause & Predict

Predict: you add a NACL rule numbered 50 that ALLOWs 203.0.113.66, and a rule numbered 100 that DENYs the same IP. Does the IP get in or get blocked? Type your guess.

Answer: It gets IN. NACL rules are evaluated in ascending number order and the FIRST match wins, then evaluation stops. Rule 50 (allow) is checked before rule 100 (deny), matches, and the packet is permitted — rule 100 is never even reached. This is the classic NACL trap: a deny placed at a higher number than a matching allow does nothing. Put your DENY rules at LOW numbers so they're evaluated first.

④ Designing it — web/app/db tiers, troubleshooting & the cheat-sheet

Let's build the canonical three-tier design every interview and the SCS-C02 exam expects. Three Security Groups, chained by reference. sg-web: allow inbound 443 from 0.0.0.0/0 (the public can reach the web tier). sg-app: allow inbound 8080 from sg-web only (the app tier trusts the web tier, nobody else). sg-db: allow inbound 3306 (MySQL) from sg-app only (the database trusts the app tier, nobody else — and certainly not the internet). Each tier trusts exactly one tier below it, by Security Group, so the chain holds even as instances scale in and out.

Then add the NACL layer for the things SGs can't do. On the public subnet's NACL, a low-numbered DENY for any CIDR you've seen attacking you (say 198.51.100.0/24), plus the all-important outbound 1024–65535 ephemeral allow so replies flow. On the database subnet's NACL, you might DENY all inbound from the internet CIDR entirely as a belt-and-braces subnet-wide block — even if a future SG mistake opens the db, the subnet gate still refuses internet traffic. That's defense in depth made concrete.

👉 So far: the three-tier SG chain (web→app→db by reference) plus a NACL deny + ephemeral allow. Next: recreate the real console screen for an SG inbound rule, the classic 'works one way' troubleshoot, and the one-card cheat-sheet.
🖥️ This is the screen you'll use to add the app-tier rule — AWS Console → VPC → Security Groups → sg-app → Inbound rules → Edit inbound rules → Add rule. (Recreated for clarity — your console matches this.)
console.aws.amazon.com · VPC · Security Groups · Edit inbound rules
1
Type
Custom TCP
Protocol
TCP
2
Port range
8080
3
Source
Custom
4
Source value
sg-0web2222webweb22 (sg-web)
Description
app accepts traffic from web tier only
Save rules

Karthik at Flipkart faces this

Karthik, an L2 engineer, gets a ticket: a new analytics box in the app subnet can reach the database fine, but the database's replies to it 'sometimes' stall, and a fresh SSH session into the box from a bastion connects but then freezes mid-session.

Likely cause

'Works one way, breaks the other' is the signature of a stateless return-path problem. Someone tightened the app subnet's custom NACL to allow inbound from the db subnet, but never added the outbound ephemeral allow — so reply packets to high client ports are dropped. The Security Groups are stateful and fine; the NACL is the leaky layer.

Diagnosis

He separates the layers: SGs are stateful so they can't be the asymmetry. That points straight at the stateless NACL's outbound rules. He pulls VPC Flow Logs for the app subnet's ENI and looks for inbound ACCEPT paired with outbound REJECT on ports in the 1024–65535 range.

AWS Console → VPC → Network ACLs → (app subnet's NACL) → Outbound rules · and VPC → Flow logs in CloudWatch Logs
Fix

Add an outbound NACL ALLOW rule (e.g. rule 200) for TCP 1024–65535 to the destination CIDRs the box replies to (or 0.0.0.0/0 for a public-facing tier). Keep any DENY rules at lower numbers so they still win.

Verify

Re-run the SSH session and the db query — both now complete without freezing. Flow Logs show the outbound ephemeral packets flipping from REJECT to ACCEPT, confirming the return path is open.

AWS CLI — the three-tier Security Group chain (web → app → db)
# web tier: public HTTPS
aws ec2 authorize-security-group-ingress --group-id sg-web \
  --protocol tcp --port 443 --cidr 0.0.0.0/0
# app tier: only from the web tier's SG
aws ec2 authorize-security-group-ingress --group-id sg-app \
  --protocol tcp --port 8080 --source-group sg-web
# db tier: MySQL only from the app tier's SG
aws ec2 authorize-security-group-ingress --group-id sg-db \
  --protocol tcp --port 3306 --source-group sg-app
Expected output
{ "Return": true }   # web rule added (443 from 0.0.0.0/0)
{ "Return": true }   # app rule added (8080 from sg-web)
{ "Return": true }   # db rule added (3306 from sg-app)
# net result: internet → web → app → db, each tier trusts only the one above
Figure 4 — SG vs NACL — the one-card cheat-sheet
Security Group versus Network ACL on one card — scope, state, allow or deny, rule order, the ephemeral return rule, and where each belongs A side-by-side cheat sheet. The left column describes the Security Group: it operates at the instance or ENI level, is stateful, supports allow rules only, evaluates all rules together, needs no return rule because it is stateful, and can reference other security groups. The right column describes the Network ACL: it operates at the subnet level, is stateless, supports both allow and deny, evaluates rules in number order with the first match winning, requires an explicit outbound ephemeral rule of 1024 to 65535 for return traffic, and matches only CIDR ranges. A bottom band gives the rule of thumb: allow-by-design and tier trust go in Security Groups, blocking a bad CIDR goes in a NACL deny. Security Group vs NACL — your one-glance card Security Group (instance / ENI)• Stateful — return traffic auto-allowed• ALLOW rules only (no deny exists)• All rules evaluated together• Can reference another SG (tier trust) Network ACL (subnet)• Stateless — both directions explicit• ALLOW and DENY both supported• Rules in number order, first match wins• Matches CIDR only (no SG references) Defaults — know colddefault SG: in from same SG, all outnew custom SG: deny in, all outdefault NACL: all in + all outnew custom NACL: DENY everything The ephemeral return ruleNACL outbound: ALLOW TCP 1024–65535Linux 32768–60999 · Win 49152–65535NAT-GW / ELB use full 1024–65535SG needs none — it's stateful First CLI commandsaws ec2 authorize-security-group-ingressaws ec2 create-network-acl-entry --egressaws ec2 describe-network-acls Symptom → causeconnects but reply hangs → NACLephemeral outbound missingFlow Logs: in ACCEPT, out REJECT Rule of thumb: ALLOW-by-design + tier trust → Security Group · BLOCK a bad CIDR → NACL DENY (low rule #)
Your one-glance card for any SG/NACL question — scope, statefulness, allow/deny, rule order, the ephemeral rule, and where each control belongs. Keep it open before any AWS networking interview.
Daily-life analogy — the society gate-pass register (allow vs ban list)

Your society's main gate (the NACL) keeps two lists: an allow list (residents and approved visitors get in) and a ban list (this delivery agent is barred — a DENY). Your flat door (the Security Group) only has a guest list — you can invite people in, but you can't 'ban' someone at your door, you just don't add them. So when you need to actively block a known troublemaker for the whole building, that goes on the gate's ban list (NACL DENY), not your flat's guest list (SG).

For the cert, this lesson sits squarely in the SCS-C02 'Infrastructure Security' domain — Security Groups and NACLs are bread-and-butter VPC controls the exam loves to test with 'request arrives, reply doesn't' trick scenarios and 'which control can DENY a subnet-wide IP' questions. If you can state statefulness, the ephemeral-port rule, the AND-gate combination, and the SG-to-SG reference without hesitating, you've got the network-security questions in the bag. Career-wise this is day-one knowledge for any AWS support or cloud-ops role in India — it comes up in nearly every interview.

Quick check · Q4 of 10

An interviewer asks Meera: "Give me the single cleanest way to let an auto-scaling app tier reach a database, without updating rules every time an app server's IP changes." Best answer?

Correct: c. Referencing sg-app in the db's Security Group rule means 'allow any instance carrying sg-app', so new app servers with new IPs are trusted automatically — no rule edits, survives auto-scaling. Hard-coding IPs in a NACL breaks on every scale event; opening the db to the world is a breach waiting to happen; and collapsing tiers into one subnet throws away the isolation you wanted.

🤖 Ask the AI Tutor

Tap any question — instant, scoped to this lesson. No login, no waiting.

Pre-curated from AWS docs + community Q&A, scoped to this lesson. For a live prod issue, paste your export into chat.techclick.in.

📝 Wrap-up assessment — six more

You've answered 4 inline. Six left. 70% (7 of 10) marks the lesson complete on your profile. Tap Submit all answers at the end.

Q5 · Remember

Which statement correctly pairs each AWS control with its level and statefulness?

Correct: c. A Security Group attaches to an instance's ENI and is stateful (return traffic auto-allowed). A Network ACL guards the subnet boundary and is stateless (every packet judged alone). The other options swap the level or the statefulness, which is the exact confusion the exam tests.
Q6 · Apply

You add a custom NACL to a subnet and allow inbound HTTPS (443). Clients can open the connection but pages never finish loading. What single change fixes it?

Correct: a. The NACL is stateless, so the reply (going to the client's high ephemeral port) needs an explicit outbound allow; 1024–65535 covers all client types. ICMP is unrelated; the SG is stateful so its outbound rule isn't the blocker; and the AZ has nothing to do with a return-path rule.
Q7 · Apply

An auto-scaling app tier must reach a database, and instances are constantly replaced with new IPs. What's the right Security Group rule on the database?

Correct: b. Referencing sg-app means 'any instance carrying the app-tier SG is trusted', so new app servers are allowed automatically regardless of IP — it survives auto-scaling. Per-IP rules break on every scale event, 0.0.0.0/0 exposes the database, and a NACL can't reference SGs (only CIDRs).
Q8 · Analyze

A NACL has rule 50 = ALLOW 203.0.113.66 and rule 120 = DENY 203.0.113.66 (same IP). Does that IP get through, and why?

Correct: d. NACLs evaluate in ascending number order and stop at the first match. Rule 50 (allow) matches first, so the packet is permitted and rule 120 is never evaluated. NACLs have no 'deny wins' precedence; lower numbers are evaluated first, not higher; and this is purely a NACL ordering question, independent of any SG.
Q9 · Analyze

VPC Flow Logs for a web server show: inbound to 443 = ACCEPT, but outbound on port 54321 = REJECT. The Security Group is unchanged and correct. Most likely root cause?

Correct: a. Inbound ACCEPT then outbound REJECT on a high port is the fingerprint of a stateless NACL with no ephemeral outbound rule — the request arrived but the reply is blocked. Security Groups can't 'become stateless'; an OS-firewall block on 443 inbound would have stopped the request (it was ACCEPTed); and a missing default route would break the request path, not just the ephemeral reply.
Q10 · Evaluate

Two engineers debate where to put a block for a malicious /24 that's scanning a subnet. Engineer A: 'add a deny in the Security Group of each instance.' Engineer B: 'add a low-numbered DENY rule in the subnet's NACL.' Who's right and why?

Correct: c. Engineer B is right: there is no such thing as a Security Group deny rule, so you cannot 'add a deny' to an SG. Blocking a bad CIDR for an entire subnet is exactly the NACL's job via an explicit DENY, and it must sit at a low rule number to be evaluated before any allow. The internet gateway isn't a filtering control, so that option is wrong too.
Lesson complete — saved to your profile.
Almost! You need 70% (7 of 10) — re-read the path that tripped you up and tap "Try again".

🧠 In your own words

Type one line: In one line, why does a request reach your EC2 instance but the reply never come back, even though your Security Group is correct? Then compare to the expert version.

Expert version: Because the subnet's NACL is stateless: it allowed the inbound request but has no outbound rule for the client's high ephemeral port, so it drops the reply — fixed by adding an outbound ALLOW for TCP 1024–65535 (the stateful Security Group, by contrast, returns replies automatically).

🗣 Teach a friend

Best way to lock it in — explain it in one line to a teammate. Tap to generate a paste-ready summary.

📖 Glossary

Security Group (SG)
Stateful virtual firewall attached to an instance's ENI. Allow-rules only; remembers connections so replies are automatic.
Network ACL (NACL)
Stateless firewall at the subnet boundary. Supports ALLOW and DENY, numbered rules evaluated in order, no memory of past traffic.
Stateful
The firewall remembers each allowed connection, so the return traffic is auto-permitted regardless of outbound rules. (Security Groups.)
Stateless
The firewall keeps no memory; each packet is judged alone, so request and reply must each be explicitly allowed. (NACLs.)
Ephemeral port
A short-lived high source port (1024–65535) the client picks; the server's reply is addressed to it. Must be allowed outbound on a NACL.
ENI
Elastic Network Interface — the virtual NIC of an instance. A Security Group attaches here, which is why the SG is 'instance-level'.
Subnet
An IP range inside a VPC, tied to one availability zone. Every subnet is associated with exactly one NACL.
Rule number (NACL)
1–32766 for your rules; evaluated lowest-first and the first match wins, then evaluation stops. Put DENY rules at low numbers.
Default NACL
The NACL a subnet gets if you attach none. Out of the box it allows ALL inbound and outbound (rule 100 allow + the * deny catch-all).
SG reference
A Security Group rule whose source is another SG, not a CIDR. Means 'allow any instance carrying that SG' — survives auto-scaling.
Defense in depth
Layering independent controls so a gap in one is caught by another — here, the subnet NACL backstops an instance-level SG mistake.
VPC Flow Logs
Per-flow records showing ACCEPT/REJECT for traffic at an ENI/subnet/VPC; the tool that proves which layer dropped a packet.

📚 Sources

  1. Amazon VPC User Guide — "Control subnet traffic with network access control lists" (NACL basics: stateless; rules numbered 1–32766, lowest-first, first match wins; default vs custom NACL behaviour; the * catch-all deny). docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html
  2. Amazon VPC User Guide — "Control traffic to your AWS resources using security groups" + "Default security groups" (SGs are stateful, allow-only; default SG self-reference inbound + all outbound; new custom SG denies inbound). docs.aws.amazon.com/vpc/latest/userguide/vpc-security-groups.html · docs.aws.amazon.com/vpc/latest/userguide/default-security-group.html
  3. Amazon VPC User Guide — "Ephemeral ports" / NACL examples (documented client ranges: Linux 32768–60999, Windows Server 2008+ 49152–65535, NAT gateway & ELB 1024–65535; AWS recommends opening 1024–65535 outbound on a NACL). docs.aws.amazon.com/vpc/latest/userguide/nacl-ephemeral-ports.html
  4. AWS re:Post — "Resolve inbound traffic ACL connections to AWS" + AWS blog "Building three-tier architectures with security groups" (real practitioner pain: stateless NACL must allow ephemeral return range; SG-to-SG referencing for web/app/db tiers). repost.aws/knowledge-center/resolve-connection-sg-acl-inbound · aws.amazon.com/blogs/aws/building-three-tier-architectures-with-security-groups/
  5. r/aws + Medium (Remy NTSHAYKOLO, "Why the need to set ephemeral ports range for NACL outbound rules") — the community gotcha: request arrives but reply is dropped when the outbound 1024–65535 NACL rule is missing; diagnose with VPC Flow Logs (inbound ACCEPT, outbound REJECT). remy-nts.medium.com/aws-nacl-why-the-need-to-set-ephemeral-ports-range-for-outbound-rules-50ee93986555
  6. AWS Certified Security – Specialty (SCS-C02) Exam Guide — Domain: Infrastructure Security (VPC security groups & network ACLs, defense-in-depth, designing secure network controls for multi-tier apps). aws.amazon.com/certification/certified-security-specialty/

What's next?

You can now read the packet path and stack SGs on NACLs. Next we move up a layer to the storage that leaks the most in the headlines: an S3 bucket that's one checkbox away from public — and exactly how to slam that door shut.