Configure WAF custom rules
This page provides examples of creating WAF custom rules in a zone or account using Terraform. The examples cover the following scenarios:
Zone-level configurations:
Account-level configurations:
For more information on custom rules, refer to Custom rules in the Cloudflare WAF documentation.
Zone-level configurations
Add a custom rule to a zone
The following example configures a custom rule in the zone entry point ruleset for the http_request_firewall_custom
phase for zone with ID <ZONE_ID>
. The rule will block all traffic on non-standard HTTP(S) ports:
resource "cloudflare_ruleset" "zone_custom_firewall" { zone_id = "<ZONE_ID>" name = "Phase entry point ruleset for custom rules in my zone" description = "" kind = "zone" phase = "http_request_firewall_custom"
rules { action = "block" expression = "(not cf.edge.server_port in {80 443})" description = "Block ports other than 80 and 443" enabled = true }
}
Account-level configurations
Create and deploy a custom ruleset
The following example creates a custom ruleset in the account with ID <ACCOUNT_ID>
containing a single custom rule. This custom ruleset is then deployed using a separate cloudflare_ruleset
Terraform resource. If you do not deploy a custom ruleset, it will not execute.
The following configuration creates the custom ruleset with a single rule:
resource "cloudflare_ruleset" "account_firewall_custom_ruleset" { account_id = "<ACCOUNT_ID>" name = "Custom ruleset blocking traffic in non-standard HTTP(S) ports" description = "" kind = "custom" phase = "http_request_firewall_custom"
rules { action = "block" expression = "(not cf.edge.server_port in {80 443})" description = "Block ports other than 80 and 443" enabled = true }
}
The following configuration deploys the custom ruleset at the account level. It defines a dependency on the account_firewall_custom_ruleset
resource and uses the ID of the created custom ruleset in action_parameters
:
resource "cloudflare_ruleset" "account_firewall_custom_entrypoint" { account_id = "<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 { action = "execute" action_parameters { id = cloudflare_ruleset.account_firewall_custom_ruleset.id } expression = "(cf.zone.name eq \"example.com\")" description = "Deploy custom ruleset for example.com" enabled = true }
}
For more information on configuring and deploying custom rulesets, refer to Work with custom rulesets in the Ruleset Engine documentation.
Add a custom rule checking for exposed credentials
The following configuration creates a custom ruleset with a single rule that checks for exposed credentials.
resource "cloudflare_ruleset" "account_firewall_custom_ruleset_exposed_creds" { account_id = "<ACCOUNT_ID>" name = "Custom ruleset checking for exposed credentials" description = "" kind = "custom" phase = "http_request_firewall_custom"
rules { action = "rewrite" action_parameters { headers { name = "Exposed-Credential-Check" operation = "set" value = "1" } } exposed_credential_check { username_expression = "url_decode(http.request.body.form[\"username\"][0])" password_expression = "url_decode(http.request.body.form[\"password\"][0])" } expression = "http.request.method == \"POST\" && http.request.uri == \"/login.php\"" description = "Add header when there is a rule match and exposed credentials are detected" enabled = true }
}
The following configuration deploys the custom ruleset. It defines a dependency on the account_firewall_custom_ruleset_exposed_creds
resource and obtains the ID of the created custom ruleset:
resource "cloudflare_ruleset" "account_firewall_custom_entrypoint" { account_id = "<ACCOUNT_ID>" name = "Account-level entry point ruleset for the http_request_firewall_custom phase deploying a custom ruleset checking for exposed credentials" description = "" kind = "root" phase = "http_request_firewall_custom"
depends_on = [cloudflare_ruleset.account_firewall_custom_ruleset_exposed_creds]
rules { action = "execute" action_parameters { id = cloudflare_ruleset.account_firewall_custom_ruleset_exposed_creds.id } expression = "(cf.zone.name eq \"example.com\")" description = "Deploy custom ruleset for example.com" enabled = true }
}