How Do You Secure Nginx with Cloudflare Access Control?

When configuring Nginx with Cloudflare proxy services, implementing proper access control requires addressing two critical aspects: managing host header validation and restricting access to Cloudflare’s edge servers. This guide provides comprehensive solutions for both challenges while maintaining optimal security for your hosting infrastructure.
Understanding the Dual Security Challenge
Security implementation for Nginx behind Cloudflare involves two distinct components: filtering requests without proper host headers (typically from bots and scanners) and ensuring that only Cloudflare edge servers can access your origin server. Both elements are crucial for maintaining robust security.
Host Header Validation Configuration
Implementing a catch-all server block helps prevent unauthorized access attempts through incorrect host headers:
# Default server block to catch invalid hosts
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _;
ssl_reject_handshake on;
return 444;
}
Automated Cloudflare IP Management
Create an automated system to maintain current Cloudflare IP ranges using shell scripting:
#!/bin/bash
# File: update_cloudflare_ips.sh
echo "# Cloudflare IP ranges - generated on $(date)" | tee /etc/nginx/cloudflare.inc > /etc/nginx/real_ip.inc
# Fetch and format IPv4 ranges
curl -s https://www.cloudflare.com/ips-v4/ | \
tee >(sed 's/$/ 0;/' >> /etc/nginx/cloudflare.inc) | \
sed 's/^/set_real_ip_from /; s/$/;/' >> /etc/nginx/real_ip.inc
# Add spacing
echo >> /etc/nginx/cloudflare.inc
echo >> /etc/nginx/real_ip.inc
# Fetch and format IPv6 ranges
curl -s https://www.cloudflare.com/ips-v6/ | \
tee >(sed 's/$/ 0;/' >> /etc/nginx/cloudflare.inc) | \
sed 's/^/set_real_ip_from /; s/$/;/' >> /etc/nginx/real_ip.inc
Implementing IP Restrictions
Configure Nginx to allow access only from Cloudflare’s edge servers using the geo module:
# Define allowed IPs using geo module
geo $denied {
default 1;
include /etc/nginx/cloudflare.inc;
}
server {
server_name example.com;
listen 443 ssl http2;
# Deny non-Cloudflare access
if ($denied) {
return 444;
}
# SSL configuration
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
}
Real IP Configuration
Properly handle visitor IP addresses:
server {
server_name example.com;
listen 443 ssl http2;
# Include real IP configuration
include /etc/nginx/real_ip.inc;
real_ip_header CF-Connecting-IP;
# Use realip_remote_addr for geo matching
geo $realip_remote_addr $denied {
default 1;
include /etc/nginx/cloudflare.inc;
}
}
Advanced Security Headers
Enhance security with appropriate HTTP headers:
server {
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
}
Maintenance and Monitoring
Implement regular maintenance procedures to keep your configuration secure:
- Schedule automated IP range updates daily
- Monitor access logs for unauthorized attempts
- Regularly verify SSL certificate validity
- Review and update security headers
Logging Configuration
Set up comprehensive logging to track access attempts and security events:
server {
# Access and error logs
access_log /var/log/nginx/example.com.access.log combined buffer=512k flush=1m;
error_log /var/log/nginx/example.com.error.log warn;
# Custom logging format for security monitoring
log_format security '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
}
Troubleshooting Common Issues
Address frequent configuration challenges:
- Verify Cloudflare IP ranges are current
- Check SSL certificate chain integrity
- Confirm proper real IP header processing
- Validate host header configurations
Performance Optimization
server {
# Buffer size optimizations
client_body_buffer_size 10K;
client_header_buffer_size 1k;
client_max_body_size 8m;
large_client_header_buffers 4 4k;
# Connection timeouts
client_body_timeout 12;
client_header_timeout 12;
keepalive_timeout 15;
send_timeout 10;
}
Conclusion
Implementing proper access control with Nginx and Cloudflare requires careful attention to both host validation and IP restriction mechanisms. By following these configuration guidelines and maintaining automated updates, you can establish a robust security framework that leverages Cloudflare’s proxy protection while ensuring direct IP access remains properly restricted.
