From 582f6050218ca514f9ea8ab40e9f8343da47df66 Mon Sep 17 00:00:00 2001 From: Rich Green Date: Wed, 15 Jan 2025 08:48:38 +0000 Subject: [PATCH] updates --- terraform/environments/core-vpc/vpc.tf | 83 ++++++++++--------- terraform/modules/r53-dns-firewall/main.tf | 18 ++-- .../modules/r53-dns-firewall/variables.tf | 2 +- 3 files changed, 59 insertions(+), 44 deletions(-) diff --git a/terraform/environments/core-vpc/vpc.tf b/terraform/environments/core-vpc/vpc.tf index fe64d5eaa..4f88856ce 100644 --- a/terraform/environments/core-vpc/vpc.tf +++ b/terraform/environments/core-vpc/vpc.tf @@ -81,41 +81,47 @@ locals { modernisation-platform-domain = "modernisation-platform.service.justice.gov.uk" modernisation-platform-internal-domain = "modernisation-platform.internal" - r53_dns_firewall_rules = { - default_rule = [ - { - action = "ALERT" - domain_list_id = "rslvr-fdl-4e96d4ce77f466b" # AWSManagedDomainsAggregateThreatList - see https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-dns-firewall-managed-domain-lists.html - priority = 1 - name = "Alert_AWSManagedDomainsAggregateThreatList" - } - ] + default_rule = [ + { + action = "ALERT" + domain_list_id = "rslvr-fdl-4e96d4ce77f466b" # AWSManagedDomainsAggregateThreatList - see https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-dns-firewall-managed-domain-lists.html + priority = 1 + name = "Alert_AWSManagedDomainsAggregateThreatList" + } + ] - additional_rules = { - core-vpc-production = [] - core-vpc-preproduction = [] - core-vpc-test = [] - core-vpc-development = [] - core-vpc-sandbox = { - garden-sandbox = [ - { - action = "BLOCK" - domain_list_id = "" # This will use the custom domain list created in the module - priority = 2 - name = "Block_CustomDomainList_GardenSandbox" - } - ] - } + additional_rules = { + core-vpc-production = [] + core-vpc-preproduction = [] + core-vpc-test = [] + core-vpc-development = [] + core-vpc-sandbox = { + garden-sandbox = [ + { + action = "BLOCK" + domain_list_id = "" # This will use the custom domain list created in the module + priority = 2 + name = "Block_CustomDomainList_GardenSandbox" + } + ] } + } + flattened_additional_rules = merge( + local.additional_rules, + { for k, v in local.additional_rules.core-vpc-production : k => v }, + { for k, v in local.additional_rules.core-vpc-preproduction : k => v }, + { for k, v in local.additional_rules.core-vpc-test : k => v }, + { for k, v in local.additional_rules.core-vpc-development : k => v }, + { for k, v in local.additional_rules.core-vpc-sandbox : k => v } + ) - custom_domain_lists = { - core-vpc-production = [] - core-vpc-preproduction = [] - core-vpc-test = [] - core-vpc-development = [] - core-vpc-sandbox = { - garden-sandbox = ["garden-example.com", "garden-malicious.com"] - } + custom_domain_lists = { + core-vpc-production = [] + core-vpc-preproduction = [] + core-vpc-test = [] + core-vpc-development = [] + core-vpc-sandbox = { + garden-sandbox = ["youtube.com"] } } } @@ -388,8 +394,9 @@ resource "aws_iam_role_policy_attachments_exclusive" "member_delegation_read_onl } # R53 Resolver DNS Firewall -# Creates a DNS Firewall rule group with rules (based on an AWS-managed or a custom domain list) for each VPC -# Logs are sent to a CloudWatch dns firewall log group +# Creates a DNS Firewall rule group with rules (based on an AWS-managed or a custom domain list defined in locals) for each VPC +# Logs are sent to a CloudWatch log group and a metric filter is created to count the number of matches +# When the Cloudwatch alarm is triggered, it will send an alert to PagerDuty/Slack module "r53_dns_firewall" { for_each = local.vpcs["core-vpc-sandbox"] source = "../../modules/r53-dns-firewall" @@ -398,12 +405,12 @@ module "r53_dns_firewall" { vpc_id = module.vpc[each.key].vpc_id rules = concat( - local.r53_dns_firewall_rules.default_rule, - lookup(local.r53_dns_firewall_rules.additional_rules, each.key, []) + local.default_rule, + lookup(local.flattened_additional_rules, each.key, []) ) - custom_domain_list_domains = lookup(local.r53_dns_firewall_rules.custom_domain_lists[terraform.workspace], each.key, []) - custom_domain_list_enabled = length(lookup(local.r53_dns_firewall_rules.custom_domain_lists[terraform.workspace], each.key, [])) > 0 + custom_domain_list_domains = lookup(local.custom_domain_lists[terraform.workspace], each.key, []) + custom_domain_list_enabled = length(lookup(local.custom_domain_lists[terraform.workspace], each.key, [])) > 0 pagerduty_integration_key = local.pagerduty_integration_keys["core_alerts_cloudwatch"] } \ No newline at end of file diff --git a/terraform/modules/r53-dns-firewall/main.tf b/terraform/modules/r53-dns-firewall/main.tf index c12589bf1..81c1895ee 100644 --- a/terraform/modules/r53-dns-firewall/main.tf +++ b/terraform/modules/r53-dns-firewall/main.tf @@ -7,7 +7,11 @@ resource "aws_route53_resolver_firewall_domain_list" "custom" { count = var.custom_domain_list_enabled ? 1 : 0 name = "${var.name}-custom-domain-list" - domains = var.custom_domain_list_domains + domains = local.fully_qualified_domains +} + +locals { + fully_qualified_domains = [for domain in var.custom_domain_list_domains : "${domain}."] } resource "aws_route53_resolver_firewall_rule" "this" { @@ -18,7 +22,7 @@ resource "aws_route53_resolver_firewall_rule" "this" { priority = var.rules[count.index].priority firewall_rule_group_id = aws_route53_resolver_firewall_rule_group.this.id name = var.rules[count.index].name - block_response = "NXDOMAIN" + block_response = var.rules[count.index].action == "BLOCK" ? "NXDOMAIN" : null } resource "aws_route53_resolver_firewall_rule_group_association" "this" { @@ -33,6 +37,11 @@ resource "aws_route53_resolver_query_log_config" "dns_firewall_log_config" { destination_arn = aws_cloudwatch_log_group.dns_firewall_log_group.arn } +resource "aws_route53_resolver_query_log_config_association" "dns_firewall_log_config_association" { + resolver_query_log_config_id = aws_route53_resolver_query_log_config.dns_firewall_log_config.id + resource_id = var.vpc_id +} + resource "aws_cloudwatch_log_group" "dns_firewall_log_group" { name = "/aws/route53resolver/dns_firewall/${var.name}" } @@ -41,10 +50,9 @@ resource "aws_cloudwatch_log_metric_filter" "dns_firewall_metric_filter" { name = "${var.name}-DNSFirewallMatches" log_group_name = aws_cloudwatch_log_group.dns_firewall_log_group.name - pattern = "{ ($.action = \"ALERT\") }" - + pattern = "{ $.firewall_rule_action = \"BLOCK\" || $.firewall_rule_action = \"ALERT\" && $.vpc_id = \"${var.vpc_id}\" }" metric_transformation { - name = "DNSFirewallMatches" + name = "${var.name}-DNSFirewallMatches" namespace = "DNSFirewall" value = "1" } diff --git a/terraform/modules/r53-dns-firewall/variables.tf b/terraform/modules/r53-dns-firewall/variables.tf index a4274e619..12f3cebdd 100644 --- a/terraform/modules/r53-dns-firewall/variables.tf +++ b/terraform/modules/r53-dns-firewall/variables.tf @@ -21,7 +21,7 @@ variable "vpc_id" { variable "association_priority" { description = "Priority of the firewall rule group association" type = number - default = 100 + default = 101 } variable "custom_domain_list_enabled" {