Time and again, Amazon Web Services (AWS) practitioners recommend to have the right combination of AWS NACLs (Network Access Control Lists, also pronounced as “Nakles”), VPC, and AWS Security Groups (SGs) to secure resources 24X7 from unwanted attacks.
AWS NACLs act as a firewall for associated subnets, controlling both inbound and outbound traffic. Whereas SGs acts as firewall at resource level.
In one of our previous posts, we spoke about 5 Not-to-Ignore Best Practices for AWS Security Groups. In this post, we will walk you through few best practices for NACLs.
Before applying the best practices for AWS NACLs, it is important to understand its basic characteristics as well as the ability to fine-tune traffic through its stateless behavior.
Unlike SGs that are stateful, AWS NACLs are stateless. On that account, changes applicable to an incoming rule will not be applicable to the outgoing rule. That is, if you want your instances to communicate over port 80 (HTTP), then you have to add an inbound as well as an outbound rule allowing port 80.
Before configuring NACLs, one must keep few recommendations in mind, such as:
When you create a VPC, it comes with a default Network ACL that allows all inbound and outbound rules. And if you create a custom NACL, both Inbound and Outbound rules are denied. If you have not created a custom network ACL, then the subnets will be associated with VPC’s default ACL automatically. This will ‘Allow’ all traffic to flow into and out of the network.
“ Cautiously allow traffic into or out of NACLs, especially if you are running a production server. Above all, keep a continual check on NACLs that allow all inbound traffic.”
Here’s an example: Assign a NACL to a public subnet with instances that can receive and send Internet traffic over port 80 (HTTP) and ephemeral ports 1024-65535. And block the traffic over port 2049 (NFS) or ports vulnerable to denial of service attacks.
“Always ensure you do not use a wide range of ports or overly permissions to NACLs during configuration, unless your applications or containers that require a wide range of ports, like Kubernetes.”
Configuring SGs and NACLs in VPC helps reduce the attack surface of your applications hosted on AWS. They mutually complement each other, because SGs allow defining the traffic to resources within the applications while NACLs allow defining the port, protocol, and source of traffic that should be explicitly denied at the subnet level.
Here is an example to show how SGs and NACLs complement each other. Say, you have a two-tier web application with web servers in one SG and a database in another. The inbound NACL rules allow connections to web servers from around the world, while the database allows inbound connection from only a list of web servers. So, web servers allow port 443 connections, while the database allows inbound 3306 connections for MySQL.
“ To prevent the servers from initiating connections over the internet, you can remove both the web server and the database SGs’ outbound rule. This way, the web servers will allow all outbound traffic to establish sessions. And the database must limit outbound connections to the web server’s private subnet IP range.”
Ineffective or misconfigured DENY rules promotes ‘ overly-permissive’ access to a VPC. This results in attacks such as DoS or DDoS. Be mindful of the order of the DENY rules within your Network ACLs. This is crucial, as ACLs are evaluated in order. For example, in the below image, the DENY rule is defined to block inbound traffic to vulnerable port 2049. If the rule does not block access to everyone (0.0.0.0/0), the inbound DENY rule is declared ineffective and should be reconfigured to protect against attacks.
It is always best to know the limitations around NACLs before configuring them in your AWS infrastructure. Here are few limitations you must never ignore:
– There is a default limit of 20 to both inbound and outbound rules per list. AWS provides additional rules on request, however the absolute maximum is 40.
– The top end limit to number of network ACLs per VPC is 200.
While creating/applying the network ACL, you can apply either inbound restriction or outbound restriction. During configuration, take care of outbound rules that allow traffic from all ports. Limit access to the required ports or port ranges. This gives least privileges to unwanted roles and reduces the possibility of unauthorized access, at the subnet level.
While best practices helps in avoiding errors or unwanted traffic, there are few NACL rules you must never ignore, such as:
– NACLs are always read in ascending order, with each rule applied against matching packets. These rules apply regardless of whether a later rule might also match. It is important to carefully sequence the NACL rules with an organized numbering system.
– AWS Network ACL Rules (both inbound and outbound) are defined in terms of the DESTINATION port
– The numbering can start at one and go as high as 32766. While assigning, it is recommended to leave a gap of at least 50 numbers between each of the NACL rules, so that there’s enough room for additional rules in the sequence for use later. Plus, never forget to apply an outbound reply rule to permit responses to inbound requests while creating the rules.
– Each Network ACL includes a rule numbered asterisk (‘*’ ). This rule ensures the inbound/outbound traffic is denied if a packet does not match any of the other numbered rules. This rule can neither be modified nor removed.
– Specify the port range for the assigned protocol to use while creating a custom rule.
As a second layer of defense, NACLs run by the rules. But you will need to configure them aptly under different scenarios. AWS has documented rules for the below scenarios:
Additionally, using Terraform, you can program NACLs rules. This helps in creating a secure infrastructure and preserving it in Infrastructure as a Code (IaaC) format.
Taking all the above rules into consideration and applying the best practices, you can always improve your AWS security posture and reduce attack surface.
But configuring the NACLs as per best practices alone is not enough. Keeping a continual check on these is of paramount importance. It doesn’t matter if you are using Terraform code or a tool like Cloud-custodian to monitor and verify NACL rules.
What matters the most is how you analyze route table and NACL configurations and further map the entire inbound and outbound traffic between subnets and NACLs continually to maintain AWS security in real-time.
Having said that, switching between multiple tabs and dashboards or lines of code is effort-intensive. Using a single visual console that can analyze and show the entire AWS network topology right from VPC level to resource level is the best way forward.