What Is Let's Encrypt?
Let's Encrypt is a free, automated Certificate Authority. It issues Domain Validation (DV) certificates that are trusted by all major browsers. Over 300 million websites use Let's Encrypt certificates.
Key facts: - Free -- no cost, ever - Automated -- certificates are issued and renewed via the ACME protocol - 90-day validity -- shorter than commercial certs, but auto-renewal handles it - Rate limited -- 50 certificates per registered domain per week
Install Certbot
Certbot is the most popular ACME client for Let's Encrypt.
Ubuntu/Debian
sudo apt update
sudo apt install certbot
With nginx plugin
sudo apt install certbot python3-certbot-nginx
With Apache plugin
sudo apt install certbot python3-certbot-apache
macOS
brew install certbot
Docker
docker run -it --rm \
-v "/etc/letsencrypt:/etc/letsencrypt" \
-v "/var/www/certbot:/var/www/certbot" \
certbot/certbot certonly
Get Your First Certificate
Automatic (nginx)
The easiest method. Certbot modifies your nginx config automatically:
sudo certbot --nginx -d example.com -d www.example.com
Automatic (Apache)
sudo certbot --apache -d example.com -d www.example.com
Manual (HTTP-01)
If you want to handle the web server config yourself:
sudo certbot certonly --webroot -w /var/www/html \
-d example.com -d www.example.com
This creates a file in /var/www/html/.well-known/acme-challenge/ that Let's Encrypt checks to verify you control the domain.
Manual (DNS-01)
Required for wildcard certificates. Certbot tells you to create a DNS TXT record:
sudo certbot certonly --manual --preferred-challenges dns \
-d "*.example.com" -d "example.com"
Certbot will display something like:
Please deploy a DNS TXT record under the name:
_acme-challenge.example.com
with the following value:
gfj9Xq...Rg85nM
Add this TXT record at your DNS provider, wait for propagation, then press Enter.
You can also use our Let's Encrypt page which handles the ACME flow through a web interface.
Where Certificates Are Stored
/etc/letsencrypt/
├── live/example.com/
│ ├── cert.pem # Your certificate
│ ├── chain.pem # Intermediate CA chain
│ ├── fullchain.pem # cert.pem + chain.pem (use this in nginx/Apache)
│ └── privkey.pem # Private key
├── archive/ # All certificate versions
└── renewal/ # Renewal configuration
Use fullchain.pem (not cert.pem) in your web server config to avoid chain issues.
Automatic Renewal
Certbot installs a systemd timer or cron job that runs certbot renew twice daily. Certificates are renewed when they're within 30 days of expiry.
Verify renewal works
sudo certbot renew --dry-run
Manual renewal
sudo certbot renew
Post-renewal hooks
Reload your web server after renewal:
sudo certbot renew --deploy-hook "systemctl reload nginx"
Or in the renewal config (/etc/letsencrypt/renewal/example.com.conf):
[renewalparams]
post_hook = systemctl reload nginx
Validation Methods Explained
HTTP-01 (most common)
Let's Encrypt requests a file at http://example.com/.well-known/acme-challenge/<token>. Your web server must serve this file on port 80.
Requirements: Port 80 open, web server running Limitations: Doesn't work for wildcard certificates
DNS-01 (required for wildcards)
Let's Encrypt checks for a TXT record at _acme-challenge.example.com.
Requirements: Access to your DNS provider's API (or manual record creation) Advantages: Works for wildcards, doesn't need a running web server
TLS-ALPN-01
Let's Encrypt connects to port 443 and checks a special TLS extension. Less common but useful when port 80 is unavailable.
Wildcard Certificates
Wildcards require DNS-01 validation. You can't use HTTP-01 for *.example.com.
# Interactive (manual DNS)
sudo certbot certonly --manual --preferred-challenges dns \
-d "*.example.com" -d "example.com"
# Automated with DNS plugin (Cloudflare example)
sudo certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
-d "*.example.com" -d "example.com"
DNS plugins exist for most providers: Cloudflare, Route 53, Google Cloud DNS, DigitalOcean, and more.
Common Issues
Port 80 is blocked
Your ISP or firewall blocks port 80. Solutions: - Use DNS-01 validation instead - Use TLS-ALPN-01 on port 443 - Use a DNS plugin for automated DNS validation
Too many certificates
Let's Encrypt limits you to 50 certificates per registered domain per week. If you hit this:
- Use a single certificate with multiple SANs instead of separate certs
- Use the staging environment for testing (--staging flag)
- Wait a week for the rate limit to reset
Certificate doesn't include www
Always include both the bare domain and www:
certbot --nginx -d example.com -d www.example.com
Renewal fails
Common causes: - Web server not running during renewal - Port 80 blocked by firewall - DNS records changed - Server moved to a new IP
Check logs: sudo journalctl -u certbot or /var/log/letsencrypt/letsencrypt.log
"Certificate not trusted" on older devices
Let's Encrypt's root certificate (ISRG Root X1) is trusted by all modern browsers. Very old Android devices (pre-7.1.1) may not trust it. Use fullchain.pem to include the cross-signed chain for maximum compatibility.
Let's Encrypt vs Other Free Options
| Provider | Validity | Wildcard | Automation | Trust |
|---|---|---|---|---|
| Let's Encrypt | 90 days | Yes (DNS-01) | ACME | Universal |
| ZeroSSL | 90 days | Yes | ACME | Universal |
| Buypass Go | 180 days | No | ACME | Universal |
| getaCert.com | 60 days (free) | No | Manual / API | Requires CA install |
| Cloudflare | 15 years | Yes | Automatic | Cloudflare proxy only |
Next Steps
- Try our Let's Encrypt integration for browser-based certificate issuance
- Generate a self-signed certificate for development (no domain needed)
- Check your domain's SSL with our SSL checker