Security Groups and Network ACLs
Security Groups and Network ACLs — Two Firewall Layers
AWS network firewalling has two layers: the Security Group (SG) attached to instances, and the Network ACL (NACL) attached to subnets. The names are similar, but the operating models differ quite a bit.
1. About the two layers
| Item | Security Group | Network ACL |
|---|---|---|
| Scope | ENI (instance) | Subnet |
| Statefulness | Stateful | Stateless |
| Default policy | Inbound deny / outbound allow | Default NACL allows everything |
| Rule types | Allow only (no deny) | Both Allow and Deny |
| Evaluation | All rules ORed | Lowest-numbered first; stop on match |
| Response traffic | Auto-allowed | Requires explicit rules |
2. Security Group — Stateful
"Stateful" means the response to an allowed inbound is auto-allowed regardless of outbound rules. Even if the SG's outbound is fully blocked, response packets to the client still go out.
Inbound:
- HTTP, Source: 0.0.0.0/0
- HTTPS, Source: 0.0.0.0/0
- SSH, Source: 203.0.113.5/32 # my IP
Outbound:
- All traffic, 0.0.0.0/0 # default
The source/destination can be not just an IP range but also another SG ID. Rules like "allow only traffic from the ALB's SG" are possible — there is no need to update IPs as instances change.
3. Network ACL — Stateless
Per subnet. Rules are evaluated in numeric order and stop at the first match.
Inbound:
100 ALLOW HTTP 0.0.0.0/0
110 ALLOW HTTPS 0.0.0.0/0
120 ALLOW TCP 1024-65535 # ephemeral response ports
* DENY ALL
Outbound:
100 ALLOW TCP 1024-65535 # ephemeral response
110 ALLOW HTTP/HTTPS
* DENY ALL
Because it is stateless, ephemeral ports (typically 1024–65535) must be specified for responses. Tightening NACLs too far blocks legitimate traffic.
4. Evaluation order across layers
Inbound packets are evaluated in NACL → SG → instance order. If either layer blocks, the packet is dropped. When troubleshooting in production, check both layers.
5. Common SG rule patterns
| Role | Inbound |
|---|---|
| ALB (public) | 80, 443 ← 0.0.0.0/0 (::/0 for IPv6) |
| Web/app EC2 | 8080 ← ALB's SG |
| RDS | 5432 ← app SG |
| Redis | 6379 ← app SG |
| Bastion | 22 ← office/home IP/32 |
DBs and Redis are not exposed directly. Only the app SG should be allowed in.
6. The danger of 0.0.0.0/0
0.0.0.0/0 means the entire internet. Frequent incidents:
- SSH 22 open to
0.0.0.0/0— A target for automated scanners. - DB port 5432 / 3306 open to
0.0.0.0/0— The DB is exposed to the entire internet. - Management UIs (e.g., Kibana 5601) open to
0.0.0.0/0.
Best practices:
- Only 80 / 443 open to
0.0.0.0/0. - SSH from office/home IP/32, or via SSM Session Manager (no port exposure).
- DB only from the app SG.
7. The role of NACLs
In most production environments, SGs alone are enough and NACLs are left at their default (allow all). NACLs shine when:
- Blocking specific IP ranges plainly (SGs cannot deny — use NACL).
- Subnet-wide blanket policies.
- Compliance requirements that mandate explicit deny rules.
Tightening NACLs incorrectly disconnects whole subnets. Be careful in production.
8. Bastion or SSM
Flows that avoid exposing SSH 22:
- Bastion (jump host) — Only one host has 22 exposed; other instances allow only the bastion's SG.
- AWS SSM Session Manager — Skip port 22 entirely; shell access is granted via IAM authentication.
The latter reduces key-management burden and writes audit logs to IAM and CloudTrail.
9. Counterparts in other clouds
- GCP — VPC Firewall Rules. Sits between SG and NACL — VPC-scoped, stateful, priority-based.
- Azure — Network Security Group (NSG). Priority-based evaluation.
The same vocabulary can hide a different model — something to verify when migrating.
10. Common pitfalls
Connections after SG changes — Some changes apply immediately; existing connections may drop. Verify with new connections during checks.
NACL ephemeral ports — Responses often get blocked. When tightening NACLs, also widen outbound response ports.
Multiple SGs as a union — When several SGs attach to one ENI, the rule set is the union (allowed if any SG allows).
IPv6 omission — Setting only 0.0.0.0/0 misses IPv6 traffic. Specify ::/0 when needed.
MyIP changing — Home internet IPs change often. Automate dynamic updates, or use VPN or SSM.
Closing thoughts
The stateful model of SGs combined with SG-ID references is much easier to use than NACLs once mastered. The most common incident is accidentally opening management ports such as 22 / 5432 / 6379 to 0.0.0.0/0, so it is safer to design toward SSM Session Manager from the start.
Next
- ec2
- deploying-options
Security Groups · Network ACL · VPC security best practices · SSM Session Manager · GCP Firewall · Azure NSG for reference.