aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Tools & DevOps

Certbot SSL: Automatic Certificates with Let's Encrypt

Certbot SSL setup is the shortest path to free, automatic HTTPS on a VPS. Certbot is the official Let's Encrypt client: it obtains the certificate, edits your web server configuration and — most importantly — renews the certificate before it expires, on its own. In this guide I walk through how the tool works, which plugin to pick and when, DNS validation for wildcard certificates, deploy hooks, and how to make renewal genuinely bulletproof.

How Certbot works: challenges and plugins

To prove to Let's Encrypt that the domain is really under your control, Certbot solves a challenge. There are two common types: HTTP-01 validation works by serving a temporary file over port 80, while DNS-01 validation adds a temporary TXT record to your domain. Single domains usually use HTTP-01, whereas wildcard (*.example.com) certificates require DNS-01.

Certbot does this through plugins. There are two kinds: an authenticator (which performs the validation — e.g. nginx, apache, webroot, standalone) and an installer (which places the certificate into your config — e.g. nginx, apache). The nginx and apache plugins play both roles, which makes them the easiest route.

Installing Certbot

The recommended install is the snap package; it always ships the latest version and sets up the renewal timer automatically. On Ubuntu/Debian:

sudo apt update
sudo apt install snapd -y
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

If you'd rather avoid snap, install from your distro repositories: sudo apt install certbot python3-certbot-nginx (or python3-certbot-apache for Apache). The version may be a bit older but works fine. Verify with certbot --version.

The easiest path: the nginx/apache plugin

On a server already running Nginx, a single command both obtains the certificate and adds the HTTPS block to your config:

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

On the first run Certbot asks for an email (for renewal warnings) and to accept the terms of service. It then asks whether to redirect HTTP to HTTPS — choose "Redirect". The logic is identical for Apache, only the plugin changes:

sudo certbot --apache -d example.com -d www.example.com

On Apache, Certbot enables mod_ssl and mod_rewrite, creates an SSL virtual host file and adds the redirect rule. On Nginx, once it finishes, test and reload the config with sudo nginx -t && sudo systemctl reload nginx.

certonly and webroot: a certificate without touching your config

Sometimes you don't want Certbot editing your web server files — the configuration is complex, or you're sitting behind a reverse proxy. In that case the certonly subcommand obtains only the certificate and leaves installation to you. The safest authenticator is webroot, because it writes the validation files into your existing document root without stopping the running server:

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

Here -w points to your site's document root; Certbot drops validation files into /.well-known/acme-challenge/ under it. If there isn't a web server running yet (port 80 is free), you can use the standalone plugin, which spins up its own temporary server for the duration of the challenge:

sudo certbot certonly --standalone -d example.com

The resulting files live under /etc/letsencrypt/live/example.com/: fullchain.pem (certificate + intermediate chain) and privkey.pem (private key). In your Nginx config you point the ssl_certificate and ssl_certificate_key directives at these two paths.

Wildcard certificates: DNS-01 validation

To cover every subdomain under *.example.com with a single certificate you need a wildcard certificate, and Let's Encrypt only issues those via DNS-01. The simplest form is manual validation:

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

Certbot hands you a TXT record (_acme-challenge.example.com); you add it in your DNS panel, wait for it to propagate, and continue. Because the manual approach forces you to intervene on every renewal, in production it's far more practical to use your DNS provider's official plugin. For Cloudflare, for example, with an API token:

sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
  -d "*.example.com" -d "example.com"

That way the TXT record is created and removed automatically, and wildcard renewal becomes fully hands-off.

Automatic renewal and deploy hooks

Let's Encrypt certificates are valid for 90 days, so Certbot's most valuable job is renewal. The snap or package install sets up a systemd timer (or cron job) that runs twice a day and renews once the certificate is within its last 30 days. Confirm it's active:

systemctl list-timers | grep certbot

To test that renewal will work without actually renewing, a dry run is essential:

sudo certbot renew --dry-run

If that command completes without errors, renewal is safe. One key point: after renewal the web server has to load the new certificate into memory. The nginx/apache plugins do this on their own, but if you installed manually with certonly, define a deploy hook:

sudo certbot certonly --webroot -w /var/www/example \
  -d example.com \
  --deploy-hook "systemctl reload nginx"

The deploy hook only runs when the certificate was actually renewed, so it doesn't reload the service unnecessarily. An existing certificate's renewal settings live in /etc/letsencrypt/renewal/example.com.conf; you can add the deploy hook there by hand too.

Common errors

  • Validation failed (timeout): usually DNS isn't pointing at your server yet, or ports 80/443 are closed. Check the IP with dig +short example.com and the ports in your firewall.
  • Rate limit: Let's Encrypt enforces weekly limits. While tweaking, use --dry-run or the --staging environment; neither consumes the real limit.
  • "too many redirects": if both Certbot and a CDN (e.g. Cloudflare "Flexible SSL") redirect, you get a loop. Set the CDN's SSL mode to "Full (strict)".
  • Renewal failing silently: run certbot renew --dry-run regularly; if the webroot path changed or a hook broke, it shows up here.

Frequently Asked Questions

What's the difference between Certbot and Let's Encrypt?

Let's Encrypt is the free certificate authority (CA) that issues the certificate. Certbot is the client software that talks to that CA over the ACME protocol: it performs validation, downloads the certificate and renews it. Other clients such as acme.sh do the same job outside of Certbot.

How many domains can go on one certificate?

By passing several -d flags in the same command you can add multiple domains (SANs) to a single certificate; Let's Encrypt supports up to 100 names per certificate. If you have many subdomains, a wildcard certificate is usually a cleaner solution.

What if I need to revoke a certificate?

If the private key leaks, revoke it with sudo certbot revoke --cert-name example.com, then clean up the renewal config with certbot delete. In normal use there's no need to revoke; expired certificates simply lose validity on their own.

Want Certbot SSL set up from scratch on your server? I can handle the whole process for you — plugin choice, wildcard certificates, deploy hooks and uninterrupted renewal. Get in touch.

Bu kategorideki tüm yazılar →

Devamı için