Route53 パブリックホストゾーンでのDNSクエリログ記録の有効化設定手順

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。
この記事では、Route 53パブリックホストゾーンのDNSクエリログ記録が有効化されていない状態について、リスクと対策を解説します。

ポリシーの説明
Route 53 の Security Hub コントロール – AWS Security Hub
Amazon Route 53 パブリックホストゾーンで DNS クエリログ記録が有効になっているかどうかを確認します。このコントロールは Amazon Route 53 パブリックホストゾーンで DNS クエリログ記録が有効になっているかどうかを確認します。
リスク
Amazon Route 53は、スケーラブルで可用性の高いドメインネームシステム (DNS) ウェブサービスです。Route 53のパブリックホストゾーンにおけるDNSクエリログ記録が有効化されていない場合、DNSレベルでの可視性が失われ、以下のようなセキュリティと運用上のリスクが発生します。
- DNSベースの攻撃の検知遅延: DNSクエリログがないと、DDoS攻撃(例: DNSリフレクション攻撃)、DNSトンネリング、マルウェアのコマンド&コントロール通信、データ窃取の試みなど、DNSを悪用した攻撃パターンを早期に検知できません。
- セキュリティインシデントの調査困難: 疑わしいドメインへの大量クエリ、予期しないDNSレコードタイプのリクエスト、通常とは異なる時間帯のクエリなど、セキュリティインシデントの兆候となるアクティビティが発生しても、ログがなければ原因究明や影響範囲の特定が非常に困難になります。
- コンプライアンス違反: 多くのセキュリティ規制やコンプライアンス要件(例: PCI DSS, HIPAA)では、ネットワークアクティビティ、特にDNSクエリの監査証跡の収集と保持が義務付けられています。ログ記録が有効でない場合、これらの要件を満たせない可能性があります。
- アプリケーションパフォーマンス問題の特定困難: DNS解決の遅延やエラーがアプリケーションのパフォーマンスに影響を与えることがあります。クエリログがないと、これらの問題をDNSレイヤーで特定し、トラブルシューティングする能力が制限されます。
- 運用上の可視性不足: どのドメインが、いつ、どこから、どのようにクエリされているかという情報がないため、トラフィックパターンの分析、新しいサービスの利用状況の把握、不正なDNS設定の発見などができません。
対策
Route 53パブリックホストゾーンのDNSクエリログ記録を有効化することは、DNSセキュリティを強化し、コンプライアンス要件を満たし、運用上の可視性を高めるために不可欠です。
- クエリログ記録の有効化: Route 53ホストゾーンに対して、DNSクエリログをCloudWatch Logsグループに送信するように設定します。
- ロググループの適切な管理: CloudWatch Logsで、DNSクエリログ用の専用ロググループを作成し、適切な保持期間を設定します。長期保存が必要な場合は、CloudWatch LogsからS3へのエクスポートも検討します。
- CloudWatchメトリクスフィルターとアラームの活用: CloudWatch LogsのDNSクエリログデータに対して、特定の異常パターン(例: 特定のドメインへの異常な大量クエリ、
ServFail
応答の急増、特定のレコードタイプへの異常なリクエスト)を検知するメトリクスフィルターを作成し、それに基づいてSNSトピックへ通知するCloudWatchアラームを設定します。 - ログの分析と可視化: CloudWatch LogsのDNSクエリログデータを、Amazon Athena、Amazon QuickSight、または他のログ分析ツールと連携させることで、DNSトラフィックの傾向分析、異常の特定、セキュリティ脅威の可視化を行います。
- IAM権限の最小化: クエリログ記録の設定を変更できるIAMユーザーやロールを最小限に制限し、多要素認証(MFA)を必須とすることで、不正な設定変更のリスクを低減します。
修復方法
AWSコンソールでの修復手順
AWSコンソールを使用して、Route 53パブリックホストゾーンのDNSクエリログ記録を有効にします。
- Route 53サービスへ移動:
- AWSコンソールにログインし、Route 53サービスを開きます。
- ホストゾーンの選択:
- 左側のナビゲーションペインで「ホストゾーン」を選択します。
- DNSクエリログを有効にしたいパブリックホストゾーンを選択します。
- クエリログ記録の有効化:
- ホストゾーンの詳細ページで、「詳細」タブ(または「クエリのログ記録」セクション)を見つけます。
- 「クエリのログ記録を管理」ボタン(または「クエリのログ記録を有効にする」ボタン)をクリックします。
- 「ロググループの選択」で、既存のCloudWatch Logsグループを選択するか、「新しいロググループを作成」を選択して、新しいロググループ名を入力します。
- *「IAM ロール」で、Route 53がCloudWatch Logsにログを書き込むための新しいIAMロールを自動的に作成するか、既存のロールを選択します。通常は自動生成を選択し、デフォルトで作成されるロールを使用します。
- 「クエリログ記録を有効にする」をクリックして設定を保存します。
- 設定後、数分でDNSクエリログが指定したCloudWatch Logsグループに表示され始めます。

