
Table of Contents
By Khimananda Oli | Last reviewed: August 2026
Managing TLS certificates manually is a reliability risk that inevitably leads to expired certificates, browser warnings, and downtime at 3 AM. To automate HTTPS with Lets Encrypt and Certbot effectively, you must move beyond simple issuance and integrate certificate lifecycle management directly into your server provisioning and deployment workflows. This guide covers the production-grade setup required to keep your Ubuntu and Nginx infrastructure secure without manual intervention.
certbot and python3-certbot-nginx packages, then run sudo certbot --nginx -d yourdomain.com. Certbot modifies your Nginx config, obtains a free DV certificate, and installs a systemd timer to handle renewals automatically before expiry.How do you install and configure Certbot on Ubuntu 24.04?
Before you can install SSL certificates on Ubuntu, ensure your system packages are current and your firewall allows HTTP/HTTPS traffic. Using the official Ubuntu repositories is generally sufficient in 2026, as they now ship recent Certbot versions compatible with the latest ACME standards.
Prerequisites and Installation
You need a registered domain pointing to your server's public IP and Nginx already installed. Verify your UFW firewall permits traffic on ports 80 and 443. If you are setting up a fresh VPS, follow the initial Ubuntu server setup guide first to establish a secure baseline.
sudo apt update
sudo apt install -y certbot python3-certbot-nginx
sudo ufw allow 'Nginx Full'
sudo ufw reload Initial Certificate Issuance
The --nginx flag tells Certbot to parse your existing Nginx configuration, modify it to serve the ACME challenge, and automatically update the server block with the correct ssl_certificate paths upon success. This plugin approach is safer than manual configuration because it reduces syntax errors.
sudo certbot --nginx -d example.com -d www.example.com Certbot will prompt for an email address (for expiry notifications), agreement to terms, and optional redirect settings. Always choose to redirect HTTP to HTTPS. After completion, verify the configuration with sudo nginx -t and reload Nginx using sudo systemctl reload nginx.
How does automated renewal work with systemd timers?
A common mistake is assuming the initial installation guarantees future validity. Certificates expire every 90 days. In modern Ubuntu releases, Certbot installs a systemd timer rather than relying solely on cron. This timer runs twice daily and only attempts renewal if the certificate expires within 30 days.
Verifying the Renewal Timer
Check the status of the renewal mechanism to confirm automation is active. If this timer is inactive or failed, your site will go offline in under three months.
sudo systemctl status certbot.timer
sudo certbot renew --dry-run The --dry-run flag simulates the renewal process against the staging environment without hitting rate limits or issuing real certificates. If this command fails, investigate immediately. Common causes include modified Nginx configs that broke the ACME challenge path or firewall rules blocking outbound HTTPS from the server.
Custom Deploy Hooks
Certbot can execute scripts after a successful renewal. This is critical for services that don't auto-detect certificate changes, such as Postfix, Dovecot, or HAProxy. Place executable scripts in /etc/letsencrypt/renewal-hooks/deploy/. They receive the new certificate path in the $RENEWED_LINEAGE environment variable.
#!/bin/bash
# /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh
if [ "$RENEWED_LINEAGE" = "/etc/letsencrypt/live/example.com" ]; then
systemctl reload postfix
systemctl reload dovecot
fi What are the differences between Nginx plugin, standalone, and webroot modes?
Certbot offers multiple validation methods. Choosing the wrong one for your infrastructure causes renewal failures when network topology changes. Understanding these trade-offs is essential for reliable operations.
| Mode | Best For | Pros | Cons |
|---|---|---|---|
| Nginx Plugin | Standard web servers | Auto-configures SSL blocks; handles reloads | Fails if Nginx config is non-standard or complex |
| Standalone | Servers without web server | No dependencies; simple setup | Requires stopping web server on port 80 during renewal |
| Webroot | Existing complex setups | No service interruption; no config parsing | Requires write access to specific web root directory |
| DNS-01 | Wildcard certs / internal | No inbound port 80 needed; supports wildcards | Requires API credentials for DNS provider |
For most Ubuntu+Nginx deployments, the plugin mode is optimal. Use webroot if you manage Nginx configurations via Ansible or Terraform and want Certbot to avoid touching your IaC-managed files. Use DNS-01 exclusively for wildcard certificates or servers behind NAT where port 80 isn't publicly routable.
How do you troubleshoot common Certbot renewal failures?
Even well-configured systems break. When you set up free SSL with Lets Encrypt and Certbot, document your validation mode and hooks. Most failures stem from one of three categories: network blocks, configuration drift, or rate limiting.
- Port 80 Blocked: Many cloud providers and corporate firewalls block inbound port 80 by default. ACME HTTP-01 challenges require this port. Check both OS-level UFW rules and cloud security groups.
- Configuration Drift: Manually editing Nginx configs after Certbot setup can remove the managed
# managed by Certbotmarkers. Certbot may then fail to locate the correct server block during renewal. Always usecertbot certificatesto inspect binding state. - Rate Limits: Let's Encrypt enforces strict limits (50 certs/domain/week). Failed dry-runs don't count, but repeated production failures do. Monitor
/var/log/letsencrypt/letsencrypt.logfor "too many requests" errors. - DNS Propagation: If you recently changed IPs or added subdomains, DNS caching may cause validation failures. Wait for TTL expiration or flush public resolvers before retrying.
If renewals fail persistently, switch to --debug-challenges flag during manual testing. This pauses execution before validation, allowing you to curl the challenge URL externally and verify reachability.
How do you harden TLS configuration after obtaining certificates?
Obtaining a certificate is only step one. Default Certbot configurations prioritize compatibility over security. For production systems handling sensitive data or requiring compliance alignment, you must tighten cipher suites and protocol versions. Review the Ubuntu security hardening guide for broader context.
Modern Cipher Suite Configuration
Create a shared SSL snippet to enforce TLS 1.2+ and modern ciphers. Include this in all server blocks rather than relying on Certbot defaults.
# /etc/nginx/snippets/ssl-hardened.conf
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; Enable OCSP stapling to improve handshake performance and privacy. Ensure your resolver is configured correctly in Nginx (resolver 1.1.1.1 valid=300s;) so stapling works reliably. Test your configuration with external scanners like Qualys SSL Labs to verify an A+ rating before going live.
Secure Your Automation Workflow Today
To successfully automate HTTPS with Lets Encrypt and Certbot, treat certificate management as infrastructure code, not an ad-hoc task. Install via official packages, verify systemd timers, select the appropriate validation mode for your architecture, and harden TLS settings beyond defaults. Monitor renewal logs proactively and test failures in staging before they impact users. If your team needs help designing a compliant, self-healing PKI strategy across multi-cloud or hybrid environments, reach out to discuss your infrastructure requirements.