# WAF Rulesets and Firewall Rules # Block non-HTTPS (should be handled by always_use_https, but explicit rule) resource "cloudflare_ruleset" "security_rules" { for_each = cloudflare_zone.domains zone_id = each.value.id name = "Security Rules" kind = "zone" phase = "http_request_firewall_custom" # Rule 1: Block requests to /admin from non-trusted IPs rules { action = "block" expression = length(var.trusted_admin_ips) > 0 ? "(http.request.uri.path contains \"/admin\") and not (ip.src in {${join(" ", var.trusted_admin_ips)}})" : "false" description = "Block admin access from untrusted IPs" enabled = length(var.trusted_admin_ips) > 0 } # Rule 2: Challenge suspicious countries rules { action = "managed_challenge" expression = length(var.blocked_countries) > 0 ? format("(ip.src.country in {%s})", join(" ", [for c in var.blocked_countries : format("\"%s\"", c)])) : "false" description = "Challenge traffic from high-risk countries" enabled = length(var.blocked_countries) > 0 } # Rule 3: Block known bad user agents rules { action = "block" expression = "(http.user_agent contains \"sqlmap\") or (http.user_agent contains \"nikto\") or (http.user_agent contains \"nmap\")" description = "Block known scanning tools" enabled = true } # Rule 4: Rate limit API endpoints rules { action = "block" ratelimit { characteristics = ["ip.src"] period = 10 requests_per_period = 30 mitigation_timeout = 60 } expression = "(http.request.uri.path starts_with \"/api/\")" description = "Rate limit API endpoints" enabled = true } } # Enable Cloudflare Managed WAF Ruleset resource "cloudflare_ruleset" "managed_waf" { for_each = { for domain, zone in cloudflare_zone.domains : domain => zone if var.enable_managed_waf && var.domains[domain].plan != "free" } zone_id = each.value.id name = "Managed WAF" kind = "zone" phase = "http_request_firewall_managed" # Cloudflare Managed Ruleset rules { action = "execute" action_parameters { id = "efb7b8c949ac4650a09736fc376e9aee" # Cloudflare Managed Ruleset } expression = "true" description = "Execute Cloudflare Managed Ruleset" enabled = true } # OWASP Core Ruleset rules { action = "execute" action_parameters { id = "4814384a9e5d4991b9815dcfc25d2f1f" # OWASP Core Ruleset } expression = "true" description = "Execute OWASP Core Ruleset" enabled = true } } # Bot Management (if available on plan) resource "cloudflare_bot_management" "domains" { for_each = { for domain, zone in cloudflare_zone.domains : domain => zone if var.enable_bot_management && var.domains[domain].plan != "free" } zone_id = each.value.id enable_js = true fight_mode = true sbfm_definitely_automated = "block" sbfm_likely_automated = "managed_challenge" sbfm_verified_bots = "allow" sbfm_static_resource_protection = false }