Security groups and NACLs

Lesson 1 of 4 in Network Security Controls.

If you learn one network fact for this exam, learn this one: security groups are stateful and network ACLs are stateless.

A security group is attached to an elastic network interface — not to an instance, and not to a subnet. It holds allow rules only, there is no rule order, and every rule is evaluated: if any rule permits the traffic, it is permitted. Because it is stateful, a connection the group allowed in is automatically allowed to answer. You never write a rule for the response.

A network ACL is attached to a subnet and applies to every ENI in it. It holds numbered allow and deny rules, evaluated in ascending rule-number order, and the first match wins — rule 100 decides before rule 200 ever runs, and an implicit deny sits at the end of the list. Because it is stateless, the response is a separate packet that must be matched by its own rule in the opposite direction, and that response leaves from an ephemeral port the client chose — which is why NACL designs carry a rule for the 1024–65535 range. Get that wrong and the symptom is unmistakable: the request arrives, the server logs it and answers, and the client hangs until it times out.

The practical consequence is that a NACL is a blunt instrument you use deliberately — to deny a specific CIDR a subnet must never talk to, or to express a subnet-wide boundary that survives somebody editing a security group. Fine-grained access control belongs in security groups, where you can say "the application tier may reach the database tier" without writing a single IP address.

Security group against network ACL — nine differences that decide exam questions
Security groupNetwork ACL

Attaches to

an ENI (so: an instance, a load balancer node, an endpoint, an RDS instance)

a subnet — every ENI in it inherits the rules

State

stateful — return traffic is automatically allowed

stateless — the response needs its own rule in the other direction

Rule types

allow only

allow and deny

Evaluation

all rules, no order — any match allows

ascending rule number, first match wins, implicit deny at the end

Can reference

CIDRs, prefix lists, and other security groups (including its own)

CIDRs only

Default object behaviour

the default SG allows all traffic from members of itself and all outbound; a new SG has no inbound rules and allows all outbound

the default NACL allows all traffic both ways; a new NACL denies everything until you add rules

Ephemeral ports

never your problem

your problem on every return leg — allow 1024–65535

Good at

tier-to-tier access, least privilege, rules that follow the workload

coarse subnet boundaries, explicit denies, a guardrail that an app team cannot edit away

Logged by

VPC Flow Logs (ACCEPT/REJECT at the ENI)

VPC Flow Logs — the same records; the rule that rejected is not named, so you reason from direction and port

Referencing a security group as a source is the design pattern worth internalizing, because it is both the least-privilege answer and a frequent exam distractor's opposite. Instead of allowing 10.0.2.0/24 to reach the database on 5432, allow sg-app to reach sg-db on 5432. Now the rule means what you intended — "the application tier may talk to the database tier" — and it keeps meaning that as instances are replaced, as the application scales across new subnets, and as somebody re-plans the address space. Nothing in the rule needs editing, and an instance that is not a member of sg-app gains nothing by living in the same subnet.

The matching anti-pattern is a security group whose inbound rule is 0.0.0.0/0 on a database port, with the team explaining that "the subnet is private so it's fine". Route tables are a different control from security groups: a private subnet with no internet route still carries lateral traffic from everything else inside the VPC, every peered VPC, and every VPN or Direct Connect attachment that routes there.

The troubleshooting method is the other thing to carry into the exam, because "connectivity is broken" questions are solved by procedure, not intuition. Trace the packet in both directions and check, at each hop, the control that applies to that hop:

  1. Route — is there a route to the destination in the source subnet's route table, and a route back in the destination's?
  2. NACL inbound at the destination subnet — does a rule with a low enough number allow this protocol and port from this source?
  3. Security group inbound at the destination ENI — is there an allow rule, and does it reference the right source security group or CIDR?
  4. The response: the security group needs nothing (stateful), but the destination subnet's NACL outbound must allow the ephemeral port range back to the client, and the client's subnet NACL must allow it inbound.

A failure at step 2 or 3 means the request never arrives — nothing in the application log. A failure at step 4 means the request arrives, the application answers, and the client times out. That asymmetry tells you which control to look at before you open a single console page.

Which ephemeral range do I actually allow?

It depends on the client: Linux kernels typically use 32768–60999, Windows Server 49152–65535, and NAT gateways and Elastic Load Balancing use 1024–65535. Because a NACL rule is coarse anyway, the documented practical answer is to allow 1024–65535 for return traffic rather than trying to be clever — and if that range feels uncomfortably wide, that is the correct instinct, and it is the argument for putting your real controls in security groups.

Rule numbers: leave gaps

Number rules in increments (100, 200, 300) so you can insert a deny at 150 later without renumbering the list. Remember that the first match wins: a deny at 150 overrides an allow at 200, and an allow at 100 means a deny at 200 for the same traffic never runs. When an exam stem shows you a NACL table, read it in number order and stop at the first match — most of these questions are testing exactly that.

The default security group

Every VPC has one, and it allows all traffic between members of itself plus all outbound. Convenient, and a quiet lateral-movement path: anything launched without an explicit security group joins it and can reach everything else in it. Treat "resources are in the default security group" in a question as a finding, and the remediation as purpose-built groups per tier.

What a security group cannot do

It cannot deny. If you need "everything except this one address", a security group cannot express it — you allow a set and deny is implicit, or you use a NACL deny rule, or you filter in Network Firewall. It also cannot inspect payloads: a security group allowing 443 allows every HTTPS request, malicious or not, which is where WAF and Network Firewall begin.

Key terms: Security group, Network ACL (NACL), Ephemeral port, Stateful vs stateless filtering

Interactive checkpoint quiz (2 questions) — open this page in a browser to take it.