Certbot and Let's Encrypt SSL
Let's Encrypt provides free TLS certificates, and Certbot automates issuing and renewing them. The main thing to get right is the ACME validation path (usually HTTP on port 80) and making sure your web server reloads after renewal.
- Make sure DNS points to your VPS and ports
80/tcpand443/tcpare reachable. - Prefer a web-server plugin (
--nginx/--apache) when available; use--webrootfor OpenLiteSpeed. - Verify the certificate live with
curl -Ivand track renewals withsystemctl list-timers.
Prerequisites
- A domain name with
A/AAAArecords pointing to this VPS. - Firewall allows inbound
80/tcpand443/tcp. - SSH access with
sudo. - A working virtual host for your domain (even if it's HTTP-only initially).
Decide how Certbot should validate
Certbot must prove you control the domain. The two common methods are:
http-01(most common): Certbot places a file under/.well-known/acme-challenge/and Let's Encrypt fetches it over HTTP (port 80).dns-01: uses DNS TXT records (useful if you cannot expose port 80).
For most VPS WordPress setups, use http-01.
Install Certbot
- Debian/Ubuntu
- RHEL/Rocky/Alma
sudo apt update
sudo apt install -y certbot
sudo dnf install -y certbot
Issue a certificate
Choose the section that matches your web server.
If you use certbot --nginx or certbot --apache, Certbot may edit your server configuration. If this is a production host, keep a backup of your web server config first.
- Nginx
- Apache
- OpenLiteSpeed
sudo apt update
sudo apt install -y python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
sudo nginx -t
sudo systemctl reload nginx
sudo apt update
sudo apt install -y python3-certbot-apache
sudo certbot --apache -d example.com -d www.example.com
sudo apachectl configtest
sudo systemctl reload apache2
OpenLiteSpeed doesn't have a first-party Certbot plugin in most distros, so use --webroot.
-
Identify your document root (example:
/var/www/example.com/html). -
Make sure OpenLiteSpeed serves
/.well-known/acme-challenge/from that docroot.
sudo mkdir -p "/var/www/example.com/html/.well-known/acme-challenge"
sudo chown -R www-data:www-data "/var/www/example.com/html/.well-known"
- Issue a certificate.
sudo certbot certonly --webroot \
-w "/var/www/example.com/html" \
-d example.com -d www.example.com
- Configure SSL in the vhost (
vhssl) and point it at:
fullchain.pem:/etc/letsencrypt/live/example.com/fullchain.pemprivkey.pem:/etc/letsencrypt/live/example.com/privkey.pem
- Reload OpenLiteSpeed.
sudo systemctl reload lsws
Verify SSL is working
curl -Iv https://example.com/
sudo certbot certificates
If you want to confirm the served certificate chain from the network:
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
Renewal
Most systems install a systemd timer for automatic renewals.
systemctl list-timers | rg -n 'certbot'
Always run a dry-run at least once:
sudo certbot renew --dry-run
Reload your web server after renew
If your web server does not automatically reload, add a deploy hook.
sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-webserver.sh >/dev/null <<'SH'
#!/usr/bin/env bash
set -euo pipefail
if systemctl is-active --quiet nginx; then
systemctl reload nginx
elif systemctl is-active --quiet apache2; then
systemctl reload apache2
elif systemctl is-active --quiet lsws; then
systemctl reload lsws
fi
SH
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-webserver.sh
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
NXDOMAIN / validation fails immediately | DNS not set or not propagated | Verify A/AAAA records and wait for propagation |
| Timeout connecting on port 80 | Firewall/security group blocks HTTP | Allow 80/tcp and verify reachability |
404 on challenge path | Wrong --webroot or vhost mismatch | Confirm the docroot that serves your domain |
403 on challenge path | App/WAF blocks /.well-known | Allow that path and retry |
| Rate limit errors | Too many requests in a short time | Wait and reduce retries; test with --dry-run |
Files and directories to know
- Certificates:
/etc/letsencrypt/live/<domain>/ - Renew configs:
/etc/letsencrypt/renewal/ - Logs:
/var/log/letsencrypt/