Networking & Content Delivery

Centralizing Domain List Management for AWS Network Firewall and Route 53 Resolver DNS Firewall

Many of our customers take a “defense in depth” approach to secure workloads within their Amazon Virtual Private Clouds (Amazon VPC). Using domain list rules in AWS Network Firewall and Amazon Route 53 Resolver DNS Firewall lets you enforce network security controls at multiple layers based on domain names. Although both DNS Firewall and Network Firewall can use domain lists, currently no feature exists for synchronizing the domain list between both services. DNS Firewall lets you define domain name filtering rules in rule groups that you associate with your VPCs. And Amazon Network Firewall filters domains by including a domain list in a stateful firewall rule.

This post walks you through automating the process of creating and updating a common domain list for Network Firewall and Route 53 Resolver DNS Firewall. Automating this functionality helps reduce complexity and risk, thereby enhancing your security posture while saving time and reducing operational burden.

Route 53 Resolver DNS Firewall is a highly-available and managed DNS firewall service for the Route 53 Resolver. It lets you easily deny/allow DNS traffic across all VPCs centrally, providing a DNS control point. Network Firewall can apply host header inspection to create a similar domain allowlist or denylist control.

Solution overview

In this solution, we provide an AWS CloudFormation template that deploys an Amazon Simple Storage Service (Amazon S3) Bucket, an Amazon S3 Event Trigger, an AWS Lambda Function, DNS Firewall Domain List and Rule Group, and Network Firewall Rule and Rule Group, along with the necessary AWS Identity and Access Management (IAM) roles. Once deployed, a text file with one-domain-per-line defines the domain list and can be uploaded to Amazon S3 to trigger the Lambda function to update domain list rules for both Network Firewall and DNS Firewall. Subsequent updates to the domain list can be performed by uploading a new list to the deployed S3 bucket. This solution adds or removes domains from an existing domain list managed by the solution each time that a new list is uploaded.

The solution doesn’t associate rule groups with Amazon VPCs or Network Firewalls, so you must complete this step. The solution architecture is in the following diagram.

Architecture diagram depicting the operational flow of the solution from left to right starting with uploading a domain list to an S3 bucket which triggers a Lambda function deploying the new rules to the firewall services.

Figure 1 – Architecture Diagram

Here is an overview of how the solution works:

  • Deploy the CloudFormation Template found in our GitHub repository.
  • Upload a file to the S3 bucket created by CloudFormation. This file is a domain list that you manage with one unique domain per row.
  • After a domain list is uploaded, an S3 Event invokes the Lambda function which manages rules, rule groups, and domain lists.
  • For DNS Firewall, the Lambda function pulls the domain list from Amazon S3 and updates a DNS Firewall Domain List.
  • For Amazon Network Firewall, the Lambda function pulls the domain list from Amazon S3 and updates the firewall rule.

Prerequisites

The following prerequisites are required to follow along with this post:

  • You must have an existing AWS account.
  • IAM role allowing CloudFormation to deploy resources.
  • List of domains, with one domain per row. Wildcarding of domains is supported with the format *.example.com.
  • Route 53 Resolver Endpoints
  • VPCs for DNS Firewall associations.
  • Network Firewall.
  • CloudFormation Template for this solution in our GitHub repository.

Launching the CloudFormation stack

To begin, launch the CloudFormation stack.

  1. Go to AWS CloudFormation in the AWS Management Console.
  2. Choose Create Stack and select “With new resources” (standard).
  3. On the Create Stack page, under Specify template, select the Upload a template file template source.
  4. Select Choose file and find the template that you downloaded in the Prerequisites steps.
  5. Choose Next to continue.
  6. On the Specify Stack Details page, give your stack a name, such as “MyStackName”.
  7. Under Parameters, review the default parameters and enter the required: BUCKETNAME, R53_RULE_TYPE, ANFW_RULE_TYPE, ANFW_RULE_GROUP_CAPACITY.
    • When deploying CloudFormation, select whether the configured domain lists will allow or deny traffic for both Network Firewall and DNS Firewall.
    • There are several parameters for the CloudFormation stack:
      • BUCKETNAME – The name of the S3 Bucket to create
      • R53_RULE_TYPE – This is the type of DNS Firewall rule action applied to the domain list. This must be of the type ALLOW, DENY, or ALERT. The DENY action requires the DENY ACTION parameter to be configured.
      • ANFW_RULE_TYPE – This is the type of stateful firewall rule action that is applied to the domain list. It must be of type ALLOWLIST or DENYLIST.
      • ANFW_RULE_GROUP_CAPACITY – This is the capacity defined for Amazon Network Firewall Rule groups. This can’t be changed after creation. Refer here to calculate capacity units.
  8. On the Configure stack options page, you can choose to add tags, choose additional options, or just choose Next.
  9. On the Review page, validate your parameters and acknowledge that IAM resources will be created. Finally, select Create stack.
  10. Once you select Create stack, you can follow the process and view the status of the deployment via the Events tab of the CloudFormation stack. When it finishes deploying, move on to the next step.

