Let's Encrypt Setup Guide: Free SSL in 5 Minutes
There is no longer any excuse for running a website over HTTP. Let's Encrypt provides free, trusted SSL certificates with automated renewal. This guide walks through every setup scenario: Nginx, Apache, wildcard certificates, and fixing the most common certbot errors.
What Is Let's Encrypt?
Let's Encrypt is a free, automated, and open Certificate Authority run by the Internet Security Research Group (ISRG). It issues Domain Validated (DV) SSL certificates at no cost and renews them automatically. As of 2026, it has issued over 4 billion certificates and secures the majority of HTTPS traffic on the internet.
Before Let's Encrypt, SSL certificates cost $50–$300 per year per domain and required manual renewal. The result was millions of sites running on HTTP or with expired certificates. Let's Encrypt eliminated both barriers.
Key facts:
- Certificates are valid for 90 days (intentionally short to encourage automation)
- Certbot, the official client, handles issuance and renewal automatically
- Trusted by all major browsers and operating systems
- Supports wildcard certificates via DNS-01 challenge
- Rate limits: 50 certificates per registered domain per week (more than enough for most use cases)
Step 1: Install Certbot
Certbot is the official ACME client for Let's Encrypt. The recommended installation method on Ubuntu/Debian uses snap, which ensures you always have the latest version:
# Ubuntu / Debian
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
# CentOS / RHEL 8+
sudo dnf install certbot python3-certbot-nginx
# Verify installation
certbot --version
Avoid installing certbot via apt on older Ubuntu versions - the distro-packaged version is often out of date and may not support the latest ACME features.
Step 2: Obtain a Certificate for Nginx
The Nginx plugin is the simplest path. It automatically edits your Nginx config to add SSL directives and redirect HTTP to HTTPS:
# Install the Nginx plugin (if not already included)
sudo apt install python3-certbot-nginx
# Issue certificate and configure Nginx automatically
sudo certbot --nginx -d example.com -d www.example.com
# What certbot will ask:
# - Email address (for renewal reminders and urgent notices)
# - Agree to Terms of Service
# - Share email with EFF (optional)
# - Redirect HTTP to HTTPS? (choose 2 = redirect)
Certbot will:
- Complete the HTTP-01 challenge (place a file in
/.well-known/acme-challenge/) - Receive the certificate from Let's Encrypt
- Store it in
/etc/letsencrypt/live/example.com/ - Edit your Nginx server block to add
ssl_certificate,ssl_certificate_key, and a 301 redirect - Reload Nginx
Step 3: Obtain a Certificate for Apache
# Install the Apache plugin
sudo apt install python3-certbot-apache
# Issue certificate and configure Apache automatically
sudo certbot --apache -d example.com -d www.example.com
The Apache plugin works identically to the Nginx plugin. It modifies your VirtualHost configuration to enable mod_ssl and adds the certificate paths.
Step 4: Verify Auto-Renewal
Certbot installs a systemd timer (or cron job on older systems) that runs twice daily to check for certificates expiring within 30 days and renews them automatically.
# Test the renewal process (dry run - no changes made)
sudo certbot renew --dry-run
# Check the systemd timer status
sudo systemctl status snap.certbot.renew.timer
# List all certificates and their expiry dates
sudo certbot certificates
If the dry run passes, auto-renewal is working correctly. Let's Encrypt sends email warnings at 20 days and 7 days before expiry if renewal fails.
Check Your SSL Certificate Instantly
Verify your certificate is valid, check the expiry date, inspect the issuer chain, and confirm TLS configuration - all from your browser, no install required.
Open SSL CheckerStep 5: Wildcard Certificates with DNS-01 Challenge
Standard certificates cover specific hostnames (e.g. example.com and www.example.com). A wildcard certificate covers all subdomains: *.example.com. To issue a wildcard certificate, Let's Encrypt requires you to prove control of the domain via a DNS TXT record (DNS-01 challenge) rather than an HTTP file.
# Request a wildcard certificate
sudo certbot certonly \
--manual \
--preferred-challenges dns \
-d "*.example.com" \
-d "example.com"
# Certbot will prompt:
# Please deploy a DNS TXT record under:
# _acme-challenge.example.com
# with the following value:
#
# Add this record in your DNS provider, wait for propagation,
# then press Enter to continue.
For automated wildcard renewal, use a DNS provider plugin instead of --manual. Certbot has plugins for Cloudflare, Route53, DigitalOcean, and many others:
# Automated wildcard renewal with Cloudflare DNS plugin
pip install certbot-dns-cloudflare
# Create credentials file
cat > /etc/letsencrypt/cloudflare.ini << EOF
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN
EOF
chmod 600 /etc/letsencrypt/cloudflare.ini
# Issue wildcard certificate
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d "*.example.com" \
-d "example.com"
Certificate File Locations
After issuance, certificates are stored in /etc/letsencrypt/live/example.com/. The four files you will reference in your web server config:
fullchain.pem- Your certificate + the intermediate chain. Use this asssl_certificatein Nginx orSSLCertificateFilein Apache.privkey.pem- Your private key. Use this asssl_certificate_keyin Nginx orSSLCertificateKeyFilein Apache. Never share this file.cert.pem- Your certificate only (without chain). Rarely used directly.chain.pem- The intermediate chain only. Used for OCSP stapling.
Hardening Your SSL Configuration
Certbot configures basic SSL, but there are additional hardening steps worth applying:
# Nginx hardened SSL block
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;
# Modern TLS configuration (TLS 1.2 + 1.3 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;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
# HSTS: tell browsers to only use HTTPS for 1 year
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
Troubleshooting Common Errors
Error: Connection refused on port 80
The HTTP-01 challenge requires port 80 to be accessible. Check: (1) your firewall allows inbound TCP 80, (2) Nginx/Apache is running, (3) no other process is blocking port 80. Run sudo netstat -tlnp | grep :80 to see what is listening.
Error: Too many certificates already issued
Let's Encrypt rate-limits to 50 certificates per registered domain per week. If you are hitting this during development/testing, use the staging environment: add --staging to your certbot command. Staging certificates are not trusted by browsers but have much higher rate limits.
Error: DNS problem / NXDOMAIN looking up A for ...
The domain must have a valid DNS A record pointing to your server's IP before certbot can validate it. Confirm with dig +short example.com. DNS changes can take up to 48 hours to propagate globally, though 5–15 minutes is typical for most providers.
Certificate not renewing automatically
Run sudo certbot renew --dry-run and examine the output. Common causes: port 80 closed in firewall (blocks HTTP challenge), web server config changed and /.well-known/acme-challenge/ is now blocked by a rule, or the systemd timer was disabled. Check sudo systemctl status snap.certbot.renew.timer.
FAQ
How long do Let's Encrypt certificates last?
Let's Encrypt certificates are valid for 90 days. This is intentional - the short validity period forces automation and limits the damage from a compromised key. Certbot is configured to renew certificates when they have 30 days or less remaining, so with twice-daily renewal checks, you will never have a certificate expire in practice.
Is Let's Encrypt as trusted as paid SSL certificates?
For Domain Validated (DV) certificates, yes. Let's Encrypt certificates are trusted by all major browsers and operating systems. They provide the same encryption as a paid DV certificate. The difference between DV and paid certificates is the validation level: EV (Extended Validation) and OV (Organization Validated) certificates verify business identity, but browsers no longer visually distinguish them (the green company name in the address bar was removed in Chrome 77). For most websites, Let's Encrypt DV certificates are exactly what you need.
Can I use Let's Encrypt for internal/private domains?
Not directly. Let's Encrypt can only issue certificates for publicly-resolvable domain names (domains that exist in the public DNS). For internal domains like app.internal.company.com, you need either: a private CA (Step CA, HashiCorp Vault PKI), a split-horizon DNS setup where the internal subdomain resolves publicly for the DNS challenge, or self-signed certificates for development environments.
What is the difference between certonly and certbot --nginx?
certbot --nginx (or --apache) issues the certificate and automatically configures your web server. certbot certonly issues the certificate but does not touch your web server config - you configure SSL manually. Use certonly when you want full control over your SSL configuration, or when certbot does not support your web server (e.g. Caddy, HAProxy).
What happens if my certificate expires?
If your certificate expires, browsers will show a security warning and refuse to connect (for sites with HSTS headers, there is no bypass option). Certbot's automatic renewal prevents this for as long as certbot can reach the ACME server and your domain's HTTP challenge passes. Monitor your certificate expiry dates actively. Check your certificate status with our SSL Checker tool.
After setting up your certificate, verify it is correctly installed and check your TLS configuration: Use our free SSL Checker here →
Usman has 10+ years of experience securing enterprise infrastructure, managing high-traffic servers, and building zero-knowledge security tools. Read more about the author.