Free SSL via Let's Encrypt: Install certbot in 10 Minutes
Free SSL via Let's Encrypt: Install certbot in 10 Minutes
Let's Encrypt is a non-profit CA that issues free SSL certificates with automatic renewal. Since 2016 it's become the de facto standard for small and mid-size businesses: setup takes 10 minutes, renewals happen automatically, and every modern browser trusts the cert. This is a full guide for installing certbot on Ubuntu/Debian and CentOS with nginx and Apache examples.
What Let's Encrypt and the ACME protocol are
Let's Encrypt uses the ACME protocol (Automatic Certificate Management Environment) — a standardized API документацию for cert issuance. A client on your server proves domain ownership via HTTP-01, DNS-01, or TLS-ALPN-01 challenge and receives a 90-day cert. Certbot is the official ACME client; alternatives: acme.sh, lego, Caddy (built-in).
Let's Encrypt rate limits:
- 50 certs per week per registered domain.
- 100 SANs per cert.
- 5 duplicate certs per week.
- 300 new orders in 3 hours per account.
Installing certbot
Ubuntu/Debian:
sudo apt update
sudo apt install certbot python3-certbot-nginx
# for Apache:
sudo apt install certbot python3-certbot-apache
CentOS/RHEL/AlmaLinux:
sudo dnf install certbot python3-certbot-nginx
Universal via snap (recommended on modern systems):
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Check: certbot --version should show 2.0+.
Issue a cert for nginx (automatic mode)
Easiest — the nginx plugin edits your config for you:
sudo certbot --nginx -d example.com -d www.example.com
Certbot asks for email (renewal notifications), ToS, and issues the cert. Files land in /etc/letsencrypt/live/example.com/. Your nginx config gets:
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
Verify: sudo nginx -t && sudo systemctl reload nginx. Open https://example.com — green padlock expected.
Manual mode via webroot
If you don't want certbot touching your nginx config (because you use a template or Ansible), fetch only the cert:
sudo certbot certonly --webroot -w /var/www/html \
-d example.com -d www.example.com
nginx must serve /.well-known/acme-challenge/ from /var/www/html:
location /.well-known/acme-challenge/ {
root /var/www/html;
}
Then wire up the cert paths in your SSL config and reload.
Standalone mode (no web server)
When no web server is configured yet, or for non-standard ports:
sudo systemctl stop nginx
sudo certbot certonly --standalone -d example.com
sudo systemctl start nginx
Certbot temporarily runs its own server on port 80. The port must be free — stop nginx/apache.
DNS-01 for wildcards
Wildcards are DNS-01 only. Cloudflare example:
# Install plugin
sudo snap install certbot-dns-cloudflare
# Token file
sudo tee /etc/letsencrypt/cloudflare.ini <<EOF
dns_cloudflare_api_token = YOUR_TOKEN
EOF
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
# Issue wildcard
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d "*.example.com" -d example.com
Similar plugins exist for Route 53, DigitalOcean, Google Cloud DNS. More about the tradeoff — wildcard vs SAN.
Automatic renewal
Certbot creates a systemd timer that runs certbot renew twice a day. Check:
sudo systemctl status certbot.timer
# or cron:
cat /etc/cron.d/certbot
Dry-run:
sudo certbot renew --dry-run
Actual renewal skips certs with > 30 days to expiry. Add a reload hook:
# /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
#!/bin/bash
systemctl reload nginx
chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
Common errors
- “DNS problem: NXDOMAIN” — domain doesn't resolve. Check A/AAAA.
- “Failed authorization: Invalid response from http://...” — port 80 blocked or webroot misconfigured.
- “too many certificates already issued” — hit the 50/week cap. Test with
--test-cert(staging). - “unable to get local issuer certificate” — broken chain, see incomplete chain.
- Android < 7.1.1 doesn't trust ISRG Root X1 — use the long chain (cross-signed).
Monitoring and alerts
Certbot automates renewal but cron can silently break (disk, DNS). Add external monitoring: Enterno.io Monitors checks expiry every 5 minutes and alerts 14/7/3 days in advance via Telegram, Email, or Slack. Insurance against a forgotten renewal becoming NET::ERR_CERT_DATE_INVALID.
Frequently asked questions
Is Let's Encrypt appropriate for commercial sites?
Yes. Let's Encrypt is used by Cloudflare, WordPress.com, Mozilla, Netflix, and millions of sites. The only limitation — no EV certs with green company-name badge.
Why 90 days instead of a year?
Shorter validity reduces compromise impact — a stolen key is useful for 3 months max. It also forces automation.
How do I issue a cert behind NAT or without a public IP?
Use DNS-01 — it doesn't need HTTP access. The server doesn't even have to be public.
Can I use Let's Encrypt on Windows Server?
Yes, via win-acme — a full-featured ACME client for IIS.
Conclusion
Let's Encrypt + certbot is the fastest path to a valid SSL: 10 minutes, free, auto-renewed. After install, verify the config via enterno.io SSL Checker and set up Monitors for Slack/Telegram expiry alerts. Next steps — enable HSTS and harden cipher suites.
ACME — RFC 8555. Certbot docs — certbot.eff.org. Let's Encrypt docs — letsencrypt.org/docs.
Check your website right now
Check now →