Certbot
Source
Using Free SSL/TLS Certificates from Let’s Encrypt with NGINX
Overview
This guide covers how to obtain, renew, and manage SSL/TLS certificates from Let’s Encrypt using Certbot’s NGINX plugin and the DNS‑01 challenge via Cloudflare. It also explains how to remove domains from existing certificates and automate certificate updates with a cron-driven script.
Prerequisites
- A server running NGINX.
- Certbot installed (
sudo certbot python3-certbot-nginx python3-certbot-dns-cloudflare). - A Cloudflare account with an API token or global API key.
- SSH access (with key) for any remote certificate distribution.
Obtain Certificates via NGINX Plugin
Use Certbot’s NGINX plugin to automatically obtain a certificate and configure NGINX in one step:
sudo certbot --nginx -d x.abair.ie
This command will:
- Obtain a certificate from Let’s Encrypt.
- Modify your NGINX configuration to use the new certs.
- Reload NGINX to apply the changes.
Remove a Domain from an Existing Certificate
To remove an unwanted domain from a multi-domain certificate:
- Open the renewal config:
sudo nano /etc/letsencrypt/renewal/yourdomain.conf - In the domains line, delete the
-d unwanted.domain.tldentry. - Re-run Certbot for the remaining domains:
sudo certbot certonly --nginx --cert-name yourdomain -d remaining.domain.tld
For a detailed walkthrough, see Remove domain from certbot and NGINX.
DNS Cloudflare Function
Certbot’s Cloudflare DNS plugin automates DNS‑01 challenges by programmatically creating and cleaning up TXT records in Cloudflare:
- Install the plugin:
sudo apt install python3-certbot-dns-cloudflare - Create credentials file (
/root/certbot-creds.ini):# Using a Global API Key
dns_cloudflare_email = your-email@example.com
dns_cloudflare_api_key = 0123456789abcdef...
# Or, using a Scoped API Token
dns_cloudflare_api_token = 0123456789abcdef... - Secure the file:
chmod 600 /root/certbot-creds.ini - Obtain or renew certificates:
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/certbot-creds.ini \
-d '*.abair.ie' -d abair.ie
This process:
- Verifies domain control via Cloudflare DNS.
- Automatically removes challenge records after issuance.
update-ssl-certs Script
Automate certificate renewal and distribution with a Bash script (update-ssl-certs.sh):
#!/bin/bash
# Paths and credentials
CERT_PATH="/etc/letsencrypt/live/abair.ie/"
CREDS="/root/certbot-creds.ini"
SSH_KEY="/root/.ssh/id_ed25519"
# Domains to renew
domains=(
"*.abair.ie"
"abair.ie"
"*.scealai.abair.ie"
"*.geabaire.abair.ie"
)
# Renew via Cloudflare DNS challenge
for d in "${domains[@]}"; do
certbot certonly \
--dns-cloudflare \
--force-renew \
--dns-cloudflare-credentials "$CREDS" \
-d "$d"
done
# Remote VM details
REMOTE_USER="services"
REMOTE_HOST="10.0.0.2"
REMOTE_PORT="22102"
# Copy certificates to services VM
scp -i "$SSH_KEY" -P "$REMOTE_PORT" \
"$CERT_PATH/fullchain.pem" "$REMOTE_USER"@$REMOTE_HOST:/etc/ssl/abair.ie
scp -i "$SSH_KEY" -P "$REMOTE_PORT" \
"$CERT_PATH/privkey.pem" "$REMOTE_USER"@$REMOTE_HOST:/etc/ssl/abair.ie
# Restart remote Docker registry to load new certs
ssh -i "$SSH_KEY" -p "$REMOTE_PORT" $REMOTE_USER@$REMOTE_HOST \
"docker compose -f /home/services/docker-registry/docker-compose.yml restart"
Scheduling: Add to root’s crontab to run every 60 days at midnight:
0 0 */60 * * /usr/local/bin/update-ssl-certs.sh >> /var/log/update-ssl-certs.log 2>&1