AWS Security Groups, NACL and ENI
This is the third blog post in the AWS Networking series. If you have been following along, you can continue with the lab we have built so far. For anyone who has just landed on this page, you can still follow along as long as you are already familiar with the basics of AWS networking. If you are completely new, however, I highly recommend checking out the introductory posts linked below to get up to speed.
In this blog post, we will look at AWS Security Groups, Network ACL (NACL) and Elastic Network Interfaces (ENI).
AWS Security Groups
So far, we have briefly touched on Security Groups when launching our instances, but let's take a proper look at them now. A Security Group acts as a virtual firewall for your EC2 instances, controlling all inbound and outbound traffic. They are a fundamental piece of network security in AWS. Unlike some other networking components, a Security Group operates at the instance level, not the subnet level. This means you can have different instances in the same subnet associated with different Security Groups, each with its own unique set of rules.
Security Groups work by using a set of rules that you define. For inbound traffic, these rules are 'allow' rules only. You specify what traffic is permitted to reach your instance, and any traffic that does not match an allow rule is automatically denied. There are no 'deny' rules. For example, you might add a rule to allow inbound HTTPS traffic on port 443 from any source (0.0.0.0/0
). This means anyone on the Internet can access the web server, but any other type of traffic, like SSH, would be blocked unless another rule specifically allows it.
For outbound traffic, the rules are also 'allow' rules only; you cannot create 'deny' rules. However, the default behaviour is the opposite of the inbound side. When you create a new Security Group, it automatically comes with a pre-configured outbound rule that allows all outbound traffic (0.0.0.0/0
) to any destination.
A critical characteristic of Security Groups is that they are stateful. This means that if you allow an incoming request to your instance, the return traffic for that same request is automatically allowed to go back out, regardless of your outbound rules. For example, if you allow inbound web traffic on port 443, you do not need to add an outbound rule to allow the web server's response to leave the instance. The Security Group understands this is part of an established connection and permits it automatically.
Please note that you can access and manage the 'Security Groups' section from two different places in the AWS console. You will find it in the left-hand navigation menu under both the EC2 service and the VPC service.
Elastic Network Interface (ENI)
Earlier, I said that we apply Security Groups to an instance. While that's functionally true, it's not technically accurate. We actually apply a Security Group to an Elastic Network Interface, or ENI. This is a good segue to understanding what an ENI is.
Think of an ENI as a virtual network card for your EC2 instance. When you create an instance, a primary ENI is automatically created and attached to it. It is this ENI that gets the private IP address from the subnet's range, a MAC address, and, if configured, an associated public IP address. The Security Group is also directly associated with the ENI, not the instance.
The key thing to understand about ENIs is that they are resources that can exist separately from an instance. While the primary ENI is created and deleted with its instance (by default), you can create additional ENIs. A standard ENI can be detached from one instance and re-attached to another instance within the same Availability Zone. This allows you to move a network interface along with its private IP addresses, MAC address, and security groups from one instance to another.
You can find and manage your Elastic Network Interfaces from the sidebar in the EC2 console under the 'Network & Security' section.
As we mentioned, the primary ENI is automatically deleted when you terminate its associated instance. However, this is just the default behaviour. You can choose to retain the ENI even after deleting the instance by selecting the interface, choosing 'Change termination behaviour' from the actions menu, and then unchecking the 'Delete on instance termination' box.
Multiple ENIs
An EC2 instance always launches with a single primary ENI, but you can attach additional ENIs to it as long as the instance type supports it. Different instance types have different limits; larger, more powerful instance types can support a higher number of network interfaces than smaller ones.
A common use case for attaching multiple ENIs is when you launch a network appliance like a firewall from the AWS Marketplace. A firewall typically requires at least two data interfaces - one for the 'inside' or trusted network, and one for the 'outside' or WAN network. You might also want a third interface for dedicated management. In this scenario, you could use the primary ENI for management, and then create and attach two more ENIs to serve as the inside and outside data plane interfaces.
You can easily create a new Elastic Network Interface by navigating to the EC2 service console and selecting 'Network Interfaces' from the menu. When you create a new ENI, a wizard allows you to configure it; you can give it a name, specify which subnet it should be in, assign a private IP automatically or manually, and select the Security Group you want to associate with it right from the start.
Once the ENI is created, attaching it to an EC2 instance is also straightforward. As shown in the image, you simply select the instance, go to the 'Actions' menu, choose 'Networking', and then select the option to 'Attach network interface'. From there, you can choose your newly created ENI from a list.
This concept is very similar to working with hypervisors like VMware ESXi or Workstation, where you can add multiple virtual network interfaces to a single Virtual Machine.
NAT Gateway and ENI
If you now look at the list of Network Interfaces in the EC2 console, you will see that a new ENI was automatically created when we launched our NAT Gateway. This ENI is placed in the public subnet we specified, and, like any other ENI, it has a private IP address and a MAC address.
You can also see the public Elastic IP that is associated with it. Please note that the public IP is not directly assigned at the ENI level itself; rather, the ENI holds a reference to the Elastic IP that the NAT Gateway service uses.
Network ACLs
The next security layer in a VPC is the Network Access Control List, or NACL. A NACL acts as a firewall that controls traffic at the subnet level. This is the first major difference from a Security Group, which operates at the instance (ENI) level.
When you create a VPC, a default NACL is automatically created and associated with all of its subnets, as you can see in the screenshot. This default NACL, by design, allows all inbound and all outbound traffic.
Unlike Security Groups, NACLs are stateless. This means that any response traffic is not automatically allowed. For example, if you allow an inbound request on a certain port, you must also create a corresponding outbound rule to allow the response traffic to leave (similar to an ACL in traditional networking). This makes managing NACL rules more complex.
Another key difference is that NACLs support both 'allow' and 'deny' rules. The rules are evaluated in numerical order, from the lowest number to the highest, and the first rule that matches the traffic is applied.
While NACLs offer a granular level of control, they are not as commonly used for day-to-day security as Security Groups are. Because they are stateless, managing the rules for both inbound and outbound traffic can become very complex, especially for applications that use a wide range of ports. Personally, I never use them, but of course, depending on your use case, you may find it useful.
Putting It All Together
To summarize the concepts we have discussed, let's look at the diagram and trace the path of network traffic from our instance.
The EC2 instance itself communicates with the network through its Elastic Network Interface (ENI). This ENI is what holds the private IP, the MAC address, and the association to our security group.
When traffic leaves the instance, it is first evaluated by the Security Group. The Security Group acts as a stateful, instance-level firewall. If the outbound traffic is permitted by the Security Group rules, it is then passed on.
Next, before the traffic can leave the subnet, it is evaluated by the Network ACL (NACL). The NACL acts as a stateless, subnet-level firewall. If the traffic is allowed by both the inbound and outbound NACL rules, it is then sent to the route table to determine its next hop, which in this case would be the Internet Gateway.