Let's Encrypt is a free, automated and open certificate authority that lets anyone obtain SSL/TLS certificates to secure their websites over HTTPS. Combined with Certbot, the EFF's official tool, the process of obtaining and renewing certificates is fully automated.
Prerequisites
Before getting started, make sure you have the following:
- A Linux server: Ubuntu 20.04+, Debian 11+ or CentOS/RHEL 8+ with root or sudo access
- A domain name: pointing to your server's IP address via a DNS A record (or AAAA for IPv6)
- An installed web server: Nginx or Apache (except in standalone mode)
- Ports 80 and 443 open: in your firewall (iptables, ufw, or cloud firewall)
Verify that your domain points to your server before running Certbot. Use the command
dig +short yourdomain.com or nslookup yourdomain.com to confirm resolution.
# Check the DNS resolution of your domain
dig +short yourdomain.com
# Check that ports 80 and 443 are open
sudo ufw status
# Or with iptables
sudo iptables -L -n | grep -E '80|443'
How Let's Encrypt works
Let's Encrypt uses the ACME protocol (Automatic Certificate Management Environment) to validate that you do control the domain for which you are requesting a certificate. The process takes place in several steps:
- Request: Certbot sends a request to the Let's Encrypt authority for the desired domain
- Challenge: Let's Encrypt proposes a validation challenge (HTTP-01, DNS-01 or TLS-ALPN-01)
- Validation: Certbot answers the challenge by placing a file on the web server or a DNS record
- Issuance: Once the challenge is validated, Let's Encrypt issues the certificate
Issued certificates have a validity period of 90 days. This short lifetime is a deliberate security decision that encourages automation and limits the impact of a private key compromise.
Challenge types
- HTTP-01: The most common. Certbot places a file in
.well-known/acme-challenge/on port 80 - DNS-01: A TXT record is created in the DNS zone. Mandatory for wildcard certificates
- TLS-ALPN-01: Validation via port 443 with a special TLS extension. Rarely used
Installing Certbot
Certbot is the official tool recommended by Let's Encrypt. Several installation methods are available.
Recommended method: Snap
Snap always guarantees the latest version of Certbot, regardless of your distribution's version:
# Install snapd if missing
sudo apt update
sudo apt install -y snapd
# Install Certbot via snap
sudo snap install --classic certbot
# Create a symbolic link for global access
sudo ln -s /snap/bin/certbot /usr/bin/certbot
# Check the installation
certbot --version
Alternative method: APT (Debian/Ubuntu)
# Installation via the system repositories
sudo apt update
sudo apt install -y certbot
# For the Nginx plugin
sudo apt install -y python3-certbot-nginx
# For the Apache plugin
sudo apt install -y python3-certbot-apache
Alternative method: pip
# Installation via pip in a virtual environment
sudo apt install -y python3 python3-venv
sudo python3 -m venv /opt/certbot/
sudo /opt/certbot/bin/pip install certbot certbot-nginx
sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot
The Snap method is recommended because it automatically handles Certbot updates. If you use APT, remember to update Certbot regularly.
Obtaining a certificate with Nginx
Certbot's Nginx plugin is able to automatically configure your web server to use the obtained certificate.
Preliminary Nginx configuration
Make sure your Nginx server block contains the server_name directive with your domain:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
root /var/www/yourdomain.com/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
Running Certbot with the Nginx plugin
# Automatically obtain and install the certificate
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
# Non-interactive mode (ideal for scripts)
sudo certbot --nginx --non-interactive --agree-tos
--email [email protected]
-d yourdomain.com -d www.yourdomain.com
Certbot will automatically:
- Obtain the certificate from Let's Encrypt
- Modify the Nginx configuration to enable SSL
- Configure the HTTP to HTTPS redirect
- Reload Nginx to apply the changes
After installation, test your certificate by visiting
https://yourdomain.com in a browser. You can also check your SSL grade on SSL Labs.
Obtaining a certificate with Apache
The Apache plugin works in a similar way to the Nginx plugin. It automatically detects your VirtualHosts and configures SSL.
# Install the Apache plugin if necessary
sudo apt install -y python3-certbot-apache
# Obtain and install the certificate
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com
# Non-interactive mode
sudo certbot --apache --non-interactive --agree-tos
--email [email protected]
-d yourdomain.com -d www.yourdomain.com
Certbot automatically configures the SSL VirtualHost, enables the mod_ssl module and creates the HTTP to HTTPS redirect.
Standalone mode
Standalone mode is useful when you do not have a web server installed or when you want to obtain a certificate without modifying the configuration of an existing server. Certbot launches its own temporary web server on port 80.
# Stop the web server if it uses port 80
sudo systemctl stop nginx # or apache2
# Obtain the certificate in standalone mode
sudo certbot certonly --standalone -d yourdomain.com -d www.yourdomain.com
# Restart the web server
sudo systemctl start nginx # or apache2
Standalone mode requires port 80 to be free. Stop any service using this port before running Certbot. Use
sudo ss -tlnp | grep :80 to check.
DNS challenge mode
The DNS challenge is the only method that allows you to obtain wildcard certificates (*.domain.com). It is also useful when port 80 is not accessible from the Internet.
Manual DNS challenge
# Request a wildcard certificate with a manual DNS challenge
sudo certbot certonly --manual --preferred-challenges dns
-d yourdomain.com -d "*.yourdomain.com"
Certbot will ask you to create a TXT record _acme-challenge.yourdomain.com in your DNS zone. You will have to do this manually via your registrar's or DNS provider's interface.
Automated DNS challenge with a plugin
To automate the renewal of wildcard certificates, use a DNS plugin. Here is the example with Cloudflare:
# Install the Cloudflare plugin
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare
# Create the credentials file
sudo mkdir -p /etc/letsencrypt
sudo tee /etc/letsencrypt/cloudflare.ini > /dev/null << 'EOF'
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN
EOF
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
# Automatically obtain the wildcard certificate
sudo certbot certonly --dns-cloudflare
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini
-d yourdomain.com -d "*.yourdomain.com"
Certbot offers plugins for many DNS providers: Cloudflare, Route53 (AWS), Google Cloud DNS, DigitalOcean, OVH, Linode and many others. Refer to the Certbot documentation for the complete list.
Automatic renewal
Let's Encrypt certificates expire after 90 days. It is essential to configure automatic renewal to avoid any service interruption.
Testing renewal
# Simulate a renewal to check the configuration
sudo certbot renew --dry-run
Systemd timer (recommended method)
If you installed Certbot via Snap, a systemd timer is already configured automatically:
# Check that the timer is active
sudo systemctl status snap.certbot.renew.timer
# View the certbot timers
sudo systemctl list-timers | grep certbot
Cron job (alternative method)
If the systemd timer is not available, set up a cron job:
# Edit the root crontab
sudo crontab -e
# Add the following line (renewal twice a day)
0 0,12 * * * /usr/bin/certbot renew --quiet --deploy-hook "systemctl reload nginx"
The --deploy-hook option runs a command only if the certificate was actually renewed. Here, Nginx is reloaded to take the new certificate into account.
Optimal SSL configuration
Obtaining a certificate is only the first step. A robust SSL configuration is essential to protect your users.
Optimized Nginx configuration
server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
# Let's Encrypt certificates
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# Protocols and cipher suites
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;
# HSTS - Force HTTPS for 1 year
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/yourdomain.com/chain.pem;
resolver 1.1.1.1 8.8.8.8 valid=300s;
resolver_timeout 5s;
# SSL session
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# Additional security headers
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
root /var/www/yourdomain.com/html;
index index.html;
}
# HTTP to HTTPS redirect
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$host$request_uri;
}
This configuration will let you obtain an A+ grade on the SSL Labs test. HSTS with preload and OCSP stapling are the key elements to reach this maximum grade.
Wildcard certificates
A wildcard certificate secures a domain and all of its first-level subdomains with a single certificate. For example, *.yourdomain.com covers api.yourdomain.com, blog.yourdomain.com, mail.yourdomain.com, etc.
# Wildcard certificate (requires DNS challenge)
sudo certbot certonly --dns-cloudflare
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini
-d yourdomain.com
-d "*.yourdomain.com"
A wildcard certificate
*.domain.com does not cover domain.com itself (add it explicitly with -d domain.com). It also does not cover lower-level subdomains such as sub.api.domain.com.
Multi-domain certificates (SAN)
A SAN (Subject Alternative Name) certificate lets you secure several different domains with a single certificate. This is useful when you host several sites on the same server.
# Multi-domain certificate
sudo certbot --nginx
-d domain1.com -d www.domain1.com
-d domain2.fr -d www.domain2.fr
-d domain3.org
# Add a domain to an existing certificate
sudo certbot --nginx --expand
-d domain1.com -d www.domain1.com
-d domain2.fr -d www.domain2.fr
-d new-domain.com
Let's Encrypt allows up to 100 domain names per SAN certificate. It is a convenient solution for consolidating the management of your certificates on a multi-site server.
Troubleshooting
Here are the most common problems encountered with Let's Encrypt and Certbot, along with their solutions.
Rate limits reached
Let's Encrypt enforces strict limits to prevent abuse:
- 50 certificates per registered domain per week
- 5 duplicate certificates per week
- 5 validation failures per account, per hostname, per hour
# Use the staging environment for testing
sudo certbot --staging --nginx -d yourdomain.com
# Check the rate limits for your domain
# See https://crt.sh/?q=yourdomain.com
HTTP-01 validation errors
# Check that port 80 is accessible from the Internet
curl -I http://yourdomain.com/.well-known/acme-challenge/test
# Check the firewall configuration
sudo ufw status verbose
# Check that the web server is running
sudo systemctl status nginx # or apache2
# View the Certbot logs
sudo tail -f /var/log/letsencrypt/letsencrypt.log
Renewal failed
# Diagnose the renewal problem
sudo certbot renew --dry-run --verbose
# Check the certificates and their expiration dates
sudo certbot certificates
# Force the renewal of a specific certificate
sudo certbot renew --cert-name yourdomain.com --force-renewal
# Check the systemd timer logs
sudo journalctl -u snap.certbot.renew.timer --since "7 days ago"
sudo journalctl -u snap.certbot.renew.service --since "7 days ago"
Common errors and solutions
- Connection refused on port 80: Check your firewall and make sure no service is blocking the port
- DNS problem: NXDOMAIN: Your domain does not point to the server. Check your DNS records
- Too many certificates already issued: Wait until the rate limiting window ends (1 week) or use
--staging - Unauthorized 403: The challenge file is not accessible. Check your web server configuration and the permissions of the
.well-knowndirectory
Always test with the
--staging flag before requesting a real certificate. The staging environment has no restrictive rate limits and lets you validate your configuration risk-free.
Conclusion
Let's Encrypt and Certbot have democratized access to SSL/TLS certificates by making the process free and automated. You now have the knowledge to:
- Install Certbot and obtain certificates for Nginx or Apache
- Use standalone mode and DNS challenges
- Configure wildcard and multi-domain certificates
- Automate renewal with systemd or cron
- Optimize your SSL configuration for an A+ grade on SSL Labs
- Diagnose and resolve common problems
HTTPS is no longer an option but a necessity for any website. With Let's Encrypt, there is no longer any excuse not to secure your communications. Take the time to configure HSTS and OCSP stapling for optimal security, and regularly verify that automatic renewal is working correctly.
Comments