Why Let’s Encrypt?

Let’s Encrypt provides free, automated SSL/TLS certificates that are trusted by all major browsers. Before Let’s Encrypt, SSL certificates cost $50-300/year and required manual renewal. Now, any website can have HTTPS for free with automatic renewal.

Certbot is the official client for Let’s Encrypt. It handles certificate issuance, installation, and renewal automatically for Nginx, Apache, and other web servers.

Prerequisites

  • A Linux server with a public IP address.
  • A domain name with DNS pointing to your server.
  • Nginx or Apache installed and serving your site on port 80.
  • Port 80 (HTTP) and 443 (HTTPS) open in your firewall.

Step-by-Step Solution

1. Install Certbot

Ubuntu/Debian:

sudo apt update
sudo apt install -y certbot python3-certbot-nginx
# Or for Apache:
# sudo apt install -y certbot python3-certbot-apache

CentOS/RHEL:

sudo dnf install -y certbot python3-certbot-nginx

2. Obtain a Certificate (Nginx)

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

Certbot will:

  1. Verify domain ownership via an HTTP-01 challenge.
  2. Obtain the certificate from Let’s Encrypt.
  3. Automatically configure your Nginx server block with SSL.
  4. Set up a redirect from HTTP to HTTPS.

For Apache:

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

For manual/standalone mode (no web server plugin):

sudo certbot certonly --standalone -d example.com

3. Verify the Certificate

# Check the certificate details
sudo certbot certificates

# Test SSL configuration
curl -vI https://example.com 2>&1 | grep -A5 "SSL certificate"

4. Configure Auto-Renewal

Certbot installs a systemd timer automatically. Verify it:

sudo systemctl list-timers | grep certbot

Or test renewal manually:

sudo certbot renew --dry-run

For custom post-renewal hooks (e.g., reloading Nginx):

# Create a renewal hook
sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
cat << 'EOF' | sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
#!/bin/bash
systemctl reload nginx
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

Troubleshooting

Validation Failed: “Connection Refused” or “Timeout"

# Verify DNS points to your server
dig +short example.com

# Verify port 80 is open
sudo ufw status | grep 80
curl -I http://example.com

"Too Many Failed Authorizations” Rate Limit

Let’s Encrypt rate-limits after 5 failed validations per hour. Fix the underlying issue and wait 1 hour. For testing, use the staging environment:

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

Certificate Renewal Fails in Cron

# Check the renewal log
sudo cat /var/log/letsencrypt/letsencrypt.log

# Common fixes:
# 1. Make sure the web server is running
# 2. Ensure port 80 is still open
# 3. Check that the renewal config hasn't been modified
sudo cat /etc/letsencrypt/renewal/example.com.conf

Wildcard Certificates (DNS-01 Challenge)

Wildcard certificates (*.example.com) require DNS-01 validation:

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

For automated DNS-01 with Cloudflare:

sudo apt install python3-certbot-dns-cloudflare
sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d "*.example.com" -d example.com

Best Practices

  • Always test with --dry-run before running renewal commands in production.
  • Use the --nginx or --apache plugin instead of standalone mode for automatic configuration.
  • Monitor certificate expiry with tools like Prometheus ssl_exporter or a simple cron script.
  • Enable HSTS after confirming SSL works: add Strict-Transport-Security: max-age=31536000 to your server config.
  • Enable OCSP stapling for faster TLS handshakes.
  • Back up /etc/letsencrypt/ — it contains your private keys and account credentials.

Summary

  • Let’s Encrypt provides free 90-day SSL certificates via Certbot.
  • Certbot auto-configures Nginx/Apache and sets up automatic renewal.
  • Troubleshoot validation by checking DNS, ports 80/443, and web server status.
  • Use DNS-01 challenges for wildcard certificates.
  • Always back up /etc/letsencrypt/ and test renewals with --dry-run.