Introduction
Cloudflare provides a powerful edge network that can enhance both the security and performance of your website. However, to protect traffic all the way to your server—not just between the visitor and Cloudflare—it’s essential to use a valid SSL/TLS certificate on your origin. Cloudflare Origin CA certificates fill this gap by encrypting data between Cloudflare and your Apache server. In this guide, we’ll walk through generating a Cloudflare Origin CA certificate, installing it on Apache, and ensuring your site benefits from full end-to-end encryption.
Prerequisites
You should already have your Apache server configured and serving web pages for your domain. While the examples below reference Ubuntu, the instructions work on most distributions (Debian, CentOS, Rocky Linux, etc.) with Apache installed.
1. Generate Certificate and Private Key in Cloudflare
Log in to the Cloudflare Dashboard and select your domain. Navigate to the SSL/TLS page from the top navigation.
On the left sidebar, click SSL/TLS, Origin Server and then click Create Certificate.

In Origin Certificate Installation, set Private Key Type to RSA with 15 years validity (the default). Then click Create.

In the next screen, the Key format should be PEM (default), and for Web Server for Installation, select Apache httpd (though the PEM file works for most web servers).
Important: Copy your Origin Certificate and Private Key to a temporary text file on your local machine. You’ll need them shortly!
When finished, click OK to close.

2. Copy Certificate and Key to Your Server
On your server, create a new directory where your certificate and key will reside. Make sure it’s somewhere secure and readable by Apache (usually root-owned with 600 or 640 permissions).
sudo mkdir -p /etc/cloudflare/
Using nano
(or your preferred editor), create a new file /etc/cloudflare/example.com.pem
(replace example.com with your domain).
sudo nano /etc/cloudflare/example.com.pem
Paste in your Origin Certificate from Cloudflare. Save and exit (press CTRL+X
, then Y
, then ENTER
).
Create another file /etc/cloudflare/example.com.key
and paste in your Private Key. Save and exit.
sudo nano /etc/cloudflare/example.com.key
3. Configure Apache
First, make sure Apache’s SSL module is enabled:
sudo a2enmod ssl
Enable mod_rewrite as well if you need to force HTTPS redirects:
sudo a2enmod rewrite
Next, open the Apache configuration file for your domain. Typically, this is located in /etc/apache2/sites-available/
on Ubuntu/Debian systems.
sudo nano /etc/apache2/sites-available/example.com.conf
Ensure you have a <VirtualHost *:80>
block serving HTTP. Underneath it (or in a separate file), add a new <VirtualHost *:443>
block to serve HTTPS. Below is an example that also forces HTTPS via rewrite rules:
<VirtualHost *:80>
ServerAdmin [email protected]
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public_html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =example.com [OR]
RewriteCond %{SERVER_NAME} =www.example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<VirtualHost *:443>
ServerAdmin [email protected]
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public_html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine on
# SSL Certificate from Cloudflare
SSLCertificateFile /etc/cloudflare/example.com.pem
# Private Key from Cloudflare
SSLCertificateKeyFile /etc/cloudflare/example.com.key
</VirtualHost>
Save and exit (CTRL+X
, Y
, ENTER
).
Check Apache configuration for syntax errors:
sudo apachectl configtest
If you see Syntax OK, restart or reload Apache:
sudo systemctl restart apache2
Note that it can take a few minutes for Cloudflare to deploy certificates globally. Once deployed, you’ll be able to access your domain via HTTPS using Cloudflare’s edge certificates.
Important: In the Cloudflare Dashboard, under SSL/TLS > Overview, make sure to set the SSL/TLS encryption mode to Full (strict). This ensures end-to-end encryption between the visitor, Cloudflare, and your origin server using the certificate you just installed.
Getting the Real Client IP Address from Cloudflare
When using Cloudflare, your Apache logs will show Cloudflare’s proxy IP rather than the real user’s IP. To preserve the client’s actual IP address, you can configure Apache to use the CF-Connecting-IP
header or mod_remoteip.
See our guide for details:
That’s it! You have successfully set up Cloudflare Origin CA with Apache. If you need to update any of your certificates, simply repeat the steps in the Cloudflare dashboard and replace the cert/key files on your server.
Let me know if this helped. Follow me on Twitter, Facebook and YouTube, or 🍊 buy me a smoothie.
Excellent guide Clear, concise and specific. Thank you.👍👌🤩
a2enmod rewrite
systemctl restart apache2
ill echo Seb’s feelings – been killing myself trying to get this done and this was so painless. I was in a rabbit hole of atrocious cloudflare documentation. Where’s the customer service? Link upon link within links – a never ending blackhole of links. I must have had 30 tabs open, by the end of it all I forgot what I was doing.
What really killed me was the link to a paid ssl service…really?
Thank for this!
I can finally stop beating my head against the brick wall over and over and over, THANK YOU! That was starting to hurt.
Hi! I followed your very clear and helpful instructions however I still get a 522 error. I’ve already configured ufw to allow CF servers through. Any advice would be greatly appreciated.
I completed the steps you outlined. But I am getting the below ERR_CERT_AUTHORITY_INVALID error for my site. What am I missing?
Your connection is not private
Attackers might be trying to steal your information (for example, passwords, messages, or credit cards). Learn more
NET::ERR_CERT_AUTHORITY_INVALID
Hi,
Great Tutorial (as always).
For a person with very limited technical understanding of Unix based VPS configurations, your step by step LEMP stack configuration for Ubuntu 20.04 droplet made the entire process a cakewalk for me and in the process taught many features/ aspects that i could not have learned even after watching many youtube tutorails/ reading blogs.
My heartfelt gratitude and sincere appreciation for the very comprehensive (& precise) posts. Keep it up.
Also, two requests
1) Post on Cloudflare configuration steps for Nginx
2) If you also cover wordpress then posts on wordpress migration from shared hosting to Digitalocean and troubleshooting etc.
Many thanks for the comment!
Thanks a lot for your work and support.
I have an additional question: the certificate between Cloudflare and my server is valid 15 years but the certificate between Cloudflare and a user browser is valid 1 year. What will happen when this year will gone? The certificate will be automatically renew or will I have to do someting to renew it?
Cloudflare should renew that for you automatically.
how can I test if it is working?
sudo tail /var/log/apache2/access.log -f
Très très très bien, trop facile ! Merci
(Very very very good, too easy !)
I have a problem. I’ve got handshake error, and i dont know where to check the error.
anyone know how to include the root origin cert? how do we use it when cloudflare already generated the normal certificate.
do we add it to the end of that file ? any help much appreciated
i’m looking for it. you found answer ?
AH00526: Syntax error on line 26 of /etc/apache2/sites-enabled/example.conf:
Invalid command ‘SSLEngine’, perhaps misspelled or defined by a module not included in the server configuration
Action ‘configtest’ failed.
Run
sudo a2enmod ssl
I get as far as the virtual host bit and when I type the command it opens nano and it is blank..anybody help or know why..
Thanks
i occured error 525 ssl handshake failed
i have open 433 port how can i resolve this!?
Hi, I ran into the same problem. I had to run “a2ensite xxx.conf” (the conf file you edited). It enables the VirtualHost, and also creates a conf file in the “sites-enabled” directory. After just that, boom, worked.
Thank you so much for helping sir
Great walkthrough. On the final step I was running into a “Invalid command ‘SSLEngine'” error, needed to run “sudo a2enmod ssl” to fix this.
Great, thanks for that.