Skip to content
Back to Blog
SSL & Security11 min read

How to Set Up Cloudflare Private Origins (Step-by-Step Guide)

Learn how to configure Cloudflare Private Origins to hide your real server IP and protect against direct-to-origin attacks with this complete walkthrough.

Written by Abdul AbrorTechnical Hosting Support Engineer
How to Set Up Cloudflare Private Origins (Step-by-Step Guide)
On this page

When you proxy traffic through Cloudflare, attackers can still bypass your protection if they discover your origin server's real IP address. Private Origins is Cloudflare's framework for ensuring connections to your server come exclusively through Cloudflare's network, blocking direct access attempts and preventing reconnaissance that could expose vulnerabilities.

This guide walks you through configuring Private Origins step-by-step, from initial setup to verification and ongoing maintenance.

Understanding Private Origins

Private Origins isn't a single toggle—it's a combination of techniques that work together:

  • Authenticated Origin Pulls: Forces your server to verify that incoming HTTPS connections originated from Cloudflare by checking client certificates
  • Origin IP firewall rules: Blocks all traffic except connections from Cloudflare's published IP ranges
  • Origin certificate encryption: Ensures end-to-end TLS encryption between Cloudflare and your server
  • DNS obfuscation: Keeps your real IP out of public records

When properly configured, attackers who discover your origin IP cannot connect to your server directly. All requests must pass through Cloudflare's edge network, where your security rules, rate limits, and WAF policies apply.

Prerequisites

Before you begin:

  • Active Cloudflare account with your domain proxied (orange cloud enabled)
  • Root or sudo access to your origin server
  • Web server running Apache, Nginx, or similar
  • SSH access to your server
  • Basic familiarity with your firewall management tool (iptables, firewalld, ufw, etc.)

Step 1: Install a Cloudflare Origin Certificate

Cloudflare Origin Certificates provide free TLS encryption between Cloudflare's edge and your server. Unlike Let's Encrypt certificates, these are trusted only by Cloudflare, which is perfect for origin security.

Generate the Certificate

  1. Log into the Cloudflare dashboard
  2. Select your domain
  3. Navigate to SSL/TLS → Origin Server
  4. Click Create Certificate
  5. Choose these settings: - Let Cloudflare generate a private key and CSR: recommended for simplicity - Hostnames: your domain and wildcard subdomain (example.com, .example.com) - Validity*: 15 years is fine for origin certificates
  6. Click Create
  7. Copy both the Origin Certificate and Private Key immediately—you won't see the private key again

Install on Your Server

Create certificate files on your origin:

sudo mkdir -p /etc/ssl/cloudflare
sudo nano /etc/ssl/cloudflare/cert.pem

Paste the Origin Certificate, save and exit. Then create the private key:

sudo nano /etc/ssl/cloudflare/key.pem

Paste the Private Key, save and exit. Set secure permissions:

sudo chmod 600 /etc/ssl/cloudflare/key.pem
sudo chmod 644 /etc/ssl/cloudflare/cert.pem

Configure Your Web Server

For Nginx, edit your site configuration:

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate /etc/ssl/cloudflare/cert.pem;
    ssl_certificate_key /etc/ssl/cloudflare/key.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    # Rest of your configuration
}

Test and reload:

sudo nginx -t
sudo systemctl reload nginx

For Apache, edit your VirtualHost:

<VirtualHost *:443>
    ServerName example.com
    ServerAlias www.example.com

    SSLEngine on
    SSLCertificateFile /etc/ssl/cloudflare/cert.pem
    SSLCertificateKeyFile /etc/ssl/cloudflare/key.pem
    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1

    # Rest of your configuration
</VirtualHost>

Test and restart:

sudo apachectl configtest
sudo systemctl restart apache2

Set Cloudflare SSL Mode

In the Cloudflare dashboard under SSL/TLS → Overview, set the mode to Full (strict). This ensures Cloudflare validates your origin certificate.

Step 2: Enable Authenticated Origin Pulls

Authenticated Origin Pulls add mutual TLS authentication, requiring Cloudflare to present a valid client certificate when connecting to your origin.

Download Cloudflare's Client Certificate

Cloudflare publishes an authenticated origin pull CA certificate. Download it to your server:

sudo curl -o /etc/ssl/cloudflare/origin-pull-ca.pem \
  https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pem
sudo chmod 644 /etc/ssl/cloudflare/origin-pull-ca.pem

Configure Your Web Server

For Nginx, add to your SSL server block:

server {
    listen 443 ssl http2;

    ssl_certificate /etc/ssl/cloudflare/cert.pem;
    ssl_certificate_key /etc/ssl/cloudflare/key.pem;
    ssl_client_certificate /etc/ssl/cloudflare/origin-pull-ca.pem;
    ssl_verify_client on;

    # Rest of your configuration
}

For Apache, add to your VirtualHost:

