On this page
The Simplest AWS Security Hack I've Shipped in a Decade
Learn how to use Route 53 DNS Firewall to block malicious domains and control outbound traffic in AWS. This guide covers setup, Terraform implementation, cost, and a safe rollout strategy for production.
DNS based firewalls are one of the easiset and fastest ways to secure your network. They have been around for decades and have been widely adopted for network security. They simply block DNS queries to malicious domains before they can even start to communicate with the internet.
When I work with our customers, I often find out that they implement all sorts of security controls like security groups, network policies, etc. but they almost always miss out on the simplest and most effective one - DNS based firewalls. DNS based firewalls are not a replacement for these other controls, but they are a powerful addition.
AWS has a very simple mechanism to achieve this on your VPC DNS resolver. It's called Route 53 Resolver DNS Firewall. It's a simple rule based firewall that sits in front of the DNS resolver your VPC already uses. When something inside the VPC asks "where is evil-c2.ru?", the firewall checks the domain against AWS's managed threat lists and returns NXDOMAIN if it's bad. The connection dies before a single packet leaves the network. That's the whole idea. Nothing runs on the host. Nothing sits in the packet path. No application has to change. It covers every EC2, Fargate task, Lambda, and EKS pod in the VPC the moment you turn it on, and most setups cost under $30 a month.
I've been in platform work for almost a decade now. I have never seen a security primitive with this effort-to-outcome ratio. AWS shipped it in 2021. Very few teams I have audited run it.
What you actually ship - a Terraform module

