Certificates from Let’s Encrypt using certbot on RHEL

Requirements:

  • Red Hat Enterprise Linux 9 (Red Hat Enterprise Linux release 9.3 (Plow))
  • Basic Linux Skills

Certificates are a pain. But they are a very necessary and vital piece to your security. Here’s how to make things a bit simpler.

Let’s Encrypt, certbot and ACME Protocol

Let’s Encrypt is a free, automated, and open certificate authority. Their root certs are present in all versions of browsers and they have a nice, free service for generating certificates. When you want an authority to issue a certificate for you, you should be able to prove you own the domain. That’s where certbot comes in, which is a command line tool which integrates with Let’s Encrypt’s ACME service to help you request, and then prove, that you own the domain. How do you prove you own a domain? By either proving you control a web server that a domain is pointing at or by updating the DNS in a unique way.

The HTTP challenge is interesting because it literally spins up a tiny web server with a file containing a key that is verified by Let’s Encrypt. However, this spins up the server on port 80 and of course, this communication is not encrypted. I’m not opening port 80 on my firewall to the outside world so I use the DNS challenge instead. When you use the DNS challenge, certbot will spit out a txt value which then requires you to go update your DNS with a TXT record with the value and then Let’s Encrypt checks it. You can do this manually, however there are plugins for further automation. If you host your domain at Cloudflare (or just use their proxy services), then you can use their APIs to interact with everything DNS, including the ability to edit DNS TXT records. There’s a certbot plugin for that – certbot-dns-cloudflare. There’s a bunch of other DNS plugins as well.

Install the Tools

First off, we are going to install the packages that we need. There are two ways to do so – bash or a nice Ansible task.

sudo dnf install certbot python3-certbot-dns-cloudflare -y
- name: Install essential packages
  ansible.builtin.dnf:
    name: "{{ item }}"
    state: present
  loop:
    - certbot
    - python3-certbot-dns-cloudflare

To access the Cloudflare API, you need to provide an API token. To generate a Cloudflare token, you will need to go to https://dash.cloudflare.com/profile/api-tokens. From the API Tokens section, click the Create Token button and configure the token using the API token templates, selecting the Edit zone DNS template. Once the token is generated, you will need to create a file on your host that contains the information.

sudo vi ~/.secrets/certbot/cloudflare.ini
dns_cloudflare_api_token = <thisisyourtoken>

Generate the Certs

We can now proceed with the command to generate the certificates using a DNS challenge which will be automatically handled using Cloudflare. Let’s take a look at the command.

certbot certonly --preferred-challenges dns-01 \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \
  -d test.yourdomain.com

When you execute this command, it runs through the ACME protocol and spits back the DNS TXT value, which the dns-cloudflare plugin then takes and creates a DNS TXT record, waits for the challenge to execute, then cleans up after itself. Once it’s completed, the certs and keys are generated and placed in your etc folder.

[snimmo@host1 ~]$ ls -l /etc/letsencrypt/live/test.yourdomain.com/
total 4
lrwxrwxrwx. 1 root root  39 Dec  8 14:46 cert.pem -> ../../archive/test.yourdomain.com/cert1.pem
lrwxrwxrwx. 1 root root  40 Dec  8 14:46 chain.pem -> ../../archive/test.yourdomain.com/chain1.pem
lrwxrwxrwx. 1 root root  44 Dec  8 14:46 fullchain.pem -> ../../archive/test.yourdomain.com/fullchain1.pem
lrwxrwxrwx. 1 root root  42 Dec  8 14:46 privkey.pem -> ../../archive/test.yourdomain.com/privkey1.pem
-rw-r--r--. 1 root root 692 Dec  8 14:46 README

Notice that the files are actually symlinks. This comes in handy if you are using them directly but becomes an issue with volumes and containers. More on this later.

Automate the Renewals

The renewal of the certs becomes easy as well. According to the docs.

The command to renew certbot is installed in one of the following locations:

  • /etc/crontab/
  • /etc/cron.*/*
  • systemctl list-timers

You can test the renewals using the following command.

sudo certbot renew --dry-run

Hopefully this makes your relationship with certificate management a bit more pleasant.