Cloudflare CDN cloud network

Connect VPS to Cloudflare: CDN + DDoS Protection

June 2026 · 7 min read

Using Cloudflare as a reverse proxy in front of your VPS is one of the most cost-effective ways to get enterprise-grade CDN, DDoS Protection, Web Application Firewall (WAF), and free SSL Certificates — without paying a dime. This article will walk you through setup from start to finish, step by step.

How Cloudflare Works with Your VPS

When you enable Cloudflare proxy (orange cloud icon), your domain's DNS points to Cloudflare's IP addresses instead of your VPS's real IP. All traffic flows through Cloudflare first, then gets forwarded to your VPS. The benefits are:

Note: Cloudflare Free Plan provides DDoS Protection, CDN, basic WAF, and free SSL for all sites. It's perfect for typical websites and APIs running on a VPS — no paid plan needed.

Step 1 — Sign Up and Add Your Domain to Cloudflare

  1. Go to dash.cloudflare.com and sign up for a free account
  2. Click "Add a Site" and enter your domain name (e.g., example.com)
  3. Select the Free plan and click Continue
  4. Cloudflare automatically scans your existing DNS records. Verify that the A record points to your VPS's IP address
  5. Copy the two Nameservers that Cloudflare assigns (e.g., ada.ns.cloudflare.com and bob.ns.cloudflare.com)
  6. Log into your domain Registrar and update the Nameservers to Cloudflare's
Time needed: Nameserver changes can take 5 minutes to 48 hours to propagate globally, but usually complete within 1–2 hours.

Step 2 — Configure DNS Records and Enable Proxy

After your Nameservers are transferred, go to the DNS tab in your Dashboard and review your records:

Warning: If your VPS runs a mail server, do not enable Proxy on the A record your MX record points to. Cloudflare Proxy only supports HTTP/HTTPS, not SMTP/IMAP/POP3.

Step 3 — Configure SSL/TLS Mode

Go to SSL/TLS → Overview and choose a mode that fits your setup:

Flexible SSL

Cloudflare connects to your browser via HTTPS but connects to your VPS via plain HTTP. Use this if your VPS doesn't have an SSL certificate yet. Good for initial testing.

Full SSL (Recommended)

Cloudflare connects to your VPS via HTTPS, but does not validate whether your certificate is valid. Your VPS must have an SSL certificate (self-signed is OK).

Full (Strict) — Most Secure

Like Full SSL, but Cloudflare verifies that your certificate is valid (Let's Encrypt or Cloudflare Origin Certificate). Strictest security option.

Recommendation: Use Full (Strict) with Cloudflare Origin Certificate. It's the most secure and never requires certificate renewal every 90 days.

Step 4 — Install Cloudflare Origin Certificate on Your VPS

An Origin Certificate is issued by Cloudflare specifically for your VPS, valid for up to 15 years, and works only when traffic flows through Cloudflare.

  1. In your Cloudflare Dashboard, go to SSL/TLS → Origin Server
  2. Click "Create Certificate"
  3. Select the hostnames you want (e.g., example.com and *.example.com)
  4. Choose certificate validity (recommended: 15 years to avoid renewal)
  5. Copy the Origin Certificate and Private Key and save them on your VPS

SSH into your VPS and create certificate files:

ssh root@YOUR_VPS_IP

# Create a directory for the certificate
mkdir -p /etc/ssl/cloudflare

# Save the Origin Certificate
nano /etc/ssl/cloudflare/cert.pem
# Paste the certificate from Cloudflare and press Ctrl+X, Y, Enter

# Save the Private Key
nano /etc/ssl/cloudflare/key.pem
# Paste the private key and press Ctrl+X, Y, Enter

# Restrict file permissions
chmod 600 /etc/ssl/cloudflare/key.pem
chmod 644 /etc/ssl/cloudflare/cert.pem

Configure Nginx to Use the Origin Certificate

nano /etc/nginx/sites-available/example.com
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;
    ssl_ciphers HIGH:!aNULL:!MD5;

    root /var/www/html;
    index index.php index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}
