diff --git a/src/content/docs/terraform/additional-configurations/ddos-managed-rulesets.mdx b/src/content/docs/terraform/additional-configurations/ddos-managed-rulesets.mdx index 558752135fa66e2..a347db390566555 100644 --- a/src/content/docs/terraform/additional-configurations/ddos-managed-rulesets.mdx +++ b/src/content/docs/terraform/additional-configurations/ddos-managed-rulesets.mdx @@ -12,7 +12,7 @@ products: - terraform --- -import { Render, RuleID } from "~/components"; +import { Render, RuleID, Tabs, TabItem, Details } from "~/components"; This page provides examples of configuring [DDoS managed rulesets](/ddos-protection/managed-rulesets/) in your zone or account using Terraform. It covers the following configurations: @@ -45,7 +45,66 @@ For more information on deploying and configuring rulesets using the Rulesets AP This example configures the [HTTP DDoS Attack Protection](/ddos-protection/managed-rulesets/http/) managed ruleset for a zone using Terraform. - + + + +
+ +At least one of the following [token permissions](/fundamentals/api/reference/permissions/) is required: + +- `HTTP DDoS Managed Ruleset Write` + +
+ +Configure the [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resource: + +```tf +resource "cloudflare_ruleset" "zone_level_http_ddos_config" { + zone_id = var.cloudflare_zone_id + name = "HTTP DDoS Attack Protection entry point ruleset" + description = "" + kind = "zone" + phase = "ddos_l7" + + rules = [{ + action = "execute" + action_parameters = { + # Cloudflare L7 DDoS Attack Protection Ruleset + id = "4d21379b4f9f4bb088e0729962c8b3cf" + overrides = { + action = "block" + sensitivity_level = "default" + rules = [ + { + # Adaptive DDoS Protection based on Locations (Available only to Enterprise zones with Advanced DDoS service) + id = "a8c6333711ff4b0a81371d1c444be2c3" + sensitivity_level = "default" + action = "managed_challenge" + }, + { + # Adaptive DDoS Protection based on User-Agents (Available only to Enterprise zones with Advanced DDoS service) + id = "7709d496081e458899c1e3a6e4fe8e55" + sensitivity_level = "default" + action = "managed_challenge" + }, + { + # HTTP requests causing a high number of origin errors. + id = "dd42da7baabe4e518eaf11c393596a9d" + sensitivity_level = "default" + action = "managed_challenge" + }, + ] + } + } + expression = "true" + description = "Zone-wide HTTP DDoS Override" + enabled = true + }] +} +``` + +
+ ```tf resource "cloudflare_ruleset" "zone_level_http_ddos_config" { @@ -90,6 +149,9 @@ resource "cloudflare_ruleset" "zone_level_http_ddos_config" { } ``` + +
+ For more information about HTTP DDoS Attack Protection, refer to [HTTP DDoS Attack Protection managed ruleset](/ddos-protection/managed-rulesets/http/). ## Example: Configure Network-layer DDoS Attack Protection @@ -103,7 +165,49 @@ This example configures the [Network-layer DDoS Attack Protection](/ddos-protect ::: - + + + +
+ +At least one of the following [token permissions](/fundamentals/api/reference/permissions/) is required: + +- `L4 DDoS Managed Ruleset Write` + +
+ +Configure the [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resource: + +```tf +resource "cloudflare_ruleset" "account_level_network_ddos_config" { + account_id = var.cloudflare_account_id + name = "Network-layer DDoS Attack Protection entry point ruleset" + description = "" + kind = "root" + phase = "ddos_l4" + + rules = [{ + ref = "override_l7_ddos_ruleset_dst_ip" + description = "Override the HTTP DDoS Attack Protection managed ruleset" + expression = "ip.dst in { 192.0.2.0/24 }" + action = "execute" + action_parameters = { + # Cloudflare L3/4 DDoS Attack Protection Ruleset + id = "3b64149bfa6e4220bbbc2bd6db589552" + overrides = { + rules = [{ + # Rule: Generic high-volume UDP traffic flows. + id = "599dab0942ff4898ac1b7797e954e98b" + sensitivity_level = "low" + }] + } + } + }] +} +``` + +
+ ```tf resource "cloudflare_ruleset" "account_level_network_ddos_config" { @@ -133,6 +237,9 @@ resource "cloudflare_ruleset" "account_level_network_ddos_config" { } ``` + +
+ For more information about Network-layer DDoS Attack Protection, refer to [Network-layer DDoS Attack Protection managed ruleset](/ddos-protection/managed-rulesets/network/). --- @@ -154,7 +261,106 @@ The order of the rules is important: the rule with the highest sensitivity level ::: - + + + +
+ +At least one of the following [token permissions](/fundamentals/api/reference/permissions/) is required: + +- `HTTP DDoS Managed Ruleset Write` + +
+ +Configure the [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resource: + +```tf +resource "cloudflare_ruleset" "zone_level_http_ddos_config" { + zone_id = var.cloudflare_zone_id + name = "HTTP DDoS - Terraform managed" + description = "" + kind = "zone" + phase = "ddos_l7" + + # The resource configuration contains two rules: + # 1. The first rule has the lowest sensitivity level (highest threshold) + # and it will block attacks. + # 2. The second rule has a higher sensitivity level (lower threshold) and + # will only apply a Log action. + # + # In practice, evaluation stops whenever a rule matches both the expression + # and the threshold, so the rule order is important: + # - When the traffic rate is below the (low) threshold of the default + # sensitivity level ('High'), no rules match (no action is applied). + # - When the traffic rate is between the thresholds of the 'Low' and + # default ('High') sensitivity levels, the first rule does not match, + # but the second rule does (traffic gets logged). + # - When the traffic rate goes above the (high) threshold of the 'Low' + # sensitivity level, the first rule matches (traffic gets blocked). + # + # The DDoS protection systems will still apply mitigation actions to incoming + # traffic when rates exceed the threshold of the _Essentially Off_ sensitivity + # level. + + rules = [ + { + ref = "l7_ddos_block_traffic_low_threshold" + description = "At the low sensitivity threshold, block the traffic" + expression = "true" + action = "execute" + action_parameters = { + # Cloudflare L7 DDoS Attack Protection Ruleset + id = "4d21379b4f9f4bb088e0729962c8b3cf" + overrides = { + rules = [ + { + # Rule: HTTP requests from known botnet (signature #4). + id = "29d170ba2f004cc787b1ac272c9e04e7" + sensitivity_level = "low" + action = "block" + }, + { + # Rule: HTTP requests with unusual HTTP headers or URI path (signature #16). + id = "60a48054bbcf4014ac63c44f1712a123" + sensitivity_level = "low" + action = "block" + }, + ] + } + } + }, + { + ref = "l7_ddos_log_default_threshold" + description = "At the default sensitivity threshold, log to see if any legitimate traffic gets caught" + expression = "true" + action = "execute" + action_parameters = { + # Cloudflare L7 DDoS Attack Protection Ruleset + id = "4d21379b4f9f4bb088e0729962c8b3cf" + overrides = { + rules = [ + { + # Rule: HTTP requests from known botnet (signature #4). + id = "29d170ba2f004cc787b1ac272c9e04e7" + sensitivity_level = "default" + action = "log" + }, + { + # Rule: HTTP requests with unusual HTTP headers or URI path (signature #16). + id = "60a48054bbcf4014ac63c44f1712a123" + sensitivity_level = "default" + action = "log" + }, + ] + } + } + }, + ] +} +``` + +
+ ```tf variable "zone_id" { @@ -239,3 +445,6 @@ resource "cloudflare_ruleset" "zone_level_http_ddos_config" { } } ``` + + +
diff --git a/src/content/docs/terraform/additional-configurations/rate-limiting-rules.mdx b/src/content/docs/terraform/additional-configurations/rate-limiting-rules.mdx index 614ccb2361f4c1d..37976902f2eba97 100644 --- a/src/content/docs/terraform/additional-configurations/rate-limiting-rules.mdx +++ b/src/content/docs/terraform/additional-configurations/rate-limiting-rules.mdx @@ -12,7 +12,7 @@ products: - terraform --- -import { Details, Render } from "~/components"; +import { Details, Render, Tabs, TabItem } from "~/components"; This page provides examples of creating [rate limiting rules](/waf/rate-limiting-rules/) in a zone or account using Terraform. @@ -41,7 +41,44 @@ For more information on configuring the previous version of rate limiting rules This example creates a rate limiting rule in zone with ID `` blocking traffic that exceeds the configured rate: - + + + +
+ +At least one of the following [token permissions](/fundamentals/api/reference/permissions/) is required: + +- `Zone WAF Write` + +
+ +Configure the [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resource: + +```tf +resource "cloudflare_ruleset" "zone_rl" { + zone_id = var.cloudflare_zone_id + name = "Rate limiting for my zone" + description = "" + kind = "zone" + phase = "http_ratelimit" + + rules = [{ + ref = "rate_limit_api_requests_ip" + description = "Rate limit API requests by IP" + expression = "(http.request.uri.path matches \"^/api/\")" + action = "block" + ratelimit = { + characteristics = ["cf.colo.id", "ip.src"] + period = 60 + requests_per_period = 100 + mitigation_timeout = 600 + } + }] +} +``` + +
+ ```tf resource "cloudflare_ruleset" "zone_rl" { @@ -66,6 +103,9 @@ resource "cloudflare_ruleset" "zone_rl" { } ``` + +
+ ` that blocks traffic for the `/api/` path exceeding the configured rate. The second `cloudflare_ruleset` resource defines an `execute` rule that deploys the custom ruleset for traffic addressed at `example.com`. - + + + +
+ +At least one of the following [token permissions](/fundamentals/api/reference/permissions/) is required: + +- `Account WAF Write` +- `Account Rulesets Write` + +
+ +Configure the [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resource: + +```tf +resource "cloudflare_ruleset" "account_rl" { + account_id = var.cloudflare_account_id + name = "Rate limiting rules for APIs" + description = "" + kind = "custom" + phase = "http_ratelimit" + + rules = [{ + ref = "rate_limit_api_ip" + description = "Rate limit API requests by IP" + expression = "http.request.uri.path contains \"/api/\"" + action = "block" + ratelimit = { + characteristics = ["cf.colo.id", "ip.src"] + period = 60 + requests_per_period = 100 + mitigation_timeout = 600 + } + }] +} + +# Account-level entry point ruleset for the 'http_ratelimit' phase +resource "cloudflare_ruleset" "account_rl_entrypoint" { + account_id = var.cloudflare_account_id + name = "Account-level rate limiting" + description = "" + kind = "root" + phase = "http_ratelimit" + + depends_on = [cloudflare_ruleset.account_rl] + + rules = [{ + # Deploy the previously defined custom ruleset containing a rate limiting rule + ref = "deploy_rate_limit_example_com" + description = "Deploy custom ruleset with RL rule" + expression = "cf.zone.name eq \"example.com\" and cf.zone.plan eq \"ENT\"" + action = "execute" + action_parameters = { + id = cloudflare_ruleset.account_rl.id + } + }] +} +``` + +
+ ```tf resource "cloudflare_ruleset" "account_rl" { @@ -111,7 +211,7 @@ resource "cloudflare_ruleset" "account_rl" { # Account-level entry point ruleset for the 'http_ratelimit' phase resource "cloudflare_ruleset" "account_rl_entrypoint" { - account_id = + account_id = "" name = "Account-level rate limiting" description = "" kind = "root" @@ -132,6 +232,9 @@ resource "cloudflare_ruleset" "account_rl_entrypoint" { } ``` + +
+ ` with: - A custom counting expression that includes a response field (`http.response.code`). - A custom JSON response for rate limited requests. - + + + +
+ +At least one of the following [token permissions](/fundamentals/api/reference/permissions/) is required: + +- `Zone WAF Write` + +
+ +Configure the [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resource: + +```tf +resource "cloudflare_ruleset" "zone_rl_custom_response" { + zone_id = var.cloudflare_zone_id + name = "Advanced rate limiting rule for my zone" + description = "" + kind = "zone" + phase = "http_ratelimit" + + rules = [{ + ref = "rate_limit_example_com_status_404" + description = "Rate limit requests to www.example.com when exceeding the threshold of 404 responses on /status/" + expression = "http.host eq \"www.example.com\" and (http.request.uri.path matches \"^/status/\")" + action = "block" + action_parameters = { + response = { + status_code = 429 + content = "{\"response\": \"block\"}" + content_type = "application/json" + } + } + ratelimit = { + characteristics = ["ip.src", "cf.colo.id"] + period = 10 + requests_per_period = 5 + mitigation_timeout = 30 + counting_expression = "(http.host eq \"www.example.com\") and (http.request.uri.path matches \"^/status/\") and (http.response.code eq 404)" + } + }] +} +``` + +
+ ```tf resource "cloudflare_ruleset" "zone_rl_custom_response" { @@ -179,6 +327,9 @@ resource "cloudflare_ruleset" "zone_rl_custom_response" { } ``` + +
+ + + + +
+ +At least one of the following [token permissions](/fundamentals/api/reference/permissions/) is required: + +- `Zone Transform Rules Write` + +
+ +Configure the [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resource: + +```tf +resource "cloudflare_ruleset" "transform_url_rewrite" { + zone_id = var.cloudflare_zone_id + name = "Transform Rule performing a static URL rewrite" + description = "" + kind = "zone" + phase = "http_request_transform" + + rules = [{ + ref = "url_rewrite_old_folder" + description = "Example URL rewrite rule" + expression = "(http.host eq \"example.com\" and http.request.uri.path eq \"/old-folder\")" + action = "rewrite" + action_parameters = { + uri = { + path = { + value = "/new-folder" + } + } + } + }] +} +``` + +
+ ```tf resource "cloudflare_ruleset" "transform_url_rewrite" { @@ -70,6 +108,9 @@ resource "cloudflare_ruleset" "transform_url_rewrite" { } ``` + +
+ + + + +
+ +At least one of the following [token permissions](/fundamentals/api/reference/permissions/) is required: + +- `Zone Transform Rules Write` + +
+ +Configure the [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resource: + +```tf +resource "cloudflare_ruleset" "transform_modify_request_headers" { + zone_id = var.cloudflare_zone_id + name = "Transform Rule performing HTTP request header modifications" + description = "" + kind = "zone" + phase = "http_request_late_transform" + + rules = [{ + ref = "modify_request_headers" + description = "Example request header transform rule" + expression = "true" + action = "rewrite" + action_parameters = { + headers = { + "my-header-1" = { + operation = "set" + value = "Fixed value" + } + "my-header-2" = { + operation = "set" + expression = "cf.zone.name" + } + "existing-header" = { + operation = "remove" + } + } + } + }] +} +``` + +
+ ```tf resource "cloudflare_ruleset" "transform_modify_request_headers" { @@ -124,6 +211,9 @@ resource "cloudflare_ruleset" "transform_modify_request_headers" { } ``` + +
+ + + + +
+ +At least one of the following [token permissions](/fundamentals/api/reference/permissions/) is required: + +- `Zone Transform Rules Write` + +
+ +Configure the [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resource: + +```tf +resource "cloudflare_ruleset" "transform_modify_response_headers" { + zone_id = var.cloudflare_zone_id + name = "Transform Rule performing HTTP response header modifications" + description = "" + kind = "zone" + phase = "http_response_headers_transform" + + rules = [{ + ref = "modify_response_headers" + description = "Example response header transform rule" + expression = "true" + action = "rewrite" + action_parameters = { + headers = { + "my-header-1" = { + operation = "set" + value = "Fixed value" + } + "my-header-2" = { + operation = "set" + expression = "cf.zone.name" + } + "existing-header" = { + operation = "remove" + } + } + } + }] +} +``` + +
+ ```tf resource "cloudflare_ruleset" "transform_modify_response_headers" { @@ -177,6 +313,9 @@ resource "cloudflare_ruleset" "transform_modify_response_headers" { } ``` + +
+ + + + +
+ +At least one of the following [token permissions](/fundamentals/api/reference/permissions/) is required: + +- `Managed headers Write` + +
+ +Configure the [`cloudflare_managed_transforms`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/managed_transforms) resource: + +```tf +resource "cloudflare_managed_transforms" "tf_example" { + zone_id = var.cloudflare_zone_id + + managed_request_headers = [{ + id = "add_visitor_location_headers" + enabled = true + }] + + managed_response_headers = [{ + id = "remove_x-powered-by_header" + enabled = true + }] +} +``` + +
+ + +```tf +resource "cloudflare_managed_headers" "tf_example" { + zone_id = "" + + managed_request_headers { + id = "add_visitor_location_headers" + enabled = true + } + + managed_response_headers { + id = "remove_x-powered-by_header" + enabled = true + } +} +``` + + +
- +Make sure you include the Managed Transforms you are updating in the correct object (`managed_request_headers` or `managed_response_headers`). For more information on Managed Transforms, refer to [Managed Transforms](/rules/transform/managed-transforms/). diff --git a/src/content/docs/terraform/additional-configurations/waf-custom-rules.mdx b/src/content/docs/terraform/additional-configurations/waf-custom-rules.mdx index 85f92043950160a..250104ab1e1ea5d 100644 --- a/src/content/docs/terraform/additional-configurations/waf-custom-rules.mdx +++ b/src/content/docs/terraform/additional-configurations/waf-custom-rules.mdx @@ -13,7 +13,7 @@ products: - waf --- -import { Render, GlossaryTooltip } from "~/components"; +import { Render, GlossaryTooltip, Tabs, TabItem, Details } from "~/components"; This page provides examples of creating [WAF custom rules](/waf/custom-rules/) in a zone or account using Terraform. The examples cover the following scenarios: @@ -45,7 +45,38 @@ For more information on deploying and configuring custom rulesets using the Rule The following example configures a custom rule in the zone entry point ruleset for the `http_request_firewall_custom` phase for zone with ID ``. The rule will block all traffic on non-standard HTTP(S) ports: - + + + +
+ +At least one of the following [token permissions](/fundamentals/api/reference/permissions/) is required: + +- `Zone WAF Write` + +
+ +Configure the [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resource: + +```tf +resource "cloudflare_ruleset" "zone_custom_firewall" { + zone_id = var.cloudflare_zone_id + name = "Phase entry point ruleset for custom rules in my zone" + description = "" + kind = "zone" + phase = "http_request_firewall_custom" + + rules = [{ + ref = "block_non_default_ports" + description = "Block ports other than 80 and 443" + expression = "(not cf.edge.server_port in {80 443})" + action = "block" + }] +} +``` + +
+ ```tf resource "cloudflare_ruleset" "zone_custom_firewall" { @@ -64,6 +95,9 @@ resource "cloudflare_ruleset" "zone_custom_firewall" { } ``` + +
+ + + + +
+ +At least one of the following [token permissions](/fundamentals/api/reference/permissions/) is required: + +- `Account WAF Write` +- `Account Rulesets Write` + +
+ +Configure the [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resource: + +```tf +resource "cloudflare_ruleset" "account_firewall_custom_ruleset" { + account_id = var.cloudflare_account_id + name = "Custom ruleset blocking traffic in non-standard HTTP(S) ports" + description = "" + kind = "custom" + phase = "http_request_firewall_custom" + + rules = [{ + ref = "block_non_default_ports" + description = "Block ports other than 80 and 443" + expression = "(not cf.edge.server_port in {80 443})" + action = "block" + }] +} +``` + +
+ ```tf resource "cloudflare_ruleset" "account_firewall_custom_ruleset" { @@ -101,6 +167,9 @@ resource "cloudflare_ruleset" "account_firewall_custom_ruleset" { } ``` + +
+ + + + +
+ +At least one of the following [token permissions](/fundamentals/api/reference/permissions/) is required: + +- `Account WAF Write` +- `Account Rulesets Write` + +
+ +Configure the [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resource: + +```tf +resource "cloudflare_ruleset" "account_firewall_custom_entrypoint" { + account_id = var.cloudflare_account_id + name = "Account-level entry point ruleset for the http_request_firewall_custom phase deploying a custom ruleset" + description = "" + kind = "root" + phase = "http_request_firewall_custom" + + depends_on = [cloudflare_ruleset.account_firewall_custom_ruleset] + + rules = [{ + ref = "deploy_custom_ruleset_example_com" + description = "Deploy custom ruleset for example.com" + expression = "(cf.zone.name eq \"example.com\") and (cf.zone.plan eq \"ENT\")" + action = "execute" + action_parameters = { + id = cloudflare_ruleset.account_firewall_custom_ruleset.id + } + }] +} +``` + +
+ ```tf resource "cloudflare_ruleset" "account_firewall_custom_entrypoint" { @@ -134,6 +240,9 @@ resource "cloudflare_ruleset" "account_firewall_custom_entrypoint" { } ``` + +
+ For more information on configuring and deploying custom rulesets, refer to [Work with custom rulesets](/ruleset-engine/custom-rulesets/) in the Ruleset Engine documentation. ## More resources diff --git a/src/content/docs/terraform/additional-configurations/waf-managed-rulesets.mdx b/src/content/docs/terraform/additional-configurations/waf-managed-rulesets.mdx index c26c9f61f02548e..b8b5dcd91cfa4cd 100644 --- a/src/content/docs/terraform/additional-configurations/waf-managed-rulesets.mdx +++ b/src/content/docs/terraform/additional-configurations/waf-managed-rulesets.mdx @@ -13,7 +13,7 @@ products: - waf --- -import { Details, Render, RuleID } from "~/components"; +import { Details, Render, RuleID, Tabs, TabItem } from "~/components"; This page provides examples of deploying and configuring [WAF Managed Rules](/waf/managed-rules/) in your zone or account using Terraform. It covers the following configurations: @@ -49,7 +49,55 @@ The IDs of WAF managed rulesets are also available in the [WAF Managed Rules](/w The following example deploys two managed rulesets to the zone with ID `` using Terraform, using a `cloudflare_ruleset` resource with two rules that execute the managed rulesets. - + + + +
+ +At least one of the following [token permissions](/fundamentals/api/reference/permissions/) is required: + +- `Zone WAF Write` + +
+ +Configure the [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resource: + +```tf +# Configure a ruleset at the zone level for the "http_request_firewall_managed" phase +resource "cloudflare_ruleset" "zone_level_managed_waf" { + zone_id = var.cloudflare_zone_id + name = "Managed WAF entry point ruleset" + description = "Zone-level WAF Managed Rules config" + kind = "zone" + phase = "http_request_firewall_managed" + + rules = [ + { + # Execute Cloudflare Managed Ruleset + ref = "execute_cloudflare_managed_ruleset" + description = "Execute Cloudflare Managed Ruleset on my zone-level phase entry point ruleset" + expression = "true" + action = "execute" + action_parameters = { + id = "efb7b8c949ac4650a09736fc376e9aee" + } + }, + { + # Execute Cloudflare OWASP Core Ruleset + ref = "execute_cloudflare_owasp_core_ruleset" + description = "Execute Cloudflare OWASP Core Ruleset on my zone-level phase entry point ruleset" + expression = "true" + action = "execute" + action_parameters = { + id = "4814384a9e5d4991b9815dcfc25d2f1f" + } + }, + ] +} +``` + +
+ ```tf # Configure a ruleset at the zone level for the "http_request_firewall_managed" phase @@ -84,6 +132,9 @@ resource "cloudflare_ruleset" "zone_level_managed_waf" { } ``` + +
+ ## Deploy managed rulesets at the account level :::note[Notes] @@ -96,7 +147,55 @@ resource "cloudflare_ruleset" "zone_level_managed_waf" { The following example deploys two managed rulesets to the account with ID `` using Terraform, using a `cloudflare_ruleset` resource with two rules that execute the managed rulesets for two hostnames belonging to Enterprise zones. - + + + +
+ +At least one of the following [token permissions](/fundamentals/api/reference/permissions/) is required: + +- `Account WAF Write` +- `Account Rulesets Write` + +
+ +Configure the [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resource: + +```tf +resource "cloudflare_ruleset" "account_level_managed_waf" { + account_id = var.cloudflare_account_id + name = "Managed WAF entry point ruleset" + description = "Account-level WAF Managed Rules config" + kind = "root" + phase = "http_request_firewall_managed" + + rules = [ + { + # Execute Cloudflare Managed Ruleset + ref = "execute_cloudflare_managed_ruleset_api_store" + description = "Execute Cloudflare Managed Ruleset on my account-level phase entry point ruleset" + expression = "http.host in {\"api.example.com\" \"store.example.com\"} and cf.zone.plan eq \"ENT\"" + action = "execute" + action_parameters = { + id = "efb7b8c949ac4650a09736fc376e9aee" + } + }, + { + # Execute Cloudflare OWASP Core Ruleset + ref = "execute_owasp_core_ruleset_api_store" + description = "Execute Cloudflare OWASP Core Ruleset on my account-level phase entry point ruleset" + expression = "http.host in {\"api.example.com\" \"store.example.com\"} and cf.zone.plan eq \"ENT\"" + action = "execute" + action_parameters = { + id = "4814384a9e5d4991b9815dcfc25d2f1f" + } + }, + ] +} +``` + +
+ ```tf resource "cloudflare_ruleset" "account_level_managed_waf" { @@ -130,6 +229,9 @@ resource "cloudflare_ruleset" "account_level_managed_waf" { } ``` + +
+ ## Configure exceptions The following example adds two [exceptions](/waf/managed-rules/waf-exceptions/) for the Cloudflare Managed Ruleset: @@ -139,7 +241,54 @@ The following example adds two [exceptions](/waf/managed-rules/waf-exceptions/) Add the two exceptions to the `cloudflare_ruleset` resource before the rule that deploys the Cloudflare Managed Ruleset: - + + + +```tf null {4-27} +resource "cloudflare_ruleset" "zone_level_managed_waf" { + # (...) + + rules = [ + { + # Skip execution of the entire Cloudflare Managed Ruleset for specific URLs + ref = "skip_cloudflare_managed_ruleset_example_com" + description = "Skip Cloudflare Managed Ruleset" + expression = "(http.request.uri.path eq \"/status\" and http.request.uri.query contains \"skip=rulesets\")" + action = "skip" + action_parameters = { + rulesets = ["efb7b8c949ac4650a09736fc376e9aee"] + } + }, + { + # Skip execution of two rules in the Cloudflare Managed Ruleset for specific URLs + ref = "skip_wordpress_sqli_rules_example_com" + description = "Skip WordPress and SQLi rules" + expression = "(http.request.uri.path eq \"/status\" and http.request.uri.query contains \"skip=rules\")" + action = "skip" + action_parameters = { + rules = { + # Format: "" = ["", ""] + "efb7b8c949ac4650a09736fc376e9aee" = ["5de7edfa648c4d6891dc3e7f84534ffa", "e3a567afc347477d9702d9047e97d760"] + } + } + }, + { + # Execute Cloudflare Managed Ruleset + ref = "execute_cloudflare_managed_ruleset" + description = "Execute Cloudflare Managed Ruleset on my zone-level phase entry point ruleset" + expression = "true" + action = "execute" + action_parameters = { + id = "efb7b8c949ac4650a09736fc376e9aee" + } + }, + # (...) + ] +} +``` + + + ```tf null {4-13,15-27} resource "cloudflare_ruleset" "zone_level_managed_waf" { @@ -185,6 +334,9 @@ resource "cloudflare_ruleset" "zone_level_managed_waf" { } ``` + + + :::caution[Important] Ensure that you place the exceptions **before** the rule that executes the managed ruleset (or some of its rules) that you wish to skip, as in the previous example. @@ -202,7 +354,46 @@ The following example adds three [overrides](/ruleset-engine/managed-rulesets/ov The following configuration includes the three overrides in the rule that executes the Cloudflare Managed Ruleset: - + + + +```tf null {11-28} + # (...) + + # Execute Cloudflare Managed Ruleset + rules = [{ + ref = "execute_cloudflare_managed_ruleset" + description = "Execute Cloudflare Managed Ruleset on my zone-level phase entry point ruleset" + expression = "true" + action = "execute" + action_parameters = { + id = "efb7b8c949ac4650a09736fc376e9aee" + overrides = { + rules = [ + { + id = "5de7edfa648c4d6891dc3e7f84534ffa" + action = "log" + enabled = true + }, + { + id = "75a0060762034a6cb663fd51a02344cb" + enabled = false + }, + ] + categories = [{ + category = "wordpress" + action = "js_challenge" + enabled = true + }] + } + } + }] + + # (...) +``` + + + ```tf null {11-26} # (...) @@ -237,13 +428,40 @@ The following configuration includes the three overrides in the rule that execut # (...) ``` + + + ## Configure payload logging This example enables [payload logging](/waf/managed-rules/payload-logging/) for matched rules of the Cloudflare Managed Ruleset, setting the public key used to encrypt the logged payload. Building upon the rule that deploys the Cloudflare Managed Ruleset, the following rule configuration adds the `matched_data` object with the public key used to encrypt the payload: - + + + +```tf null {11-13} + # (...) + + # Execute Cloudflare Managed Ruleset + rules = [{ + ref = "execute_cloudflare_managed_ruleset" + description = "Execute Cloudflare Managed Ruleset on my zone-level phase entry point ruleset" + expression = "true" + action = "execute" + action_parameters = { + id = "efb7b8c949ac4650a09736fc376e9aee" + matched_data = { + public_key = "Ycig/Zr/pZmklmFUN99nr+taURlYItL91g+NcHGYpB8=" + } + } + }] + + # (...) +``` + + + ```tf null {11-13} # (...) @@ -265,6 +483,9 @@ Building upon the rule that deploys the Cloudflare Managed Ruleset, the followin # (...) ``` + + + ## Configure the OWASP paranoia level, score threshold, and action The OWASP managed ruleset supports the following configurations: @@ -284,7 +505,48 @@ The following example rule of a `cloudflare_ruleset` Terraform resource performs - Sets the score threshold to `60` (_Low_). - Sets the ruleset action to `log`. - + + + +```tf null {11-31} + # (...) + + # Execute Cloudflare OWASP Core Ruleset + rules = [{ + ref = "execute_owasp_core_ruleset" + description = "Execute Cloudflare OWASP Core Ruleset" + expression = "true" + action = "execute" + action_parameters = { + id = "4814384a9e5d4991b9815dcfc25d2f1f" + overrides = { + # By default, all PL1 to PL4 rules are enabled. + # Set the paranoia level to PL2 by disabling rules with + # tags "paranoia-level-3" and "paranoia-level-4". + categories = [ + { + category = "paranoia-level-3" + enabled = false + }, + { + category = "paranoia-level-4" + enabled = false + }, + ] + rules = [{ + id = "6179ae15870a4bb7b2d480d4843b323c" + action = "log" + score_threshold = 60 + }] + } + } + }] + + # (...) +``` + + + ```tf null {11-28} # (...) @@ -320,3 +582,6 @@ The following example rule of a `cloudflare_ruleset` Terraform resource performs # (...) ``` + + +