Skip to content

Block malicious domain resolution using Route 53 Global Resolver DNS Firewall

10 minute read
Content level: Intermediate
1

Demonstrates how to configure DNS Firewall rules in a Route 53 Global Resolver DNS View to block malicious domains using custom domain lists, AWS managed lists, and DGA advanced threat detection, with OCSF log verification.

Background

DNS Firewall is the security layer within Global Resolver that evaluates DNS queries sent to Global Resolver before resolution. Queries matching a Block rule are denied and do not proceed to resolution. Queries matching an Alert rule are logged but permitted to continue.

Note: DNS Firewall only protects DNS queries sent to Global Resolver endpoints. Clients can bypass this protection by using other DNS resolvers or external DoH/DoT services. Direct IP connections also bypass domain-based DNS controls. For comprehensive coverage, use network-level policies to enforce Global Resolver usage, restrict unauthorized encrypted DNS services, and control direct outbound connections.

Architecture overview

DNS Firewall Architecture Diagram

Query flow from left to right:

  1. Client (office/remote/branch) sends DNS query to Global Resolver Anycast IP
  2. Global Resolver authenticates the client
  3. DNS Firewall evaluates the query
  4. Queries not blocked proceed to normal resolution
  5. Query Logging records all queries and Firewall actions

Prerequisites

  1. An AWS account with IAM permissions: AmazonRoute53GlobalResolverFullAccess + CloudWatchLogsFullAccess
  2. Latest AWS CLI v2 installed, run aws route53globalresolver help to confirm the subcommand is available
  3. Your public IPv4 address: curl -4 -s https://checkip.amazonaws.com

Step 1: Create the Global Resolver

  1. Log in to the AWS Console and switch Region to us-east-2

  2. Open Route 53, then in the left menu click Global Resolver -> Global resolvers Global Resolver

  3. Click Create global resolver Create global resolver

  4. Configuration:

    • Resolver name: enter a descriptive name
    • Regions: select at least 2 Regions closest to your clients
    • IP address type: Dual-stack
  5. Click Create Configuration Dual-stack

  6. Wait for status to become Operational (approximately 3-5 minutes)

  7. Note the assigned Anycast IPv4 addresses (needed for testing) Anycast IPv4 addresses

Step 2: Create a DNS View

Create a DNS View

  1. Click into your Global Resolver
  2. DNS views tab -> Create DNS view
  3. Enter the DNS view name
  4. Keep other options at their defaults:
    • DNSSEC validation: Enable
    • Firewall rules fail open behavior: Disable
    • EDNS client subnet: Enable
  5. Click Create
  6. Wait for status to become Operational

Step 3: Configure Access Source

Configure Access Source

  1. Navigate into your DNS View -> Access sources tab
  2. Click Create access source
  3. Configuration:
    • Name: enter a descriptive name
    • CIDR block: your public IPv4/32 (exact match for your IP)
    • Protocol: Do53
  4. Click Create
  5. Wait for status to become Operational Operational Region

Step 4: Enable Query Logging

Add Query Logging

Enable logging before running tests to ensure all test queries are captured.

  1. Go back to the Global Resolver details page

  2. In the Resolver details section, find Observability Region -> click Edit -> select US East (Ohio) us-east-2 -> Save

  3. Click the Log delivery tab

  4. Click Add -> To Amazon CloudWatch Logs Amazon CloudWatch Logs

  5. Log type: keep GLOBAL_RESOLVER_LOGS

  6. Destination log group: use the system-recommended path (format: /aws/vendedlogs/route53globalresolver/...) Log type

  7. Click Add

Step 5: Create a custom domain list