<VirtualHost *:443>
    SSLEngine on
    SSLCertificateFile /etc/ssl/cloudflare/cert.pem
    SSLCertificateKeyFile /etc/ssl/cloudflare/key.pem

    SSLCACertificateFile /etc/ssl/cloudflare/origin-pull-ca.pem
    SSLVerifyClient require
    SSLVerifyDepth 1

    # Rest of your configuration
</VirtualHost>

Test configuration and reload your web server.

Enable in Cloudflare Dashboard

  1. Go to SSL/TLS → Origin Server
  2. Scroll to Authenticated Origin Pulls
  3. Toggle to On

Test your site loads correctly through Cloudflare. If you see connection errors, double-check your web server configuration and certificate paths.

Step 3: Restrict Traffic to Cloudflare IPs

Now configure your firewall to accept HTTPS connections only from Cloudflare's network.

Get Cloudflare IP Ranges

Cloudflare publishes their IP ranges. You'll need both IPv4 and IPv6 lists. Create a script to update them automatically:

sudo mkdir -p /etc/cloudflare
sudo nano /usr/local/bin/update-cloudflare-ips.sh

Add this script:

#!/bin/bash
curl -s https://www.cloudflare.com/ips-v4 -o /etc/cloudflare/ips-v4.txt
curl -s https://www.cloudflare.com/ips-v6 -o /etc/cloudflare/ips-v6.txt

Make it executable and run it:

sudo chmod +x /usr/local/bin/update-cloudflare-ips.sh
sudo /usr/local/bin/update-cloudflare-ips.sh

Configure Firewall Rules

Using UFW (Ubuntu/Debian):

# Allow SSH first - critical!
sudo ufw allow 22/tcp

# Allow HTTP for redirects
sudo ufw allow 80/tcp

# Delete any existing HTTPS allow rules
sudo ufw status numbered
# Note the number of any 443/tcp rules and delete them

# Allow HTTPS only from Cloudflare IPs
for ip in $(cat /etc/cloudflare/ips-v4.txt); do
    sudo ufw allow from $ip to any port 443 proto tcp
done

for ip in $(cat /etc/cloudflare/ips-v6.txt); do
    sudo ufw allow from $ip to any port 443 proto tcp
done

# Enable firewall if not already enabled
sudo ufw enable
sudo ufw status

Using firewalld (CentOS/RHEL/Rocky):

# Create a custom zone for Cloudflare
sudo firewall-cmd --permanent --new-zone=cloudflare
sudo firewall-cmd --permanent --zone=cloudflare --add-service=http
sudo firewall-cmd --permanent --zone=cloudflare --add-service=https

# Add Cloudflare IPs to the zone
for ip in $(cat /etc/cloudflare/ips-v4.txt); do
    sudo firewall-cmd --permanent --zone=cloudflare --add-source=$ip
done

for ip in $(cat /etc/cloudflare/ips-v6.txt); do
    sudo firewall-cmd --permanent --zone=cloudflare --add-source=$ip
done

# Remove HTTPS from public zone
sudo firewall-cmd --permanent --zone=public --remove-service=https

# Reload firewall
sudo firewall-cmd --reload
sudo firewall-cmd --list-all-zones | grep -A 10 cloudflare

Using iptables directly:

# Flush existing HTTPS rules (be careful)
sudo iptables -D INPUT -p tcp --dport 443 -j ACCEPT

# Allow Cloudflare IPs
for ip in $(cat /etc/cloudflare/ips-v4.txt); do
    sudo iptables -I INPUT -p tcp -s $ip --dport 443 -j ACCEPT
done

# Drop all other HTTPS traffic
sudo iptables -A INPUT -p tcp --dport 443 -j DROP

# Save rules
sudo iptables-save | sudo tee /etc/iptables/rules.v4

Automate IP Updates

Cloudflare occasionally updates their IP ranges. Schedule your update script:

sudo crontab -e

Add this line to check weekly:

0 3 * * 0 /usr/local/bin/update-cloudflare-ips.sh && /usr/local/bin/apply-firewall-rules.sh

Create the apply script with your firewall commands from above.

Step 4: Lock Down DNS Records

Even with origin protection, your real IP might leak through DNS history or public records.

Audit Your DNS

  1. Check all DNS records in Cloudflare's DNS dashboard
  2. Ensure your A and AAAA records for web traffic point through Cloudflare (orange cloud icon)
  3. Look for any records that expose your origin IP: - Old A records for direct access - MX records pointing to the same IP - TXT records with IP references - Subdomains not proxied through Cloudflare

Separate Mail Server IPs

If you run mail on the same server, either:

  • Move email to a different IP or server (recommended)
  • Accept that your mail server IP will be public
  • Use Cloudflare Area 1 or a third-party mail gateway

MX records cannot be proxied, so mail server IPs are inherently discoverable.

Change Your Origin IP

If your origin IP is already public, consider requesting a new IP from your hosting provider after implementing these protections. This gives you a clean slate.

