Subchapter 91.1
references/blocking-malicious-domains.mdMarkdown21 KBView on GitHub
Domain expertise for filtering DNS queries leaving a VPC against known-malicious domains and blocking matches at the Amazon-provided resolver using Route 53 Resolver DNS Firewall (also called Route 53 DNS Firewall). Covers the precondition that decides whether the firewall sees any traffic at all, building rule groups from AWS-managed and custom domain lists, choosing the block action mode, and reusing one rule group across a customer’s VPCs.
Does not cover fanning the same protection across many accounts with Route 53 Profiles, or general Profile configuration. Those are separate skills.
Execute commands using the AWS MCP server when connected (sandboxed execution, audit logging, observability). Fall back to the AWS CLI otherwise.
To block malicious domains for a VPC, follow the procedure exactly. See the Procedure section below.
The procedure covers:
DNS Firewall only inspects queries that reach the Amazon-provided resolver (the .2 resolver,
shown as AmazonProvidedDNS). If the VPC’s Dynamic Host Configuration Protocol (DHCP) option set
points DNS at a custom resolver, the firewall sees nothing and has no effect, with no error.
Constraints:
A blocked query can be answered three ways. The right choice depends on how the customer wants the application to fail, because the wrong choice creates support cases that look like generic resolution failures.
| Mode | What the client sees | Use when |
|---|---|---|
NXDOMAIN | The domain does not exist | The application should fail fast, as if the name is unregistered |
NODATA | An empty answer | The failure should be quiet (can resemble a network issue) |
OVERRIDE | A CNAME to a domain you supply | Traffic should be redirected to a sinkhole or inspection host (DNS Firewall returns a CNAME, not an IP) |
Constraints:
Static managed and custom lists catch known-bad domains. DNS Firewall Advanced extends protection with four additional rule types that do not use customer domain lists:
| Rule type | Detection method | Use when |
|---|---|---|
| DGA (Domain Generation Algorithm) | ML-based behavioral detection | Malware that generates random-looking domains for command-and-control |
| DNS Tunneling | ML-based behavioral detection | Data exfiltration via DNS query/response payloads |
| Threat categories | Rule-based categorization | Blocking domains by threat type (e.g., malware, ransomware, spyware, C2) — broader than the Foundational managed lists |
| Content categories | Rule-based categorization | Blocking domains by content type (e.g., gambling, adult content, streaming) for acceptable-use enforcement |
DGA and DNS tunneling rules support confidence thresholds (HIGH, MEDIUM, LOW) that control the sensitivity of detection. Higher confidence means fewer false positives but may miss some threats.
Constraints:
DNS Firewall billing has three dimensions a customer should know before rollout:
Constraints:
Rule groups are reusable. You SHOULD associate one rule group with all of the customer’s VPCs rather than creating a separate rule group per VPC. Per-VPC duplication drifts over time as new domains land in some rule groups but not others, leaving inconsistent protection.
The VPC sends DNS to a custom resolver, not AmazonProvidedDNS. Confirm the DHCP option set
uses the .2 resolver before building rules. This is the most common cause and surfaces no error.
The block action mode does not match the desired client behavior. Choose NXDOMAIN, NODATA,
or OVERRIDE based on how the application should fail. See the decision table above.
A separate rule group was created per VPC. Associate one reusable rule group across all VPCs.
Domain lists were hand-curated without an AWS-managed list. Start from a managed list (malware, botnet command-and-control, or the aggregate threat list) and add custom lists on top.
This procedure filters DNS queries leaving a VPC against known-malicious domains and blocks matches at the Amazon-provided resolver using Route 53 Resolver DNS Firewall. It verifies the precondition that decides whether the firewall sees any traffic, creates and populates a rule group, sets the block action mode, associates the rule group across the customer’s VPCs, and surfaces the console link to verify the result.
vpc-0abc123). All VPCs in a
single run should share the Region.us-east-1).NXDOMAIN, NODATA, or OVERRIDE. Must be confirmed with
the customer before creating rules (see Step 4); do not default it silently.block_action is OVERRIDE): The domain name to
return as a CNAME for blocked queries. OVERRIDE supports a CNAME target only, not an IP.Constraints for parameter acquisition:
Check for required tooling and credentials before starting.
Constraints:
aws sts get-caller-identityaws sts assume-role) rather than long-lived IAM user access keys.DNS Firewall only inspects queries that reach the Amazon-provided resolver. If the VPC’s DHCP option set points DNS at a custom resolver, the firewall inspects nothing.
Constraints:
You MUST retrieve each VPC’s associated DHCP option set:
aws ec2 describe-vpcs --vpc-ids {vpc_id} --region {region} --query 'Vpcs[0].DhcpOptionsId'You MUST inspect the option set’s domain-name-servers value:
aws ec2 describe-dhcp-options --dhcp-options-ids {dhcp_options_id} --region {region}A domain-name-servers value of AmazonProvidedDNS means the firewall will see the queries.
Any other value (a custom resolver IP) means it will not
If a VPC uses a custom resolver, you MUST tell the customer plainly that DNS Firewall will not filter that VPC’s traffic, and MUST NOT continue building rules for it as though it were protected. The console surfaces no error for this case
Create one rule group and reference an AWS-managed domain list as the foundation, adding custom lists on top only as needed.
Constraints:
You MUST create a single rule group for reuse, not one per VPC:
aws route53resolver create-firewall-rule-group --name {rule_group_name} --region {region}You SHOULD start from one or more AWS-managed domain lists. The four publicly available managed lists are:
AWSManagedDomainsMalwareDomainList — domains associated with malware distribution and hostingAWSManagedDomainsBotnetCommandandControl — domains used for botnet command-and-controlAWSManagedDomainsAggregateThreatList — combined multi-threat list (superset of malware,
ransomware, botnet, spyware, DNS tunneling domains; includes domains from the other lists)AWSManagedDomainsAmazonGuardDutyThreatList — domains from Amazon GuardDuty DNS security
findings (internally generated threat intelligence)
List the managed lists in the Region to find their IDs:aws route53resolver list-firewall-domain-lists --region {region}The managed list is referenced by its Id, not its friendly name. You MUST resolve the friendly
name to its Id from list-firewall-domain-lists output before creating the rule
You MUST treat custom domain lists as additive, not as the foundation. If the customer supplied
custom_domains, create a custom list and add the domains with update-firewall-domains
(inline domains use update-firewall-domains, not import-firewall-domains):
aws route53resolver create-firewall-domain-list --name {custom_list_name} --region {region}
aws route53resolver update-firewall-domains --firewall-domain-list-id {list_id} \
--operation ADD --domains {domain1} {domain2} --region {region}For a bulk list, import-firewall-domains loads domains from an Amazon S3 file and supports only
--operation REPLACE (it overwrites the list); it does not accept inline --domains:
aws route53resolver import-firewall-domains --firewall-domain-list-id {list_id} \
--operation REPLACE --domain-file-url s3://{bucket}/{key} --region {region}Add a rule to the rule group that references each domain list with the confirmed block action.
Constraints:
You MUST confirm the block action with the customer before creating the rule, because the mode changes application behavior on a block:
NXDOMAIN — the client is told the domain does not exist (fail fast)NODATA — the client gets an empty answer (quiet failure)OVERRIDE — the client is returned a CNAME to a domain you supply (redirect to a sinkhole)You SHOULD offer an ALERT-first rollout for an unfamiliar managed list: create the rule with
--action ALERT first, confirm from query logs that legitimate domains are not caught, then
switch the rule to --action BLOCK. ALERT logs the match and permits the query, avoiding an
outage from a false positive on a list the customer has not validated
For NXDOMAIN or NODATA:
aws route53resolver create-firewall-rule \
--firewall-rule-group-id {rule_group_id} \
--firewall-domain-list-id {list_id} \
--priority {priority} --action BLOCK --block-response {NXDOMAIN|NODATA} \
--name {rule_name} --region {region}For OVERRIDE, you MUST supply override_target, a DNS record type, and a TTL:
aws route53resolver create-firewall-rule \
--firewall-rule-group-id {rule_group_id} \
--firewall-domain-list-id {list_id} \
--priority {priority} --action BLOCK --block-response OVERRIDE \
--block-override-domain {override_target} --block-override-dns-type CNAME \
--block-override-ttl {ttl} --name {rule_name} --region {region}If legitimate domains are caught by a managed list or a broad custom list, create a higher-priority ALLOW rule for those specific domains. Because DNS Firewall evaluates rules by priority (lowest number first) and stops at the first match, an ALLOW rule with a lower priority number than the BLOCK rule overrides the block for that domain.
Constraints:
You SHOULD create a custom domain list of known-good domains and an ALLOW rule at a priority lower (higher precedence) than the BLOCK rule:
aws route53resolver create-firewall-domain-list --name {allowlist_name} --region {region}
aws route53resolver update-firewall-domains --firewall-domain-list-id {allowlist_id} \
--operation ADD --domains {legitimate_domain1} {legitimate_domain2} --region {region}
aws route53resolver create-firewall-rule \
--firewall-rule-group-id {rule_group_id} \
--firewall-domain-list-id {allowlist_id} \
--priority {priority_lower_than_block} --action ALLOW \
--name {allow_rule_name} --region {region}You MUST set the ALLOW rule’s priority to a lower number than the BLOCK rule it overrides
Query logging is required to monitor ALERT rules, detect false positives, and confirm rules are matching expected traffic.
Constraints:
You MUST enable Resolver query logging on each protected VPC (this is the security-required control stated in Security Considerations; the log destination MUST have encryption at rest):
aws route53resolver create-resolver-query-log-config \
--name {log_config_name} \
--destination-arn {destination_arn} \
--region {region}
aws route53resolver associate-resolver-query-log-config \
--resolver-query-log-config-id {config_id} \
--resource-id {vpc_id} --region {region}The destination can be a CloudWatch Logs log group, an S3 bucket, or a Data Firehose delivery stream.
You MUST enable encryption at rest on the query log destination, because query logs contain the
domain names a VPC’s workloads resolve: a KMS key on the CloudWatch Logs log group
(aws logs associate-kms-key), SSE-S3 or SSE-KMS on the S3 bucket, or server-side encryption on
the Data Firehose stream
Query log records include firewall_rule_group_id, firewall_rule_action, and
firewall_domain_list_id for ALERT and BLOCK actions — use these to verify rules are
matching expected traffic before switching from ALERT to BLOCK
Associate the single rule group with every VPC that passed the Step 2 precondition.
Constraints:
You MUST associate the same rule group with each protected VPC rather than creating new rule groups:
aws route53resolver associate-firewall-rule-group \
--firewall-rule-group-id {rule_group_id} \
--vpc-id {vpc_id} --priority {priority} \
--name {association_name} --region {region}You MUST skip any VPC flagged in Step 2 as using a custom resolver, and remind the customer why
Confirm the associations and hand the customer the console link to verify.
Constraints:
You MUST verify each association reached COMPLETE:
aws route53resolver list-firewall-rule-group-associations \
--firewall-rule-group-id {rule_group_id} --region {region}You MUST present the rule group detail console view, filling {region} with the VPCs’ Region
and {ruleGroupId} with the rule group ID returned by create-firewall-rule-group in Step 3.
Note the fragment is RulegroupId (lowercase g):
https://{region}.console.aws.amazon.com/vpcconsole/home?region={region}#DNSFirewallRuleGroupDetails:RulegroupId={ruleGroupId}{
"vpc_ids": ["vpc-0abc123", "vpc-0def456"],
"region": "us-east-1",
"managed_domain_list": "AWSManagedDomainsMalwareDomainList",
"block_action": "NXDOMAIN"
}Created rule group rslvr-frg-0123456789abcdef0 referencing AWSManagedDomainsMalwareDomainList
with a BLOCK/NXDOMAIN rule.
- Associated with vpc-0abc123 (COMPLETE)
- Associated with vpc-0def456 (COMPLETE)
Verify in the console:
https://us-east-1.console.aws.amazon.com/vpcconsole/home?region=us-east-1#DNSFirewallRuleGroupDetails:RulegroupId=rslvr-frg-0123456789abcdef0The VPC sends DNS to a custom resolver, not AmazonProvidedDNS. Re-check the DHCP option set
(Step 2). DNS Firewall surfaces no error for this case.
The block action mode does not match the desired client behavior. Re-create the rule with the mode that matches how the application should fail (Step 4).
A separate rule group was created per VPC. Consolidate onto one reusable rule group and re-associate (Steps 3 and 5).
Check the association status with list-firewall-rule-group-associations. A VPC can have a
limited number of associated rule groups; remove an unused association before adding another.
AWS provides test domains for each managed list. Query these from within a protected VPC to confirm the firewall is active and rules are matching. The format is:
controldomain1.{listname}.firewall.route53resolver.{region}.amazonaws.comFor example:
dig controldomain1.botnetlist.firewall.route53resolver.us-east-1.amazonaws.comA successful block returns the configured block response (NXDOMAIN, NODATA, or OVERRIDE). If the query resolves normally, the firewall is not inspecting the VPC’s traffic.
aws sts assume-role) rather than
long-lived IAM user access keys, and prefer read-only credentials for inspection steps.