Cloudflare Security Configuration Guide for Developers
A practical guide to Cloudflare's security features: WAF rules, DDoS protection, SSL/TLS strict mode, DNSSEC, Zero Trust Access, Bot Management, and hiding your origin IP.
Cloudflare sits in front of millions of websites, but most teams use only a fraction of its security capabilities. The default settings provide some protection, but a properly configured Cloudflare setup is a significant force multiplier for your security posture. This guide covers the key configurations that actually make a difference.
SSL/TLS: Use Strict Mode (Not Flexible)
The single most important SSL/TLS setting in Cloudflare is the encryption mode. Many teams leave it on "Flexible," which means Cloudflare encrypts traffic from visitors to Cloudflare but sends plaintext HTTP to your origin server. This creates a security gap: data is encrypted in transit from the user's perspective but exposed between Cloudflare and your server.
Set SSL/TLS mode to Full (Strict):
- Go to SSL/TLS → Overview
- Select Full (strict)
This requires a valid certificate on your origin server (Let's Encrypt, your CA, or a Cloudflare Origin CA certificate). With Full (strict), Cloudflare verifies your origin certificate and only connects over HTTPS.
Additional TLS settings to configure:
- Minimum TLS Version: Set to TLS 1.2 at minimum. TLS 1.3 preferred where your client base supports it.
- TLS 1.3: Enable (it's faster due to 0-RTT and more secure).
- Automatic HTTPS Rewrites: Rewrites mixed content HTTP links to HTTPS in page source.
- Always Use HTTPS: 301 redirect all HTTP to HTTPS.
- HSTS: Enable with a minimum
max-ageof 31536000 (1 year). Only addincludeSubDomainsandpreloadif you're certain all subdomains support HTTPS.
SSL/TLS → Edge Certificates → HTTP Strict Transport Security (HSTS)
WAF Rules and Managed Rulesets
Cloudflare WAF operates at the application layer and inspects HTTP requests for malicious patterns before they reach your origin.
Managed Rulesets (Pro plan and above):
Cloudflare provides pre-built rule sets that you can toggle per rule or override globally:
- Cloudflare Managed Ruleset: Covers OWASP Top 10 attack patterns
- Cloudflare OWASP Core Ruleset: More aggressive OWASP CRS rules
- Cloudflare Exposed Credentials Check: Detects credential stuffing attempts
Enable them under Security → WAF → Managed Rules.
Custom WAF Rules using the Firewall Rules engine:
# Block requests with suspicious user agents
(http.user_agent contains "zgrab" or http.user_agent contains "masscan" or http.user_agent eq "")
# Block common scanner paths
(http.request.uri.path contains "/.env" or
http.request.uri.path contains "/wp-admin" or
http.request.uri.path contains "/phpmyadmin")
# Rate limit API endpoints
(http.request.uri.path matches "^/api/" and http.request.method eq "POST")
Use the Challenge action rather than Block where possible for ambiguous traffic — it presents a browser challenge that bots fail but humans pass, reducing false positive impact.
Transform Rules vs Page Rules
Cloudflare is deprecating Page Rules in favor of the newer Rules engine. Transform Rules handle URL rewrites and header modifications:
# Add security headers via Response Header Modification
Rule: all requests
Action: Set header
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Configuration Rules handle settings overrides (SSL mode, caching, browser integrity checks) per URL pattern. These are more flexible and composable than Page Rules.
DDoS Protection
Cloudflare's DDoS protection is enabled by default at all plan tiers, but you should understand how to tune it.
HTTP DDoS Attack Protection operates on Cloudflare's global network and automatically detects volumetric and protocol attacks. The managed ruleset has two sensitivity levels:
- Default: Balanced between blocking attacks and minimizing false positives
- High: More aggressive blocking; appropriate for APIs that don't serve browsers
Override specific rules that generate false positives for your traffic pattern under Security → DDoS → HTTP DDoS attack protection.
Advanced DDoS (Enterprise): Enables network-layer (L3/L4) DDoS protection for Magic Transit customers and provides finer-grained controls.
For application-layer DDoS, rate limiting rules are your primary tool:
# Limit to 100 requests per minute per IP on login endpoint
Path: /auth/login
Method: POST
Rate: 100 requests / 1 minute
Action: Block for 10 minutes
Characteristics: IP address
DNSSEC
DNSSEC prevents DNS cache poisoning attacks by cryptographically signing DNS records. Cloudflare manages DNSSEC automatically — you just need to enable it and add the DS record to your registrar.
- Go to DNS → Settings → DNSSEC → Enable DNSSEC
- Cloudflare generates a DS record with the key tag, algorithm, digest type, and digest
- Add this DS record at your domain registrar (e.g., Route 53, Namecheap, GoDaddy)
Verify DNSSEC is working:
dig +dnssec yourdomain.com A
# Should see RRSIG records in the answer section
dig DS yourdomain.com @8.8.8.8
# Should return your DS record
DNSSEC propagation takes up to 48 hours. Use https://dnssec-debugger.verisignlabs.com/ to verify the full chain of trust.
Cloudflare Access (Zero Trust)
Cloudflare Access replaces VPNs with identity-aware access control for internal applications. Instead of exposing an admin panel or internal tool to the internet, you put it behind Access, which enforces authentication (SSO, GitHub OAuth, Google, email OTP) before any request reaches your origin.
Setting up an Access application:
- Zero Trust → Access → Applications → Add an Application
- Select Self-hosted, enter your application URL
- Create a policy: e.g., allow users where email ends with
@yourdomain.comand is part of theengineeringgroup in your IdP - Enable Cloudflare Tunnel (formerly Argo Tunnel) to route traffic to your internal service without exposing any ports:
# Install cloudflared
brew install cloudflare/cloudflare/cloudflared
# Authenticate
cloudflared tunnel login
# Create a tunnel
cloudflared tunnel create my-internal-app
# Configure
cat > ~/.cloudflared/config.yml << EOF
tunnel: <TUNNEL_ID>
credentials-file: /home/user/.cloudflared/<TUNNEL_ID>.json
ingress:
- hostname: internal.yourdomain.com
service: http://localhost:8080
- service: http_status:404
EOF
# Run
cloudflared tunnel run my-internal-app
With this setup, your internal service has no inbound firewall rules — traffic only flows outbound from cloudflared to Cloudflare's edge.
Bot Management
Cloudflare Bot Management (Pro: Bot Fight Mode, Enterprise: full Bot Management) distinguishes legitimate bots (Googlebot, monitoring services) from malicious ones (scrapers, credential stuffers, DDoS bots).
Bot Fight Mode (Pro and above): Automatically challenges requests that Cloudflare identifies as bot traffic. Enable it under Security → Bots.
Custom bot rules give you more control:
# Block known bad bots but allow verified good bots
(cf.bot_management.score lt 30 and not cf.bot_management.verified_bot)
# Challenge medium-confidence automated traffic
(cf.bot_management.score ge 30 and cf.bot_management.score lt 60)
The cf.bot_management.score field ranges from 1 (definitely a bot) to 99 (definitely human). Tune your thresholds based on your traffic patterns using Bot Analytics before enforcing.
Hiding Your Origin IP Address
Cloudflare is only effective if attackers cannot discover and directly target your origin server, bypassing Cloudflare entirely.
Steps to protect origin IP:
- Never expose origin IP in DNS: All DNS records for the domain should be proxied (orange cloud). Unproxied records reveal the IP.
- Check historical DNS records: Attackers use services like SecurityTrails or Shodan to find IPs that were exposed before Cloudflare was added. If your origin IP was ever public, change it.
- Restrict origin server to Cloudflare IPs only: Add firewall rules on your origin that only accept inbound HTTP/HTTPS from Cloudflare's published IP ranges:
# nginx - only allow Cloudflare IPs
geo $cloudflare_ip {
default 0;
103.21.244.0/22 1;
103.22.200.0/22 1;
103.31.4.0/22 1;
104.16.0.0/13 1;
104.24.0.0/14 1;
108.162.192.0/18 1;
131.0.72.0/22 1;
141.101.64.0/18 1;
162.158.0.0/15 1;
172.64.0.0/13 1;
173.245.48.0/20 1;
188.114.96.0/20 1;
190.93.240.0/20 1;
197.234.240.0/22 1;
198.41.128.0/17 1;
}
server {
listen 80;
if ($cloudflare_ip = 0) {
return 403;
}
}
- Use Cloudflare Tunnel: As described above — no inbound ports means no origin IP exposure at all.
- Authenticated Origin Pulls: Configure mutual TLS between Cloudflare and your origin. Cloudflare presents a client certificate; your origin rejects requests without it.
# Require Cloudflare client certificate
ssl_client_certificate /etc/nginx/certs/cloudflare.crt;
ssl_verify_client on;
With these controls in place, Cloudflare's security perimeter holds regardless of what attackers discover about your infrastructure.