Use AWS NACLs to Secure an Old AWS Network Load Balancer
Today, I received a call from a customer. They wanted to restrict access to their public Network Load Balancer (AWS NLB), ensuring that only specific IPs could reach certain ports. As straightforward as this may sound, the situation quickly became more complex.
Upon examining the NLB settings, I discovered that the NLB was an older version. AWS presented a message that read: "No security group associated. Because this load balancer was created without a security group, these settings can't be changed. To utilize security groups, ensure that one is specified during the creation of the load balancer." This meant that I couldn't simply attach a security group to the NLB to control access.
Initially, I attempted to restrict the IPs using the security groups associated with the EC2 instances in the private subnet. Despite my efforts, the NLB endpoint remained accessible from the outside world. It became clear that the usual method of securing the load balancer via EC2 security groups wasn't an option here.
The Solution: Using AWS NACLs
Given the constraints, I turned to Network ACLs (NACLs) as the solution. NACLs operate at the subnet level, providing a way to control inbound and outbound traffic to and from the subnet. Here’s how I implemented the solution:
-
Identify Specific User IPs: First, I gathered the IP addresses of the users who needed access to ports 5000 and 5001.
-
Configure Inbound NACL Rules: I set up NACL rules to allow access from the specific user IPs to ports 5000 and 5001, while permitting all other traffic on different ports.
Inbound Rules:
-
Allow Specific User IPs (Ports 5000 and 5001):
1Rule #: 100 2Type: Custom TCP Rule 3Protocol: TCP (6) 4Port Range: 5000-5001 5Source: 192.168.1.100/32 (Replace with the actual user IP) 6Allow/Deny: Allow
-
Allow All Other Traffic:
1Rule #: 200 2Type: Custom TCP Rule 3Protocol: TCP (6) 4Port Range: 0-65535 5Source: 0.0.0.0/0 6Allow/Deny: Allow
- Configure Outbound NACL Rules:
To ensure responses could return to the clients, I configured the outbound rules to allow all traffic.
- Allow All Outbound Traffic:
1Rule #: 100 2Type: ALL Traffic 3Protocol: All 4Port Range: All 5Destination: 0.0.0.0/0 6Allow/Deny: Allow
NACL Configuration Example
Inbound Rules:
Rule number | Type | Protocol | Port Range | Source | Allow/Deny |
---|---|---|---|---|---|
100 | Custom TCP Rule | TCP (6) | 5000-5001 | 192.168.1.100/32 | Allow |
101 | Custom TCP Rule | TCP (6) | 5000-5001 | 0.0.0.0/0 | Deny |
200 | All traffic | All | All | 0.0.0.0/0 | Allow |
* | All traffic | All | All | 0.0.0.0/0 | Deny |
Outbound Rules:
Rule number | Type | Protocol | Port Range | Destination | Allow/Deny |
---|---|---|---|---|---|
100 | All traffic | All | All | 0.0.0.0/0 | Allow |
* | All traffic | All | All | 0.0.0.0/0 | Deny |
Note: This configuration not only controls NLB traffic but also affects all traffic within the VPC. Ensure that the NACL rules are carefully configured to avoid any unintended disruptions to other services and traffic in the VPC.
Verification
After configuring the NACLs, I conducted a series of tests:
-
From Allowed IPs: I verified that users from the specified IPs could access ports 5000 and 5001 without issues.
-
From Non-Allowed IPs: I ensured that access to ports 5000 and 5001 was blocked for IPs, not on the allowed list.
-
Other Ports: I confirmed that other ports (e.g., 80, 443) remained accessible to everyone as intended.
Conclusion
The configuration changes worked perfectly, and the customer's requirements were met. This experience reinforced the importance of understanding and leveraging NACLs, especially when dealing with legacy setups that don’t support modern features like security groups. By carefully planning and implementing NACL rules, we successfully secured the NLB and met the customer's needs.