When running an application on a VPC, enterprise companies often limit inbound HTTP traffic as part of company's security measures. This is primarily to prevent applications from accessing malicious domains.
Traditionally, in this situation, many companies build and operate an explicit forward proxy server, however there are always two problems.
- Scalability
Outbound traffic used across the enterprise requires a large amount of bandwidth, which requires a lot of resources and traffic shaping on proxy servers. - Application compatibility
As not all application allows users to specify proxy servers for outbound access, those "proxy-unaware" applications were not available on the corporate network.
With AWS Network Firewall, you can build managed domain filtering solution without having any proxy servers. Network Firewall allows you to filter the outbound traffic from your VPC to unfavorable domains. Addition to the wider bandwidth, it provides application transparent domain filtering, where applications are no longer required to configure any explicit proxy servers.
This solution is build on top of Terraform, so you need to have some familiarity to deploy it.
-
Get AWS Account
-
Setup IAM user and access, secret keys
-
Install tfenv
-
Install terraform cli tool version
0.14.7
or above, via tfevntfenv install 0.14.7
-
set Terraform version
tfenv use 0.14.7
-
Configure your Terraform state backend
In order to make the deployment stable, it is highly recommend to store your Terraform state file in Amazon S3, or equivalent cloud storage. inenvs/dev/backend.tf
file, you can specify your own amazon S3 bucket.terraform { backend "s3" { bucket = "<YOUR OWN S3 BUCKET NAME>" key = "<STATE FILE NAME>" region = "<S3 REGION>" } }
-
Configure your the AWS region to deploy
Inenvs/dev/provider.tf
file,provider "aws" { region = "<YOUR REGION TO DEPLOY>" }
-
Initialize Terraform
cd envs/dev terraform init
-
Configure Allowed Domain List
Now this is the most fun part. Inenvs/dev
, you will seeallowed_domains.yml
file. This file is the list to which the application on private subnet to access. You can add, delete the domain list as you want.
IMPORTANT
This solution is basically "Allowed List", so the domains that is not on theallowed_domains.yml
, they are going to beDENIED
. -
Deploy it.
terraform apply
Once you spin up your resources defined by this Terraform files, you can create your EC2 instance to play with. Now this network assumes EC2 instances are not connected to the internet, you should utilize AWS SSM Session Manager to jump in to your test instance.
-
Create IAM Role for EC2 Instance
You just create EC2 IAM Role and attache AWS Managed Policy AmazonSSMManagedInstanceCore -
Create your EC2 instances on private subnet
Note that you don't need to open security group for any SSH port. You can use default security group in this case. -
Jump in to the test instance
aws ssm start-session --target <YOUR EC2 INSTANCE ID>
Now this is the moment you are probably excited. Once you can jump in to your test box, the easiest way to test it out is to use curl command
curl -vvvv https://www.microsoft.com
It works. You can get contents from the server but,
curl -vvvv https://www.twitter.com
In this case you won't get any response from the server. This is because the network firewall blocks the traffic. You can also check the CloudWatch Logs if your traffic is allowed or denied.
Happy Traffic Control! :-)
Firewall gateway is a gateway that handle the traffic. It's pretty unique so if you want to more dive deep you should check this blog.
Why is here? Because it prevent from being disconnected from your EC2 located on private subnet.
If you added some domain related to AWS endpoint in allowed_domains.yml
, what would happened? You would lose your connection to your app because Firewall Gateway would block the traffic too. In order to prevent this situation, SSM endpoints allow your to bypass Network firewall, so you can keep your connection whatever you did wrong.
Please follow Input and Output following.
Variable | Type | Description |
---|---|---|
vpc_cidr_block | String |
Automatically create /24 subnets in the VPC, so please specify larger CIDR range. |
Output | Type | Description |
---|---|---|
igw | String |
Internet Gateway (IGW) ID. |
firewall_subnet_1_id | String |
Firewall subnet ID located in first availability zone. |
firewall_subnet_2_id | String |
Firewall subnet ID located in second availability zone. |
public_subnet_1_id | String |
Public subnet ID located in first available zone. |
public_subnet_2_id | String |
Public subnet ID located in second available zone. |
public_subnet_1_route_table_id | String |
Route table ID for public subnet ID located in first available zone. |
public_subnet_2_route_table_id | String |
Route table ID for public subnet ID located in second available zone. |
Variables | Type | Description |
---|---|---|
igw | String |
Internet Gateway (IGW) ID. |
firewall_subnet_az_1 | String |
Firewall subnet ID located in first availability zone. |
firewall_subnet_az_2 | String |
Firewall subnet ID located in second availability zone. |
public_subnet_az_1 | String |
Public subnet ID located in first available zone. |
public_subnet_az_2 | String |
Public subnet ID located in second available zone. |
public_subnet_1_route_table_id | String |
Route table ID for public subnet ID located in first available zone. |
public_subnet_1_route_table_id | String |
Route table ID for public subnet ID located in second available zone. |
No output defined.