Associating rule groups

Since the solution doesn’t associate the rule groups that it creates with a Network Firewall or VPC, you must manually associate Network Firewall Rule Groups with a Network Firewall Policy and DNS Firewall Rule Groups with VPCs.

Review deployed resources

Now that you have deployed Rules, Rule Groups, and Domain Lists via CloudFormation, you can review them in the Console.

In the Network Firewall Console, you can see the Network Firewall Rule Group and the stateful rule with the domain list:

Figure 2 - Centralizing-Domain-List-Management

Figure 2 – Centralizing-Domain-List-Management

In the DNS Firewall Console, you can now see the managed rule group, rule, and domain list:

Screen shot displaying the Route 53 Resolver DNS firewall domain list portion of the AWS console

Figure 3 – Route 53 Resolver DNS Firewall Domain List with imported domains

You can check which domains were imported to the domain lists for each service by reviewing Amazon CloudWatch Logs for each Lambda invocation.

Screen shot displaying the Log events of successfully imported domains and any that are excluded in the log events section of the CloudWatch service in the AWS Console.

Figure 4 – CloudWatch Logs showing successfully imported domains and any that are excluded.

You can see in Figure 2 that the solution will discard improperly formatted domain names or domain names that don’t use the correct wildcard format. The solution logs the number of valid domains processed and imported to the domain lists, as well as the number of invalid domains that were discarded.

Solution testing

With the solution now deployed and rule groups associated with a Network Firewall Policy and a VPC, you can test that the solution works.

We tested this solution by executing dig and curl commands against domains in our denylist from an Amazon Elastic Compute Cloud (Amazon EC2) instance protected by Network Firewall and DNS Firewall.

When the DNS Firewall and Network Firewall blocklists are configured and associated, dig returns an empty DNS response and a curl times out.

You can also test Network Firewall via curl as follows:

Executing curl -I https://example.com prior to deploying the domain list returns a valid response. After deployment, you can see the client attempting a TLS connection that never completes, since it’s dropped by Network Firewall after inspecting the host header. Our client can resolve DNS in this case because we haven’t cleared the local DNS cache yet.

Screen shot of a terminal window showing the AWS CLI depicting the curl command as outlined in the blog

Figure 5 – Successful curl test through Network Firewall

Screen shot of a terminal window showing the AWS CLI depicting the dig command completing successfully as outlined in the blog

Figure 6 – Successful dig response from Route 53

Screen shot of a terminal window showing the AWS CLI depicting the verbose curl showing failed TLS handshake after deploying domain denylist

Figure 7 – verbose curl showing failed TLS handshake after deploying domain denylist

Screen shot of a terminal window showing the AWS CLI depicting the dig test showing empty DNS response after deploying domain denylist

Figure 8 – dig test showing empty DNS response after deploying domain denylist

You can test DNS Firewall configuration with dig, as follows:

Executing dig example.com +short returns a valid DNS response prior to deploying the domain denylist. After deploying the domain denylist and clearing the local DNS cache, dig example.com +short returns no answer. If you deployed the solution with the DENY_ACTION parameter set to NXDOMAIN, then the response would be NXDOMAIN.

Clean up

To avoid incurring future charges, delete the domain list from the created S3 bucket, then delete the resources created by deleting the CloudFormation stack. You can delete the provisioned CloudFormation stack via the CloudFormation Console documentation or the AWS Command Line Interface (AWS CLI) instructions. To delete resources created by the CloudFormation stack you must manually disassociate rule groups and empty the Amazon S3 bucket created by CloudFormation.

Conclusion

In this post, we provided a solution that automates and centralizes the creation and updating of domain lists that can be used for Network Firewall and DNS Firewall. The solution lets you easily use a single domain list across both services to support a “defense in depth” strategy for your VPC workloads. You can also take a stricter, “walled-garden” approach by creating “allowlists” that permit outbound traffic and DNS queries only to domains that you specify.

For more information reference the Network Firewall Developer Guide and the DNS Firewall Developer Guide. You can also clone or contribute to the solution in our GitHub repository.

Steve Bruggemann

Steve Bruggeman is a Principal Technical Account Manager at AWS where he helps customers operate their workloads at any scale, with a focus on Networking and Resiliency. In his spare time, Steve enjoys tinkering with home automation or going for a spirited drive.

Chris Sereno

Chris Sereno is a Solutions Architect at AWS with a background in network analysis. He is passionate about helping customers deliver performant and reliable applications. In his spare time he enjoys creating music with his keyboards.