Step 5: Additional Hardening

Disable Direct IP Access

Configure your web server to reject requests made directly to your IP:

Nginx:

server {
    listen 443 ssl http2 default_server;
    server_name _;
    ssl_certificate /etc/ssl/cloudflare/cert.pem;
    ssl_certificate_key /etc/ssl/cloudflare/key.pem;
    return 444;
}

Apache:

<VirtualHost *:443>
    ServerName _default_
    SSLEngine on
    SSLCertificateFile /etc/ssl/cloudflare/cert.pem
    SSLCertificateKeyFile /etc/ssl/cloudflare/key.pem
    <Location />
        Require all denied
    </Location>
</VirtualHost>

Validate Cloudflare Headers

Cloudflare adds headers to requests. You can add additional validation in your application:

  • Check for CF-Connecting-IP header
  • Validate CF-Ray header exists
  • Log and alert on requests without Cloudflare headers that somehow passed firewall rules

Monitor Access Logs

Regularly check web server logs for connection attempts that bypassed Cloudflare:

sudo grep -v "CF-" /var/log/nginx/access.log | tail -50

Any successful connection without Cloudflare headers indicates a gap in your protection.

Verification and Testing

Test Through Cloudflare

Visit your site normally. Everything should work:

curl -I https://example.com

Look for CF-Ray and other Cloudflare headers.

Test Direct Connection

Attempt to connect directly to your origin IP:

curl -vI https://YOUR_ORIGIN_IP

This should fail with a connection timeout or TLS error. If it succeeds, review your firewall rules and Authenticated Origin Pulls configuration.

Test from External Network

Use a VPS or VPN outside your network to verify firewall rules work correctly:

telnet YOUR_ORIGIN_IP 443

The connection should hang or be rejected.

Check DNS Leaks

Use online tools to verify your origin IP isn't exposed:

  • Historical DNS lookup tools
  • SSL certificate transparency logs (check SANs don't reference origin IP)
  • Search your domain in Shodan or Censys to see what IPs are associated

Troubleshooting Common Issues

Site returns 525 or 526 errors: Your origin certificate is invalid or Authenticated Origin Pulls misconfigured. Verify certificate paths and that SSL mode is Full (strict).

Site loads but some requests fail: Check that all subdomains used by your site are proxied through Cloudflare or excluded from origin pull verification.

Cannot SSH to server: If you locked yourself out with firewall rules, access your server through your hosting provider's console and review rules. Always keep SSH access separate from web traffic restrictions.

Cloudflare shows offline status: Your origin is rejecting Cloudflare's health checks. Verify firewall rules include all Cloudflare IP ranges and Authenticated Origin Pulls is properly configured.

Certificate warnings on origin: Ensure you're using a Cloudflare Origin Certificate, not a standard CA certificate. Set Cloudflare SSL mode to Full (strict), not Flexible or Full only.

Ongoing Maintenance

  • Update Cloudflare IPs: Automate this check monthly
  • Monitor certificate expiration: Origin certificates last up to 15 years but check expiry dates annually
  • Review firewall logs: Weekly checks for bypass attempts
  • Audit DNS records: Quarterly review for new records that might expose origin
  • Test failover: Periodically disable Cloudflare proxy to ensure you can access origin directly when needed for maintenance

Conclusion

Private Origins configuration significantly hardens your infrastructure by ensuring all traffic flows through Cloudflare's security stack. The combination of Authenticated Origin Pulls, IP-restricted firewall rules, and proper SSL configuration makes direct-to-origin attacks extremely difficult.

Implementation takes an hour or two but provides ongoing protection against reconnaissance, DDoS bypass attempts, and direct exploitation of origin vulnerabilities. Schedule regular maintenance checks and automate IP list updates to maintain your security posture over time.

The effort is worthwhile for any production site where availability and security matter—especially high-traffic sites, those handling sensitive data, or targets of frequent attacks.

FAQ

Does this work on free Cloudflare plans?

Yes. Origin Certificates and Authenticated Origin Pulls are available on all plans including Free.

Will this break my existing SSL certificate?

You'll replace your existing certificate with a Cloudflare Origin Certificate. Visitors see Cloudflare's certificate, not yours, so this is transparent to end users.

Can attackers still DDoS my origin?

If they discover your IP before you implement these protections, they can DDoS it. Change your origin IP after setup for maximum protection.

What about WebSocket connections?

WebSockets proxied through Cloudflare will also require Authenticated Origin Pulls. Ensure your WebSocket endpoint uses the same SSL configuration.

Do I need to do this for every subdomain?

Firewall rules protect the entire server. Authenticated Origin Pulls apply per certificate—use a wildcard Origin Certificate to cover all subdomains.

Can I use this with a load balancer?

Yes. Apply these configurations to each origin server behind your load balancer. The load balancer itself should also restrict access to Cloudflare IPs if it has a public IP.