Security Group vs NACL: Key Differences and When to Use Each
Security Group acts as a virtual firewall for instances controlling inbound and outbound traffic at the instance level, while a Network ACL (NACL) controls traffic at the subnet level with stateless rules. Security Groups are stateful and allow return traffic automatically, whereas NACLs are stateless and require explicit rules for both inbound and outbound traffic.Quick Comparison
This table summarizes the main differences between Security Groups and Network ACLs in AWS.
| Feature | Security Group | Network ACL (NACL) |
|---|---|---|
| Scope | Instance level | Subnet level |
| Type | Stateful (remembers traffic) | Stateless (no memory of traffic) |
| Rules | Allow rules only | Allow and deny rules |
| Default behavior | Deny all inbound, allow all outbound | Deny all inbound and outbound by default |
| Rule evaluation | All rules evaluated before allowing traffic | Rules evaluated in order, first match applies |
| Use case | Control instance access | Control subnet traffic flow |
Key Differences
Security Groups act like a protective shield around individual instances. They are stateful, meaning if you allow incoming traffic on a port, the response traffic is automatically allowed back out without extra rules. They only have allow rules, so you specify what traffic is permitted, and everything else is blocked by default.
Network ACLs (NACLs) work at the subnet level and are stateless. This means you must explicitly allow both inbound and outbound traffic separately. NACLs support both allow and deny rules, giving you more granular control to block specific traffic. Rules are processed in order, and the first matching rule decides the action.
Because Security Groups are stateful and easier to manage, they are typically used to protect instances directly. NACLs provide an additional layer of security at the subnet level, useful for broad traffic filtering or blocking unwanted IP ranges.
Code Comparison
Here is an example of how to create a Security Group that allows inbound HTTP traffic on port 80 using AWS CLI.
aws ec2 create-security-group --group-name MyWebSG --description "Allow HTTP traffic" aws ec2 authorize-security-group-ingress --group-name MyWebSG --protocol tcp --port 80 --cidr 0.0.0.0/0
Network ACL Equivalent
Here is how to create a Network ACL and add a rule to allow inbound HTTP traffic on port 80 using AWS CLI.
aws ec2 create-network-acl --vpc-id vpc-123abc aws ec2 create-network-acl-entry --network-acl-id acl-123abc --rule-number 100 --protocol tcp --port-range From=80,To=80 --egress false --rule-action allow --cidr-block 0.0.0.0/0 aws ec2 create-network-acl-entry --network-acl-id acl-123abc --rule-number 101 --protocol tcp --port-range From=80,To=80 --egress true --rule-action allow --cidr-block 0.0.0.0/0
When to Use Which
Choose Security Groups when you want to control access to individual instances easily with stateful rules that automatically allow return traffic. They are simpler and recommended for most instance-level security needs.
Choose Network ACLs when you need to control traffic at the subnet level, require explicit deny rules, or want an additional layer of security to block unwanted IP addresses or protocols before traffic reaches instances.