Fortify Your AWS Network Security with AWS Network Firewall: A Complete Guide (Terraform Code included)
Tags: aws, cloud, terraform, devops
Published: 2023-03-06 10:28:05

> I've wanted to write about this since last December, when I participated in a session at AWS Community Day Sri Lanka 2022, which was organised by AWS User Group Colombo. During the session, I delivered a speech and demonstrated how awesome and simple it is to set up an AWS Network firewall. later on, with Terraform, I was able to codify my demo to infrastructure as code. I hope you all enjoy this step-by-step guided workshop.

# What you will get from this post (Hands on Lab)

- Understand AWS Network Security
- Learn about few of AWS Networking Services
- Step-by-Step guide on how to deploy AWS Network Firewall using terraform

# Prerequisites

- AWS Account
- Terraform (Version is available in the Github repo)
- To use this lab, you need to have a basic understanding of the following services.
 - VPC, Route Tables
 - Transit Gateway
 - VPC Endpoints

But before we dive into the AWS Network Firewall, it's essential that we comprehend a few things.

# Basic AWS Network Security and Limitations

When you have multiple AWS accounts and VPCs, it is difficult to monitor, govern, and enforce security on the network resources.

- A complicated hybrid network configuration in which multiple AWS networking services are linked with on-premises environments and AWS VPN traffic.
- Manage multiple Security Groups and Limited rules supported by Security Groups. As of this writing, only 60 inbound rules for IPv4 and 60 inbound rules for IPv6 traffic are supported.

# Little bit about AWS PrivateLink and VPC Endpoints, VPC Endpoint Services

![AWS PrivateLink](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qpkirktttkda19g83i5q.png)

> Ref : https://docs.aws.amazon.com/vpc/latest/privatelink/concepts.html

AWS PrivateLink is a networking service offered by AWS that allows for secure and private communication between VPCs and AWS services without the need for traffic to pass through the internet or a NAT gateway. It uses VPC endpoints to establish a private connection between your VPC and AWS services via the AWS network, thereby avoiding the public internet.

You can create a private, highly available and scalable connection between your VPC and AWS services or your own application services running on EC2 instances, AWS Lambda functions, or other AWS resources using VPC endpoints and endpoint services.

# Little bit about the Gateway Load Balancer

![Gateway Load Balancer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ku35xdcwrlbbw6tjpll5.png)

> Ref : https://aws.amazon.com/blogs/networking-and-content-delivery/integrate-your-custom-logic-or-appliance-with-aws-gateway-load-balancer/

Gateway Load Balancers enable the deployment, scalability, and management of virtual appliances such as firewalls, intrusion detection and prevention systems, and deep packet inspection systems. It combines a transparent network gateway (a single entry and exit point for all traffic) and traffic distribution while scaling your virtual appliances with demand.

For an example, if you want to deploy Trendmicro, Fortinet, Palo Alto Networks, or any other vendor's Appliances as your Firewall in your AWS Cloud Infrastructure, Gateway Load Balancer fulfils that requirement.

## You may be wondering why this guy is talking everything but AWS Network Firewall 

![dogo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fjvv0gfcajeh3eia9poi.png)


> **AWS Network Firewall is actually powered by AWS Gateway Load Balancer.**

Yes! Yes, you read that correctly. So, what is the difference between Gateway Load Balancer and AWS Network Firewall? Simply put, if you want to use a third-party firewall solution as an appliance, you can pick Gateway Load Balancer, but you must manage the infrastructure of the firewall instance. However, if you require a Firewall solution that can be deployed fast, is a managed service and is highly available, then AWS Network Firewall is the solution.

# Let's go to AWS Network Firewall now

![yay meme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mab9garc9ffsygawbaj1.png)

AWS Network Firewall is a fully managed network security service offered by AWS that enables users to set up, manage, and scale firewall protection across their VPC and on-premises networks.

# AWS Network Firewall Supports

- OSI Layer 3 and 7 Traffic Filtering
- Domain name filtering
- More number of rules
- Inspect traffic between VPCs (Through TGW) or inbound/outbound Internet traffic
- AWS Direct Connect and AWS VPN traffic running through AWS Transit Gateway
- Managed rules from the AWS Marketplace

