How to obtain free SSL certificates with Letsencrypt, Certbot, and Cloudflare
Abstract
Let’s say you host some services by yourself. You should make your services secure right?
Maybe you want your users to feel safe while using your apps? Maybe you just want to see a little green padlock next to your URLs?
Either way, this guide will show you step by step how to obtain free SSL certs for your webserver using Letsencrypt, Certbot, and Cloudflare.
Why
Using this method, you can have valid ssl certs to use on your https websites or apps.
They will be signed by letsencrypt
and should be auto renewed with certbot
No ports are required to be opened for this since it uses api to modify DNS records. This allows for valid ssl certs to be used by any site, including internal only ones.
Prerequisites
This guide assumes you have a few things set up already.
- A running webserver of any kind
- Root or Sudo access to the webserver
- A Cloudflare account
- A domain name
- Your domains DNS records in Cloudflare
Installing
We will follow this guide to install certbot with snap (for some reason…) Choose the correct webserver and distro. All steps are outlined below. You must follow these steps on the machine with your web server.
Installing Certbot, for NGINX on Debian 10
Install Snap
Install snap if not installed already. If snap is installed already, you can skip this section. These instructions are for Debian based distros.
Update apt
sudo apt update
sudo apt install snapd
Install Core
sudo snap install core
Test the install
sudo snap install hello-world
hello-world
Install Certbot
Since we need to use the snap version, make sure there are no other versions of certbot installed
sudo apt remove certbot
Install certbot via snap
sudo snap install --classic certbot
Execute the following instruction on the command line on the machine to ensure that the certbot command can be run.
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Confirm plugin containment level
Run this command on the command line on the machine to acknowledge that the installed plugin will have the same classic containment as the Certbot snap.
sudo snap set certbot trust-plugin-with-root=ok
Install the correct plugin for dns challenges. We will use cloudflares
sudo snap install certbot-dns-cloudflare
Setting up Cloudflare credentials
The cloudflare dns challenge plugin needs credentials to be able to insert a TXT DNS record via cloudflare API.
Generate a Cloudflare token
You need a token from cloudflare to be able to access their api. From the plugin page:
Use of this plugin requires a configuration file containing Cloudflare API credentials, obtained from your Cloudflare dashboard.
Previously, Cloudflare’s “Global API Key” was used for authentication, however this key can access the entire Cloudflare API for all domains in your account, meaning it could cause a lot of damage if leaked.
Cloudflare’s newer API Tokens can be restricted to specific domains and operations, and are therefore now the recommended authentication option.
The Token needed by Certbot requires Zone:DNS:Edit permissions for only the zones you need certificates for.
Using Cloudflare Tokens also requires at least version 2.3.1 of the cloudflare python module. If the version that automatically installed with this plugin is older than that, and you can’t upgrade it on your system, you’ll have to stick to the Global key.
- Go to your Cloudflare Dashboard
- Navigate to My Profile -> API Tokens -> Create Token
- Use the
Edit Zone DNS
template - Edit the details to your liking. Just be sure that DNS Zone can be edited for the correct domain
- Continue to summary -> Create token
- Copy your token to paste it into a config file later. The token will not be shown again if you navigate away from the page.
Create the config file
Find a suitable place to hold the token config file and use an editor to make a file to paste it in. You could use roots home folder.
sudo nano /root/cloudflare.ini
Paste the token in. Use this template
# Cloudflare API token used by Certbot
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567
If you are unable to use a token and must use the Global API Key, use this
# Cloudflare API credentials used by Certbot
dns_cloudflare_email = [email protected]
dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234
Run Certbot
Now that certbot, the Cloudflare DNS plugin, and the config file is in place, we run certbot to get an ssl cert
To acquire a certificate for example.com
certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/cloudflare.ini \
-d example.com
To acquire a single certificate for both example.com and www.example.com
certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/cloudflare.ini \
-d example.com \
-d www.example.com
To acquire a wildcard certificate for example.com
certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/cloudflare.ini \
-d "*.example.com"
To acquire a certificate for example.com, waiting 60 seconds for DNS propagation
certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/cloudflare.ini \
--dns-cloudflare-propagation-seconds 60 \
-d example.com
Once you have ran a command from above, test that certbot will automatically renew your cert.
sudo certbot renew --dry-run
Add the certificate to NGINX
We must use the new certificate on our web-server. This is using NGINX
Make an include file (Optional)
It would be easiest to make an includes file so we don’t need to retype things all the time.
Make a directory to hold our include files
sudo mkdir -p /etc/nginx/includes
Make a config file for our ssl
sudo nano /etc/nginx/includes/ssl-cert.conf
Add the following lines into it. This assumes you had a wildcard cert.
Change
ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem;
Include your cert in NGINX servers
Now that we have our cert, we include it in any virtual servers in NGINX
With includes file
In your virtual server, use the include directive to use the conf file we created above. Add this to your server:
include /etc/nginx/includes/ssl-cert.conf;
Without includes file
If you didn’t make an includes file, just be sure to include the right NGINX commands. Be sure to change <domain>
to the domain you got a certificate for.
ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem;