3.5
Security Groups vs NACLs and Ephemeral Ports
Stateful vs stateless filtering, rule order, ephemeral ports, a three-tier rule set, and timeout vs connection refused.
34 min Reading + animations
Tip: tap or hover any dotted-underlined term to see what it means.
By the end of this lesson you will be able to
- Explain the two firewall layers of a VPC and where each one sits.
- Write security group rules, including rules that reference other security groups.
- Write network ACL rules, apply “first match wins”, and avoid the custom-NACL and rule-order traps.
- Explain stateful vs stateless filtering and add the ephemeral-port rules that stateless filtering needs.
- Build a complete rule set for a web tier and a database tier, and debug “timeout” vs “connection refused”.
#Two layers of firewall
Every packet that enters or leaves an instance in a VPC can be filtered twice:
- A network ACL (NACL) at the subnet boundary. It checks every packet entering or leaving the subnet.
- A security group (SG) around each instance (strictly, around each network interface). It checks packets entering or leaving that one instance.
Traffic from the internet to a web server passes the subnet’s network ACL first, then the instance’s security group. The reply leaves through the security group and then the network ACL.
#Security groups
A security group is a set of allow rules. Each rule names a protocol, a port range and a source (for inbound) or destination (for outbound). The source can be:
- a CIDR block, for example
0.0.0.0/0(anyone) or203.0.113.25/32(one address); - another security group, meaning “any network interface that has that security group attached”;
- a managed prefix list (a named list of CIDR blocks).
How security groups behave:
| Behaviour | Detail |
|---|---|
| Allow rules only | There is no “deny” rule. Anything not allowed is dropped. |
| Stateful | If a request is allowed in, its reply is allowed out automatically, and vice versa. Outbound rules are not even consulted for replies. |
| All rules evaluated | No order, no numbers: if any rule allows the traffic, it is allowed. |
| Defaults for a new group | No inbound rules (all inbound blocked) and one outbound rule allowing all traffic. |
| Attached to network interfaces | An instance can have several security groups (5 per interface by default); their rules are combined. One group can be attached to many instances. |
| Scope | A security group belongs to one VPC in one Region. |
| Changes are immediate | Editing a rule affects existing instances right away; no restart. |
| Quotas | 60 inbound and 60 outbound rules per group by default (adjustable). |
Security groups operate outside the instance: blocked traffic never reaches the operating system, so the instance cannot see it or log it.
#Referencing other security groups
The most powerful feature is using a security group as the source of a rule. Instead of “allow port 3306 from 10.0.1.0/24”, you write “allow port 3306 from sg-web”. Then:
- any instance with
sg-webattached can connect, wherever it is in the VPC; - new web servers launched by an Auto Scaling group are allowed automatically;
- nothing else in the same subnet is allowed, even with a neighbouring address.
This is how tiers are chained: load balancer → web servers → database, each group allowing only the group in front of it. It works within a VPC, and across peered VPCs in the same Region.
#Ports you must recognise
| Port | Protocol | Used for |
|---|---|---|
| 22 | SSH | Log in to a Linux instance; also SFTP (file transfer over SSH) |
| 21 | FTP | Unencrypted file transfer |
| 80 | HTTP | Unencrypted websites |
| 443 | HTTPS | Encrypted websites and APIs |
| 3389 | RDP | Remote Desktop to a Windows instance |
| 3306 | MySQL / MariaDB / Aurora MySQL | Database connections |
| 5432 | PostgreSQL / Aurora PostgreSQL | Database connections |
A real example: a WordPress site on one EC2 instance. Everyone must see the site, so the security group allows HTTP (80) and HTTPS (443) from 0.0.0.0/0. You also need SSH (22) to maintain the server, but only from your own home or office address, for example 203.0.113.25/32, never from 0.0.0.0/0. On the exam, port 22 open to 0.0.0.0/0 is always the “bad practice” option.
#Network ACLs
A network ACL is a numbered list of allow and deny rules applied at the subnet boundary.
| Behaviour | Detail |
|---|---|
| Allow and deny | Rules can explicitly deny, which makes NACLs the tool for blocking a specific IP address or range. |
| Stateless | Nothing is remembered. A reply is a new packet and must match its own rule in the other direction. |
| Numbered, first match wins | Rules are checked from the lowest number up (1 to 32766). The first rule that matches decides, and later rules are never read. |
| Final catch-all | Every NACL ends with a * rule that denies anything no numbered rule matched. It cannot be edited or removed. |
| One per subnet | A subnet is associated with exactly one NACL; one NACL can serve many subnets. A new subnet uses the VPC’s default NACL. |
| Numbering habit | AWS suggests steps of 100 (100, 200, 300…) so you can insert rules in between later. |
| Quotas | 20 rules per direction by default (adjustable to 40). |
Network ACLs can only reference CIDR blocks, never security groups.
#Default vs custom network ACLs
This is one of the most frequently tested traps:
- The default NACL (created with every VPC) allows all inbound and all outbound traffic.
- A custom NACL you create denies all inbound and all outbound traffic until you add rules.
Network ACL rules: first match wins
The same two rules in two orders. Watch the scanner stop at the first rule that matches.
Scenario
Inbound rules (lowest number first)
| Rule # | Type | Source | Action |
|---|---|---|---|
| 100 | All traffic | 203.0.113.50/32 | Deny |
| 200 | TCP 80 | 0.0.0.0/0 | Allow |
| * | All traffic | 0.0.0.0/0 | Deny |
The attacker’s packet arrives. Rule 100 is checked first: source 203.0.113.50/32 matches.
#Stateful vs stateless and ephemeral ports
Every TCP connection has two ends, and both use a port:
- The server listens on a well-known port: 80, 443, 3306…
- The client uses a temporary port chosen by its operating system for this one connection: an ephemeral port.
So a browser on 198.51.100.20 might send 198.51.100.20:50105 → 10.0.1.10:80, and the reply travels 10.0.1.10:80 → 198.51.100.20:50105. The reply goes to the client’s ephemeral port.
A stateful security group handles this for you. A stateless network ACL does not: its outbound rules must allow the replies to the clients’ ephemeral ports, and if your servers are the clients (calling a database or an API), its inbound rules must allow the replies coming back to their ephemeral ports.
Ephemeral port ranges differ by system:
| Client | Ephemeral range |
|---|---|
| Most Linux kernels (including Amazon Linux) | 32768–60999 |
| Windows Server 2008 and later, IANA recommendation | 49152–65535 |
| AWS NAT gateway, Elastic Load Balancing, Lambda | 1024–65535 |
Because a public web server’s clients can be anything, the usual rule is TCP 1024–65535, which covers all of them.
One request, two firewalls, both directions
A browser asks a web server for a page. The network ACL checks at the subnet edge, the security group at the instance.
Scenario
The browser picks a random source port (an ephemeral port, here 50105) and connects to port 80. The packet reaches the subnet boundary first.
Self-checkQuestion
You must block a single malicious IP address from reaching every instance in a subnet. What should you use?
#Security groups vs network ACLs
| Security group | Network ACL | |
|---|---|---|
| Applies to | Instances / network interfaces it is attached to | Every resource in the associated subnets |
| Rules | Allow only | Allow and deny |
| State | Stateful: replies allowed automatically | Stateless: replies need their own rules |
| Evaluation | All rules, no order | By number, lowest first, first match wins |
| Sources | CIDR blocks, other security groups, prefix lists | CIDR blocks only |
| Default | New group: no inbound, all outbound | Default NACL: allow all. Custom NACL: deny all |
| Typical use | The main, fine-grained control for every resource | Coarse subnet guardrails and blocking specific addresses |
In practice, most designs put precise rules in security groups and keep network ACLs simple (often the default), adding NACL rules for subnet-wide guardrails or to block known bad addresses.
#A complete two-tier rule set
A classic exam scenario: VPC 10.0.0.0/16, a public web subnet 10.0.1.0/24 serving HTTP/HTTPS, and a private database subnet 10.0.2.0/24 running MySQL on port 3306.
Web subnet NACL, inbound
| Rule # | Type | Source | Action | Purpose |
|---|---|---|---|---|
| 50 | All traffic | 203.0.113.50/32 | Deny | Block a known bad actor |
| 100 | TCP 80 | 0.0.0.0/0 | Allow | HTTP visitors |
| 110 | TCP 443 | 0.0.0.0/0 | Allow | HTTPS visitors |
| 120 | TCP 1024–65535 | 10.0.2.0/24 | Allow | Replies from the database |
| * | All traffic | 0.0.0.0/0 | Deny | Everything else |
Web subnet NACL, outbound
| Rule # | Type | Destination | Action | Purpose |
|---|---|---|---|---|
| 100 | TCP 1024–65535 | 0.0.0.0/0 | Allow | Replies to browsers (ephemeral ports) |
| 110 | TCP 3306 | 10.0.2.0/24 | Allow | Queries to the database subnet only |
| * | All traffic | 0.0.0.0/0 | Deny | Everything else |
Database subnet NACL, inbound
| Rule # | Type | Source | Action | Purpose |
|---|---|---|---|---|
| 100 | TCP 3306 | 10.0.1.0/24 | Allow | Database connections from the web subnet only |
| * | All traffic | 0.0.0.0/0 | Deny | The internet and everything else |
Database subnet NACL, outbound
| Rule # | Type | Destination | Action | Purpose |
|---|---|---|---|---|
| 100 | TCP 1024–65535 | 10.0.1.0/24 | Allow | Query results back to the web servers |
| * | All traffic | 0.0.0.0/0 | Deny | Nothing leaves for the internet |
A web tier and a database tier, rule by rule
VPC 10.0.0.0/16 · web subnet 10.0.1.0/24 · database subnet 10.0.2.0/24 (MySQL on 3306). Each step shows the rule that decided.
Scenario
Web NACL · inbound
| Rule # | Type | Source / destination | Action |
|---|---|---|---|
| 50 | All traffic | 203.0.113.50/32 | Deny |
| 100 | TCP 80 | 0.0.0.0/0 | Allow |
| 110 | TCP 443 | 0.0.0.0/0 | Allow |
| 120 | TCP 1024–65535 | 10.0.2.0/24 | Allow |
| * | All traffic | 0.0.0.0/0 | Deny |
The visitor’s HTTPS request enters the web subnet. Web inbound rules: 50 does not match this source; 100 is port 80, no; 110 allows TCP 443. Allow.
Three things worth noticing in this design:
- Web outbound rule 110 is redundant: rule 100 (1024–65535 to anywhere) already covers 3306 and is checked first. It does no harm and documents intent, but it is not what allows the traffic.
- Rule 50 blocks all traffic, not just port 80. A deny on port 80 alone would still let the attacker in on 443 through rule 110.
- The web servers cannot start outbound connections to the internet on 80/443 (for example, to download updates): outbound only allows high ports. That is fine for a strict design, but updates would then need a proxy, a NAT path with matching rules, or VPC endpoints.
The matching security groups are simpler, because they are stateful and can reference each other:
| Security group | Inbound rule |
|---|---|
sg-web | TCP 80 and 443 from 0.0.0.0/0 (or from the load balancer’s security group, if there is one) |
sg-db | TCP 3306 from sg-web |
#Try it yourself
# Security groups: web allows HTTPS from anywhere, db allows MySQL only from the web group
WEB=$(aws ec2 create-security-group --group-name web --description web --vpc-id $VPC --query GroupId --output text)
DB=$(aws ec2 create-security-group --group-name db --description db --vpc-id $VPC --query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id $WEB --protocol tcp --port 443 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id $DB --protocol tcp --port 3306 --source-group $WEB
# Network ACL: block one address with a low rule number
aws ec2 create-network-acl-entry --network-acl-id $NACL --ingress --rule-number 50 \
--protocol -1 --cidr-block 203.0.113.50/32 --rule-action deny
# Debug from a client: timeout vs refused
curl -m 5 http://203.0.113.25/ # "timed out" → firewall; "Connection refused" → no app listening
#Summary
Key takeaways
- A VPC has two filters: network ACLs at the subnet boundary and security groups at each instance.
- Security groups: allow rules only, stateful, all rules evaluated together, can reference other security groups; new groups block all inbound and allow all outbound.
- Network ACLs: allow and deny, stateless, numbered and first match wins, end with a
*deny, CIDR blocks only, one per subnet. Use them to block specific IPs. - Default NACL allows everything; a new custom NACL denies everything.
- Replies go to the client’s ephemeral port. Stateless NACLs need explicit rules for them; 1024–65535 covers every client type (Linux uses 32768–60999, Windows 49152–65535).
- “Request arrives, reply never does” → network ACL. Timeout → a firewall; connection refused → no application listening.
- Chain tiers with security groups that reference each other (
sg-dballows 3306 fromsg-web); never open a database port to0.0.0.0/0.
Answer on your own first, then read the explanation, even when you got it right.
Self-checkQuestion
A security group allows inbound TCP 443 from 0.0.0.0/0 and has its default outbound rule removed (no outbound rules). Can clients still receive HTTPS responses?
Self-checkQuestion
A team creates a new network ACL, associates it with a production subnet, and the application immediately goes offline. Why?
Self-checkQuestion
Which source should the database security group use to allow MySQL connections only from the application servers, including ones launched later by Auto Scaling?
Self-checkQuestion
Which two statements about network ACLs are true?
Choose 2
Self-checkQuestion
Where does a network ACL filter traffic?
Self-checkQuestion
A security group has just been created and none of its rules have been changed. What does it allow?
Self-checkQuestion
An administrator must connect to a Windows instance with Remote Desktop. Which port must the security group allow from the administrator’s address?
Self-checkQuestion
An application tier connects to an Aurora PostgreSQL cluster. Which port should the database security group allow from the application tier’s security group?
Self-checkQuestion
A small company runs a WordPress site on one EC2 instance. Which inbound security group rules follow best practice?
Self-checkQuestion
A colleague insists: ‘Our web servers’ security group needs an outbound rule for TCP 1024–65535, otherwise replies to visitors will be dropped.’ What is correct?
Self-checkQuestion
An instance has two security groups attached. sg-admin allows TCP 22 from 203.0.113.25/32 and sg-web allows TCP 443 from 0.0.0.0/0. Which inbound traffic reaches the instance?
Self-checkQuestion
Which of these cannot be used as the source of a security group inbound rule?
Self-checkQuestion
Which two statements about security groups are true?
Choose 2
Self-checkQuestion
A developer runs curl against an instance on port 8080 and gets ‘Connection refused’ immediately. What is the most likely cause?
Self-checkQuestion
Users report that a website hangs for about 30 seconds and then shows a timeout. The web server process is running and listening on port 443. Where should a solutions architect look first?
Self-checkQuestion
A client cannot connect to TCP 443 on an instance: the connection times out. Which two causes fit this symptom?
Choose 2
Self-checkQuestion
What is true about the rule marked * at the end of every network ACL?
Self-checkQuestion
A solutions architect adds a new subnet to an existing VPC and does not associate it with any network ACL. What does the subnet get at the NACL layer?
Self-checkQuestion
A network ACL has these inbound rules: rule 100 allows TCP 80 from 0.0.0.0/0; rule 200 denies all traffic from 198.51.100.7/32; rule * denies all. What happens to a TCP 80 packet from 198.51.100.7?
Self-checkQuestion
A team adds an inbound network ACL rule 200 that denies all traffic from 203.0.113.50/32. Rule 100 already allows all traffic from 0.0.0.0/0. The attacker at 203.0.113.50 still gets through. What should they do?
Self-checkQuestion
A network ACL has these inbound rules: rule 90 denies TCP 22 from 203.0.113.0/24; rule 100 allows all traffic from 0.0.0.0/0; rule * denies all. What happens to a TCP 443 packet from 203.0.113.40?
Self-checkQuestion
A browser at 198.51.100.20 opens a connection from port 50105 to a web server at 10.0.1.10 on port 80. What are the source and destination of the server’s reply?
Self-checkQuestion
By default, which ephemeral port range does the Linux kernel, including Amazon Linux, use for outgoing connections?
Self-checkQuestion
Which two can use source ports anywhere from 1024 to 65535, which is one reason network ACL rules usually open the whole 1024–65535 range?
Choose 2
Self-checkQuestion
A company hosts a website on EC2 instances in a public subnet with a custom network ACL. The security group allows TCP 80 and 443 from 0.0.0.0/0. The NACL inbound rules allow TCP 80 and 443 from 0.0.0.0/0, and the outbound rules allow only TCP 80 and 443 to 0.0.0.0/0. Users cannot load the site. What should the solutions architect change?
Self-checkQuestion
Two instances are in the same subnet. The subnet’s network ACL is a fresh custom NACL with only the * deny rules. Instance B’s security group allows TCP 5432 from instance A’s security group. Can A connect to B on port 5432?
Self-checkQuestion
The database subnet’s network ACL must allow MySQL connections only from the web tier, which runs in subnet 10.0.1.0/24 and uses the security group sg-web. What should the inbound NACL rule’s source be?
Self-checkQuestion
A company runs a three-tier application: an internet-facing Application Load Balancer, web servers in an Auto Scaling group, and an Aurora MySQL database. Only the load balancer may reach the web servers, and only the web servers may reach the database. Which security group design meets this?
Self-checkQuestion
In the lesson’s web subnet NACL, outbound rule 100 allows TCP 1024–65535 to 0.0.0.0/0 and rule 110 allows TCP 3306 to 10.0.2.0/24. A web server sends a query to 10.0.2.15 on port 3306. Which rule allows the packet?
Self-checkQuestion
In the lesson’s web subnet NACL, why does inbound rule 50 deny all traffic from 203.0.113.50/32 instead of only TCP 80?
Self-checkQuestion
The web servers in the lesson’s two-tier design must download updates directly from the internet over HTTPS (the subnet already routes to an internet gateway). Which two network ACL changes are needed?
Choose 2
Self-checkQuestion
Which statement about network ACLs is false?