# Certbot — Automate Let's Encrypt TLS Certificates

> Practical guide to Certbot — issue, auto-renew and manage Let's Encrypt TLS certificates, with plugins for Apache, NGINX and DNS challenges.

Source: https://www.jpkc.com/db/en/cheatsheets/web-servers/certbot/

<!-- PROSE:intro -->
Certbot is the EFF's official ACME client and the standard way to obtain free TLS certificates from Let's Encrypt. A single command lets you issue certificates, install them straight into Apache or NGINX and set up automatic renewal. Plugins for webroot, standalone and DNS challenges cover every server setup – including wildcard certificates via DNS-01. This guide walks you through the key commands, from your first certificate to unattended renewal via a systemd timer.
<!-- PROSE:intro:end -->

## Obtaining Certificates

`certbot certonly --webroot -w <webroot> -d <domain>` — Obtain a certificate using the webroot method (no server restart needed).

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

`certbot certonly --standalone -d <domain>` — Obtain a certificate using a temporary standalone server (requires port 80 free).

```bash
certbot certonly --standalone -d example.com
```

`certbot certonly --nginx -d <domain>` — Obtain a certificate using the NGINX plugin (auto-configures NGINX).

```bash
certbot certonly --nginx -d example.com -d www.example.com
```

`certbot certonly --apache -d <domain>` — Obtain a certificate using the Apache plugin (auto-configures Apache).

```bash
certbot certonly --apache -d example.com
```

`certbot certonly --dns-<provider> -d <domain>` — Obtain a certificate using DNS-01 challenge (for wildcards and internal servers).

```bash
certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/cloudflare.ini -d '*.example.com'
```

`certbot certonly --manual -d <domain>` — Obtain a certificate with manual challenge steps (interactive).

```bash
certbot certonly --manual -d example.com --preferred-challenges dns
```

`certbot --preferred-challenges http` — Specify the preferred challenge type (http-01 or dns-01).

```bash
certbot certonly --standalone --preferred-challenges http -d example.com
```

## Auto-Install (Server Plugins)

`certbot --nginx` — Obtain and automatically install a certificate for NGINX.

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

`certbot --apache` — Obtain and automatically install a certificate for Apache.

```bash
certbot --apache -d example.com -d www.example.com
```

`certbot --nginx --redirect` — Install certificate and automatically add HTTP to HTTPS redirect.

```bash
certbot --nginx --redirect -d example.com
```

`certbot --nginx --no-redirect` — Install certificate without adding a redirect.

```bash
certbot --nginx --no-redirect -d example.com
```

`certbot install --cert-name <name>` — Install a previously obtained certificate into the web server.

```bash
certbot install --nginx --cert-name example.com
```

## Certificate Management

`certbot certificates` — List all certificates managed by Certbot with their details.

```bash
certbot certificates
```

`certbot renew` — Renew all certificates that are due for renewal.

```bash
certbot renew
```

`certbot renew --dry-run` — Test the renewal process without actually renewing.

```bash
certbot renew --dry-run
```

`certbot renew --force-renewal` — Force renewal of all certificates regardless of expiry.

```bash
certbot renew --force-renewal
```

`certbot renew --cert-name <name>` — Renew a specific certificate by name.

```bash
certbot renew --cert-name example.com
```

`certbot delete --cert-name <name>` — Delete a certificate and its associated files.

```bash
certbot delete --cert-name old.example.com
```

`certbot update_symlinks` — Fix broken symlinks in the live directory.

```bash
certbot update_symlinks
```

## Renewal Hooks

`certbot renew --pre-hook "<command>"` — Run a command before attempting renewal (e.g., stop a service).

```bash
certbot renew --pre-hook "systemctl stop nginx"
```

`certbot renew --post-hook "<command>"` — Run a command after a renewal attempt (whether successful or not).

```bash
certbot renew --post-hook "systemctl start nginx"
```

`certbot renew --deploy-hook "<command>"` — Run a command only after a successful renewal.

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

`/etc/letsencrypt/renewal-hooks/deploy/` — Place executable scripts here to run automatically after successful renewals.

```bash
#!/bin/bash
systemctl reload nginx
```

`/etc/letsencrypt/renewal-hooks/pre/` — Scripts run before each renewal attempt.

```bash
ls /etc/letsencrypt/renewal-hooks/pre/
```

`/etc/letsencrypt/renewal-hooks/post/` — Scripts run after each renewal attempt.

```bash
ls /etc/letsencrypt/renewal-hooks/post/
```

## Certificate Options

`certbot --key-type ecdsa` — Request an ECDSA certificate (smaller, faster than RSA).

