Automated Wildcard Certificate with Certbot and DNS

Certbot is a package available on many Linux distributions that simplifies the registration and management of Let’s Encrypt certificates. This post covers the setup of automated certificate renewal for wildcard domains using DNS challenges.

Prerequisites

This guide was tested on Ubuntu 26.04 Server. It should work on any Debian based distribution.

You need sudo or root access to install packages and configure cron jobs. The instructions work on most Linux distributions that include a certbot package. You must have control over DNS records for your domain to complete the DNS challenge process.

Install Certbot

Certbot is a small package. While some prefer to dockerise certificate management, the package is lightweight enough that running it directly is simpler than containerization. Install certbot with your package manager:

sudo apt install certbot -y

Once installed, generate a certificate request for your domain. Replace the domain name and email address with your own values. The asterisk prefix indicates a wildcard certificate:

sudo /usr/bin/certbot certonly --manual \
  --preferred-challenges=dns \
  --email=<your email address> \
  --server https://acme-v02.api.letsencrypt.org/directory \
  --agree-tos -d *.<your domain>

On first run, certbot asks whether to share your email address with the Electronic Frontier Foundation. You can decline. For wildcard certificates, you must agree to have your IP address logged. Certbot then presents a DNS challenge:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for *.<your domain>
-----------------------------------------------
Please deploy a DNS TXT record under the name:

_acme-challenge.<your domain>.

with the following value:

FQ3bQIiaJGCNSr2blahblahblahxWcfH1wcPaAo

Before continuing, verify the TXT record has been deployed. Depending on the DNS
provider, this may take some time, from a few seconds to multiple minutes. You can
check if it has finished deploying with aid of online tools, such as the Google
Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.<your domain>.
Look for one or more bolded line(s) below the line ';ANSWER'. It should show the
value(s) you've just added.
------------------------------------------------
Press Enter to Continue

Complete the DNS Challenge

Create a DNS TXT record with the name and value provided by certbot. Use your DNS provider’s management interface to add the record. Wait several minutes for DNS propagation before pressing Enter. Certbot verifies the TXT record to confirm domain ownership, then downloads the certificate:

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/<your domain>/fullchain.pem
Key is saved at: /etc/letsencrypt/live/<your domain>/privkey.pem
This certificate expires on 2023-12-24.
These files will be updated when the certificate renews.

Certbot creates a folder structure in /etc/letsencrypt/live where domain certificates are stored and maintained. The TXT record can be deleted after successful verification.

Test Certificate Renewal

Certbot checks whether any certificate is within a few weeks of expiration and renews it if necessary. Otherwise it does nothing. This behavior allows safe daily execution without overwhelming the Let’s Encrypt service:

sudo certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/<your domain>.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Certificate not yet due for renewal

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The following certificates are not due for renewal yet:
  /etc/letsencrypt/live/<your domain>/fullchain.pem expires on 2023-12-24 (skipped)
No renewals were attempted.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Repeat the certificate generation process for each domain requiring a certificate.

Automate Renewal Checks

Add certbot to cron to check for certificate renewals automatically. Certbot checks all configured domains by default:

sudo crontab -e

Add a line to run certbot weekly at 1 AM on Tuesday:

0 1 * * 2 /usr/bin/certbot renew

Optional: Distribute Certificates to Services

Many applications can reference certificates directly from /etc/letsencrypt/live but will not automatically reload them. Some services must be restarted to read updated certificates. The certificate format and location requirements vary by application.

For certificates on remote hosts, key-based SSH authentication allows automated copying without manual intervention. The following example script performs several certificate distribution tasks.

Create a directory for the script:

sudo mkdir -p /opt/sslupdate/

Create the script file:

sudo nano /opt/sslupdate/sslupdate.sh

Add the following content, adjusting paths and hostnames for your environment:

#!/bin/bash
# Remove the readme file
rm /etc/letsencrypt/live/README
# Create PEM certificates for each domain type
for domain in $(ls /etc/letsencrypt/live/); do
  cd /etc/letsencrypt/live/
  cat ./$domain/privkey.pem ./$domain/cert.pem > ./$domain/combined.pem
  done
# Copy certificates to a windows share if mounted
if [[ $(findmnt -m "/mnt/certificates") ]]; then
  echo "Cert share mounted"
  cp -LRv /etc/letsencrypt/live/* /mnt/certificates/
  else echo "Certificates share not mounted"
  fi
# Send certificates to a linux system over ssh
  # Update online hosting services
  scp /etc/letsencrypt/live/<your domain>/fullchain.pem \
  root@domainname.com:/usr/local/ispconfig/interface/ssl/ispserver.crt
  scp /etc/letsencrypt/live/<your domain>/privkey.pem \
  root@<your server>:/usr/local/ispconfig/interface/ssl/ispserver.key
# Restart services that need to re-read certificate updates
  # Example: Restart lighttpd which hosts pihole on this server
  #systemctl restart lighttpd.service
# Send a Discord notification
  #Example: /opt/discord/discord.sh "server40" "Certbot processed a renewal, please test it."

This script checks for a mounted share where certificates are stored, creates combined PEM files for applications that require them, copies certificates to remote systems via SCP, restarts services, and sends notifications. The script only executes when certbot successfully renews a certificate.

Configure Automatic Post-Renewal Actions

Certbot includes a deploy-hook option that runs a script only when a renewal succeeds. Update the cron job:

sudo crontab -e

Modify the certbot line to include the deploy-hook:

0 1 * * 3 /usr/bin/certbot renew --deploy-hook /opt/sslupdate/sslupdate.sh

Make the script executable:

sudo chmod +x /opt/sslupdate/sslupdate.sh

Test the script manually before relying on automated execution. Verify that paths, hostnames, and service names match your environment. You now have automated certificate renewal and distribution for wildcard certificates across multiple domains.

AI assistance is used on this site for language, formatting, and turning research into a consistent template. It is not used to perform the underlying research or verify technical claims. Every command, configuration, and step in this post is tested by hand before publication.

Leave a Reply

Your email address will not be published. Required fields are marked *

twelve − two =