# Test the config
nginx -t

# Reload Nginx
systemctl reload nginx

Configure Apache to Use the Origin Certificate

nano /etc/apache2/sites-available/example.com-ssl.conf
<VirtualHost *:443>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/html

    SSLEngine on
    SSLCertificateFile    /etc/ssl/cloudflare/cert.pem
    SSLCertificateKeyFile /etc/ssl/cloudflare/key.pem

    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
</VirtualHost>
a2enmod ssl
a2ensite example.com-ssl
systemctl reload apache2

Step 5 — Configure Your Firewall to Accept Traffic Only from Cloudflare

To prevent attackers from accessing your VPS's real IP directly, block ports 80/443 to everyone except Cloudflare:

# Download Cloudflare IP ranges
curl -s https://www.cloudflare.com/ips-v4 -o /tmp/cf_ipv4.txt
curl -s https://www.cloudflare.com/ips-v6 -o /tmp/cf_ipv6.txt

# Remove old iptables rules for ports 80/443
iptables -D INPUT -p tcp --dport 80 -j ACCEPT 2>/dev/null
iptables -D INPUT -p tcp --dport 443 -j ACCEPT 2>/dev/null

# Allow only Cloudflare IPv4
while read ip; do
  iptables -I INPUT -p tcp --dport 80 -s "$ip" -j ACCEPT
  iptables -I INPUT -p tcp --dport 443 -s "$ip" -j ACCEPT
done < /tmp/cf_ipv4.txt

# Block all other IPs
iptables -A INPUT -p tcp --dport 80 -j DROP
iptables -A INPUT -p tcp --dport 443 -j DROP

# Save rules (Debian/Ubuntu)
apt-get install -y iptables-persistent
netfilter-persistent save
Warning: Make sure your SSH port (22 or custom) is still open before saving iptables rules. Otherwise, you will lock yourself out of the VPS.

Step 6 — Configure WAF and Security Rules

Go to Security → WAF in your Cloudflare Dashboard:

Enable Managed Rules (Free Plan)

Configure Security Level

Go to Security → Settings and adjust your Security Level:

Step 7 — Configure Caching for Static Assets

Go to Caching → Configuration:

