Block a list of IPs in Cloudflare: an IP list, one rule, and a script that keeps it current

Block thousands of IPs in Cloudflare on any plan: an IP list, one WAF custom rule, and a tested script that refreshes the list from a free feed every six hours.

To block a list of IP addresses in Cloudflare, put them in an IP list and block the list with one WAF custom rule: ip.src in $your_list. Every plan has IP lists, and the Free plan allows one list with up to 10,000 addresses. To keep the list current, a short script can replace its contents through Cloudflare's API on a timer. FFraud's free lists hold 500 to 2,500 addresses each, so they fit a Free plan.

#What does each Cloudflare plan allow?

PlanCustom listsList items, all listsCustom rules
Free110,0005
Pro1010,00020
Business1010,000100
Enterprise1,000500,0001,000

IP lists take single IPv4 and IPv6 addresses, IPv4 ranges from /8 to /32 and IPv6 ranges from /12 to /128, mixed in one list. Cloudflare's own Managed IP Lists come with Enterprise only. On every other plan, the list is yours to fill.

FFraud's free lists against the 10,000-item limitAddresses per list on October 25, 2026, beside the item limit of Cloudflare's Free, Pro and Business plans
  1. worst.txt500
  2. badips.txt2,000
  3. webattack.txt2,000
  4. freships.txt2,500
  5. All four, merged6,314
  6. Plan limit (Free to Business)10,000

Source: FFraud free lists, read October 25, 2026, 19:03 UTC; Cloudflare WAF documentation

#How do you create the list and the rule?

  1. In the Cloudflare dashboard, open your account's Lists page under Configurations and create a list of type IP. Name it with lowercase letters, numbers and underscores, up to 50 characters, such as ffraud_badips.
  2. Add the addresses: type them in, or upload a CSV file with one address per line. The script below fills the list for you instead.
  3. In the zone you want to protect, create a custom rule with this expression and the action Block: (ip.src in $ffraud_badips).

One rule covers the whole list, however long it grows. If your own monitoring or office addresses could ever land on a list, put a rule with the action Skip for them above the block rule.

#How do you keep the list current?

Cloudflare's API can replace every item of a list in one call: a PUT on the list's items deletes the old ones and writes the new ones, as one background operation. The script below downloads a FFraud list, builds the items, sends the replace, and waits until Cloudflare reports it complete. It needs only curl, grep, awk and sed.

/usr/local/bin/ffraud-cloudflare-list
#!/bin/sh
# Replace a Cloudflare IP list with FFraud's free attacker list, then wait until Cloudflare has applied it.
# A failed download, a short list or an oversized list leaves the Cloudflare list as it is.
set -eu
: "${CF_API_TOKEN:?set CF_API_TOKEN (permission: Account Filter Lists Edit)}"
: "${CF_ACCOUNT_ID:?set CF_ACCOUNT_ID}"
: "${CF_LIST_ID:?set CF_LIST_ID}"
LIST_URL="${LIST_URL:-https://ffraud.com/free/badips.txt}"
API="https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT_ID/rules/lists"

tmp=$(mktemp)
trap 'rm -f "$tmp" "$tmp.json"' EXIT

curl -fsS --max-time 30 "$LIST_URL" -o "$tmp"

# One address per line. Addresses hold only hex digits, dots and colons, so no JSON escaping is needed.
grep -E '^([0-9]{1,3}(\.[0-9]{1,3}){3}|[0-9a-fA-F]*:[0-9a-fA-F:]+)$' "$tmp" \
  | awk 'BEGIN { printf "[" } { printf "%s{\"ip\":\"%s\",\"comment\":\"FFraud free list\"}", (NR > 1 ? "," : ""), $0 } END { print "]" }' \
  > "$tmp.json"

n=$(grep -o '"ip"' "$tmp.json" | wc -l)
if [ "$n" -lt 100 ]; then echo "only $n addresses in the download, list left as it is" >&2; exit 1; fi
if [ "$n" -gt 10000 ]; then echo "$n addresses exceed the 10,000-item limit, list left as it is" >&2; exit 1; fi

