Skip to content

Instantly share code, notes, and snippets.

@oleg-koval
Created April 23, 2026 14:24
Show Gist options
  • Select an option

  • Save oleg-koval/50e1a29b2c4de62d19b31ca1991494ec to your computer and use it in GitHub Desktop.

Select an option

Save oleg-koval/50e1a29b2c4de62d19b31ca1991494ec to your computer and use it in GitHub Desktop.
Blocking Countries via Cloudflare WAF Custom Rules

Blocking Countries via Cloudflare WAF Custom Rules

Prerequisites

  • Cloudflare API Token with Zone:Rulesets:Edit permission
  • Zone IDs for each domain

1. Get Zone IDs

curl -s -X GET \
  "https://api.cloudflare.com/client/v4/zones?account.id=YOUR_ACCOUNT_ID&status=active" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" | jq '.result[] | {name: .name, id: .id}'

2. Check Existing Custom Firewall Rulesets

curl -s -X GET \
  "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/rulesets" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" | \
  jq '.result[] | select(.phase == "http_request_firewall_custom")'

3a. Create a NEW Custom Ruleset with Block Rule

If no existing http_request_firewall_custom ruleset exists:

curl -s -X POST \
  "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/rulesets" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "name": "default",
    "description": "WAF Custom Rules",
    "kind": "zone",
    "phase": "http_request_firewall_custom",
    "rules": [
      {
        "action": "block",
        "description": "Block traffic from Russia, Belarus, Iran, and North Korea",
        "enabled": true,
        "expression": "(ip.src.country in {\"RU\" \"BY\" \"IR\" \"KP\"})"
      }
    ]
  }' | jq '.success'

3b. Update an EXISTING Custom Ruleset

If a ruleset already exists (use the ruleset ID from step 2):

curl -s -X PUT \
  "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/rulesets/RULESET_ID" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "description": "WAF Custom Rules",
    "rules": [
      {
        "action": "block",
        "description": "Block traffic from Russia, Belarus, Iran, and North Korea",
        "enabled": true,
        "expression": "(ip.src.country in {\"RU\" \"BY\" \"IR\" \"KP\"})"
      }
    ]
  }' | jq '.success'

4. Verify the Rule is Active

curl -s -X GET "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/rulesets/RULESET_ID"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment