If you also want to reject requests that aren’t from Cloudflare:
http {
# Load realip module (if not already loaded)
load_module modules/ngx_http_realip_module.so;
# Include Cloudflare IPs for realip module
include /etc/nginx/cloudflare-ips.conf;
# Geo block to check if original IP is from Cloudflare
geo $realip_remote_addr $is_cloudflare {
default 0;
include /etc/nginx/cloudflare-ips-geo.conf;
}
# Use CF-Connecting-IP header for real client IP
real_ip_header CF-Connecting-IP;
server {
listen 80;
server_name example.com;
# Deny requests not from Cloudflare IPs
if ($is_cloudflare != 1) {
return 403;
}
# Rest of your configuration...
}
}
which references the following files with simple formats.
# cloudflare-ips-geo.conf
# Cloudflare IP ranges for geo module
2400:cb00::/32 1;
2606:4700::/32 1;
2803:f800::/32 1;
2405:b500::/32 1;
2405:8100::/32 1;
2a06:98c0::/29 1;
# cloudflare-ips.conf
# Cloudflare IP ranges for realip module
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
Updating
Here’s a reference script for fetching updates. You could run it periodically via cron.
#!/bin/bash
# Fetch Cloudflare IP ranges
curl -s https://www.cloudflare.com/ips-v4 -o /tmp/cf-ips-v4
curl -s https://www.cloudflare.com/ips-v6 -o /tmp/cf-ips-v6
# Generate set_real_ip_from directives
echo "# Cloudflare IP ranges for realip module" > /etc/nginx/cloudflare-ips.conf
cat /tmp/cf-ips-v4 | while read line; do
echo "set_real_ip_from $line;" >> /etc/nginx/cloudflare-ips.conf
done
cat /tmp/cf-ips-v6 | while read line; do
echo "set_real_ip_from $line;" >> /etc/nginx/cloudflare-ips.conf
done
# Generate geo block entries
echo "# Cloudflare IP ranges for geo module" > /etc/nginx/cloudflare-ips-geo.conf
cat /tmp/cf-ips-v4 | while read line; do
echo "$line 1;" >> /etc/nginx/cloudflare-ips-geo.conf
done
cat /tmp/cf-ips-v6 | while read line; do
echo "$line 1;" >> /etc/nginx/cloudflare-ips-geo.conf
done
# Test and reload NGINX
nginx -t && systemctl reload nginx