Zone Lockdown — Restrict Access to Origins
In this tutorial, you'll learn about Zone Lockdown. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
Zone Lockdown lets you restrict access to specific URLs or paths on your site so they are only reachable from trusted IPs, CIDR ranges, or countries — ideal for admin panels, staging environments, and API backends.
What You Will Learn
You will learn how Zone Lockdown differs from IP Access Rules, how to configure it for sensitive endpoints, and how to combine it with WAF for defence in depth.
Why It Matters
Exposing admin interfaces to the public internet is a leading cause of data breaches. Zone Lockdown reduces the attack surface by ensuring only trusted IPs can reach sensitive paths, even if credentials are compromised.
Real-World Use Case
A WordPress admin dashboard at /wp-admin/ is restricted to the company office IP range and VPN subnet. An attacker who steals admin credentials from a coffee shop WiFi cannot log in because the request is blocked at Cloudflare's edge.
How Zone Lockdown Works
Zone Lockdown evaluates the request path against configured URL patterns. If the path matches a lockdown rule and the source IP is not in the allowed list, Cloudflare returns a 403 immediately — before any WAF rule or origin request.
flowchart LR
A[Visitor Request] --> B{Path matches Lockdown?}
B -->|No| C[Normal WAF processing]
B -->|Yes| D{IP in allowed list?}
D -->|Yes| C
D -->|No| E[403 Forbidden]
C --> F[Origin Server]
Dashboard Configuration
- Navigate to Security > WAF > Tools in your Cloudflare dashboard.
- Under Zone Lockdown, click Create rule.
- Enter the URL(s) to protect (e.g.
example.com/admin/*). - Add allowed IPs or CIDR ranges.
- Optionally restrict to specific countries.
- Click Add rule to activate.
API: Lock Down an Admin Path
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/firewall/lockdowns" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"urls": ["example.com/admin/*"],
"configurations": [
{"target": "ip", "value": "203.0.113.0/24"},
{"target": "ip", "value": "198.51.100.5"}
]
}'
Expected output:
{
"result": {
"id": "lockdown_id",
"urls": ["example.com/admin/*"],
"configurations": [
{"target": "ip", "value": "203.0.113.0/24"},
{"target": "ip", "value": "198.51.100.5"}
]
},
"success": true
}
Python: Manage Multiple Lockdown Rules
import os
import requests
ZONE_ID = os.environ["CLOUDFLARE_ZONE_ID"]
TOKEN = os.environ["CLOUDFLARE_API_TOKEN"]
BASE = f"https://api.cloudflare.com/client/v4/zones/{ZONE_ID}/firewall/lockdowns"
headers = {
"Authorization": f"Bearer {TOKEN}",
"Content-Type": "application/json",
}
# Create lockdowns for multiple sensitive paths
paths = [
{"url": "example.com/wp-admin/*", "ips": ["10.0.0.0/8"]},
{"url": "example.com/staging/*", "ips": ["198.51.100.0/24"]},
{"url": "example.com/.env", "ips": ["203.0.113.1"]},
]
for entry in paths:
payload = {
"urls": [entry["url"]],
"configurations": [
{"target": "ip", "value": ip} for ip in entry["ips"]
],
}
resp = requests.post(BASE, json=payload, headers=headers)
print(f"{entry['url']}: {resp.status_code} {resp.json()['success']}")
Expected output:
example.com/wp-admin/*: 200 True
example.com/staging/*: 200 True
example.com/.env: 200 True
Testing Lockdown with curl
Verify that a lockdown is active before and after applying:
# Before lockdown — should return 200 or application response
curl -I https://example.com/admin/
# After lockdown — should return 403 Forbidden
curl -I https://example.com/admin/
# From allowed IP — should return 200
curl -I --header "CF-Connecting-IP: 203.0.113.1" https://example.com/admin/
Expected output for blocked request:
HTTP/2 403
server: cloudflare
cf-ray: ...
Common Mistakes
| Mistake | Consequence |
|---|---|
| Forgetting your own IP | You lock yourself out of the admin panel |
| Using relative paths without domain | Rule never matches |
Not covering subdirectories with * |
Only the exact path is protected |
| Creating overlapping lockdowns | Inconsistent behaviour — first match wins |
| Locking down paths used by Webhooks | Third-party services get 403 errors |
Practice Questions
- How does Zone Lockdown differ from an IP Access Rule with Block mode?
- What happens if a request matches a lockdown rule but the IP is not in the allowed list?
- Why should you include the wildcard
*at the end of a protected path?
Challenge
Write a script that audits all existing Zone Lockdown rules in your Cloudflare zone and reports any that contain expired or deprecated IP ranges. Use the Cloudflare API and output a CSV report.
Real-World Task
Your company has three offices with dynamic IPs and a VPN with a static range. Configure a Zone Lockdown rule that protects the /internal/* path, allowing only the VPN range plus the three office subnets. Test with curl before and after.
FAQ
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro — security-first tools for the modern web.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro