letsencrypt/certbot tips

Letsencrypt uses certbot for certificate management. If your certificate is not auto renewing follow the runbook below:

  1. Check if certbot is scheduled to auto-renew. Do this by running:
$ systemctl list-timers | grep certbot
Thu 2025-01-30 10:56:00 UTC 17h left Wed 2025-01-29 12:32:03 UTC 4h 27min ago snap.certbot.renew.timer snap.certbot.renew.service

we see that certbot is scheduled to auto-renew

  1. Check past renewal attempts
$ sudo journalctl -u snap.certbot.renew.service --no-pager --since "2 days ago"

I see there are failures when certbot attempted to renew the certificate in the past:

Jan 28 10:56:03 systemd[1]: Starting snap.certbot.renew.service - Service for snap application certbot.renew...
Jan 28 10:59:01 certbot.renew[2467823]: Failed to renew certificate mysite.com with error: Could not bind TCP port 80 because it is already in use by another process on this system (such as a web server). Please stop the program in question and then try again.
Jan 28 10:59:01 certbot.renew[2467823]: All renewals failed. The following certificates could not be renewed:
Jan 28 10:59:01 certbot.renew[2467823]: /etc/letsencrypt/live/mysite.com/fullchain.pem (failure)
Jan 28 10:59:01 certbot.renew[2467823]: 1 renew failure(s), 0 parse failure(s)
Jan 28 10:59:01 systemd[1]: snap.certbot.renew.service: Main process exited, code=exited, status=1/FAILURE
Jan 28 10:59:01 systemd[1]: snap.certbot.renew.service: Failed with result 'exit-code'.
Jan 28 10:59:01 systemd[1]: Failed to start snap.certbot.renew.service - Service for snap application certbot.renew.
  1. This failure Could not bind TCP port 80 because it is already in use by another process is because nginx is running on port 80. Open /etc/letsencrypt/renewal/essofore.com.conf
# Options used in the renewal process
[renewalparams]
authenticator = standalone

authenticator = standalone is the problem. Change it to authenticator = nginx.

  1. Other useful commands. To do a dry run, run:
 sudo certbot renew --dry-run

You should see output similar to following:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/mysite.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Simulating renewal of an existing certificate for mysite.com and www.mysite.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/mysite.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

5. check

$ sudo openssl x509 -in /etc/letsencrypt/live/essofore.com/fullchain.pem -text -noout

By default, the snap version of Certbot runs twice per day. The way to verify this is by running:

systemctl list-timers | grep certbot

this should give output like following:

Wed 2025-08-20 23:29:00 UTC 2h 58min Wed 2025-08-20 06:25:23 UTC 14h ago snap.certbot.renew.timer snap.certbot.renew.service

What this means:

  • last run happened 14h ago on Wed 2025-08-20 06:25:23 UTC
  • next run will happen at Wed 2025-08-20 23:29:00 UTC in 2h 58min

snap.certbot.renew.timer is the systemd unit that is responsible for running the certbot service. The service checks for renewal and then exits. To inspect the timer:

$ systemctl cat snap.certbot.renew.timer
# /etc/systemd/system/snap.certbot.renew.timer
[Unit]
# Auto-generated, DO NOT EDIT
Description=Timer renew for snap application certbot.renew
Requires=snap-certbot-4890.mount
After=snap-certbot-4890.mount
X-Snappy=yes
[Timer]
Unit=snap.certbot.renew.service
OnCalendar=*-*-* 06:25
OnCalendar=*-*-* 23:29
[Install]
WantedBy=timers.target

if you inspect the service itself you may see something like

$ systemctl status snap.certbot.renew.service
○ snap.certbot.renew.service - Service for snap application certbot.renew
Loaded: loaded (/etc/systemd/system/snap.certbot.renew.service; static)
Active: inactive (dead) since Wed 2025-08-20 06:25:24 UTC; 14h ago
TriggeredBy: ● snap.certbot.renew.timer
Process: 79847 ExecStart=/usr/bin/snap run --timer=00:00~24:00/2 certbot.renew (code=exited, status=0/SUCCESS)
Main PID: 79847 (code=exited, status=0/SUCCESS)
CPU: 694ms
Aug 20 06:25:23 ip-172-31-63-44 systemd[1]: Starting snap.certbot.renew.service - Service for snap application certbot.renew...
Aug 20 06:25:24 ip-172-31-63-44 systemd[1]: snap.certbot.renew.service: Deactivated successfully.
Aug 20 06:25:24 ip-172-31-63-44 systemd[1]: Finished snap.certbot.renew.service - Service for snap application certbot.renew.

The inactive (dead) is not a cause for concern and is expected because the service checks for renewal and then exits. we can verify service exited normally code=exited, status=0/SUCCESS.

To run certbot for specific domains

sudo certbot -v --nginx --domains domain1,domain2,domain3

If there is no nginx configuration for the listed domains I have seen it fail with:

Could not automatically find a matching server block for xxx. Set the `server_name` directive to use the Nginx installer

It does save the certificate and also set up the auto-renewal task. Its just not possible to create a NGINX configuration for the listed domains because it cannot find any configuration for listed domains. All that is left is to write the nginx config yourself. You can find the cert and key under:

Certificate is saved at: /etc/letsencrypt/live/xxx/fullchain.pem
Key is saved at: /etc/letsencrypt/live/xxx/privkey.pem

How can I check if my certificate is indeed set to auto-renew?

Great question 👍 — you want to see exactly which domains are tied to each certificate and will be attempted at renewal. Certbot keeps that metadata in renewal configuration files.


1. List all certificates Certbot knows about

sudo certbot certificates

This prints something like:

Found the following certs:
  Certificate Name: xxxx
    Domains: xxxx
    Expiry Date: 2025-11-18 11:42:01+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/xxx/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/xxx/privkey.pem

  • Certificate Name = internal name Certbot uses (often the first domain you requested).
  • Domains = all hostnames covered by that cert.
  • These are exactly what Certbot will check when it runs renew.

2. Inspect the renewal config file directly

Each certificate has a file under /etc/letsencrypt/renewal/:

ls /etc/letsencrypt/renewal/

You’ll see files like xxx.conf.
Open one:

sudo cat /etc/letsencrypt/renewal/xxx.conf

Inside you’ll find:

cert = /etc/letsencrypt/live/xxx/cert.pem
privkey = /etc/letsencrypt/live/xxx/privkey.pem
chain = /etc/letsencrypt/live/xxx/chain.pem
fullchain = /etc/letsencrypt/live/xxx/fullchain.pem

[renewalparams]

authenticator = nginx installer = nginx account = abcdef123456 server = https://acme-v02.api.letsencrypt.org/directory

The [renewalparams] section controls how renewal will run.
The list of domains comes from the symlink in /etc/letsencrypt/live/..., which is always up-to-date.


3. Test renewal for a specific cert

If you want to be absolutely sure which domains it’s going to try:

sudo certbot renew --cert-name xxx --dry-run -v

This will print the exact domains it attempts.


Summary:

  • Run sudo certbot certificates → shows all domains covered per cert.
  • Look in /etc/letsencrypt/renewal/*.conf for config.
  • Use certbot renew --cert-name … --dry-run to test renewal end-to-end.

Deleting a certificate

If you move your website to another server you will want to update certbot to forget about the domain and stop renewing certificate for it. To do that first run

sudo certbot certificates

to see what certificates are being managed by certbot and just delete the certificate of the website that you are no longer hosting on the server. Do that by running:

 sudo certbot delete --cert-name  <cert-name>

Update domains associated with a certificate

We basically tell certbot to issue a new certificate for the domains we want.

sudo certbot certonly --nginx --cert-name xxx -d domains

The key is to use the --cert-name option which will override the existing certificate.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
You are updating certificate xxx to include new domain(s):
(None)
You are also removing previously included domain(s):
(None)
Did you intend to make this change?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(U)pdate certificate/(C)ancel: U

If you don’t use the --cert-name option with same certificate name, a new certificate will get issued and the old one will stay as-is.

This entry was posted in Computers, programming, Software and tagged , , , , . Bookmark the permalink.

Leave a comment