Terraformでの修復手順
TerraformでRoute 53パブリックホストゾーンのDNSクエリログ記録を有効にするには、aws_route53_query_logging_config
リソースを使用します。これには、クエリログを保存するためのCloudWatch Logsグループと、Route 53がログを書き込むためのIAMロールが必要です。
# CloudWatch Logsグループを定義 (DNSクエリログ用)
resource "aws_cloudwatch_log_group" "route53_query_logs" {
name = "/aws/route53/your-domain.com-query-logs" # ホストゾーン名に合わせて変更
retention_in_days = 30 # ログの保持期間 (必要に応じて変更)
tags = {
Environment = "Production"
}
}
# Route 53がCloudWatch Logsにログを書き込むためのIAMロールを定義
resource "aws_iam_role" "route53_query_logging_role" {
name = "route53-query-logging-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "route53.amazonaws.com"
}
},
]
})
}
# IAMロールにCloudWatch Logsへの書き込み権限を付与するポリシーを定義
resource "aws_iam_role_policy" "route53_query_logging_policy" {
name = "route53-query-logging-policy"
role = aws_iam_role.route53_query_logging_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"logs:CreateLogStream",
"logs:PutLogEvents",
]
Effect = "Allow"
Resource = "${aws_cloudwatch_log_group.route53_query_logs.arn}:*"
},
]
})
}
# Route 53 パブリックホストゾーン (既存のものを参照するか、Terraformで作成)
# この例では、既存のホストゾーンを参照します
data "aws_route53_zone" "selected_zone" {
name = "your-domain.com." # あなたのドメイン名に置き換えてください (末尾にドットを忘れずに)
private_zone = false
}
# Route 53 ホストゾーンのDNSクエリログ記録を有効化
resource "aws_route53_query_logging_config" "main" {
zone_id = data.aws_route53_zone.selected_zone.zone_id
cloudwatch_log_group_arn = aws_cloudwatch_log_group.route53_query_logs.arn
}
# (オプション) CloudWatch Logsのメトリクスフィルターとアラームの例
/*
resource "aws_cloudwatch_metric_alarm" "high_servfail_alarm" {
alarm_name = "Route53-HighServFail-Alarm"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
metric_name = "ServFailCount" # メトリクスフィルターで定義するメトリクス名
namespace = "Route53DNSQueryLogs" # メトリクスフィルターで定義する名前空間
period = 300 # 5分
statistic = "Sum"
threshold = 50 # 50件以上のServFailでアラーム
dimensions = {
LogGroupName = aws_cloudwatch_log_group.route53_query_logs.name
}
alarm_description = "High number of DNS ServFail responses in Route 53 query logs"
alarm_actions = [aws_sns_topic.dns_alert_topic.arn] # 適切なSNSトピックに置き換え
ok_actions = [aws_sns_topic.dns_alert_topic.arn]
}
# CloudWatch Logsのメトリクスフィルターの例 (ServFail応答をカウント)
resource "aws_cloudwatch_log_metric_filter" "servfail_filter" {
name = "ServFailDnsQueries"
log_group_name = aws_cloudwatch_log_group.route53_query_logs.name
pattern = "[..., responseCode = ServFail, ...]" # 実際のログフォーマットに合わせてパターンを調整
metric_transformation {
name = "ServFailCount"
namespace = "Route53DNSQueryLogs"
value = "1"
}
}
*/
上記の例では、以下のリソースを定義しています。
aws_cloudwatch_log_group.route53_query_logs
: DNSクエリログが送信されるCloudWatch Logsグループ。aws_iam_role.route53_query_logging_role
およびaws_iam_role_policy.route53_query_logging_policy
: Route 53がCloudWatch Logsにログを書き込むために必要なIAMロールとポリシー。data "aws_route53_zone" "selected_zone"
: ログ記録を有効にする対象の既存パブリックホストゾーンを参照するためのデータソース。aws_route53_query_logging_config.main
: Route 53のDNSクエリログ記録を有効にするメインのリソース。zone_id
とcloudwatch_log_group_arn
を指定します。
your-domain.com.
などのプレースホルダーは、実際の環境に合わせて修正してください。特にドメイン名の末尾にはドット .
を含める必要があります。
最後に
この記事では、Route 53パブリックホストゾーンのDNSクエリログ記録が有効化されていない状態について、リスクと対策を解説しました。DNSクエリログ記録を有効化することは、DNSレベルでの脅威検知、セキュリティインシデント調査、コンプライアンス遵守、および運用上の可視性向上に不可欠です。これにより、DNSインフラストラクチャのセキュリティと信頼性を強化し、より安全なアプリケーション運用をサポートします。
この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。
運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。
最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。