| |

LFCE 105 ๐Ÿง certbot โ€” Automated Certificates

โฑ๏ธ Estimated read: 12 min | |

Certbot is the reference ACME client for Let’s Encrypt. It performs the domain validation, requests the certificate, installs it into the web server configuration, and schedules the automatic renewal. The previous chapter covered the Let’s Encrypt concepts; this chapter covers the commands that make the automation work. The LFCE exam expects the candidate to configure the host-based security for a service, and certbot is the tool that turns the Let’s Encrypt CA into a working TLS configuration.

The client has several modes, and the choice depends on the web server and the validation requirements. The --nginx and --apache plugins are the fully automatic modes: they read the server configuration, add the TLS directives, and reload the service. The --webroot mode is the semi-automatic mode: it places the challenge file in the document root, but the administrator configures the TLS directives manually. The --standalone mode is the mode for the servers without a web server running, and the --manual mode is the mode for the DNS challenge and the wildcard certificates . The certbot renew command is the renewal mechanism, and the systemd timer runs it twice a day .

Key point: The certificate files are written to /etc/letsencrypt/live/<domain>/, and the fullchain.pem is the file that the server configuration should reference. The privkey.pem is the private key, and the cert.pem and chain.pem are the separate components . The certbot renew --dry-run is the test that confirms the renewal works without consuming the production rate limits .


Why certbot requires the plugin and the renewal timer

The plugin problem.

Certbot is not a web server; it is a client that talks to the CA and the web server. The plugin is the adapter that performs the validation and the installation for the specific server. The --nginx plugin reads the nginx configuration, finds the server block, adds the ssl_certificate directives, and reloads the service . The --webroot mode does not touch the configuration; it only places the challenge file, and the administrator adds the TLS directives manually . The --standalone mode starts a temporary server on the port 80, which requires the port to be free .

The renewal problem.

The Let’s Encrypt certificates are valid for 90 days, and the renewal must happen before the expiry. The certbot renew command checks the certificates and renews the ones that are due. The systemd timer runs the command twice a day, which provides multiple opportunities to renew without forcing the issuance on every run . The --dry-run option performs the renewal against the staging environment, which confirms the process works without the production rate limits .

The deploy-hook problem.

The renewal replaces the certificate files, but the running service does not reload them automatically unless the plugin handles it. The --deploy-hook option runs a command after a successful renewal, which is the mechanism that reloads the service. The certbot renew --deploy-hook "systemctl reload nginx" is the pattern for the manual configurations . The nginx and apache plugins handle the reload themselves, so the deploy hook is only needed for the other services.


a. The installation and the certificate issuance

The installation is the package manager command, and the issuance is the plugin command.

# Debian / Ubuntu
sudo apt install certbot python3-certbot-nginx

# RHEL / Rocky
sudo dnf install certbot python3-certbot-nginx

# Obtain the certificate with the nginx plugin
sudo certbot --nginx -d example.com -d www.example.com

The certbot --nginx command reads the nginx configuration, finds the server block for the domain, adds the TLS directives, and reloads the service . The -d flag specifies the domain, and it can be repeated for the multiple domains . The command prompts for the email address, the terms of service, and the HTTP-to-HTTPS redirect, and it completes the issuance and the installation in one step .

The webroot mode is the alternative for the manual configuration.

# Obtain the certificate with the webroot mode
sudo certbot certonly --webroot -w /var/www/html -d example.com -d www.example.com

The certonly flag tells certbot to obtain the certificate without installing it . The --webroot -w /var/www/html specifies the document root, and certbot places the challenge file at /var/www/html/.well-known/acme-challenge/ . The administrator then adds the ssl_certificate directives to the server configuration manually.

The DNS challenge is the mode for the wildcard certificates.

# Obtain the wildcard certificate with the DNS challenge
sudo certbot certonly --manual --preferred-challenges dns -d example.com -d "*.example.com"

The --manual --preferred-challenges dns tells certbot to use the DNS-01 challenge . Certbot prints the TXT record values, and the administrator adds them to the DNS zone. The CA queries the DNS, and the certificate is issued after the validation . The manual DNS challenge is not automatable, so the DNS plugins (such as certbot-dns-cloudflare) are the mechanism for the automated wildcard renewal .


b. The certificate files and the server configuration

The certificate files are written to /etc/letsencrypt/live/<domain>/, and the server configuration references them.

# The certificate files
ls /etc/letsencrypt/live/example.com/
# cert.pem, chain.pem, fullchain.pem, privkey.pem

The fullchain.pem is the file that the server should use, because it contains the server certificate and the intermediate chain . The privkey.pem is the private key, and it must be protected. The cert.pem and the chain.pem are the separate components, which are useful for the specific configurations .

The nginx configuration references the files.

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
}

The ssl_certificate points to the fullchain.pem, and the ssl_certificate_key points to the privkey.pem . The include /etc/letsencrypt/options-ssl-nginx.conf adds the recommended TLS settings, and the ssl_dhparam adds the DH parameters . The nginx -t command validates the configuration before the reload.


c. The renewal and the deploy hook

The renewal is the certbot renew command, and the timer runs it automatically.

# Test the renewal
sudo certbot renew --dry-run

# Renew the certificates that are due
sudo certbot renew

# Renew with the deploy hook
sudo certbot renew --deploy-hook "systemctl reload nginx"

The --dry-run performs the renewal against the staging environment, which confirms the process works without the production rate limits . The renew command checks the certificates and renews the ones that are within the renewal window . The --deploy-hook runs the command after a successful renewal, which is the mechanism that reloads the service .

The timer is the automatic mechanism.

# Check the timer
systemctl list-timers | grep certbot

# Enable the timer if it is not active
sudo systemctl enable --now certbot.timer

The systemctl list-timers shows the next run, and the enable --now starts the timer if it is not active . The timer runs certbot renew twice a day, and the deploy hook or the plugin handles the service reload .


Complete Example Session

# ============================================
# PART 1: INSTALL CERTBOT
# ============================================
sudo apt install certbot python3-certbot-nginx

# ============================================
# PART 2: OBTAIN WITH THE NGINX PLUGIN
# ============================================
sudo certbot --nginx -d example.com -d www.example.com

# ============================================
# PART 3: CHECK THE FILES
# ============================================
sudo ls /etc/letsencrypt/live/example.com/

# ============================================
# PART 4: VERIFY THE CERTIFICATE
# ============================================
sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -dates

# ============================================
# PART 5: CHECK THE TIMER
# ============================================
systemctl list-timers | grep certbot

# ============================================
# PART 6: TEST THE RENEWAL
# ============================================
sudo certbot renew --dry-run

# ============================================
# PART 7: THE WEBROOT MODE
# ============================================
sudo certbot certonly --webroot -w /var/www/html -d example.com

# ============================================
# PART 8: THE DNS WILDCARD
# ============================================
sudo certbot certonly --manual --preferred-challenges dns -d example.com -d "*.example.com"

# ============================================
# PART 9: THE DEPLOY HOOK
# ============================================
sudo certbot renew --deploy-hook "systemctl reload nginx"

# ============================================
# PART 10: THE REVOCATION
# ============================================
sudo certbot revoke --cert-name example.com

The ten parts demonstrate the certbot lifecycle: the installation, the nginx plugin, the file check, the verification, the timer, the renewal test, the webroot mode, the DNS wildcard, the deploy hook, and the revocation. The critical verification is Part 6: the --dry-run confirms the renewal process works without the production rate limits.


Quick Reference

Installation

DistributionCommand
Debian / Ubuntuapt install certbot python3-certbot-nginx
RHEL / Rockydnf install certbot python3-certbot-nginx

Certificate Issuance

ModeCommandUse Case
Nginx plugincertbot --nginx -d example.comAutomatic install
Apache plugincertbot --apache -d example.comAutomatic install
Webrootcertbot certonly --webroot -w /var/www/html -d example.comManual config
Standalonecertbot certonly --standalone -d example.comNo web server
DNS wildcardcertbot certonly --manual --preferred-challenges dns -d "*.example.com"Wildcard

Certificate Files

FileContent
fullchain.pemServer cert + intermediates
privkey.pemPrivate key
cert.pemServer cert only
chain.pemIntermediates only

Renewal

CommandPurpose
certbot renewRenew the due certificates
certbot renew --dry-runTest the renewal
certbot renew --deploy-hook "cmd"Run the command after the renewal
systemctl enable --now certbot.timerEnable the automatic timer

Best Practices

โœ… Do This:

# Use the nginx plugin for the automatic install
certbot --nginx -d example.com                                  # โœ…

# Use the --dry-run before the production renewal
certbot renew --dry-run                                         # โœ…

# Use the fullchain.pem in the server config
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem # โœ…

# Use the deploy hook for the manual services
certbot renew --deploy-hook "systemctl reload postfix"          # โœ…

# Check the timer
systemctl list-timers | grep certbot                            # โœ…

# Use the DNS plugin for the automated wildcard
# The manual DNS is not automatable                              # โœ…

โŒ Don’t Do This:

# Use the manual DNS in the production automation
# The manual challenge is not automatable                        # โŒ

# Forget the port 80 for the HTTP-01
# The renewal fails if the port is blocked                       # โŒ

# Ignore the rate limits
# The retry loop exhausts the Duplicate Certificate limit        # โŒ

# Use the cert.pem instead of the fullchain.pem
# The client cannot build the chain                              # โŒ

# Forget the deploy hook for the non-plugin services
# The service keeps the old certificate until the reload         # โŒ

Common Pitfalls

PitfallWhy It HappensFix
The HTTP-01 failsThe port 80 is blockedOpen the port 80 or use the DNS-01
The wildcard failsThe HTTP-01 usedUse the DNS-01
The rate limit hitThe retry loopStop the retries, use --dry-run
The service serves the old certNo reload after the renewalAdd the deploy hook
The chain incompleteThe cert.pem usedUse the fullchain.pem

Real-World Examples

1. Nginx plugin

certbot --nginx -d example.com -d www.example.com

2. Webroot mode

certbot certonly --webroot -w /var/www/html -d example.com

3. Standalone mode

certbot certonly --standalone -d example.com

4. DNS wildcard

certbot certonly --manual --preferred-challenges dns -d example.com -d "*.example.com"

5. Test the renewal

certbot renew --dry-run

6. The deploy hook

certbot renew --deploy-hook "systemctl reload nginx"

7. The timer

systemctl list-timers | grep certbot

8. The certificate files

ls /etc/letsencrypt/live/example.com/

9. The revocation

certbot revoke --cert-name example.com

10. The nginx config

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

Visual

The Certbot Modes

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THE PLUGIN VS THE WEBROOT VS THE STANDALONE                 โ”‚
โ”‚                                                              โ”‚
โ”‚  Plugin (--nginx):                                           โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ Reads the nginx config                                 โ”‚  โ”‚
โ”‚  โ”‚ Adds the TLS directives                                โ”‚  โ”‚
โ”‚  โ”‚ Reloads the service                                    โ”‚  โ”‚
โ”‚  โ”‚ Fully automatic                                        โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                                                              โ”‚
โ”‚  Webroot (--webroot):                                        โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ Places the challenge file in the document root         โ”‚  โ”‚
โ”‚  โ”‚ Does not touch the config                              โ”‚  โ”‚
โ”‚  โ”‚ The admin adds the TLS directives manually             โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                                                              โ”‚
โ”‚  Standalone (--standalone):                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ Starts a temporary server on the port 80               โ”‚  โ”‚
โ”‚  โ”‚ Requires the port to be free                           โ”‚  โ”‚
โ”‚  โ”‚ No web server running                                  โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Renewal Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THE TIMER RUNS THE RENEWAL TWICE A DAY                      โ”‚
โ”‚                                                              โ”‚
โ”‚  certbot.timer                                               โ”‚
โ”‚       โ”‚                                                      โ”‚
โ”‚       โ–ผ                                                      โ”‚
โ”‚  certbot renew                                               โ”‚
โ”‚       โ”‚                                                      โ”‚
โ”‚       โ”œโ”€โ”€ checks the certificates                           โ”‚
โ”‚       โ”œโ”€โ”€ renews the due ones                               โ”‚
โ”‚       โ”œโ”€โ”€ runs the deploy hook                              โ”‚
โ”‚       โ””โ”€โ”€ reloads the service                               โ”‚
โ”‚                                                              โ”‚
โ”‚  The --dry-run tests the process against the staging.        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Certificate Files

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THE fullchain.pem IS THE FILE TO USE                        โ”‚
โ”‚                                                              โ”‚
โ”‚  /etc/letsencrypt/live/example.com/                          โ”‚
โ”‚  โ”œโ”€โ”€ fullchain.pem  โ†’ the server cert + the intermediates    โ”‚
โ”‚  โ”œโ”€โ”€ privkey.pem    โ†’ the private key                        โ”‚
โ”‚  โ”œโ”€โ”€ cert.pem       โ†’ the server cert only                   โ”‚
โ”‚  โ””โ”€โ”€ chain.pem      โ†’ the intermediates only                 โ”‚
โ”‚                                                              โ”‚
โ”‚  The server config uses the fullchain.pem and the privkey.pemโ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
ClientCertbot
Automatic plugin--nginx, --apache
Manual config--webroot
No web server--standalone
Wildcard--manual --preferred-challenges dns
Certificate files/etc/letsencrypt/live/<domain>/
Server filefullchain.pem
Key fileprivkey.pem
Renewalcertbot renew
Testcertbot renew --dry-run
Timercertbot.timer
Deploy hook--deploy-hook "systemctl reload <service>"

Key takeaways:

  • Certbot is the ACME client that automates the Let’s Encrypt certificate lifecycle. The --nginx and --apache plugins perform the validation and the installation automatically, and the --webroot mode performs the validation without touching the configuration .
  • The fullchain.pem is the file that the server should reference. It contains the server certificate and the intermediate chain, and the client uses it to build the chain to the trusted root .
  • The certbot renew command is the renewal mechanism. The systemd timer runs it twice a day, and it renews the certificates that are within the renewal window . The --dry-run tests the process against the staging environment .
  • The deploy hook is the mechanism for the manual service reload. The --deploy-hook "systemctl reload nginx" runs the command after a successful renewal, which is the pattern for the services that the plugin does not manage .
  • The DNS challenge is the mode for the wildcard certificates. The --manual --preferred-challenges dns is the manual form, and the DNS plugins (such as certbot-dns-cloudflare) are the automated form .
  • The rate limits require the careful testing. The --dry-run and the staging environment avoid the production rate limits during the testing, and the retry loops can exhaust the Duplicate Certificate limit .

Remember: Certbot is the tool that turns the Let’s Encrypt CA into the working TLS configuration. The plugin mode is the automatic path, the webroot mode is the manual path, and the DNS mode is the wildcard path. The certificate files are in /etc/letsencrypt/live/<domain>/, and the fullchain.pem is the file to use. The renewal is the automatic, and the deploy hook is the mechanism for the manual services. The result is the HTTPS that is configured once and maintained without the manual intervention.


Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!