I hope everyone familiar with Let’s Encrypt. It is a free, automated and open Certificate Authority widely used to create TLS certificate. While setting up this Website and Mastodon instance I realized that automated Let's Encrypt generation process changed drastically from last year. Both ghost-cli and mastodon setup is broken while setting up SSL with Let's Encrypt since I haven't opened HTTP port for NGINX in my Uncomplicated Firewall (UFW)

I noticed Certbot now officially supports snaps and moved away from distribution-specific packaging. Snap as a default packaging mechanism for Certbot, came as a surprise for me. Certbot snap now supports the x86_64, ARMv7, and ARMv8 architectures.

My domain DNS is hosted in Cloudflare and in this post, I am explaining how wildcard certificate generation using Let's Encrypt DNS method using cloudflare example.  This post is primarily addressing setup in Ubuntu 20.04, but apart from snap installation, remaining steps will be the same in all distributions. snapcraft website has detailed instructions on how to install snap

  1. Make sure snap is installed. Ubuntu 20.04 comes with snap. Make sure the package is up to date.
sudo apt update
sudo apt install snapd
sudo snap install core; sudo snap refresh core
Install and update snapd

2.   Remove any certbot packages in distribution. many automated scripts install old versions of certbot. Use your distribution specific command.

sudo apt-get remove certbot

3.   Install certbot via snap and acknowledge that the installed plugin will have the same classic containment as the Certbot snap.

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo snap set certbot trust-plugin-with-root=ok

4.Install the DNS plugin. This method is the same for many DNS api providers as Digital Ocean, Linode, Google etc, and not limited to Cloudflare. Read related documentation here

sudo snap install --beta certbot-dns-cloudflare

You can use the following command for other providers. replace <provider> with brand as per documentation. Certbot is actively pushing standardization to DNS verification process and there is an RFC2136 addressing this. I hope within few years, all providers will comply with the standard and we dont need to follow specific packaging and instructions for each provider. If you are interested follow this documentation for how it works.

sudo snap install --beta certbot-dns-<provider>

5.   Connect the DNS plugin snap to the Certbot snap. I am showing cloudflare example alone

sudo snap connect certbot:plugin certbot-dns-cloudflare

6.  Setup your DNS plugin credentials. The suggested method is to use a DNS Zone edit API key via Cloudflare Dashboard.   Previously, Cloudflare’s “Global API Key” was used for authentication. Now it is not needed. Now API Tokens can be restricted to specific domains and operations.  Create API Token -> Edit zone DNS (use the template) and give Zone:DNS:Edit permissions for only the zones you need certificates for. You can select specific zone / all domains from Zone Resources option based on your use case. Copy the API key.

Cloudflare API Token creation Screenshot

7.   On your non root user make a secret credentials file to store key

mkdir -p ~/.secrets/certbot/
nano ~/.secrets/certbot/cloudflare.ini 

8.   Paste your API key to cloudflare.ini file in following template  

# Cloudflare API token used by Certbot
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567
Example credential token file for certbot

9.    For key issuing with wildcard certificate type following command. If you need specific subdomain support instead of wildcard, replace * with a subdomain (such as www.)

certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \
  -d example.com \
  -d *.example.com
To acquire a single certificate for both example.com and *.example.com

The certificates will be stored in /etc/letsencrypt/live/example.com  location. You need to manually add it to your NGINX / other web server configuration.

10. Test automatic certificate renewal by running the following command. This will set up cron job or systemd timer that will renew your certificates automatically before they expire.

sudo certbot renew --dry-run

If you are running Cloudflare just as a fast DNS manager, Let's Encrypt Certificate will be visible on your website. If you are running it in proxied mode, You need to setup Full(Strict) as the SSL/TLS mode. The visible certificate on your website will be provided by Cloudflare, while Let's Encrypt Certificate secures the website to Cloudflare traffic.

There is more to write on SSL/TLS including how to set up an A+ ranking cert using Let's Encrypt in 2020. That is for another day.

* Cover Image by Paulanthony George, Published by CIS India,  Licensed under CC-BY 4.0 License