Create a custom domain list

  1. Navigate to Global Resolver -> Domain lists tab (important: this is NOT the Domain lists under VPC Resolver in the left menu, those are separate regional resources)

  2. Click Create domain list

  3. Enter a name Enter a name

  4. Click Create -> wait for status to become Operational

  5. Click into the domain list -> Add domains Add domains

  6. Select Specify domains manually Specify domains

  7. Enter domains to block, for example:

    • malicious-test.example.com
    • *.phishing-demo.net
    • bad-site.org
  8. Click Add domains -> wait for status to become Operational again

Note: Domain lists support exact matching and wildcard matching (*.example.com matches all subdomains). DNS Firewall matches against the query string, even non-existent domains will be blocked.

Step 6: Create DNS Firewall rules

Rule A: Custom domain list Block

Custom domain list Block

  1. Navigate to DNS View -> DNS Firewall rules tab

  2. Click Create rule

  3. Configuration:

    • Rule name: enter a descriptive name
    • Rule configuration type: Customer managed domain lists
    • Domain lists: select the domain list created in Step 5
    • Query type: leave empty (matches all query types)
    • Action: Block
    • Response to send for Block action: NXDOMAIN Configuration Block
  4. Click Create rule

  5. Wait for rule status to become Operational

Rule B: AWS managed domain list Block

AWS managed domain list Block Block

  1. Click Create rule
  2. Configuration:
    • Rule name: enter a descriptive name
    • Rule configuration type: AWS managed domain lists
    • Select the Malware category from the dropdown
    • Action: Block
    • Response to send for Block action: NXDOMAIN
  3. Click Create rule
  4. Wait for rule status to become Operational

Rule C: DGA Advanced Threat Detection

Create rule DNS Firewall Advanced protections Rule Action

  1. Click Create rule
  2. Configuration:
    • Rule name: enter a descriptive name
    • Rule configuration type: DNS Firewall Advanced protections
    • Protection type: Domain Generation Algorithms (DGAs)
    • Confidence threshold: HIGH
    • Action: Block
    • Response to send for Block action: NXDOMAIN
  3. Click Create rule
  4. Wait for rule status to become Operational

Verify the rule list

After creation, confirm all three rules show Operational status in the DNS Firewall rules tab.

Note: Priority is automatically assigned by the system in creation order (1, 2, 3...). Lower numbers execute first. To adjust execution order, select a rule -> Edit -> modify the Priority value.

Step 7: Test and verify

From an authorized client, run the following queries to test resolver behavior, then use logs and metrics to validate applicable firewall rules.

Important: A dig response code (such as NXDOMAIN) alone cannot confirm whether a query was blocked by DNS Firewall or the domain simply does not exist. The definitive verification is the CloudWatch log entry:

  • action_name = "Denied" -> the query was blocked
  • action_name = "Allowed" -> the query was permitted
  • firewall_rule_id, when present, identifies the rule associated with the decision

An Alert match is confirmed only when action_name = "Allowed", firewall_rule_id matches the expected rule, and that rule is configured with the Alert action.

Test 1: Normal domain resolution

dig @<Anycast-IP> aws.amazon.com

Expected dig result: Returns A records with NOERROR. Expected log entry: action_name = "Allowed", rcode = "NOERROR", and no firewall_rule_id matching Rules A, B, or C.

This confirms the Global Resolver is functioning and your access source is authorized.

Test 2: Custom domain list Block (Rule A)

dig @<Anycast-IP> malicious-test.example.com

Expected dig result: NXDOMAIN (the Block response configured in Rule A). Expected log entry: action_name = "Denied", enrichments[].data.firewall_rule_id matches Rule A.

Note: This domain also does not exist in public DNS, so the NXDOMAIN response alone is ambiguous. The log entry with action_name = "Denied" and the matching rule ID is the definitive proof of a firewall block.

The wildcard entry *.phishing-demo.net in the custom domain list also matches anything.phishing-demo.net. Because Rule A has the highest priority (lowest number), any query matching the custom list is intercepted by Rule A regardless of whether it might also appear in an AWS managed list.

Test 3: AWS managed domain list verification (Rule B)