> As of the time of writing, AWS Network Firewall does not support (DPI) Deep Packet Inspection for encrypted traffic. Gateway Load Balancer is the best solution if you are looking for such a solution. As well as the following:
- VPC peering traffic
- Virtual private gateways
- Inspection of AWS Global Accelerator traffic
- Inspection of AmazonProvidedDNS traffic for Amazon EC2

> I'm not going to deep into detail about AWS Network Firewall offerings because we have these excellent documents instead. [](url)https://aws.amazon.com/network-firewall/faqs/

---

# Architecture of The Lab

![ Architecture of The Lab - devops with zack](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xphzt7ts31hxy9b4cutt.jpeg)

### Clone the project

`git clone https://github.com/devopswithzack/lab-aws-networkfirewall.git`

`cd lab-aws-networkfirewall`

Once cloned, open it in an IDE such as VSCODE. Before we proceed, we must make some changes.

### Generate the keys for EC2 instances

![Generate the keys for EC2 instances](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l15lw91g6nf87qwvtksj.png)

### Then copy the public key and paste in the `env.tfvars`

![Then copy the public key and paste in the `env.tfvars`](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2hz5wlvhreiz2ig46j50.png)

![Then copy the public key and paste in the `env.tfvars`](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gn8argag1swv562eqru2.png)

> This is an optional step. Use only if your backend is an S3 bucket and you want to keep your state in DynamoDB.

![This is an optional step. Use only if your backend is an S3 bucket and you want to keep your state in DynamoDB.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1pybol5mkmc7n6u0xs39.png)

### Run a terraform init

`terraform init`

> My backend is a S3 bucket and I use dynamo db to lock my state. If you use the same, you can use the `backend.conf` file with `terraform init -backend-config=backend.conf`.

### Once all done , run `terraform plan` to verify the resources that you are going to create.

`terraform plan -var-file=env.tfvars`

### Now we can apply using the terraform apply

`terraform apply -var-file=env.tfvars`

Type `yes` and enter to the prompt.

this will take some time to deploy.

I'm going to cover two scenarios in this lab.

1. Bastion host in the Egrees VPC public subnet accessing the App EC2 instance in the App VPC.

2. App EC2 in the APP VPC's private subnet accessing `https://www.google.com`.

---

# Let's test the AWS Network Firewall.

![Let's test the AWS Network Firewall.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7qqtu68ubbd9codjk71m.jpeg)

> The numbers listed below correspond to the yellow circled numbers in the architecture diagram.

# Scenario 1

SSH into the JUMP HOST, which is on the Public subnet and has port 22 open to the public.

1- SSH from JUMP HOST to the APP EC2 in the APP VPC's Private Subnet
2 - Routing to `10.0.0.8/8` results in TGW
3 - It should go to Inspection VPC, according to the TGW attachment
4 - Direct traffic to the AWS Network Firewall VPC Endpoint `vpce-az-a-id`
5 - After passing through the firewall, the traffic is routed to the tgw route tables
6 - TGW routes traffic to `10.1.0.0/16` and sends it to App VPC

# Scenario 2

The app server attempts to connect the `https://www.google.com`.

7 - Access to `https://www.google.com`
8 - Any traffic should go to the TGW, according to the Route Tables
9 - According to the TGW attachment, it should go to Inspection VPC
10 - Send traffic directly to the AWS Network Firewall VPC Endpoint `vpce-az-a-id`
11 - Traffic is routed to the tgw route tables after passing through the firewall
12 - Internet traffic is routed to the Egress VPC using the TGW Route Tables
13 - A NAT Gateway traffic route
14 - The Internet Gateway directs traffic to `https://www.google.com`

# Test 1 - Check the SSH Traffic

1. SSH to The Jump Host using the public IP, Both APP EC2 and the JUMP host

![SSH to The Jump Host using the public IP, Both APP EC2 and the JUMP host](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tk67lkbnt7hvo0ph0y3f.png)

2. Now copy the same SSH Private key we created to the Jump host as `sshkey.pem` and set the permission as `chmod 400 sshkey.pem`

3. Get the private IP of the APP EC2 from the console and try to SSH from the JUMP HOST

![Get the private IP of the APP EC2 from the console and try to SSH from the JUMP HOST](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/95inax4c88zgt3sa91g4.png)

You may notice that it will take some time and that you will be given a timeout.

![timeout](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2k0kbc9ehpxk0dt4e0nq.png)

In one of the AWS Network Firewall Rule Groups, SSH Access has been blocked.

```terraform
# Block SSH
resource "aws_networkfirewall_rule_group" "block_ssh" {
  capacity = 50
  name     = "block-ssh"
  type     = "STATEFUL"
  rule_group {
    rules_source {
      stateful_rule {
        action = "DROP"
        header {
          destination      = "ANY"
          destination_port = "ANY"
          direction        = "ANY"
          protocol         = "SSH"
          source           = "ANY"
          source_port      = "ANY"
        }
        rule_option {
          keyword  = "sid"
          settings = ["1"]
        }
      }
    }
  }

}
```

Let's now manually remove the rule from the console and try it again.

4. Navigate to the VPC in AWS Console, then select 'Firewalls' from the Network Firewall section

There are two rule groups under Stateful Rule Groups.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mhxwdzgi0k8melt551db.png)

