diff --git a/.secrets.baseline b/.secrets.baseline index 07aaefc..c5ce2a4 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "^.secrets.baseline$", "lines": null }, - "generated_at": "2024-09-24T15:47:09Z", + "generated_at": "2024-10-03T17:34:00Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -104,7 +104,7 @@ "hashed_secret": "83c1003f406f34fba4d6279a948fee3abc802884", "is_secret": false, "is_verified": false, - "line_number": 589, + "line_number": 590, "type": "Hex High Entropy String" } ], diff --git a/tf_files/aws/commons/outputs.tf b/tf_files/aws/commons/outputs.tf index c798199..5e541cf 100644 --- a/tf_files/aws/commons/outputs.tf +++ b/tf_files/aws/commons/outputs.tf @@ -114,3 +114,12 @@ output "aurora_cluster_master_password" { output "es_endpoint" { value = module.commons_vpc_es[0].es_endpoint } + +## +# Output WAF arn +## + +output "waf_arn" { + description = "WAF arn - annotate the cluster ingress" + value = module.aws_waf[0].waf_arn +} \ No newline at end of file diff --git a/tf_files/aws/commons/variables.tf b/tf_files/aws/commons/variables.tf index 0e82e12..0e8dbaa 100644 --- a/tf_files/aws/commons/variables.tf +++ b/tf_files/aws/commons/variables.tf @@ -1048,3 +1048,44 @@ variable "enable_vpc_endpoints" { variable "deploy_es_role" { default = false } + +variable "deploy_waf" { + default = false +} + +variable "base_rules" { + description = "Base AWS Managed Rules" + type = list(object({ + managed_rule_group_name = string + priority = number + override_to_count = list(string) + })) + default = [ + { + managed_rule_group_name = "AWSManagedRulesAmazonIpReputationList" + priority = 0 + override_to_count = ["AWSManagedReconnaissanceList"] + }, + { + managed_rule_group_name = "AWSManagedRulesPHPRuleSet" + priority = 1 + override_to_count = ["PHPHighRiskMethodsVariables_HEADER", "PHPHighRiskMethodsVariables_QUERYSTRING", "PHPHighRiskMethodsVariables_BODY"] + }, + { + managed_rule_group_name = "AWSManagedRulesWordPressRuleSet" + priority = 2 + override_to_count= ["WordPressExploitableCommands_QUERYSTRING", "WordPressExploitablePaths_URIPATH"] + }, + ] +} + +variable "additional_rules" { + description = "Additional AWS Managed Rules" + type = list(object({ + managed_rule_group_name = string + priority = number + override_to_count = list(string) + })) + default = [] +} + diff --git a/tf_files/aws/commons/waf.tf b/tf_files/aws/commons/waf.tf new file mode 100644 index 0000000..907857b --- /dev/null +++ b/tf_files/aws/commons/waf.tf @@ -0,0 +1,8 @@ +module "aws_waf" { + source = "../modules/waf" + count = var.deploy_waf ? 1 : 0 + vpc_name = var.vpc_name + base_rules = var.base_rules + additional_rules = var.additional_rules + depends_on = [module.cdis_vpc.vpc_id, module.cdis_vpc.vpc_peering_id] +} \ No newline at end of file diff --git a/tf_files/aws/modules/waf/main.tf b/tf_files/aws/modules/waf/main.tf new file mode 100644 index 0000000..30df09b --- /dev/null +++ b/tf_files/aws/modules/waf/main.tf @@ -0,0 +1,52 @@ +resource "aws_wafv2_web_acl" "waf" { + name = "${var.vpc_name}-waf" + description = "WAF per environment for tailored security." + scope = "REGIONAL" + + default_action { + allow {} + } + + dynamic "rule" { + for_each = concat(var.base_rules, var.additional_rules) + content { + name = "AWS-${rule.value.managed_rule_group_name}" + priority = rule.value.priority + override_action { + none {} + } + statement { + managed_rule_group_statement { + vendor_name = "AWS" + name = rule.value.managed_rule_group_name + + dynamic "rule_action_override" { + for_each = length(rule.value.override_to_count) > 0 ? rule.value.override_to_count : [] + content { + action_to_use { + count {} + } + name = rule_action_override.value + } + } + } + } + + visibility_config { + sampled_requests_enabled = true + cloudwatch_metrics_enabled = true + metric_name = "AWS-${rule.value.managed_rule_group_name}" + } + } + } + + tags = { + Environment = "${var.vpc_name}" + } + + visibility_config { + cloudwatch_metrics_enabled = false + metric_name = "WebAclMetrics" + sampled_requests_enabled = false + } +} \ No newline at end of file diff --git a/tf_files/aws/modules/waf/output.tf b/tf_files/aws/modules/waf/output.tf new file mode 100644 index 0000000..c18f9b7 --- /dev/null +++ b/tf_files/aws/modules/waf/output.tf @@ -0,0 +1,8 @@ +## +# Output WAF arn +## + +output "waf_arn" { + description = "WAF arn - annotate the cluster ingress" + value = aws_wafv2_web_acl.waf.arn +} \ No newline at end of file diff --git a/tf_files/aws/modules/waf/variables.tf b/tf_files/aws/modules/waf/variables.tf new file mode 100644 index 0000000..b514e5a --- /dev/null +++ b/tf_files/aws/modules/waf/variables.tf @@ -0,0 +1,37 @@ +variable "vpc_name" {} + +variable "base_rules" { + description = "Base AWS Managed Rules" + type = list(object({ + managed_rule_group_name = string + priority = number + override_to_count = list(string) + })) + default = [ + { + managed_rule_group_name = "AWSManagedRulesAmazonIpReputationList" + priority = 0 + override_to_count = ["AWSManagedReconnaissanceList"] + }, + { + managed_rule_group_name = "AWSManagedRulesPHPRuleSet" + priority = 1 + override_to_count = ["PHPHighRiskMethodsVariables_HEADER", "PHPHighRiskMethodsVariables_QUERYSTRING", "PHPHighRiskMethodsVariables_BODY"] + }, + { + managed_rule_group_name = "AWSManagedRulesWordPressRuleSet" + priority = 2 + override_to_count= ["WordPressExploitableCommands_QUERYSTRING", "WordPressExploitablePaths_URIPATH"] + }, + ] +} + +variable "additional_rules" { + description = "Additional AWS Managed Rules" + type = list(object({ + managed_rule_group_name = string + priority = number + override_to_count = list(string) + })) + default = [] +} diff --git a/tf_files/aws/waf/manifest.json b/tf_files/aws/waf/manifest.json new file mode 100644 index 0000000..0071c4a --- /dev/null +++ b/tf_files/aws/waf/manifest.json @@ -0,0 +1,5 @@ +{ + "terraform": { + "module_version" : "1.2" + } + } \ No newline at end of file diff --git a/tf_files/aws/waf/output.tf b/tf_files/aws/waf/output.tf new file mode 100644 index 0000000..98f299f --- /dev/null +++ b/tf_files/aws/waf/output.tf @@ -0,0 +1,8 @@ +## +# Output WAF arn +## + +output "waf_arn" { + description = "WAF arn - annotate the cluster ingress" + value = module.aws_waf[0].waf_arn +} \ No newline at end of file diff --git a/tf_files/aws/waf/root.tf b/tf_files/aws/waf/root.tf new file mode 100644 index 0000000..e4889c9 --- /dev/null +++ b/tf_files/aws/waf/root.tf @@ -0,0 +1,19 @@ +terraform { + backend "s3" { + encrypt = "true" + } + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } +} + +module "aws_waf" { + source = "../modules/waf" + count = var.deploy_waf ? 1 : 0 + vpc_name = var.vpc_name + base_rules = var.base_rules + additional_rules = var.additional_rules +} \ No newline at end of file diff --git a/tf_files/aws/waf/variables.tf b/tf_files/aws/waf/variables.tf new file mode 100644 index 0000000..7fbe616 --- /dev/null +++ b/tf_files/aws/waf/variables.tf @@ -0,0 +1,41 @@ +variable "deploy_waf" { + default = false +} + +variable "vpc_name" {} + +variable "base_rules" { + description = "Base AWS Managed Rules" + type = list(object({ + managed_rule_group_name = string + priority = number + override_to_count = list(string) + })) + default = [ + { + managed_rule_group_name = "AWSManagedRulesAmazonIpReputationList" + priority = 0 + override_to_count = ["AWSManagedReconnaissanceList"] + }, + { + managed_rule_group_name = "AWSManagedRulesPHPRuleSet" + priority = 1 + override_to_count = ["PHPHighRiskMethodsVariables_HEADER", "PHPHighRiskMethodsVariables_QUERYSTRING", "PHPHighRiskMethodsVariables_BODY"] + }, + { + managed_rule_group_name = "AWSManagedRulesWordPressRuleSet" + priority = 2 + override_to_count= ["WordPressExploitableCommands_QUERYSTRING", "WordPressExploitablePaths_URIPATH"] + }, + ] +} + +variable "additional_rules" { + description = "Additional AWS Managed Rules" + type = list(object({ + managed_rule_group_name = string + priority = number + override_to_count = list(string) + })) + default = [] +} \ No newline at end of file