You create five things:
- A rule group pointing at AWS's four managed threat lists:
AWSManagedDomainsMalwareDomainList,AWSManagedDomainsBotnetCommandandControl,AWSManagedDomainsAmazonGuardDutyThreatList,AWSManagedDomainsAggregateThreatList - A rule group with your own policy-forbidden domains (webhook.site, transfer.sh, pastebin mirrors, crypto miners)
- Rule group associations to each VPC you want covered
- A Resolver query log config writing every DNS query to CloudWatch
- A metric filter, alarm, and SNS topic for notifications on blocked queries
Under 200 lines of Terraform.
Terraform implementation
Here's the shape of it:
data "aws_route53_resolver_firewall_domain_list" "botnet" {
name = "AWSManagedDomainsBotnetCommandandControl"
}
resource "aws_route53_resolver_firewall_rule_group" "managed" {
name = "managed-threat-blocks"
}
resource "aws_route53_resolver_firewall_rule" "botnet" {
name = "block-botnet-c2"
firewall_rule_group_id = aws_route53_resolver_firewall_rule_group.managed.id
firewall_domain_list_id = data.aws_route53_resolver_firewall_domain_list.botnet.id
priority = 10
action = "BLOCK"
block_response = "NXDOMAIN"
}
resource "aws_route53_resolver_firewall_rule_group_association" "managed" {
firewall_rule_group_id = aws_route53_resolver_firewall_rule_group.managed.id
vpc_id = var.vpc_id
priority = 101
name = "managed-block"
}
resource "aws_route53_resolver_query_log_config" "vpc" {
name = "vpc-dns-logs"
destination_arn = aws_cloudwatch_log_group.dns.arn
}
resource "aws_route53_resolver_query_log_config_association" "vpc" {
resolver_query_log_config_id = aws_route53_resolver_query_log_config.vpc.id
resource_id = var.vpc_id
}Three things to be careful about:
- Association priority ordering. Allowlist rule groups need a lower number than blocklists, or the block wins. I use 50 for allow, 101+ for block. The priority lives on the association, not the rule group.
block_response = "NXDOMAIN", notNODATA. NXDOMAIN makes the client fail cleanly. NODATA can leave some resolvers hanging in a retry loop.- Query logging is a separate resource. The firewall decides whether to block. The query log config is what actually writes entries. You need both, and both need VPC associations.
What you get back, immediately
Malware C2 communication is blocked for every workload, automatically. EC2, ECS, Fargate, Lambda, EKS pods. Anything using the VPC resolver, which is almost everything by default. When a compromised container tries to phone home to evil-c2.ru, the resolver returns NXDOMAIN. The connection dies at the DNS layer. No packet leaves your VPC.
You get a complete DNS audit trail in CloudWatch. Every query, every VPC, every source IP. When something goes sideways — supply chain compromise, malicious npm package, leaked credential being abused — you can answer "what did it try to talk to?" in minutes.
You enforce egress policy without asking app teams to do anything. Want to block webhook.site, transfer.sh, and anonymous file upload services? Add them to a domain list. Done. No config change in any app. No proxy PAC file. No VPN rules.
Safety against DNS-over-HTTPS bypass attempts
DNS Firewall catches DNS-over-HTTPS bypass attempts.
Modern malware increasingly uses DoH to talk to 1.1.1.1, dns.google, or attacker-controlled resolvers, routing around traditional egress proxies that can't see inside TLS. But the first step of DoH is still resolving the DoH endpoint. If that endpoint is in a threat list, the lookup fails before the HTTPS tunnel ever opens.
How do I suggest rolling this out?
Deploy in ALERT mode. Do not enable BLOCK mode in the beginning to avoid unexpected blockages. Wait two weeks. Run this CloudWatch Insights query:
fields query_name, firewall_domain_list_id
| filter firewall_rule_action = "ALERT"
| stats count(*) as hits by query_name
| sort hits descFlip to BLOCK one managed list at a time. Start with BotnetCommandandControl (highest confidence, fewest false positives). End with AggregateThreatList (broadest, highest false-positive rate). Wait a week between flips. If something breaks, you know which list did it.
The cost math
For a typical setup:
| Workload scale | Monthly cost |
|---|---|
| 10 services, 1 VPC, 10M queries | $15 |
| 20 services, 3 VPCs, 50M queries | $70 |
| 50 services, 5 VPCs, 200M queries | $260 |
Its not a complete egress solution
"It's not a complete egress solution." Correct. It doesn't inspect payloads. It doesn't block IP-literal traffic from malware that hardcodes IPs. It doesn't replace security groups or NAT gateways with fixed egress IPs.
However, it's a great addition to your egress security posture. It's a simple and effective way to block malicious domains before they can even start to communicate with the internet.
Frequently Asked Questions
What is Route 53 DNS Firewall?
Route 53 DNS Firewall is an AWS service that filters outbound DNS queries at the VPC resolver level, allowing you to block malicious domains, command-and-control (C2) traffic, and unwanted destinations before any connection is established.
How does Route 53 DNS Firewall work?
Route 53 DNS Firewall evaluates DNS queries against managed and custom domain lists. If a domain is flagged, it returns an NXDOMAIN response, stopping communication before traffic leaves your VPC.
Does Route 53 DNS Firewall require agents?
No, Route 53 DNS Firewall is completely agentless. It works at the VPC DNS resolver level and automatically protects EC2, Lambda, Fargate, and EKS workloads without any application changes.
Can Route 53 DNS Firewall block malware?
Yes, it blocks malware by preventing DNS resolution of malicious domains, including botnet command-and-control servers, using AWS managed threat intelligence lists.
Does Route 53 DNS Firewall support Lambda and EKS?
Yes, it works automatically with Lambda, EKS, EC2, and Fargate as long as they use the default VPC DNS resolver.
What is the cost of Route 53 DNS Firewall?
Pricing depends on DNS query volume and rule groups. Most small to mid-sized setups typically cost between $15 and $70 per month.
Should I enable BLOCK mode immediately?
No, it’s recommended to start in ALERT mode, monitor DNS queries for false positives, and gradually move to BLOCK mode to avoid breaking production workloads.
Conclusion
Route 53 DNS Firewall is one of those rare AWS features that’s simple to set up but makes a real difference. With just a bit of configuration, you can block malicious domains, reduce risk from compromised workloads, and finally get visibility into what your systems are trying to reach outside your VPC.
It’s not meant to replace everything else in your security stack, but it solves a problem that a lot of teams don’t even realize they have—uncontrolled outbound traffic.
If you haven’t tried it yet, start in alert mode, watch what shows up, and then move to blocking step by step. You’ll likely catch things you didn’t expect.
For the effort involved, it’s easily one of the highest-impact security improvements you can make in AWS.
Ship it or get in touch with KubeNine on (https://kubenine.com) to understand it further.
Read More on KubeBlogs
If you're exploring DevOps, Kubernetes, and cloud infrastructure, these guides will help you go deeper:
- How Kubernetes Routes Pod Traffic with a Single Egress IP
https://www.kubeblogs.com/how-civo-kubernetes-routes-pod-traffic-single-egress-ip-explained/ - GP3 vs GP2 EBS Volumes: Performance and Cost Comparison
https://www.kubeblogs.com/gp3-vs-gp2-ebs-volume-aws/ - How to Set Up a Self-Hosted GitHub Actions Runner
https://www.kubeblogs.com/self-hosted-github-actions-runner/
These articles cover Kubernetes networking, AWS storage optimization, and CI/CD infrastructure — useful when scaling beyond local development environments.