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:

  1. Identify Specific User IPs: First, I gathered the IP addresses of the users who needed access to ports 5000 and 5001.

  2. 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
    
  1. 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:

  1. From Allowed IPs: I verified that users from the specified IPs could access ports 5000 and 5001 without issues.

  2. From Non-Allowed IPs: I ensured that access to ports 5000 and 5001 was blocked for IPs, not on the allowed list.

  3. 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.

I :heart: AWS! :smile: Enjoy