Skip to content

Commit

Permalink
update module
Browse files Browse the repository at this point in the history
  • Loading branch information
richgreen-moj committed Jan 16, 2025
1 parent 667601c commit d23b9ea
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 86 deletions.
64 changes: 8 additions & 56 deletions terraform/environments/core-vpc/vpc.tf
Original file line number Diff line number Diff line change
Expand Up @@ -80,60 +80,16 @@ locals {

modernisation-platform-domain = "modernisation-platform.service.justice.gov.uk"
modernisation-platform-internal-domain = "modernisation-platform.internal"

default_rule = [
{
action = "BLOCK"
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 = "Block_AWSManagedDomainsAggregateThreatList"
},
{
action = "BLOCK"
domain_list_id = "rslvr-fdl-4fc4edfc63854751" # AWSManagedDomainsMalwareDomainList - see https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-dns-firewall-managed-domain-lists.html
priority = 2
name = "Block_AWSManagedDomainsMalwareDomainList"
},
{
action = "BLOCK"
domain_list_id = "rslvr-fdl-3268f74d91fe418f" # AWSManagedDomainsBotnetCommandandControl - see https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-dns-firewall-managed-domain-lists.html
priority = 3
name = "Block_AWSManagedDomainsBotnetCommandandControl"
},
{
action = "BLOCK"
domain_list_id = "rslvr-fdl-876a86d96f294739" # AWSManagedDomainsAmazonGuardDutyThreatList - see https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-dns-firewall-managed-domain-lists.html
priority = 4
name = "Block_AWSManagedDomainsAmazonGuardDutyThreatList"
}
]

additional_rules = {
dns_firewall_allowed_domains = {
core-vpc-production = []
core-vpc-preproduction = []
core-vpc-test = []
core-vpc-development = []
core-vpc-sandbox = {
garden-sandbox = [
{
action = "ALERT"
domain_list_id = "" # This will use the custom domain list created in the module
priority = 5
name = "Alert_CustomDomainList_GardenSandbox"
}
]
garden-sandbox = ["google.com"]
}
}
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 = {
dns_firewall_blocked_domains = {
core-vpc-production = []
core-vpc-preproduction = []
core-vpc-test = []
Expand Down Expand Up @@ -412,8 +368,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 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
# By default the AWS managed domain lists are blocked - see https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-dns-firewall-managed-domain-lists.html
# A custom list of blocked or allowed domains can be defined in locals
# R53 Query logging is enabled and sends logs to a CloudWatch where a metric filters for blocked traffic
# 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"]
Expand All @@ -422,13 +379,8 @@ module "r53_dns_firewall" {
name = each.key
vpc_id = module.vpc[each.key].vpc_id

rules = concat(
local.default_rule,
lookup(local.flattened_additional_rules, each.key, [])
)

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
allowed_domains = lookup(local.dns_firewall_allowed_domains[terraform.workspace], each.key, [])
blocked_domains = lookup(local.dns_firewall_blocked_domains[terraform.workspace], each.key, [])

pagerduty_integration_key = local.pagerduty_integration_keys["core_alerts_cloudwatch"]
}
54 changes: 40 additions & 14 deletions terraform/modules/r53-dns-firewall/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,51 @@ resource "aws_route53_resolver_firewall_rule_group" "this" {
name = "${var.name}-r53-dns-firewall-rule-group"
}

resource "aws_route53_resolver_firewall_domain_list" "custom" {
count = var.custom_domain_list_enabled ? 1 : 0
resource "aws_route53_resolver_firewall_domain_list" "allow" {
name = "${var.name}-allow-domain-list"
domains = [for domain in var.allowed_domains : "${domain}."]
}

name = "${var.name}-custom-domain-list"
domains = local.fully_qualified_domains
resource "aws_route53_resolver_firewall_domain_list" "block" {
name = "${var.name}-block-domain-list"
domains = [for domain in var.blocked_domains : "${domain}."]
}

locals {
fully_qualified_domains = [for domain in var.custom_domain_list_domains : "${domain}."]
# locals {
# fully_qualified_domains = [for domain in var.allowed_domains : "${domain}."]
# }

resource "aws_route53_resolver_firewall_rule" "default_block" {
for_each = {
"AWSManagedDomainsAggregateThreatList" = "rslvr-fdl-4e96d4ce77f466b"
"AWSManagedDomainsMalwareDomainList" = "rslvr-fdl-4fc4edfc63854751"
"AWSManagedDomainsBotnetCommandandControl" = "rslvr-fdl-3268f74d91fe418f"
"AWSManagedDomainsAmazonGuardDutyThreatList" = "rslvr-fdl-876a86d96f294739"
}

action = "BLOCK"
firewall_domain_list_id = each.value
priority = each.key == "AWSManagedDomainsAggregateThreatList" ? 2 : each.key == "AWSManagedDomainsMalwareDomainList" ? 3 : each.key == "AWSManagedDomainsBotnetCommandandControl" ? 4 : 5
firewall_rule_group_id = aws_route53_resolver_firewall_rule_group.this.id
name = "Block_${each.key}"
block_response = var.block_response # defaults to NXDOMAIN
}

resource "aws_route53_resolver_firewall_rule" "this" {
count = length(var.rules)
resource "aws_route53_resolver_firewall_rule" "allow" {
action = "ALLOW"
firewall_domain_list_id = aws_route53_resolver_firewall_domain_list.allow.id
priority = 1
firewall_rule_group_id = aws_route53_resolver_firewall_rule_group.this.id
name = "Allow_${var.name}_domain_list"
}

action = var.rules[count.index].action
firewall_domain_list_id = var.rules[count.index].domain_list_id != "" ? var.rules[count.index].domain_list_id : aws_route53_resolver_firewall_domain_list.custom[0].id
priority = var.rules[count.index].priority
resource "aws_route53_resolver_firewall_rule" "block" {
action = "BLOCK"
firewall_domain_list_id = aws_route53_resolver_firewall_domain_list.block.id
priority = 6
firewall_rule_group_id = aws_route53_resolver_firewall_rule_group.this.id
name = var.rules[count.index].name
block_response = var.rules[count.index].action == "BLOCK" ? "NXDOMAIN" : null
name = "Block_${var.name}_domain_list"
block_response = var.block_response # defaults to NXDOMAIN
}

resource "aws_route53_resolver_firewall_rule_group_association" "this" {
Expand All @@ -44,13 +69,14 @@ resource "aws_route53_resolver_query_log_config_association" "dns_firewall_log_c

resource "aws_cloudwatch_log_group" "dns_firewall_log_group" {
name = "/aws/route53resolver/dns_firewall/${var.name}"
retention_in_days = 90
}

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 = "{ $.firewall_rule_action = \"BLOCK\" || $.firewall_rule_action = \"ALERT\" && $.vpc_id = \"${var.vpc_id}\" }"
pattern = "{ $.firewall_rule_action = \"BLOCK\" && $.vpc_id = \"${var.vpc_id}\" }"
metric_transformation {
name = "${var.name}-DNSFirewallMatches"
namespace = "DNSFirewall"
Expand Down
27 changes: 11 additions & 16 deletions terraform/modules/r53-dns-firewall/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,6 @@ variable "name" {
type = string
}

variable "rules" {
description = "List of firewall rules"
type = list(object({
action = string
domain_list_id = string
priority = number
name = string
}))
}

variable "vpc_id" {
description = "The ID of the VPC to associate with the DNS Firewall rule group"
type = string
Expand All @@ -24,14 +14,19 @@ variable "association_priority" {
default = 101
}

variable "custom_domain_list_enabled" {
description = "Enable custom domain list"
type = bool
default = false
variable "block_response" {
description = "The way that you want DNS Firewall to block the request. Supported Valid values are NODATA, NXDOMAIN, or OVERRIDE"
type = string
default = "NXDOMAIN"
}
variable "allowed_domains" {
description = "List of allowed domains"
type = list(string)
default = []
}

variable "custom_domain_list_domains" {
description = "List of custom domains"
variable "blocked_domains" {
description = "List of blocked domains"
type = list(string)
default = []
}
Expand Down

0 comments on commit d23b9ea

Please sign in to comment.