op=$(curl -fsS -X PUT "$API/$CF_LIST_ID/items" \
  -H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: application/json" \
  --data @"$tmp.json" | sed -n 's/.*"operation_id": *"\([^"]*\)".*/\1/p')
if [ -z "$op" ]; then echo "Cloudflare returned no operation id" >&2; exit 1; fi

i=0
while [ "$i" -lt 30 ]; do
  status=$(curl -fsS "$API/bulk_operations/$op" -H "Authorization: Bearer $CF_API_TOKEN" \
    | sed -n 's/.*"status": *"\([a-z]*\)".*/\1/p')
  case "$status" in
    completed) echo "list replaced with $n addresses"; exit 0 ;;
    failed) echo "Cloudflare reported the bulk operation as failed" >&2; exit 1 ;;
  esac
  i=$((i + 1))
  sleep 5
done
echo "still $status after 150 seconds; Cloudflare finishes it on its own" >&2
exit 1

Create an API token with the permission Account Filter Lists Edit. The account ID sits in the dashboard's URL, and this call prints each list with its ID:

shell
curl -s "https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT_ID/rules/lists" \
  -H "Authorization: Bearer $CF_API_TOKEN"

FFraud rebuilds its free lists every six hours, so run the script on the same rhythm. One cron line does it, in /etc/cron.d/ffraud-cloudflare-list, with the three variables set in the file above it: 40 */6 * * * root /usr/local/bin/ffraud-cloudflare-list. For a website, set LIST_URL to webattack.txt. Four runs a day of 2,000 items stay far below Cloudflare's limit of 1,000,000 item changes in 12 hours.

What we tested

We ran the script's download, filter and item building on all four FFraud lists on October 25, 2026, and checked every item file with a JSON parser and every address with Python's address parser:

test run, October 25, 2026, 19:03 UTC
free/badips.txt        items  2000  IPv4  2000  IPv6   0  invalid 0  under 10,000: True
free/webattack.txt     items  2000  IPv4  2000  IPv6   0  invalid 0  under 10,000: True
sizzling/worst.txt     items   500  IPv4   500  IPv6   0  invalid 0  under 10,000: True
sizzling/freships.txt  items  2500  IPv4  2473  IPv6  27  invalid 0  under 10,000: True
all four merged, unique: 6314

The replace and status calls follow Cloudflare's API documentation; we did not run them against a live account. Run the script once by hand and check the list in the dashboard before you schedule it.

#Should the rule block or challenge?

Block when the list holds attackers of the thing you protect, such as web attackers in front of a website. Choose Managed Challenge for signups, logins and checkouts, where one listed address can carry many real people, such as a mobile carrier's CGNAT gateway. A challenge lets them through and stops the scripts.

#What about IP Access rules?

IP Access rules block one address or range per rule, up to 50,000 rules per account on every plan. They suit a handful of addresses you block by hand. For a feed that changes every few hours, a list is the better fit: one rule, and one API call to refresh it.

#Can you load a bigger list?

Up to the plan's item limit: 10,000 below Enterprise, 500,000 on Enterprise. FFraud's full malicious IP database holds about 1.58 million addresses, more than any plan takes. Load that one at your origin server instead, with ipset or a geo map in nginx. Our comparison of free blocklists shows what else fits under 10,000.

#Questions people ask

How do I add a large list of IP addresses to block in Cloudflare?

Create an IP list, fill it by CSV upload or with the API's replace call, and block it with one custom rule, ip.src in $your_list. Lists hold up to 10,000 addresses below Enterprise.

Is it possible to upload a list of IP addresses to block?

Yes. A list accepts a CSV file with one address per line, or a JSON array of items through the API.

How do I block an IP range in Cloudflare?

Add the range to an IP list in CIDR form, such as 203.0.113.0/24. Lists take IPv4 ranges from /8 to /32 and IPv6 ranges from /12 to /128.

How do I block multiple IP addresses at once in Cloudflare?

Put them all in one IP list and block the list with one custom rule. Adding or replacing addresses later changes nothing in the rule.

Should I use IP Access rules or a list with a custom rule?

IP Access rules for a few addresses blocked by hand. A list with one custom rule for anything longer, and for any list you refresh from a feed.

To check why one address is on a list, paste it into the free IP blacklist check.

Sources

  1. Lists, Cloudflare WAF documentation
  2. Custom lists, Cloudflare WAF documentation
  3. Custom rules, Cloudflare WAF documentation
  4. IP Access rules, Cloudflare WAF documentation
  5. Lists API, Cloudflare WAF documentation, October 15, 2026
  6. Lists API endpoints, Cloudflare WAF documentation
  7. Get bulk operation status, Cloudflare API reference
  8. List JSON object, Cloudflare WAF documentation
  9. cloudflare_list resource, Cloudflare Terraform provider
  10. Free lists badips, webattack, worst and freships, read October 25, 2026, FFraud