Again, this is my another experiment under the security domain. Security is receiving greater attention every day, and we can’t deny its importance.

This document discusses implementing the AWS Network Firewall to secure a protected EC2 instance.

Why Network Firewall?

I encountered an issue where our project’s architecture, using multiple EC2 instances for SFTP file transactions, is becoming unsustainable. AWS EC2 instances allow a maximum of 16 Security Groups (SGs), with each SG containing hundreds of rules. However, the attached ENI can only handle 1,000 rules, limiting us to 10 SGs.

As the client base grows, so does the need for IP whitelisting, leading to the creation of new EC2 instances. Currently, we’ve scaled to 5 EC2 instances, but don’t plan to add more. This expansion is purely for IP whitelisting.

After researching, I found AWS Network Firewall to be a promising solution, as it supports up to 1,000,000 CIDRs, offers auto-scaling, and more.

Implementing AWS Network Firewall Multi AZ Architecture

To implement AWS Network Firewall, you need at least one dedicated subnet for the firewall, or one dedicated subnet in each availability zone (AZ) you plan to use.

In my case, I created two public subnets in AZs us-east-1a and us-east-1b. These subnets are for the firewall only and should not contain the resources you want to protect, as the firewall cannot protect resources within the subnet it’s deployed in.

Concept of AWS Network Firewall

First, create a firewall subnet that is public-facing, and set up a firewall in that subnet. This automatically creates a VPC endpoint as a gateway load balancer.

Next, create a protected subnet where you’ll place the resources you want to secure. The gateway for this protected subnet should be the VPC endpoint created earlier.

When a request comes from the internet, it first passes through the network firewall. If the request matches your defined rules, it is forwarded to the protected subnet. Similarly, when a request is sent from the protected subnet to the internet, it goes through the firewall before reaching the internet

Implementing AWS Network Firewall

VPC and Subnets

First, I created a VPC with the CIDR block 10.24.0.0/16.

Then, I created an Internet Gateway and two firewall subnets in us-east-1a (10.24.10.0/24) and us-east-1b (10.24.11.0/24), attaching a route table with the Internet Gateway.

You can use a /28 subnet for the network firewall if no other resources are needed, as it only requires one available IP, and /28 is the smallest subnet size AWS allows.

Next, I created two protected subnets in AZ us-east-1a (10.24.20.0/24) and us-east-1b (10.24.21.0/24).

Then, I created a network firewall in the firewall subnets, selecting the two subnets I created earlier. This automatically creates Gateway Load Balancer VPC Endpoints in each subnet.

Now, we need to update the route table for routing traffic.

Route Table

Internet Gateway Route Table: We need to create a route table for the Internet Gateway to ensure that requests coming from the internet or going to the internet are forwarded to the Gateway Load Balancer VPC Endpoint(Network Firewall).

Additionally, we need to add the Internet Gateway to the edge association of this route table.

DestinationTarget
10.24.0.0/16local
10.24.20.0/28vpce-1a
10.24.21.0/28vpce-1b

Public Firewall Subnet Route Table: The route table for the public firewall subnet should be similar to the route table for public subnets. The Internet Gateway should be the route used to reach the internet.

DestinationTarget
10.24.0.0/16local
0.0.0.0/0igw-xx

Protected Subnet Route Table: The destination for internet-bound traffic in the protected subnets should be the network firewall VPC endpoint, ensuring that all traffic is filtered by the firewall before reaching the internet.

DestinationTarget
10.24.0.0/16local
0.0.0.0/0vpce-1a, vpce-1b

Network Firewall Rule Creation:

Let’s go back to setting up the network firewall rules. After creating the network firewall, the next step is to define a policy.

A policy contains two types of rule groups: stateless and stateful. Within each rule group, you can add specific security rules.

  • Create a Policy: In my case, I didn’t use stateless rules and only used stateful rules.

    • For stateless rules, I set the default action to forward to stateful rules.
    • For stateful rules, the default action is to drop all connections and alert on all connections.
  • Adding Rules in Stateful Rule Group: You can add rules with different methods for defining IP CIDRs:

    • Rule Variable: Create a variable, assign IPs to it, and then use the variable in the rule. This can also be done for port numbers.

    • IP Set Reference: Create a variable, but reference a prefix list instead of adding individual IP CIDRs directly.

    • Directly Adding IP CIDRs: You can also choose to directly add individual IP CIDRs to your rule, without using variables or prefix lists. This approach is simpler but might be less flexible if you need to reuse the same set of IP addresses in multiple places.

📝 Note:

  • When creating rules, even though there are protocol names like SSH, FTP, and HTTP, these names didn’t work for me directly. I had to use the TCP protocol and specify the port numbers.
  • Rule variables are assigned with a $, and IP set references are assigned with an @ in rules.

Limitation:

  • A firewall policy can have a maximum of 20 rules in each rule group, applicable to both stateless and stateful rules.
  • A rule group within a policy can have a maximum of 30,000 entries. This total is the combined capacity of all the entries from the individual rules attached to the same rule group. For example, if a rule group has a capacity of 30,000 entries and you create two rules with a capacity of 100 entries each, the total number of entries used will be 200 entries (200/30,000).
  • Rule Variables: The total value for rule variables (IP addresses) can only be up to 8,192 characters.
  • Prefix List Limit: A prefix list can have a maximum of 1,000 CIDRs per list.
  • IP Set Reference Limit: A rule group can reference a maximum of five IP sets(5 prefix list). This means that a single rule group can handle up to 5,000 IPs. To achieve the capability of handling 1,000,000 CIDRs per firewall, multiple rule groups need to be created.

Thanks for reading,

-Alon