Introduction to Let's Encrypt
Let's Encrypt is a free, automated, and open certificate authority (CA) that issues SSL/TLS certificates to anyone with a domain name. It uses the ACME (Automatic Certificate Management Environment) protocol to validate domain ownership and provision domain-validated certificates. Because certificates are issued with a 90-day lifetime, Let's Encrypt is designed from the ground up to encourage — and require — fully automated renewal, eliminating the manual, error-prone processes of traditional certificate management.
Why Automate SSL Certificates?
🚀 Deploy your AI agent in 10 minutes
Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.
Try it free →Automating SSL certificate issuance and renewal is not just a convenience — it is a critical operational and security practice. Manual certificate rotation often leads to expired certificates, resulting in outages, broken trust, and SEO penalties. Automated renewal ensures continuous HTTPS protection without human intervention. It also enables developers and operators to adopt HTTPS everywhere at zero cost, improving privacy, data integrity, and user confidence across the web.
Core Tools and Clients
The most widely used client for Let's Encrypt is Certbot, maintained by the Electronic Frontier Foundation. Other popular ACME clients include acme.sh (lightweight, shell-based, great for DNS challenges), lego (Go library and CLI), and built-in integrations in web servers like Caddy and Traefik. Certbot offers plugins for popular web servers (Nginx, Apache) and DNS providers, making it the easiest starting point for most deployments.
Step-by-Step Setup: Certbot with Nginx on Ubuntu
This walkthrough assumes you have a running Ubuntu server, a public IP address, and DNS records already pointing to your server for the domains you want to secure. We'll obtain a certificate, configure Nginx automatically, and enable unattended renewal.
Install Certbot and the Nginx Plugin
Update your package list and install Certbot along with its Nginx integration:
sudo apt update
sudo apt install certbot python3-certbot-nginx
Obtain and Install a Certificate
Run Certbot with the Nginx plugin. It will modify your Nginx configuration to serve HTTPS using the newly acquired certificate. Replace example.com and www.example.com with your actual domain(s).
sudo certbot --nginx -d example.com -d www.example.com
You'll be prompted for an email address (for expiration notices) and to agree to the terms of service. Certbot then completes the HTTP-01 challenge, obtains the certificate, and updates your Nginx config. Reload Nginx if necessary:
sudo systemctl reload nginx
Verify Auto-Renewal
Certbot automatically creates a systemd timer (or a cron job) that runs renewal twice a day. Renewal only happens when a certificate is near expiry. Test the entire renewal process in dry-run mode to confirm everything works:
sudo certbot renew --dry-run
Check the timer status to ensure it is active:
sudo systemctl status certbot.timer
sudo systemctl list-timers --all
The timer triggers certbot renew; after a successful renewal, Certbot automatically reloads the web server to apply the new certificate.
Wildcard Certificates and DNS Challenge
Wildcard certificates (e.g., *.example.com) require the DNS-01 challenge because HTTP-01 cannot validate arbitrary subdomains. This challenge proves domain ownership by creating a temporary TXT record in your DNS zone. For full automation, use a DNS provider plugin instead of the manual mode.
Example: Automated Wildcard with Cloudflare
Install the Cloudflare DNS plugin for Certbot:
sudo apt install python3-certbot-dns-cloudflare
Create a credentials file (restrict its permissions to root only) containing your Cloudflare API token with DNS edit permissions:
sudo nano /etc/letsencrypt/dnscloudflare.ini
Add the following line:
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN
Set strict file permissions:
sudo chmod 600 /etc/letsencrypt/dnscloudflare.ini
Now request a wildcard certificate:
sudo certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/dnscloudflare.ini \
-d *.example.com -d example.com
The certonly subcommand obtains the certificate without modifying web server configuration. You'll then manually configure your web server to use the certificate files stored in /etc/letsencrypt/live/. Renewal will automatically use the same plugin and credentials.
Best Practices for Automated SSL
- Always test with dry-run first — use
certbot renew --dry-runafter any configuration change to avoid hitting rate limits or breaking production. - Monitor expiration regularly — run
certbot certificatesto see expiry dates, and integrate monitoring (e.g., check output with a script or monitoring tool). - Restrict credentials files — any file containing API tokens (DNS plugins) must have permissions
600and be owned by root. - Use the staging environment for testing — add
--test-certto your commands when experimenting. This avoids hitting production rate limits (50 certificates per registered domain per week). - Prefer webroot or DNS challenges for non-root users — the webroot method places a file in your webroot directory and works without root privileges if the webroot is writable. The standalone method requires binding to port 80, which needs root (or setcap).
- Combine with HSTS and OCSP stapling — after enabling HTTPS, add the
Strict-Transport-Securityheader and configure OCSP stapling to improve security and performance. - Consider built-in ACME servers — Caddy and Traefik handle certificates entirely automatically, ideal for containerized or simplified deployments.
- Use post-renewal hooks — Certbot allows hooks in
/etc/letsencrypt/renewal-hooks/to restart services, update load balancers, or push new certificates to other systems after renewal.
Troubleshooting Common Issues
Rate limiting: Let's Encrypt enforces strict limits (e.g., 5 failures per account per hour). If you encounter "too many requests," use the staging environment (--test-cert) or wait for the limit window to reset.
DNS propagation delays: The DNS-01 challenge waits for the TXT record to be visible. Some providers have slow propagation. Increase the propagation delay via --dns-propagation-seconds or use a provider with fast DNS updates.
Firewall/port 80 accessibility: The HTTP-01 challenge requires an incoming connection on port 80 from Let's Encrypt's validation servers. Ensure your firewall and security groups allow HTTP traffic during certificate issuance.
Webroot path errors: When using the webroot authenticator, the path must exist and be writable. Verify that the server serves /.well-known/acme-challenge/ from the specified webroot without redirects or authentication.
Expired certificates despite timer: Check if the timer is active (systemctl status certbot.timer) and if the renewal command succeeds. Inspect logs at /var/log/letsencrypt/letsencrypt.log.
Conclusion
Setting up automatic SSL certificates with Let's Encrypt transforms a once-tedious manual process into a reliable, zero-cost, hands-off operation. By leveraging tools like Certbot and its DNS plugins, you can secure any domain — including wildcards — and ensure certificates never expire without your attention. The ACME ecosystem continues to mature, making HTTPS the default for modern web infrastructure. Adopting these practices not only protects your users but also aligns with industry best practices for security and automation. Start small, test with staging, and soon you'll have a robust, fully automated SSL pipeline that just works.