AWS Security Group vs NACL

AWS security group and network ACL
author valts

by Valts Ausmanis · August 14, 2024

AWS network security is one of the foundations that should be taken seriously, especially when you deploy your AWS resources in Amazon Virtual Private Cloud (VPC). There are two main building blocks that allow you to control access to AWS resources within the VPC - security groups and network access control lists (NACLs). While both play a fundamental role in controlling inbound and outbound traffic to your AWS resources, there are important differences between them. In this article, we will take a closer look at the differences between security groups and network ACLs.

In This Article

What is AWS Security Group?

security groups

A security group acts as a virtual firewall that controls the traffic allowed to reach and leave AWS resources (like EC2 instances, load balancers, RDS database instances, VPC endpoint interfaces, Redis instances, etc.) within your VPC.

When creating new inbound and outbound rules, you need to specify the following:

  • Protocol: The protocol to allow (e.g., TCP, UDP, ICMP).
  • Port range: The range of ports to allow (e.g., 22, 3500-3510).
  • Source/destination: The source or destination for the allowed traffic (e.g., IP address, another security group).

In the example below, we have added two rules to a security group that allow TCP traffic on ports 443 and 80 from any IP address. Since these ports are used for HTTP/HTTPS traffic, this means that if you run your own web servers on public EC2 instances with this security group assigned, anyone could now access your website.

security group inbound rules

What is AWS Network Access Control List?

network access control lists

Network access control list (NACL) acts as a virtual firewall to allow or deny inbound or outbound traffic at subnet level. Similar to security groups, you can create new inbound and outbound rules for network ACL by providing:

  • Rule number: The priority of the rule (lowest number has highest priority) that will be effective in case there are other rules.
  • Protocol: The protocol to allow (e.g., TCP, UDP, ICMP).
  • Port range: The range of ports to allow (e.g., 443, 4000-4010).
  • Source/destination: The source or destination for the allowed traffic.
  • Allow/deny flag: Whether to allow or deny the traffic

In the example below, you can see the default NACL inbound rules (by default associated to all the subnets in VPC). The first rule allows all inbound traffic from any source, while the last rule denies all traffic and would be effective if no other allow rules are specified.

nacl inbound rules

What are the Differences Between Security Group and NACL?

While both NACL and security group serve the same purpose of controlling inbound and outbound traffic to and from AWS resources, there are differences between the two. Let's compare them by describing each difference with practical examples.

Instance Level vs Subnet Level

Security groups are assigned at the instance level, more specifically to a network interface. Every EC2 instance, RDS, Redis, etc., deployed in a specific subnet in the VPC has a network interface assigned.

network interface

Network ACLs are associated at the subnet level. All the rules in a specific network ACL automatically apply to all instances deployed in the associated subnet.

network acl subnets

Now, let’s see how this difference works in practice. We’ll deploy two EC2 instances in public subnets and assign them a security group that allows ICMP traffic from any IP address. We'll use the default network access control list assigned to the subnets, which allows all inbound and outbound traffic.

visualized security groups

We will now attempt to ping the EC2 instance at its assigned public IP address (ex. 54.217.161.49) to check if we can establish communication:

ec2 ping success

As shown in the screenshot above, we successfully communicated with the newly created instance.

Now, let’s modify the NACL rule to deny ICMP traffic for all resources deployed in the associated subnets, that includes both newly created EC2 instances in our case.

visualized nacl

Then, run the same command (e.g., ping 54.217.161.49) to check if we can still communicate with the EC2 instance.

ec2 ping failure

As shown in the screenshot above, the change in the NACL inbound rules has disabled all ICMP traffic, and this rule overrides the one in the security group.

Stateful vs Stateless

Security groups are stateful, meaning that if an inbound rule allows specific traffic (e.g., TCP 443), it automatically allows the corresponding outbound traffic, regardless of the outbound rules.

Network ACLs are stateless, which means separate rules are required for inbound and outbound traffic. For example, if you allow TCP 443 inbound traffic, it does not automatically permit the same outbound traffic. This means that, for a TCP 443 requester (ex. open a website via browser) to receive a response, we must add a separate TCP 443 allow outbound rule.

Now, let’s deploy a new EC2 instance with the same security group with inbound rule for ICMP traffic from any IP address.

security group icmp allow

We will modify the default NACL to allow inbound ICMP traffic without a corresponding outbound rule:

nacl icmp deny rules

When we try to ping the EC2 instance – it’s not possible to communicate:

ping ec2

This clearly shows why a network ACL is “stateless” and that both inbound and outbound rules must be created to allow specific traffic to reach or leave AWS resources.