AWS managed domain lists are not publicly browsable, so you cannot select a guaranteed-matching domain for on-demand testing.

Recommended verification approach:

  1. Configure Rule B with the Alert action (instead of Block). In Alert mode, matching queries are permitted rather than blocked, but the match is recorded.
  2. Monitor for a log entry where:
    • action_name = "Allowed"
    • enrichments[].data.firewall_rule_id matches Rule B's rule ID
  3. You can also confirm matches through DNS Firewall sampled requests or CloudWatch metrics for the rule.
  4. Once you observe real matches confirming Rule B is evaluating correctly, change the action to Block for production enforcement.

This follows the AWS best practice for managed domain lists: deploy in Alert mode first, validate through logs and metrics, then enable Block.

Test 4: DGA advanced threat detection (Rule C)

dig @<Anycast-IP> aef3fbb2bc7dqrb6n.ev11-test.example.com

Observed result: In this test, the domain was not classified as DGA-generated at HIGH confidence. The CloudWatch log shows action_name = "Allowed", rcode = "NOERROR".

DGA detection evaluates DNS queries for characteristics associated with algorithmically generated domains. The HIGH confidence threshold prioritizes lower false-positive rates, so a single synthetic random-looking domain is not guaranteed to trigger the rule.

For Rule C's current Block configuration, confirm a match only when action_name = "Denied" and enrichments[].data.firewall_rule_id matches Rule C.

Verify logs in CloudWatch

After running the test queries, navigate to CloudWatch Logs -> Log groups -> select the /aws/vendedlogs/route53globalresolver/... log group created in Step 4.

Each query generates an OCSF-formatted log entry. Key fields to examine:

  • query.hostname: the domain that was queried
  • action_name: "Allowed" (query permitted) or "Denied" (blocked by firewall)
  • rcode: "NOERROR" (the DNS query completed without a protocol error, although the response might contain no answer records), "NXDOMAIN" (firewall block response or non-existent domain), or "REFUSED"
  • enrichments[].data.firewall_rule_id: the specific rule associated with the decision (present for both Block and Alert matches)
  • enrichments[].data.dns_view_id: the DNS View that processed the query

The screenshot below shows CloudWatch log entries for four sample queries:

  • aws.amazon.com: Allowed, NOERROR — normal resolution confirmed
  • malicious-test.example.com: Denied, NXDOMAIN — custom domain list block (Rule A) confirmed
  • anything.phishing-demo.net: Denied, NXDOMAIN — blocked by the custom wildcard *.phishing-demo.net in Rule A (not Rule B)
  • A separate DGA-style test domain: Allowed, NOERROR — HIGH confidence DGA detection was not triggered for this domain

This test run confirms that Rule A is blocking as expected. It does not validate Rule B, and Rule C did not trigger. Validate Rule B in Alert mode before enabling Block, and validate Rule C through subsequent rule-specific log matches.

The screenshot below shows sample log entries for all four test cases. resolution

Summary

This article showed how to configure three DNS Firewall rule types for Route 53 Global Resolver: a custom domain list with Block, an AWS managed domain list using an Alert-before-Block workflow, and DGA advanced protection with Block at HIGH confidence. The test run confirmed the custom domain list block; the managed domain list and DGA rule require subsequent rule-specific matches for validation. Use the CloudWatch OCSF log fields action_name and enrichments[].data.firewall_rule_id as definitive evidence, rather than relying on dig response codes alone.

References

  1. [Route 53 Global Resolver] https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/gr-what-is-global-resolver.html
  2. [DNS Firewall for Global Resolver] https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/gr-configure-manage-firewall-rules.html
  3. [Managed domain lists] https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/gr-managed-domain-lists.html
  4. [Global Resolver DNS query logging - OCSF format] https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/gr-gain-visibility-into-dns-activity.html
  5. [Open Cybersecurity Schema Framework] https://schema.ocsf.io/