Egress Controls with Amazon Route 53 DNS Resolver Firewall
Learn how to secure your infrastructure and make it cost-effective.
Have you ever considered the connection between an infrastructure's security and cost effectiveness go hand in hand? Most often, when we think about security, our minds go to adversaries and risk, controls and inspection, compliance and auditing. However, paying attention to your security posture and understanding what happens with network traffic, both desired and undesired, contributes to cost effective design in a cloud environment, too.
In this tutorial, we will focus on controlling egress traffic with the Amazon Route 53 DNS Resolver Firewall. Our first goal is to provide a secure environment, ensuring that only desired egress traffic is allowed. Our second goal, and really a side outcome of the capabilities we'll enable, is that we'll minimize our cloud costs for egress traffic.
For the purpose of this tutorial, egress traffic refers to traffic from our protected subnet within our Virtual Private Cloud (VPC), leaving the VPC, and being routed toward the internet.
We'll also work with the Amazon Route 53 DNS Resolver Firewall, Amazon EC2 Instances, and Amazon Virtual Private Clouds.
- How to configure Custom Domain Lists in Amazon Route 53 DNS Resolver Firewall and use that list in a filtering rule.
- How to use Managed Domain Lists in Amazon Route 53 DNS Resolver Firewall.
- How to enable logging to see what DNS queries are blocked as a result of the rules you have enabled.
Before starting this tutorial, you will need the following:
This is the first of a three-part series:
With Amazon Route 53 Resolver DNS Firewall, you define domain name filtering rules in rule groups that you associate with your VPCs. You can specify lists of domain names to allow or block, and you can customize the responses for the DNS queries that you block.
A primary use of Route 53 Resolver DNS Firewall is to block communication with known malicious domains and/or only allow communication with trusted domains. This is one of the features we will be configuring in this tutorial.
Not only can DNS Firewall prevent the resolution of untrusted domains (and the IP addresses needed to communicate with them) but it can also help prevent DNS exfiltration of your data. DNS exfiltration can happen when there is unauthorized access that compromises resources in your VPC. DNS queries can then be used to send data or tunnel other network protocols out of the VPC to malicious DNS servers.
With DNS Firewall, you can monitor and control the domains that your application workloads can query. You can deny access to the domains that AWS knows to be malicious and allow other queries to pass through.
Alternately, you can build a DNS Allow-List model where you implement a default deny to all domains except for the ones that you explicitly trust.
DNS Firewall and AWS Network Firewall both offer domain name filtering, but for different types of traffic. With DNS Firewall and AWS Network Firewall together, you can configure domain-based filtering for traffic over two different network egress paths.
DNS Firewall provides filtering for outbound DNS queries that pass through the Route 53 Resolver from within your VPCs. You can also configure DNS Firewall to send custom responses for queries to blocked domain names.
AWS Network Firewall provides filtering for all network traffic that is routed through firewall endpoints, but does not have visibility into queries made to the Route 53 Resolver.
In this tutorial, we focus on filtering the initial DNS request that AWS Network Firewall wouldn't normally have visibility into. To understand why this is important, let's examine our sample architecture seen in the following image.
The above image is a simplified, single availability zone, distributed deployment architecture.
Traffic from protected workloads going to the Internet is routed via the default route (0.0.0.0/0) to a Network Firewall endpoint which in turn has a default route pointing to a NAT Gateway endpoint. You can see this highlighted in numbers 1 and 2 of the simplified distributed deployment image.
The Public subnet where the NAT Gateway is located has a default route pointing to the Internet Gateway for the VPC, and it also has a specific route for return traffic to protected workloads pointing to the Network Firewall endpoint. This ensures the traffic is symmetric for full inspection. You can see this highlighted in number 3 and 4. With a NAT Gateway deployed in a dedicated public subnet, instances in private subnets can communicated with resources on the Internet.
This is the typical egress traffic flow when AWS Network Firewall is deployed. However, what's not depicted in the above image is the traffic flow for DNS Queries within the VPC.
In the image below, we can see what the traffic flow with DNS resolution looks like.
The Amazon Route 53 Resolver operates on the .2 address of each VPC subnet. Therefore, when DNS queries are sent, they are not evaluated by DNS Firewall because the query does not leave the private subnet and traverse the firewall subnet.
Considering a firewall architecture such as the one used in this tutorial, there are a few areas that lend themselves to a cost efficient architecture:
DNS traffic doesn't cross VPCs.
DNS traffic does not cross VPCs and it doesn't need to traverse the Internet. By keeping the DNS local we won't incur additional cost for the egress data.
DNS control makes sure that malicious connections are not made out of the VPC, thus reducing the compute and data costs.
A common technique for bad actors is to establish command and control connections from internal resources. The compute resource can then be used to initiate DDoS attacks, mine crypto, and perform other nefarious acts. By blocking DNS requests to Top-Level Domains(TLDs) that are known to be malicious, you essentially block this command and control channel from happening. This keeps compute costs and data costs down.
Modify the current architecture to use a centralized inspection VPC.
While this is not specific to this tutorial, you can make a minor adjustments to the firewall configuration and use a centralized inspection VPC rather than a distributed VPC. This will minimize the cost involved with having a firewall endpoint distributed across VPCs.
This tutorial starts with a baseline configuration that's built with an AWS CloudFormation template that you can find in the sample code repo. You will need to deploy the template
Egress-Controls-Tutorial.yaml in your own AWS environment before following along with the tutorial.
Once you have the CloudFormation Template deployed, we will check the baseline posture of the environment. We are checking to see that certain traffic is allowed out of the environment. Once verified we will configure the Amazon Route 53 resolve DNS firewall to block this undesired egress traffic and we will also enable logging.
Note: Deploying this CloudFormation template in your environment will incur costs. By using the template you assume all responsibility for these costs as well as the cleanup of the environment afterwards. We will walk you through the process at the end of this tutorial, but it is your responsibility to ensure the environment is cleaned up.
Let's begin by connecting to our test EC2 server instance and running a script to test egress traffic.
- Begin by navigating to CloudFormation in the AWS Console.
Click on the "Create stack" option and add the stack from the tutorial repo called Egress-Controls-Tutorial.yaml.
Name the stack and select an availability zone as seen below. Click next and finish the creation pages.
- Once the stack is in a create complete state, navigate into the stack by clicking on the stack name.
Outputsand check the resources that are created.
TestHostSessionin the key column. The URL link for
TestHostSessionopens an interactive shell on an Amazon EC2 instance (TestInstance1 in the earlier diagram) within an AWS Network Firewall protected subnet which you will be using to send test traffic in this tutorial.
Click on the link to connect to it. You may find it useful to open this in a separate tab, so you can return here to use this and the other links as shortcuts. There are also links to the AWS Network Firewall, Route 53 Resolver DNS Firewall, and CloudWatch Logs services.
In the interactive shell, change into the
ssm-userhome folder using the
Clone the git repo into the ssm-user home directory using the
git clone https://github.com/build-on-aws/testing-egress-controls-for-cloud-workloads.gitcommand.
cd into the
Run the test script using the command
sh egress-check.shcommand. This should show that nothing is currently being blocked.
Note: in this tutorial we will only be using the checks in the R53 DNS FIREWALL CONTROLS section of the output. This testing script is used in for other tutorials and not all of the tests performed are addressed in this tutorial.
In the subsequent portions of this tutorial, we will configure the Amazon Route 53 Resolver DNS firewall to filter our DNS queries and Internet-bound traffic until these tests return a
Let's configure the Amazon Route 53 Resolver DNS Firewall.
In this section, we will use Amazon Route 53 DNS Firewall to create a custom list of commonly abused top-level domains (TLDs) and set them to be blocked within our Egress VPC.
A domain list is a set of domain-matching specifications you can use in a Route 53 Resolver DNS firewall rule to ALLOW, BLOCK, or ALERT against matching domains. Within a single rule group you can have many rules that each match against a different domain list. You can create your own lists, and there are also AWS-managed lists which will be discussed in later sections of the lab. When you associate a rule group with a VPC, DNS firewall compares the DNS queries against the domain list in the rules and handles the DNS queries according the matching rule’s action.
In this step, we create a domain list that will specify the domain-matching patterns for top-level domains that will be blocked.
Navigate to VPC → DNS firewall (remember there is a shortcut link labeled R53DNSFWConsole in the
Outputsof the CloudFormation stack) and click on Domain lists.
Here you can see any custom lists created as well as AWS managed domain lists.
Click on Add domain list shown in the image below.
- Give the domain list a name of your choosing.
- Enter TLD-matching patterns from the image below(one-per-line) following the format shown (e.g.
*acts as a wildcard to match all the subdomains within each of these TLDs.
- We can always write exceptions later to our broad TLD-matching rules by creating an
ALLOWrule to match any needed exceptions and giving it a higher priority than our
- We'll use this list to BLOCK ten commonly abused top-level domains in our VPC.
- After entering the domains, click on Add domain list.
DNS Firewall rule groups are a set of rules that will allow, deny, or alert on DNS request that match the associated domain lists. In this step we are going to create a rule group and add the domain list just created.
- In the AWS Management Console, navigate to VPC → DNS firewall → Rule groups and click on Create rule group.
- Give a name to rule group and click next.
- Click on Add rule to add the domain list you just created.
- Enter a name for the rule and select the previously created domain list from the drop down and select BLOCK for the action on matches.
- Select OVERRIDE in the response for Block action and enter
dns-firewall-blockas the custom response and
CNAMEas record type.
- Having an override value in our response action makes it easier to say with certainty that a particular query was blocked by DNS Firewall as NXDOMAIN or NODATA responses could also indicate the absence of a queried record, rather than a BLOCK response from DNS Firewall. The CNAME value can also be used to redirect a blocked request to a web page with details on why the domain resolution was blocked.
- Leave TTL as
0and click on Add rule (DO NOT CLICK
Nextas it will skip adding the created rule). After you have added the rule you may click
- You can set the priority for the rules in this page which controls the order in which rules are evaluated. The first rule that matches a domain query will determine the action taken. If we were creating
ALLOWrule exceptions a
BLOCKrule, we would use this screen to increase the priority for the
- Leave the default value and click Next.
- Adding tags are optional. Leave blank and and click Next
- On the final Review and create screen click on Create rule group.
- You can now see the rule group created in the console. Note it is currently Not Associated to a VPC.
- In this step, we will associate a VPC with the newly created Rule group. Click on Rule group and then on Associate VPC as shown below.
- You will see multiple VPCs from the drop down. Select EgressVPC. After selecting the VPC, click on
Associateto associate the VPC with Rule group.
- You can see the VPC associated with the rule group once done.
You have deployed and created a DNS Firewall Rule group, configured a rule to BLOCK matches from a custom domain list, and associated this config with the tutorial Egress VPC.
- Navigate to the EC2 session and execute the test script. You can see that
Resolution of domains in Abused Top Level Domainsis changed from Allowed to Blocked.
- If some TLDs are still being resolved double-check the values entered in our custom domain list. It should contain all these domain matching patterns (one per line).
*.ru *.cn *.xyz *.cyou *.pw *.ws *.gq *.surf *.cf *.ml
At this point we have successfully created DNS Firewall Domain lists and rule groups and have associated them with a VPC. We are now blocking traffic from commonly abused top level domains.
In the next section we will work with managed Domain Lists.
Amazon Route 53 Resolver DNS Firewall comes with Managed Domain Lists that can be used to block the resolution of domain names associated with malicious activity or other potential threats.
AWS provides the following Managed Domain Lists, in the Regions where they are available, for all users of Route 53 Resolver DNS Firewall.
AWSManagedDomainsMalwareDomainList – Domains associated with sending malware, hosting malware, or distributing malware.
AWSManagedDomainsBotnetCommandandControl – Domains associated with controlling networks of computers that are infected with spamming malware.
AWSManagedAggregateThreatList – Domains associated with multiple DNS threat categories including malware, ransomware, botnet, spyware, and DNS tunneling to help block multiple types of threats.
AWSManagedDomainsAmazonGuardDutyThreatList – Domains associated with DNS security threats, such as malware, command and control, or cryptocurrency related activity, sourced from Amazon GuardDuty.
AWS Managed Domain Lists cannot be downloaded or browsed. To protect intellectual property, you can't view or edit the individual domain specifications within the AWS Managed Domain Lists. While this may seem a bit restrictive, the real benefit is that it also helps prevent malicious users from designing threats that specifically circumvent published lists. The reality of it all is that you don't want these lists to be published.
So in this section we are going to remove some of the manual work on our part, and not write a custom list. Instead, we will use the managed domain lists, that are created and maintained by AWS, to filter egress DNS queries.
Let's return to our test script and see the result of the
testergress command again. By running the script in the EC2 session again, we observe that DNS resolution of domains within the Botnet, Malware, and Amazon GuardDuty threat lists are currently allowed.
egress-check.shscript uses control/test domains managed by AWS which can be used for verifying the response of a rule configured to match on a managed list.
In the next steps, we create a new rule group with rules that block the managed domain lists.
- Similar to the previous section, in the AWS Console, navigate to Rule Groups and click on
add rule group. Enter a name to the Rule group and click on
- Click on
- We will add the botnet managed domain list in this step. Enter a name for the rule, select
Add AWS managed domain listand select
AWSManagedDomainsBotnetCommandandControlfrom the domain list dropdown.
OVERRIDEas response, and give
dns-firewall-blockas the record value. Select
CNAMEas Record type, leave
0as TTL and click on
Add rule. (In some test sandbox environments we saw an error that failed rule creation when selecting the CNAME override. You can also select
NXDOMAINoption for the block instead if you get this.)
- Similarly, add two more rules for
AWSManagedDomainsMalwareDomainList. You can see three rule groups as shown below. Click
- Click Next at screens for Set rule priority and Add tags to keep default values.
- At Review and create screen click on
Create rule group.
- The newly created rule group is not associated with a VPC. Click on
Associate the VPC.
EgressVPCand Click on
We have now created a new rule group and associated managed domain lists to block malicious FQDNs tracked by these lists.
- Note that we've associated two separate DNS Firewall rule groups with our Egress VPC
- The first rule group assigned to the VPC has a higher priority (lower number) which can be viewed for reach rule group on the Associated VPCs tab.
- Priority for multiple rule groups attached to a single VPC is determined by the order they were associated with the VPC with earlier associated rule groups having a higher priority.
- In most cases it will be easiest to manage the priority of rules by combining into a single rule group.
- Navigate to the EC2 Test host instance and execute
egress-check.shto test the results of our new configuration.
- If any of the domain checks is still showing
ALLOWED, double-check the rules in your new rule group.
- One reason it may still show
ALLOWEDis if any domains being queried are still cached locally on our test instance - which might happen if not enough time has lapsed from our last run of
egress-check.sh(in the last exercise).
- You can find the test domains used for this exercise by running the following command:
cat egress-check.sh | grep controldomain. You can then run a
digcommand against these domains to see if the response is coming from a cache. Run repeated
dig's to watch the TTL (time to live) value decrease until it reaches
0and then re-run
egress-check.shto verify the tests change to
At this point we have successfully blocked resolution of domains in the managed lists using DNS Firewall.
To log the DNS queries that are filtered by DNS Firewall rules that originate in your VPCs, you need to configure Query Logging in Route 53.
This is a best practices for security across your AWS environment including VPCs where you are not using Route 53 Resolver DNS Firewall. Query logging has the added benefit of showing DNS firewall rule actions.
By default Route 53 > Resolver > Query logging opens in N. Virginia (us-east-1) region. Make sure you select the Region where the tutorial is running. If appropriate region is not selected from the drop down, depending on the access permission, you might run into an error.
- We need to configure Query logging to start logging the queries that are filtered by DNS Firewall. Query logging is under the Route 53 in AWS Console. Navigate to Route 53 → Resolver → Query logging.
- Click on Configure Query logging.
- Enter a name
[egress-query-logging]for this configuration. You can save these logs to CloudWatch logs, S3 buckets, or a Kinesis Data Firehose delivery stream. Select CloudWatch Logs, log group, and send the logs to a new log group by creating a new log group[/aws/route53/egress-wf-query-logging].
- Add egressVPC to this Query logging.
- Click on Configure query logging to complete the set up.
- We can see the Query logging details as shown below once we've completed the configuration.
- Navigate to the EC2 session and execute the command
nslookup google.cn. Since DNS queries resolving this domain name are blocked you can see that the server cannot find the domain.
- Navigate to CloudWatch dashboard on the AWS Console. Click on Logs, then
Log groupsand then click on the log group created for query logging in this tutorial.
- Click on the latest log group.
google.cnin the search bar and observe the results.
- We can see that the traffic is blocked. We can also see the custom response
dns-firewall-blockthat we gave while creating the DNS Rule group.
In this portion of the tutorial, we have evaluated DNS Firewall rules using Query Logging with CloudWatch Logs.
- First, go to
VPC -> DNS Firewall -> Rule Groupsto disassociate the VPC from each of the rules.
- Next, delete the rules from each of the two rule groups you created.
- Navigate to
VPC -> DNS Firewall -> Rule groups. Select the Rule groups and click on Delete.
- Finally to
VPC -> DNS Firewall -> Domain Lists. Select the Domain List and click on Delete.
- Navigate to the CloudFormation Console, select the CloudFormation stack we created in beginning of this tutorial and click on
- You can see a message that it's a permanent deletion. Click on
Deleteon the prompt.
- It may take few minutes to delete the resources and the status will be updated to
- Navigate to CloudWatch, click on Log groups, select the log group you created during this tutorial and click on
- Next navigate to Route 53 > Resolver > Query Logging, select the
- Click Stop logging queries.
- Type delete and click
And that's it!
In this tutorial, we learned how to use Route 53 DNS Firewall to secure our VPC egress traffic. We configured a custom list of TLDs that we don't want our cloud resources communicating with. By blocking resolution to these TLDs we not only protected our account, but we also controlled egress traffic cost. We also controlled egress traffic using managed lists. Remember, the benefit to the managed lists is that we don't have to come up with them ourselves. Rather, we have expert guidance from AWS that curates and manages these lists for us. Lastly, we enabled logging and now have visibility into the DNS queried traffic that we blocked.
What we have seen here is just one aspect of controlling egress traffic. Implementing this simple approach to filtering DNS traffic can improve our security posture and minimizing costs incurred with undesired egress traffic. If you're interested in other aspects of managing your security posture and controlling costs have a look at the tutorial: Manage Security and Costs Across the Enterprise With AWS Organizations.
If you enjoyed this tutorial, found any issues, or have feedback for us, please send it our way!