Rules Processing Order

Security groups aggregate all the rules before deciding to allow specific traffic. For example, if an EC2 instance has two security groups—one allowing inbound traffic for TCP 80 and another allowing inbound traffic for TCP 443—this means that both ports 80 and 443 are available for inbound TCP traffic.

However, NACLs evaluate rules in order based on the rule number, starting with the lowest, when deciding whether to allow or deny specific traffic.

Let’s look at a practical example: we'll use the same deployed EC2 instance and existing security group, and update the NACL inbound rules by adding a "deny all inbound traffic" rule, but with a higher rule number (“102”) than the one used for the ICMP rule:nacl rule number deny all traffic

After the changes we can still successfully ping the EC2 instance because the ICMP allow rule has the higher number than deny all rule:

Allow Only vs Allow / Deny Rules

When you add an inbound or outbound rule to a security group, it always means that you are allowing traffic from a specific source or to a specific destination.

For network ACLs, there is an additional parameter “Allow/Deny”, when creating inbound or outbound rules. This parameter defines whether the specific traffic (e.g., TCP 443) from the source/destination (e.g., 0.0.0.0/0) should be allowed or denied.

nacl allow deny parameter

Source / Destination for Rules

For a security group, as a source or destination for rules, you can provide:

  • A range of IPv4/IPv6 addresses in CIDR block notation, such as 201.0.114.5/32 for a single IP address or 201.0.114.0/24 for an IPv4 range.
  • A security group ID, such as sg-064f447fd320f7b48.
  • A prefix list ID, such as pl-1234abc1234abc123.

For NACLs, as the source or destination for rules, you can only provide a range of IPv4/IPv6 addresses in CIDR block notation.

When using security groups, it's common to specify a security group as the source or destination in the rules. This means that you allow specific traffic to or from all AWS resources assigned to that security group.

Now, to demonstrate using a security group as a source, let's create a load balancer with a security group that allows TCP traffic on ports 80 and 443 from all IP addresses:

public access security group

And create EC2 instances that allow traffic from the load balancer's security group:

security group rule source as security group

These security group rules allow EC2 instances to receive inbound traffic (TCP 80/443) only from the load balancer because of the specified source group ID (sg-0b7db3359ca04bcce).

One NACL vs Multiple Security Groups

One subnet can have one network ACL assigned, whereas one network interface can have multiple security groups assigned.

There are limits on the number of:

  • Security groups you can assign to one network interface: the default is 5, which can be increased to 16.
  • Inbound/outbound rules per security group: the default is 60, which can be increased.
  • Security groups you can create per region: the default is 2500, which can be increased.

By using multiple security groups, you gain more granular control over inbound/outbound traffic. You can create security groups with a least privilege approach, defining the minimum necessary permissions for specific AWS resources.

Default Security Group and Network ACL Configurations for Your VPC

When you create a VPC or use the default one, it comes with a default security group and a network ACL. Default NACL is associated with all subnets in the specific VPC, and the default security group is used when you provision new EC2 instances, load balancers, etc., without specifying your own security groups.

The default configurations are different:

  • For the security group, all inbound traffic is allowed only from resources that are assigned to this default security group, while all outbound traffic is allowed.default security group
  • For the NACL, all inbound and outbound traffic is allowed. There is an additional default deny rule that you can’t modify, which denies all traffic if no other rules are specified.default nacl

When to Use Each?

I guess anyone (including AWS), who has worked on configuring VPC network traffic will agree that using security groups should be considered the primary approach to controlling inbound and outbound traffic to your VPCs. The main reason is that security groups are more flexible than network ACLs, offering features like stateful filtering and the ability to specify other security groups as the source or destination.

Some even compare NACLs to "...physical networking where nearly all controls were managed by subnet and VLAN boundaries". I would agree that for the majority of VPC network configurations, security groups should be used—just because they’re much more versatile and allow a single network interface to have multiple groups, enabling more granular and least-privilege access control. However, I would still use network ACLs as secondary control, with rules that should be common for all instances, such as denying a specific subset of traffic (e.g., SSH on port 22) to all instances deployed in specific subnet/s.



Looking for a tool to automatically visualize your Security Groups and Network ACLs?

Try out Cloudviz.io and visualize your AWS cloud environment in seconds

Start your free trial

As experienced AWS architects and developers, our goal is to provide users an easy way to create stunning AWS architecture diagrams and detailed technical documentation. Join us to simplify your diagramming process and unleash the beauty of your cloud infrastructure


Copyright © 2019 - 2024 Cloudviz Solutions SIA