```bash
certbot certonly --nginx --key-type ecdsa -d example.com
```

`certbot --rsa-key-size <bits>` — Set the RSA key size (default: 2048).

```bash
certbot certonly --nginx --rsa-key-size 4096 -d example.com
```

`certbot --email <email>` — Set the email for urgent renewal and security notices.

```bash
certbot --email admin@example.com -d example.com
```

`certbot --agree-tos` — Agree to the Let's Encrypt Terms of Service non-interactively.

```bash
certbot --agree-tos --email admin@example.com -d example.com
```

`certbot --non-interactive` — Run in non-interactive mode (fail rather than prompt).

```bash
certbot certonly --non-interactive --webroot -w /var/www/html -d example.com
```

`certbot --expand -d <domains>` — Add domains to an existing certificate.

```bash
certbot --expand -d example.com -d blog.example.com -d shop.example.com
```

`certbot --cert-name <name> -d <new-domains>` — Replace the domain list for an existing certificate.

```bash
certbot --cert-name example.com -d example.com -d www.example.com -d api.example.com
```

## File Locations

`/etc/letsencrypt/live/<domain>/fullchain.pem` — The full certificate chain (cert + intermediate). Use this for ssl_certificate in NGINX.

```bash
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
```

`/etc/letsencrypt/live/<domain>/privkey.pem` — The private key. Use this for ssl_certificate_key in NGINX.

```bash
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
```

`/etc/letsencrypt/live/<domain>/cert.pem` — The server certificate only (without chain).

```bash
cat /etc/letsencrypt/live/example.com/cert.pem
```

`/etc/letsencrypt/live/<domain>/chain.pem` — The intermediate certificate(s) only.

```bash
cat /etc/letsencrypt/live/example.com/chain.pem
```

`/etc/letsencrypt/renewal/<domain>.conf` — Renewal configuration file for a certificate.

```bash
cat /etc/letsencrypt/renewal/example.com.conf
```

`/var/log/letsencrypt/letsencrypt.log` — Certbot log file for troubleshooting.

```bash
tail -100 /var/log/letsencrypt/letsencrypt.log
```

## Automation & Cron

`0 0,12 * * * certbot renew --quiet` — Recommended cron job: attempt renewal twice daily (only renews if due).

```bash
0 0,12 * * * /usr/bin/certbot renew --quiet
```

`systemctl list-timers | grep certbot` — Check if systemd auto-renewal timer is active.

```bash
systemctl list-timers | grep certbot
```

`systemctl status certbot.timer` — Check the status of the certbot systemd timer.

```bash
systemctl status certbot.timer
```

`certbot renew --quiet --deploy-hook "systemctl reload nginx"` — Auto-renewal with automatic NGINX reload on success.

```bash
0 3 * * * certbot renew --quiet --deploy-hook "systemctl reload nginx"
```

## Testing & Staging

`certbot --staging` — Use the Let's Encrypt staging server (higher rate limits, untrusted certs).

```bash
certbot certonly --staging --nginx -d test.example.com
```

`certbot --dry-run` — Simulate the certificate request without saving anything.

```bash
certbot certonly --dry-run --webroot -w /var/www/html -d example.com
```

`certbot revoke --cert-path <path>` — Revoke a certificate (e.g., if the private key was compromised).

```bash
certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem
```

`certbot revoke --cert-path <path> --reason keycompromise` — Revoke with a specific reason code.

```bash
certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem --reason keycompromise
```

<!-- PROSE:outro -->
## Conclusion

Certbot takes the entire certificate lifecycle off your hands: once configured, your certificates renew unattended through the systemd timer or a cron job. When setting things up and testing, mind the Let's Encrypt rate limits and use `--dry-run` or `--staging` instead of spending real requests. Reach for `--force-renewal` only when you truly need it – every forced renewal counts against your rate limit. Verify automatic renewal regularly with `certbot renew --dry-run`.

## Further Reading

- [Certbot – official documentation](https://eff-certbot.readthedocs.io/) – reference and guides
- [certbot.eff.org](https://certbot.eff.org/) – the EFF's interactive setup instructions
- [Let's Encrypt](https://letsencrypt.org/) – background, rate limits and documentation
<!-- PROSE:outro:end -->

## Related Commands

- [apache](https://www.jpkc.com/db/en/cheatsheets/web-servers/apache/) – web server Certbot can configure directly
- [caddy](https://www.jpkc.com/db/en/cheatsheets/web-servers/caddy/) – web server with automatic HTTPS out of the box
- [ferron](https://www.jpkc.com/db/en/cheatsheets/web-servers/ferron/) – modern web server with built-in TLS