5. Disassociate the `block-ssh` from the rule group

![Disassociate the `block-ssh` from the rule group](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nyrw2olhp5tm213j9aif.png)

> Wait 1-2 Minutes

6. SSH to the APP EC2 from the JUMP HOST. Now you should be able to SSH

![SSH to the APP EC2 from the JUMP HOST. Now you should be able to SSH](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tzfjld73tl03un00f3ls.png)

7. Do not exit the APP EC2, as we will try the next scenario

# Test 2 - Access `https://www.google.com` from the APP EC2 server

As you are still in the APP EC2 server try to `curl` the `https://www.google.com` You will get a time out eventually

![As you are still in the APP EC2 server try to `curl` the `https://www.google.com` You will get a time out eventually](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vjnua88nqfwecq4290oz.png)

In one of the AWS Network Firewall Rule Groups, Accessing `google.com` is been blocked.

The IP CIDR range from APP VPC is not permitted to access '*.google.com', according to the terraform resource code block below.

```terraform
# Block google.com
resource "aws_networkfirewall_rule_group" "block_google" {
  capacity = 100
  name     = "block-google"
  type     = "STATEFUL"
  rule_group {
    rule_variables {
      ip_sets {
        key = "HOME_NET"
        ip_set {
          definition = [module.app_vpc.vpc_cidr_block]
        }
      }
    }
    rules_source {
      rules_source_list {
        generated_rules_type = "DENYLIST"
        target_types         = ["HTTP_HOST", "TLS_SNI"]
        targets              = [".google.com"]
      }
    }
  }
}
```

### Let's now manually remove the rule from the console and try it again. Follow the same steps in Test scenario one to access the rule groups

![Let's now manually remove the rule from the console and try it again. Follow the same steps in Test scenario one to access the rule groups](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n9b0nukyc6lgud2jzf2b.png)

> Wait 1-2 Minutes

### Now curl the `https://www.google.com` url from the APP EC2  Server

![Now curl the `https://www.google.com` url from the APP EC2  Server](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h7ae8s8oztaxfpkq0lpy.png)

Now you should be able to access `https://www.google.com`.

---

# CloudWatch Logs

### In the AWS Console, go to CloudWatch and select the logs groups

![In the AWS Console, go to CloudWatch and select the logs groups](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ur2bsln2i105cak3ksvu.png)

2. You should be able to see the alert logs, click on them, and examine the logs

## Block SSH

![Block SSH](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ex3bubouwtg8beid0klk.png)

## Block Google.com

![Block Google.com](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y3k0gmzlar73sf7ktj9h.png)

---
# Delete the lab

When you're finished testing, make sure to delete the stack to avoid charging.`terraform destroy -var-file=env.tfvars`

---

# Let's wrap this up

You now understand how the AWS Network Firewall works and how to integrate it into your infrastructure. If you want to contribute to this LAB, please open a PR in the repo: [](url)https://github.com/awsfanboy/lab-aws-networkfirewall . I welcome feedback and suggestions, so please leave them in the comments or email them to `hello@awsfanboy.com`.