Create a Page Rule to cache all static files:

  1. Go to Rules → Page Rules and click "Create Page Rule"
  2. URL pattern: example.com/static/*
  3. Setting: Cache Level → Cache Everything
  4. Edge Cache TTL: 1 month

Step 8 — Configure Always Use HTTPS and HSTS

In your Cloudflare Dashboard, go to SSL/TLS → Edge Certificates:

Warning: Enabling HSTS preload makes it very difficult to remove later. Make sure your website supports HTTPS 100% before enabling HSTS.

Verify Your Configuration is Working Correctly

After setup is complete, test with these commands:

# Check that the response header contains "cf-ray" from Cloudflare
curl -sI https://example.com | grep -E "cf-ray|server|x-cache"

# Check the SSL certificate issuer
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -issuer -dates

# Check that HTTP redirects to HTTPS
curl -sI http://example.com | grep location

You should see the cf-ray: header in the response and the certificate issuer should be Cloudflare Inc ECC CA-3 or CloudFlare Origin CA.

Common Issues & Troubleshooting

Error 521 — Web server is down

Cloudflare cannot connect to your VPS. Check:

Error 525 — SSL Handshake Failed

Your VPS certificate has an issue. Check:

Redirect Loop (ERR_TOO_MANY_REDIRECTS)

This occurs when SSL Mode is Flexible but your VPS also redirects HTTP to HTTPS. Fix by changing SSL Mode to Full or disabling the HTTP→HTTPS redirect on your VPS.


Complete Setup Summary

Setting up Cloudflare in front of your VPS involves these key steps:

  1. Sign up for Cloudflare and add your domain, then change your Registrar's Nameservers
  2. Configure DNS A records and enable Proxy (orange cloud) for your main domain
  3. Choose Full (Strict) SSL Mode for maximum security
  4. Create an Origin Certificate from Cloudflare and install it on Nginx/Apache
  5. Configure your firewall to accept ports 80/443 traffic only from Cloudflare IP ranges
  6. Enable WAF Managed Rules to protect against OWASP Top 10 attacks
  7. Set up caching for static assets to reduce load on your VPS
  8. Enable Always Use HTTPS and HSTS
Benefits Summary: After complete setup, your VPS automatically gets DDoS protection, your real IP stays hidden, SSL renewal is automatic, static content loads faster from edge nodes near users, and WAF filters malicious traffic before it reaches your VPS — all free on Cloudflare's Free Plan.

Verify Cloudflare is Working Correctly

# Check that the response header contains cf-ray from Cloudflare
curl -sI https://example.com | grep -i "cf-ray\|server\|x-cache"

# Check the SSL certificate issuer (should be Cloudflare)
echo | openssl s_client -connect example.com:443 2>/dev/null \
  | openssl x509 -noout -issuer -dates

# Check that HTTP redirects to HTTPS correctly
curl -sI http://example.com | grep -i location

# Check the IP that DNS resolves to (should be Cloudflare, not your VPS)
dig +short A example.com
Tip: If you see a header like cf-ray: xxxxxxxx-BKK and the issuer is E6 or Cloudflare Inc ECC CA-3, traffic is flowing through Cloudflare correctly.

Additional Common Troubleshooting Issues

Error 522 — Connection timed out

Unlike 521, this means Cloudflare can establish a TCP connection but doesn't receive a response in time — usually caused by a firewall blocking Cloudflare IPs.

# Check if Cloudflare IPs are blocked
iptables -L INPUT -n | grep -E "80|443"

# Check that Nginx is listening on port
ss -tlnp | grep -E "80|443"

# Download the latest Cloudflare IP ranges
curl -s https://www.cloudflare.com/ips-v4 | head

Cache Not Updating — Users See Old Content

Cloudflare caches static files at edge servers. You need to purge the cache when content changes.

# Purge all cache via Dashboard:
# Caching → Configuration → Purge Everything

# Or purge specific URLs via API
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/purge_cache" \
  -H "Authorization: Bearer API_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"files":["https://example.com/style.css"]}'

WebSocket Not Working Through Cloudflare

Cloudflare supports WebSocket, but you must enable it first.

# Enable in Dashboard:
# Network → WebSockets → On

# Verify your Nginx config supports WebSocket upgrade
location /ws/ {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

Visitor Real IP is Incorrect in Logs (Showing Only Cloudflare IP)

Configure Nginx to use the CF-Connecting-IP header instead.

# Add to nginx.conf http section
set_real_ip_from 103.21.244.0/22;   # Cloudflare IP ranges
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 173.245.48.0/20;
real_ip_header CF-Connecting-IP;

sudo nginx -t && sudo systemctl reload nginx

Frequently Asked Questions

Is Cloudflare Free Plan Enough for a Typical Website?

Yes. Free Plan provides unlimited DDoS protection, global CDN, basic WAF, free SSL, and basic analytics. Perfect for most websites. Features requiring paid upgrade include Advanced WAF Rules, Image Optimization, Real-time Analytics, and Priority Support.

Can Cloudflare See Our HTTPS Traffic?

Yes. Cloudflare acts as a man-in-the-middle that decrypts SSL at the edge, re-encrypts it, then forwards to your VPS (SSL Termination at Edge). Your request/response data flows through Cloudflare's hands, even with Full (Strict) mode. For true end-to-end encryption that Cloudflare cannot see, use Cloudflare Tunnel or don't use Cloudflare proxy.

Can We Use Cloudflare's Origin Certificate on Other Websites?

No. Cloudflare Origin Certificates only work when traffic flows through Cloudflare. If you access your VPS directly (bypassing Cloudflare), browsers will show a warning because this certificate is not trusted by standard browser CA stores.