
Table of Contents
By Khimananda Oli | Last reviewed: August 2026
Securing web traffic is no longer optional; browsers flag unencrypted sites as unsafe, and search engines penalize them in rankings. A proper HTTPS setup with Let's Encrypt and Certbot provides free, automated TLS certificates that satisfy modern security standards without manual renewal overhead. This guide walks you through the complete implementation on Ubuntu and Nginx, from initial installation to hardened production configuration.
certbot --nginx -d yourdomain.com to obtain and configure a certificate automatically, and verifying the systemd timer handles renewals. This process takes under five minutes on a properly configured Ubuntu server with public DNS resolution.How does HTTPS setup with Let's Encrypt and Certbot work?
Understanding the ACME (Automated Certificate Management Environment) protocol prevents misconfiguration later. When you request a certificate, Certbot must prove domain ownership to Let's Encrypt before issuance occurs. The most common validation method for web servers is HTTP-01, where Certbot places a temporary challenge file at /.well-known/acme-challenge/ that Let's Encrypt retrieves via HTTP to verify control.
This validation requires port 80 to be accessible from the internet. If your firewall blocks inbound HTTP or your DNS doesn't resolve correctly to this server, validation fails immediately. Before starting any free SSL setup, confirm your domain resolves to the correct IP and that UFW allows ports 80 and 443. For deeper network preparation, review the Ubuntu network troubleshooting guide if connectivity issues arise.
How do you install and configure Certbot on Ubuntu?
The official Certbot PPA provides the latest stable release, which matters because Let's Encrypt periodically deprecates older ACME protocol versions. On Ubuntu 22.04 or 24.04, use the following sequence:
sudo apt update
sudo apt install -y certbot python3-certbot-nginx
sudo ufw allow 'Nginx Full'
sudo ufw reload The python3-certbot-nginx plugin is critical—it modifies your Nginx configuration automatically instead of requiring manual edits. Without it, you'd need to generate certificates separately and edit server blocks by hand, increasing error risk.
Obtaining your first certificate
Run Certbot with the Nginx plugin to handle both issuance and configuration in one step:
sudo certbot --nginx -d example.com -d www.example.com Certbot will prompt for an email address (used for expiry warnings), agreement to terms, and optional EFF newsletter signup. After successful validation, it modifies your Nginx config to include SSL directives and redirects HTTP to HTTPS. Test the configuration before reloading:
sudo nginx -t
sudo systemctl reload nginx A common mistake is skipping the syntax test. If Certbot's modifications conflict with existing custom directives, Nginx fails silently on reload, leaving your site down. Always validate.
How do you automate certificate renewal with Certbot?
Let's Encrypt certificates expire after 90 days. Manual renewal defeats the purpose of automation. Certbot installs a systemd timer during package installation, but you should verify it's active rather than assume:
sudo systemctl status certbot.timer
sudo certbot renew --dry-run The dry-run test simulates renewal without hitting rate limits. If it succeeds, automatic renewal works. If it fails, check these common causes:
- DNS changes: Domain no longer points to this server
- Firewall rules: Port 80 blocked after initial setup
- Nginx config errors: Syntax issues prevent reload post-renewal
- Rate limits: Too many requests for the same domain set recently
For production systems, I recommend adding a post-renewal hook to reload Nginx only when renewal actually occurs, avoiding unnecessary service interruptions:
sudo nano /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh #!/bin/bash
systemctl reload nginx
echo "$(date): Nginx reloaded after cert renewal" >> /var/log/certbot-renewal.log sudo chmod +x /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh This approach integrates cleanly with monitoring. If you're building observability around certificate expiry, see the Prometheus metrics fundamentals guide for exporting cert expiry as a metric.
What security hardening steps follow HTTPS setup with Let's Encrypt and Certbot?
Obtaining a certificate is table stakes. Production deployments require additional hardening to achieve strong SSL Labs ratings and resist downgrade attacks. Edit your Nginx server block after Certbot completes its initial configuration:
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
# Modern cipher suite (TLS 1.2+ only)
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;
# Session caching reduces handshake overhead
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# HSTS prevents protocol downgrade attacks
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# OCSP stapling improves TLS performance
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 valid=300s;
resolver_timeout 5s;
root /var/www/html;
index index.html;
} | Hardening Directive | Purpose | Risk if Omitted |
|---|---|---|
ssl_protocols TLSv1.2 TLSv1.3 | Disables vulnerable TLS 1.0/1.1 | POODLE, BEAST attacks possible |
Strict-Transport-Security | Forces HTTPS for 2 years | SSL stripping attacks on first visit |
ssl_session_tickets off | Prevents ticket key compromise | Forward secrecy weakened |
ssl_stapling on | Server provides OCSP response | Client privacy leaked to CA |
ssl_prefer_server_ciphers off | Trusts client cipher preference | Incompatible with modern clients |
After applying these changes, test your configuration at SSL Labs. Aim for an A+ rating. If you receive warnings about missing HSTS preload eligibility or weak key exchange, revisit the cipher suite and header configuration. For broader server hardening beyond TLS, consult the Ubuntu security hardening guide.
How do you troubleshoot common Certbot failures?
Even straightforward HTTPS setup with Let's Encrypt and Certbot encounters issues. Here are the most frequent problems and their resolutions:
- "Unable to reach challenge URL": Verify DNS propagation with
dig +short example.com. Confirm UFW allows port 80:sudo ufw status numbered. Check that no CDN or proxy intercepts the challenge path. - "Too many certificates already issued": Let's Encrypt enforces rate limits (5 certs/week per domain set). Use
--dry-runfor testing. Wait 7 days or use a subdomain variation if blocked. - "Plugin not found": You installed
certbotwithoutpython3-certbot-nginx. Reinstall:sudo apt install python3-certbot-nginx. - "Permission denied" on renewal: The systemd timer runs as root, but manual tests may fail if run without sudo. Always prefix with
sudofor renewal commands. - Nginx fails after renewal: Custom config conflicts with Certbot's managed block. Move custom directives outside the
# managed by Certbotsection or useincludefiles.
Logging helps diagnose intermittent issues. Certbot writes to /var/log/letsencrypt/letsencrypt.log. For persistent problems, increase verbosity: sudo certbot renew --dry-run -v --debug-challenges. This outputs each validation step, revealing exactly where the process stalls.
Securing Your Production TLS Deployment
A successful HTTPS setup with Let's Encrypt and Certbot is just the foundation. Maintain security by monitoring certificate expiry through your observability stack, auditing cipher configurations quarterly as standards evolve, and testing renewals monthly in staging environments before production dependencies accumulate. If you manage multiple domains or need centralized secret storage for TLS artifacts across services, explore Kubernetes secrets management or HashiCorp Vault integration for larger fleets.
Need help implementing this on your infrastructure or auditing an existing TLS deployment? Get in touch for a consultation tailored to your environment.