- Knowledge Base
- Amazon Web Services
- Amazon Route 53
- Enable Query Logging for Route 53 Hosted Zones
Ensure that Domain Name System (DNS) query logging is enabled for your Amazon Route 53 hosted zones in order to address DNS security and compliance requirements. This allows Amazon Route 53 to log information about the queries that Route 53 receives, such as the domain or subdomain that was requested, the date and time of the query, the DNS record type (e.g. A or AAAA), and the DNS response code, such as "NoError" or "ServFail". Once the DNS query logging is enabled and configured, Amazon Route 53 will send the log files to Amazon CloudWatch Logs.
Enabling DNS query logging for Amazon Route 53 hosted zones can be useful for regular auditing, investigations, and troubleshooting where regulated workloads must address the most stringent security and compliance requirements.
Audit
To determine if DNS query logging is enabled for your public Route 53 hosted zones, perform the following operations:
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon Route 53 console at https://console.aws.amazon.com/route53/.
03 In the main navigation panel, under Dashboard, choose Hosted zones.
04 Click inside the Filter hosted zones by property or value box, select Type, type Public and press Enter, to return the list with the public hosted zones created within your AWS cloud account.
05 Click on the domain name of the public hosted zone that you want to examine.
06 Choose Configure query logging from the console top menu to access the query logging configuration available for the selected hosted zone.
07 In the Log group section, check the Log group dropdown list for the name of the CloudWatch Logs log group where Amazon Route 53 saves queries made for DNS records within the selected hosted zone. If there is no CloudWatch Logs log group selected for the Log group, DNS query logging is not enabled for the selected Amazon Route 53 hosted zone.
08 Repeat steps no. 5 – 7 for each public hosted zone created with Amazon Route 53 service.
Using AWS CLI
01 Run list-hosted-zones command (OSX/Linux/UNIX) to list the ID of each Amazon Route 53 hosted zone created in your AWS cloud account:
aws route53 list-hosted-zones --query "HostedZones[*].Id"
02 The command output should return an array with the requested hosted zone IDs:
[ "/hostedzone/ABCD1234ABCD1234ABCD", "/hostedzone/ABCDABCD1234ABCDABCD" ]
03 Run get-hosted-zone command (OSX/Linux/UNIX) using the ID of the DNS hosted zone that you want to examine as the identifier parameter and custom query filters to determine whether the selected hosted zone is public or private:
aws route53 get-hosted-zone --id /hostedzone/ABCD1234ABCD1234ABCD --query "HostedZone.Config.PrivateZone"
04 The command output should return the requested configuration information (false for public, true for private). If the get-hosted-zonecommand output returns true, the Audit process ends here, otherwise you can continue the process with the next step:
false
05 Run list-query-logging-configs command (OSX/Linux/UNIX) to describe the DNS query logging configuration defined for the specified public hosted zone. Each configuration object defines where Amazon Route 53 saves DNS query logs and specifies the hosted zone that you want to log queries for:
aws route53 list-query-logging-configs --hosted-zone-id "/hostedzone/ABCD1234ABCD1234ABCD" --query "QueryLoggingConfigs"
06 The command output should return the requested configuration information (metadata):
[]
If the list-query-logging-configs command output returns an empty array (i.e. []), as shown in the example above, DNS query logging is not enabled for the selected Amazon Route 53 hosted zone.
07 Repeat steps no. 3 and 4 for each public hosted zone created with Amazon Route 53 within your AWS cloud account.
Remediation / Resolution
To enable and configure Domain Name System (DNS) query logging for your public Amazon Route 53 hosted zones, perform the following operations:
Using AWS CloudFormation
01 CloudFormation template (JSON):
{ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "CloudWatchLogGroup": { "Type": "AWS::Logs::LogGroup", "Properties": { "LogGroupName": "/aws/route53/domain.com", "RetentionInDays": 7 } }, "CloudWatchLogGroupPolicy": { "Type": "AWS::Logs::ResourcePolicy", "Properties": { "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "route53.amazonaws.com" }, "Action": [ "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/route53/domain.com:*" } ] } } }, "Route53HostedZone": { "Type": "AWS: : Route53: : HostedZone", "Properties": { "HostedZoneConfig": { "Comment": "Route53 public hosted zone for domain.com" }, "Name": "domain.com", "HostedZoneTags": [ { "Key": "Owner", "Value": "IT" } ], "QueryLoggingConfig": { "CloudWatchLogsLogGroupArn": { "Fn::GetAtt": [ "CloudWatchLogGroup", "Arn" ] } } } } } }
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09' Resources: CloudWatchLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: /aws/route53/domain.com RetentionInDays: 7 CloudWatchLogGroupPolicy: Type: AWS::Logs::ResourcePolicy Properties: PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: route53.amazonaws.com Action: - logs:CreateLogStream - logs:PutLogEvents Resource: arn:aws:logs:us-east-1:123456789012:log-group:/aws/route53/domain.com:* Route53HostedZone: Type: 'AWS: : Route53: : HostedZone' Properties: HostedZoneConfig: Comment: Route53 public hosted zone for domain.com Name: domain.com HostedZoneTags: - Key: Owner Value: IT QueryLoggingConfig: CloudWatchLogsLogGroupArn: !GetAtt 'CloudWatchLogGroup.Arn'
Using Terraform (AWS Provider)
01 Terraform configuration file (.tf):
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } } required_version = ">= 0.14.9" } provider "aws" { profile = "default" region = "us-east-1" } data "aws_caller_identity" "current" {} resource "aws_cloudwatch_log_group" "cloudwatch-log-group" { name = "/aws/route53/domain.com" retention_in_days = 7 } data "aws_iam_policy_document" "iam-policy-document" { statement { actions = [ "logs:CreateLogStream", "logs:PutLogEvents" ] resources = ["arn:aws:logs:us-east-1:123456789012:log-group:/aws/route53/domain.com:*"] principals { identifiers = ["route53.amazonaws.com"] type = "Service" } } } resource "aws_cloudwatch_log_resource_policy" "cloudwatch-log-group-policy" { policy_name = "route53-query-logging-policy" policy_document = data.aws_iam_policy_document.iam-policy-document.json } resource "aws_route53_zone" "route53-hosted-zone" { name = "domain.com" comment = "Route53 public hosted zone for domain.com" tags = { Owner = "IT" } } resource "aws_route53_query_log" "route53-query-logging" { depends_on = [aws_cloudwatch_log_resource_policy.cloudwatch-log-group-policy] zone_id = aws_route53_zone.route53-hosted-zone.zone_id cloudwatch_log_group_arn = aws_cloudwatch_log_group.cloudwatch-log-group.arn }
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon Route 53 console at https://console.aws.amazon.com/route53/.
03 In the main navigation panel, under Dashboard, choose Hosted zones.
04 Click inside the Filter hosted zones by property or value box, select Type, type Public and press Enter, to return the list with the public hosted zones created within your AWS cloud account.
05 Click on the domain name of the public hosted zone that you want to reconfigure.
06 Choose Configure query logging from the console top menu and provide the following information:
- Select Create log group from the Log group dropdown list.
- For New log group name, provide a unique name for the CloudWatch Logs log group where Amazon Route 53 will publish the DNS query logs created for the selected hosted zone. AWS recommends naming your log group as a path such as
/aws/route53/<domain-name>
, where<domain-name>
is the name of your Amazon Route 53 domain. - Route 53 needs permission from a resource policy to publish logs to your new CloudWatch Logs log group. Choose Grant permissions to apply the necessary permissions.
- Choose Create to create a new DNS query logging configuration for the selected Amazon Route 53 hosted zone. To view the published DNS query logs, navigate to Amazon CloudWatch Logs console at https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#logsV2:log-groups.
07 Repeat steps no. 4 – 6 to enable and configure DNS query logging for other public hosted zones created within your AWS cloud account.
Using AWS CLI
01 Run create-log-group command (OSX/Linux/UNIX) to create the CloudWatch Logs log group where Amazon Route 53 will publish your DNS query logs. AWS recommends naming your log group as a path such as /aws/route53/<domain-name>
, where <domain-name>
is the name of your Route 53 domain (the command does not produce an output):
aws logs create-log-group --region us-east-1 --log-group-name /aws/route53/trendmicro.com
02 Run describe-log-groups command (OSX/Linux/UNIX) using the name of the newly created log group as the identifier parameter and custom query filters to describe the log group ARN:
aws logs describe-log-groups --region us-east-1 --log-group-name /aws/route53/trendmicro.com --query 'logGroups[*].arn'
03 The command output should return the requested Amazon Resource Name (ARN):
[ "arn:aws:logs:us-east-1:123456789012:log-group:/aws/route53/trendmicro.com:*" ]
04 Run put-resource-policy command (OSX/Linux/UNIX) to grant Amazon Route 53 the required permissions to write to the CloudWatch Logs log group created at the previous steps:
aws logs put-resource-policy --region us-east-1 --policy-name cc-dns-query-logging-policy --policy-document '{ "Version": "2012-10-17", "Statement": [{ "Sid": "Route53LogsToCloudWatchLogs", "Effect": "Allow", "Principal": { "Service": "route53.amazonaws.com"}, "Action":[ "logs:PutLogEvents","logs:CreateLogStream"],"Resource": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/route53/trendmicro.com:*"}]}'
05 The command output should return the implemented policy document (JSON format):
{ "resourcePolicy": { "policyName": "cc-dns-query-logging-policy", "policyDocument": "{ \"Version\": \"2012-10-17\", \"Statement\": [{ \"Sid\": \"Route53LogsToCloudWatchLogs\", \"Effect\": \"Allow\", \"Principal\": { \"Service\": \"route53.amazonaws.com\"}, \"Action\":[ \"logs:PutLogEvents\",\"logs:CreateLogStream\"],\"Resource\": \"arn:aws:logs:us-east-1:123456789012:log-group:/aws/route53/trendmicro.com:*\"}]}", "lastUpdatedTime": 1611597634355 } }
06 Run create-query-logging-config command (OSX/Linux/UNIX) using the ARN of the new CloudWatch Logs log group as value for the --cloud-watch-logs-log-group-arn configuration parameter, to create a new query logging configuration which defines where to save DNS query logs generated for the selected Amazon Route 53 hosted zone. After you create the query logging configuration, Amazon Route 53 begins to publish query log data to the associated CloudWatch Logs log group:
aws route53 create-query-logging-config --hosted-zone-id "/hostedzone/ABCD1234ABCD1234ABCD" --cloud-watch-logs-log-group-arn "arn:aws:logs:us-east-1:123456789012:log-group:/aws/route53/trendmicro.com:*"
07 The command output should return the metadata for the new query logging configuration:
{ "Location": "https://route53.amazonaws.com/2013-04-01/queryloggingconfig/abcd1234-abcd-1234-abcd-1234abcd1234", "QueryLoggingConfig": { "HostedZoneId": "ABCD1234ABCD1234ABCD", "CloudWatchLogsLogGroupArn": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/route53/trendmicro.com:*", "Id": "abcd1234-abcd-1234-abcd-1234abcd1234" } }
08 Change the AWS cloud region by updating the --region command parameter value and repeat steps no. 1 – 7 to enable and configure DNS query logging for other public hosted zones available in your AWS account.
References
- AWS Documentation
- Monitoring Amazon Route 53
- Public DNS query logging
- Working with log groups and log streams
- AWS Command Line Interface (CLI) Documentation
- route53
- list-hosted-zones
- list-query-logging-configs
- create-query-logging-config
- logs
- create-log-group
- describe-log-groups
- put-resource-policy