---
title: "How to Set Up End-to-End CloudFlare SSL Encryption"
description: "Securing connections to your server is always a good plan. Learn how to set up an end-to-end Cloudflare SSL encryption in this tutorial!"
canonical: "https://adamtheautomator.com/cloudflare-ssl/"
---

# How to Set Up End-to-End CloudFlare SSL Encryption

> Securing connections to your server is always a good plan. Learn how to set up an end-to-end Cloudflare SSL encryption in this tutorial!

Source: https://adamtheautomator.com/cloudflare-ssl/

---

ATA Learning

Tap to hide

[

ATA Learning

](/)

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Search for:  

*   [](https://twitter.com/adbertram)
*   [](https://github.com/Adam-the-Automator)
*   [](https://www.linkedin.com/company/adam-the-automator-llc)
*   [](/feed/)

![How to Set Up End-to-End CloudFlare SSL Encryption](https://adamtheautomator.com/wp-content/uploads/2021/07/How-to-Set-Up-End-to-End-SSL-Encryption-with-CloudFlare.jpg)

# How to Set Up End-to-End CloudFlare SSL Encryption

[![](https://secure.gravatar.com/avatar/f08b754bc0dce1c76685f6afa93185ecfb6f861fd14f993286e06bba69eaeb8b?s=192&d=mm&r=g)Adam Listek](https://adamtheautomator.com/author/alistek/)14 July 20219 min. read

Categories: [IT Ops](/category/it-ops/)

Tags:[CloudFlare](/tag/cloudflare/)

Table of Contents

*   [Prerequisites](#h-prerequisites)
*   [Setting up Cloudflare Universal SSL: Only the Beginning](#h-setting-up-cloudflare-universal-ssl-only-the-beginning)
*   [Configuring Full End-to-End SSL Encryption](#h-configuring-full-end-to-end-ssl-encryption)
*   [Setting up Full SSL/TLS Encryption with a Self-Signed Certificate](#h-setting-up-full-ssl-tls-encryption-with-a-self-signed-certificate)
*   [Generating a Self-Signed Certificate](#h-generating-a-self-signed-certificate)
*   [Configuring NGINX](#h-configuring-nginx)
*   [Generating Origin Certificates for Full (strict) SSL/TLS Encryption](#h-generating-origin-certificates-for-full-strict-ssl-tls-encryption)
*   [Enabling Full (strict) SSL/TLS Encryption with LetsEncrypt](#h-enabling-full-strict-ssl-tls-encryption-with-letsencrypt)
*   [Conclusion](#h-conclusion)

Setting up SSL for any website is a challenge. Site visitors, browsers, and search engines reward a properly [Secure Sockets Layer (SSL)](https://www.cloudflare.com/learning/ssl/what-is-ssl/) secured website. Previously, this process involved purchasing, installing, and configuring an [SSL certificate](https://www.cloudflare.com/learning/ssl/what-is-an-ssl-certificate/). But with [Cloudflare SSL](https://developers.cloudflare.com/ssl/get-started), you can complete the process of configuring SSL with only a few clicks!

In this article, you will learn how to configure your site with SSL encryption via Cloudflare. So work your way up to end-to-end encrypted SSL connections!

## Prerequisites

To follow along with this tutorial, there are a few prerequisites required below:

*   A Cloudflare account with an existing website and domain [pointed to the Cloudflare nameservers](https://developers.cloudflare.com/fundamentals/get-started/).
*   An Ubuntu Linux server with [NGINX](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/) installed and configured. _This tutorial demonstrates using Linux and NGINX, but the same general process works for [IIS](https://stackify.com/iis-web-server/) or [Apache](https://www.sumologic.com/blog/apache-web-server-introduction/)._

Related:[How to Host an Azure Static Website Backed by CloudFlare](https://adamtheautomator.com/azure-static-website/)

## Setting up Cloudflare Universal SSL: Only the Beginning

There are several ways you can configure an SSL using Cloudflare. Often, the quickest method is to go for [Universal SSL](https://developers.cloudflare.com/ssl/edge-certificates/universal-ssl). Why? With Universal SSL, instead of finding and purchasing an SSL certificate, Cloudflare provisions a certificate, then all the traffic sent through Cloudflare will use that certificate.

After enabling Universal SSL, Cloudflare presents a valid SSL certificate to both visitors and search engines. Cloudflare also does not require configuring the server or website to use that certificate—slick!

1\. Launch your web browser and log in to the [Cloudflare dashboard](https://dash.cloudflare.com/login).

2\. Navigate to your site from the account domain list, as shown below.

![Choose the site to change options for.](https://adamtheautomator.com/wp-content/uploads/2021/07/Untitled-2021-07-13T134641.849.png)

Choose the site to change options for.

3\. Now, click on **SSL/TLS** to view your site’s encryption options.

![The SSL/TLS Encryption mode page](https://adamtheautomator.com/wp-content/uploads/2021/07/not_secure.png)

The SSL/TLS Encryption mode page

4\. Choose the **Flexible** option to enable Universal SSL. Once selected, the change takes effect immediately. Your site now is encrypted between the browser and Cloudflare!

![Enabling Universal SSL on Cloudflare](https://adamtheautomator.com/wp-content/uploads/2021/07/flexi.png)

Enabling Universal SSL on Cloudflare

## Configuring Full End-to-End SSL Encryption

Although Universal SSL is a great option to start securing sites, it leaves the traffic between the server and Cloudflare unsecured. Thankfully, there are two encryption modes for encrypting traffic from Cloudflare to the server, Full and Full (strict) encryption each with mainly different certification installation requirements.

*   Full – Requires a certificate on the server, but this may be a self-signed certificate.
*   Full (strict) – The installed server-side certificate must be a valid certificate.

Let’s go over the difference between these encryptions and how to set them up.

### Setting up Full SSL/TLS Encryption with a Self-Signed Certificate

Unlike Universal SSL, Full SSL/TLS encryption requires your webserver to properly serve an SSL certificate to encrypt the traffic from the server to Cloudflare. There are many ways to accomplish this, but this tutorial demonstrates steps in a Linux server with NGINX.

#### Generating a Self-Signed Certificate

To encrypt the connection between Cloudflare and your origin server, you need an SSL certificate. Since Full SSL/TLS encryption mode does not require the certificate to be fully trusted, you can use a self-signed certificate to get running quickly.

[1\. Secure Shell (SSH)](https://adamtheautomator.com/ssh-command-in-linux/) into your Linux webserver.

2\. Change (`cd`) to the standard Ubuntu SSL directory (`/etc/ssl`) by running the command below. `cd /etc/ssl`

```bash
cd /etc/ssl
```

![Navigating to the /etc/ssl directory.](https://adamtheautomator.com/wp-content/uploads/2021/07/root_2.png)

Navigating to the `/etc/ssl` directory

3\. Now, generate both the public and private keys for your site with the `openssl` command. To do so, run the `openssl` command below.

This command accomplishes a few things:

*   Requests (`req`) an X.509 certificate provided by the `-x509` parameter.
*   When referenced by NGINX, allows NGINX to read the certificate on startup using the `-nodes` parameter.
*   Specifies the number of `days`, the certificate is valid.
*   Creates a new public and private key with `-newkey` with via 2048-bit RSA encryption (`rsa:2048`).
*   Saves the private key to `/etc/ssl/private/nginx-selfsigned.key` with the `-keyout` parameter.
*   Saves the public key to `/etc/ssl/certs/nginx-selfsigned.crt` using the `-out` parameter.

```bash
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
```

Related:[How To Set up OpenSSL on Windows 10 (PowerShell)](https://adamtheautomator.com/openssl-windows-10/)

> _If `openssl` returns a benign error of `Can't load /root/.rnd into RNG`, you’ll need to comment out the `#RANDFILE = $ENV::HOME/.rnd` line in `/etc/ssl/openssl.cnf`. All modern versions of `openssl` fall back to using the system `/dev/urandom` device for random entropy data and do not require a specific file for seeding._

4\. After successfully running the command, openssl will prompt you for some information. Below you’ll find all values provided for this tutorial.

*   **Country Name:** `US`
*   **State or Province Name:** `Illinois`
*   **Locality Name:** `Bloomington`
*   **Organizational Name:** `Test Company, LLC`
*   **Organizational Unit Name:** _<blank>_
*   **Common Name:** `test.adamlistek.me`
*   **Email Address:** `adam.listek@adamtheautomator.com`

![Generating a self-signed certificate](https://adamtheautomator.com/wp-content/uploads/2021/07/rsa.png)

Generating a self-signed certificate

5\. Lastly, verify that the certificate exists using the `test` command. If the `test` command returns (`echo $?`) `0`, then the file exists as expected. You can see in the following screenshot that each command returned a **0** value.

```bash
test -f /etc/ssl/private/nginx-selfsigned.key; echo $?
 test -f /etc/ssl/certs/nginx-selfsigned.crt; echo $?
```

![Verifying that the certificate files exist](https://adamtheautomator.com/wp-content/uploads/2021/07/zero.png)

Verifying that the certificate files exist

#### Configuring NGINX

Now that the certificate has been generated and stored in the `/etc/ssl/certs` and `/etc/ssl/private` key locations, NGINX must be configured to apply the certificate and serve the site content.

NGINX site configurations are defined in `server` blocks that are typically contained in virtual host files. In the example below, the basic site configuration is stored in the `test.adamlistek.me.conf` file and included in the main `nginx.conf` file.

1\. First, create a new virtual host file with the name of your choice, but for this example, name it `test.adamlistek.me.conf` under the `/etc/nginx/vhosts.d` directory. Then copy the content below to the virtual host file and save it.

> _Replace the `test.adamlistek.me` domain name with your own, as this is just for demonstration purposes. And if the `/etc/nginx/vhosts.d`_ _location does not exist, create the directory by running `mkdir /etc/nginx/vhosts.d`._

```bash
server {
   # Listen on port 80 for IPv4 and IPv6
   listen 80;
   listen [::]:80;
 server_name test.adamlistek.me;
 # Perform a 301 redirect with any parameters to the SSL server block below
   return 301 https://test.adamlistek.me$request_uri;
 }
 server {
   # Listen on port 443 for IPv4 and IPv6 with HTTP2 enabled (requires SSL)
   listen 443 ssl http2;
   listen [::]:443 ssl http2;
 server_name test.adamlistek.me;
 # The location of the public and private certificate
   ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
   ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
 # The location of the web files to load, this is the default NGINX location
   root /usr/share/nginx/html;
 # The default file to serve on a root domain request
   index index.html;
 }
```

2\. Verify that your primary NGINX configuration file, `/etc/nginx/nginx.conf` contains the necessary `include` line within the `http` block, located at the end of the block.

```powershell
# Server configurations go here
 …
 http {
     # Additional configurations go here
     …
     # Include Virtual Hosts
     include /etc/nginx/vhosts.d/*.conf;
 }
```

3\. Restart NGINX with the following command if you’re on [systemd](https://systemd.io/), which is a modern system and service manager for Linux.

```javascript
service nginx restart
```

4\. Back to Cloudflare, verify that the self-signed certificate is working. To do that, disable the “orange-cloud” for the **DNS** record under **Proxy status,** as shown below. Disabling the “orange-cloud” option bypasses Cloudflare and serves requests directly from the webserver.

![Disabling Cloudflare proxying via Proxy Status.](https://adamtheautomator.com/wp-content/uploads/2021/07/Untitled-2021-07-13T135904.565.png)

Disabling Cloudflare proxying via Proxy Status.

5\. Ensure that the site is returning the newly created self-signed certificate by navigating to the website in your web browser. Doing so will result in a warning page, shown below.

![Displaying the self-signed certificate error.](https://adamtheautomator.com/wp-content/uploads/2021/07/Untitled-2021-07-13T140005.706.png)

Displaying the self-signed certificate error.

6\. Finally, enable Full TLS/SSL encryption on Cloudflare. To do that, re-enable the “orange-cloud” Cloudflare Proxy Status on the DNS record that you previously disabled. Then navigate to the **SSL/TLS** tab and click the **Full** radio button shown below.

![Enabling Full SSL/TLS encryption on Cloudflare.](https://adamtheautomator.com/wp-content/uploads/2021/07/full.png)

Enabling Full SSL/TLS encryption on Cloudflare.

### Generating Origin Certificates for Full (strict) SSL/TLS Encryption

The Full encryption mode does not guarantee that the certificate presented by the web server has an actual valid certificate chain. So instead, go with non-strict encryption, and Cloudflare will accept any certificate presented by the server.

Cloudflare offers the ability to generate a free TLS certificate to secure your origin server connection. But there are two downsides to using a Cloudflare-provided origin certificate. One is that you need to generate and install the certificate manually. The second is the certificate appears like a self-signed certificate that any browser wouldn’t trust other than Cloudflare.

> _It’s possible to automate certificate generation using the [Origin CA Create Certificate API](https://developers.cloudflare.com/api/#origin-ca-create-certificate) endpoint, but that is beyond the scope of this tutorial._

1\. Navigate to the Origin Server by going to the **SSL/TLS** tab —> **Original Server**, as you see below, and click the **Create Certificate** button.

![Navigating to the Origin Server page.](https://adamtheautomator.com/wp-content/uploads/2021/07/create_cert.png)

Navigating to the Origin Server page.

2\. As you can see below, the default options are already set to generate a wildcard certificate for the domain with 15 years of validity—sweet! So leave the default options and generate the certificate by clicking on the **Create** button at the lower-right corner of the page.

> _A wildcard certificate, shown as `*.domain.com`, means that any subdomain will also be covered by this certificate including [www](http://www)._

![Creating a Cloudflare-provided origin server certificate.](https://adamtheautomator.com/wp-content/uploads/2021/07/create_orig_cert.png)

Creating a Cloudflare-provided origin server certificate.

3\. Add the newly created certificate to your Linux system by saving the private and public keys first with the [GNU nano](https://www.howtogeek.com/howto/42980/the-beginners-guide-to-nano-the-linux-command-line-text-editor/) text editor. Since there are two keys to save, you’ll need to save the key files one at a time.

> _Make sure to save the Private Key as it’s only available by the time you generated an Original Certificate. If you accidentally lose this key, revoke the certificate and re-issue a new certificate._

Open a terminal, then create and open the public key file (`nginx-test.adamlistek.me.crt`) in nano by running the first command below.

Next, go back to Cloudflare and copy the **Origin Certificate** key (public key) by clicking on the **Click to copy** option, as shown below. Then paste (Ctrl+U) the public key you copied to the public key file opened in nano. Save the changes (Ctrl+O) and exit (Ctrl+X) from nano.

After saving the public key file, repeat the same process from creating the key file, copying the key from Cloudfare, and saving it on the key file. But this time you’re creating the private key file (`nginx-test.adamlistek.me.key`).

```bash
# The public key, under the Origin Certificiate section
 nano /etc/ssl/certs/nginx-test.adamlistek.me.crt
# The private key, under the section of the same name
 nano /etc/ssl/private/nginx-test.adamlistek.me.key
```

![Copying the public/private certificate key information.](https://adamtheautomator.com/wp-content/uploads/2021/07/cert_mod.png)

Copying the public/private certificate key information.

4\. Now you’ve created the public and private keys, point NGINX to the location of the certificates. Do so by modifying the `test.adamlistek.me.conf` configuration file with the below lines, modified to support your domain.

```powershell
 ssl_certificate /etc/ssl/certs/nginx-test.adamlistek.me.crt;
 ssl_certificate_key /etc/ssl/private/nginx-test.adamlistek.me.key;
```

5\. To apply the new certificates, restart NGINX with the following command.

```bash
service nginx restart
```

6\. Now back to the **SSL/TLS** tab in Cloudflare, update the SSL/TLS encryption mode by clicking on **Full (strict)**, as you see below.

![Setting the Encryption mode to Full (strict).](https://adamtheautomator.com/wp-content/uploads/2021/07/full_strict.png)

Setting the Encryption mode to Full (strict).

### Enabling Full (strict) SSL/TLS Encryption with LetsEncrypt

The biggest downside with using a Cloudflare origin certificate is that it’s only Cloudflare-trusted. Suppose you need a fully browser-trusted certificate, either as a fallback or for further control. In that case, LetsEncrypt offers the ability to generate a proper certificate.

Although you can use any valid certificate, LetsEncrypt is a common choice to generate a valid certificate. There are multiple LetsEncrypt clients available, but this tutorial demonstrates the [acme.sh](https://github.com/acmesh-official/acme.sh) client.

Since you’re already on Cloudflare, one of the best methods for DNS provisioning with LetsEncrypt is via the DNS option.

1\. First, open your terminal and install [acme.sh](http://acme.sh) via the `curl` command.

```bash
curl https://get.acme.sh | sh
```

![Installing the acme.sh client.](https://adamtheautomator.com/wp-content/uploads/2021/07/acme.png)

Installing the [acme.sh](https://github.com/acmesh-official/acme.sh) client.

2\. Next is to create or modify the `account.conf` file located in the installation directory to add the saved Cloudflare API keys. These keys can be found in the [Profile —> API tokens](https://dash.cloudflare.com/profile/api-tokens) section of the Cloudflare dashboard.

Although you can create a specific permission-limited token, for the purposes of this tutorial, apply the Global API Key instead, as shown below.

```bash
SAVED_CF_Key='cloudflareglobalapikey'
 SAVED_CF_Email='adam.listek@adamtheautomator.com'
```

3\. Generate the certificate via the following command. Notice the command below tells `acme.sh` client to use Cloudflare (`dns_cf`) to verify (`--dns`) ownership of the certificate. Then sets the waiting time (`--dnsslep`) to 20 seconds before issuing (`--issue`) the certificate to (`-d`) the domain (`test.adamlistek.me`).

When the command completes, below, you’ll see the paths where you can locate your certificate, certificate key, intermediate CA certificate, and full chain certificates.

```bash
acme.sh --issue --dns dns_cf --dnssleep 20 -d test.adamlistek.me
```

![Generating the LetsEncrypt certificate.](https://adamtheautomator.com/wp-content/uploads/2021/07/issued_mod.png)

Generating the LetsEncrypt certificate.

4\. Like before, modify the NGINX site configuration to change the location of the `ssl_certificate` and `ssl_certificate_key`. Make sure to replace `/home/user` with the location of where your [acme.sh](http://acme.sh) installation is.

```bash
ssl_certificate /home/user/.acme.sh/test.adamlistek.me/test.adamlistek.me.csr;
 ssl_certificate_key /home/user/.acme.sh/test.adamlistek.me/test.adamlistek.me.key;
```

5\. Apply the new configuration by restarting NGINX with the following command.

```bash
service nginx restart
```

6\. Finally, update your Cloudflare SSL/TLS encryption mode by going to **SSL/TLS** tab, then click on **Full (strict)**.

![Setting the Encryption mode to Full (strict).](https://adamtheautomator.com/wp-content/uploads/2021/07/full_strict-1.png)

Setting the Encryption mode to Full (strict).

## Conclusion

Throughout this tutorial, you’ve learned how to secure your site with the various Cloudflare provided SSL/TLS options. Adding LetsEncrypt to your Cloudflare SSL configuration adds a flexible and user-managed origin certificate option as well!

With the knowledge of various options to secure the connection to the site visitor, will you work way up to a fully secure connection to your server with Cloudflare SSL?

Share this article

[Share on X](https://twitter.com/intent/tweet?url=https%3A%2F%2Fadamtheautomator.com%2Fcloudflare-ssl%2F&text=How%20to%20Set%20Up%20End-to-End%20CloudFlare%20SSL%20Encryption)[Share on Facebook](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fadamtheautomator.com%2Fcloudflare-ssl%2F)[Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fadamtheautomator.com%2Fcloudflare-ssl%2F)

## Related Posts

![](https://adamtheautomator.com/wp-content/uploads/2022/03/Tapping-Cloudflare-Load-Balancing-to-Route-Server-Traffic.jpg)

### [Cloudflare Load Balancing to Route Server Traffic (Step by Step)](/cloudflare-load-balancing/)

Learn how to configure Cloudflare’s load balancing and say goodbye to applications and system outrages due to traffic spikes in this step-by-step tutorial!

![](https://adamtheautomator.com/wp-content/uploads/2026/07/featured_image-4.png)

### [Migrate from EWS to Microsoft Graph API](/migrate-ews-microsoft-graph-api/)

Move EWS mailbox automation to Microsoft Graph with a practical inventory, permissions, PowerShell SDK, and cutover validation checklist.

![](https://adamtheautomator.com/wp-content/uploads/2026/06/featured_image-21.png)

### [Automate SOC 2 Compliance with PowerShell](/automate-soc-2-compliance-powershell/)

A comprehensive walkthrough on using PowerShell and Azure Policy as Code to automate evidence collection and enforce SOC 2 compliance controls across enterprise cloud environments.

## Categories

*   [IT Ops](/category/it-ops/)
*   [Cloud](/category/cloud/)
*   [DevOps](/category/devops/)
*   [Home Ops](/category/home-ops/)
*   [Information Security](/category/infosec/)
*   [Software Development](/category/software-development/)

## Site

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Copyright 2026© ATA Learning | [Privacy Policy](/privacy/)
