Let's Encrypt has transformed the web in just a few years: free SSL certificates, automatic renewal, and wildcard support are all available at no cost. In 2026 there is no reason to leave a site on HTTP. This guide covers installing certificates on Apache and Nginx with Certbot, configuring auto-renewal, and resolving common problems.
Before you begin, make sure your domain points to your server (the A record is configured) and ports 80 and 443 are open. Check the current SSL status using the SSL checker. For long-term monitoring of certificate expiration, use SSL Monitor.
What is Let's Encrypt
A brief history
Let's Encrypt is a nonprofit certificate authority (CA), launched in 2015 with support from Mozilla, Cisco, Google, and others. Its goal is to make HTTPS accessible to everyone. Billions of certificates have been issued over the years. Certificates are valid for 90 days (previously 60), encouraging renewal automation.
Features
| Parameter | Value |
|---|---|
| Cost | Free |
| Validity period | 90 days |
| Validation type | DV (Domain Validation) |
| Wildcard | Yes (via DNS challenge) |
| Certificate limit | 50 per domain per week |
| Duplicate limit | 5 per week |
ACME protocol
Let's Encrypt uses the ACME (Automated Certificate Management Environment) protocol to automate certificate issuance. Certbot is the most popular ACME client, supporting HTTP-01 and DNS-01 challenges for domain validation.
Installing Certbot
Ubuntu / Debian
# Обновление пакетов
sudo apt update
# Установка Certbot и плагина для Nginx или Apache
# Для Nginx:
sudo apt install certbot python3-certbot-nginx -y
# Для Apache:
sudo apt install certbot python3-certbot-apache -y
# Только Certbot (без плагинов, для ручной настройки):
sudo apt install certbot -yCentOS / RHEL / Rocky Linux
# Установка EPEL (если не установлен)
sudo dnf install epel-release -y
# Certbot для Nginx
sudo dnf install certbot python3-certbot-nginx -y
# Certbot для Apache
sudo dnf install certbot python3-certbot-apache -yVerify the installation
certbot --version
# certbot 2.x.xInstalling a certificate on Nginx
Automatic mode (recommended)
Certbot can configure Nginx itself: add a location block for the ACME challenge and configure SSL.
# Один домен
sudo certbot --nginx -d example.com
# Несколько доменов (один сертификат)
sudo certbot --nginx -d example.com -d www.example.com
# Интерактивный режим: email для уведомлений, согласие с ToSCertbot will ask for:
- An email address for expiration notifications
- Agreement to the terms of service
- Optionally, an HTTP → HTTPS redirect (recommended)
Manual Nginx configuration
If you prefer full control, configure Nginx manually and use certbot certonly.
Step 1. Set up a temporary server for the ACME challenge:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/html;
location /.well-known/acme-challenge/ {
root /var/www/html;
allow all;
}
location / {
return 301 https://$host$request_uri;
}
}Step 2. Create a directory and obtain the certificate:
sudo mkdir -p /var/www/html/.well-known/acme-challenge
sudo chown -R www-data:www-data /var/www/html
sudo certbot certonly --webroot -w /var/www/html -d example.com -d www.example.comStep 3. Add an SSL block to Nginx:
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 (см. раздел ниже)
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
root /var/www/html;
index index.html;
# ... остальная конфигурация
}Step 4. Reload Nginx:
sudo nginx -t
sudo systemctl reload nginxFull Nginx configuration with SSL
# Редирект HTTP → HTTPS
server {
listen 80;
server_name example.com www.example.com;
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
return 301 https://$host$request_uri;
}
}
# HTTPS
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;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}Installing a certificate on Apache
Automatic mode
sudo certbot --apache -d example.com -d www.example.comCertbot will automatically:
- Find virtual hosts
- Add SSL configuration
- Configure a redirect (if you choose one)
Manual Apache configuration
Step 1. Enable the SSL and rewrite modules:
sudo a2enmod ssl rewrite
sudo systemctl restart apache2Step 2. Obtain the certificate:
sudo certbot certonly --webroot -w /var/www/html -d example.com -d www.example.comStep 3. Create a virtual host for HTTPS:
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/html
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
<Directory /var/www/html>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>Step 4. Redirect HTTP → HTTPS:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect permanent / https://example.com/
</VirtualHost>Step 5. Restart Apache:
sudo apache2ctl configtest
sudo systemctl restart apache2Wildcard certificates (DNS challenge)
Subdomains such as *.example.com require DNS validation: Let's Encrypt verifies that you control the domain through a TXT record.
Obtaining a wildcard certificate
sudo certbot certonly --manual --preferred-challenges dns -d example.com -d "*.example.com"Certbot will display instructions:
Please deploy a DNS TXT record under the name _acme-challenge.example.com with the following value:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Before continuing, verify the record is deployed.Actions:
- Create a TXT record
_acme-challenge.example.comwith the specified value - Wait for DNS propagation (1–10 minutes; check using
dig TXT _acme-challenge.example.com) - Press Enter in Certbot
Automating the DNS challenge
To automatically renew wildcard certificates, use plugins:
- certbot-dns-cloudflare — for Cloudflare
- certbot-dns-route53 — for AWS Route 53
- certbot-dns-google — for Google Cloud DNS
Example for Cloudflare:
sudo apt install python3-certbot-dns-cloudflare -yCreate a file containing the API token:
# /etc/letsencrypt/cloudflare.ini
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKENchmod 600 /etc/letsencrypt/cloudflare.ini
sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini -d example.com -d "*.example.com"Certificate auto-renewal
Certbot system timer
Certbot creates a systemd timer for automatic renewal. Check its status:
sudo systemctl status certbot.timer
sudo systemctl list-timers | grep certbotRenewal runs twice a day. Certbot renews certificates 30 days before they expire.
Run renewal manually
# Сухой прогон (без реального обновления)
sudo certbot renew --dry-run
# Реальное обновление
sudo certbot renewReload the web server after renewal
By default, Certbot reloads Apache/Nginx after renewal. For custom scripts, use hooks:
# /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
#!/bin/bash
systemctl reload nginxchmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.shCron as a fallback
If systemd is unavailable:
0 0,12 * * * certbot renew --quiet --post-hook "systemctl reload nginx"Recommended SSL settings
Modern protocols and ciphers
Certbot creates a file, options-ssl-nginx.conf (or options-ssl-apache.conf), with recommended settings. Key parameters:
Nginx:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;Apache:
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384HSTS (optional)
Adds the Strict-Transport-Security header to enforce HTTPS in the browser:
Nginx:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;Apache:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"Check security headers using the Security Headers checker.
Common problems and solutions
Error: "Could not find a virtual host"
Certbot could not find a suitable virtual host. Make sure the configuration specifies the correct server_name (Nginx) or ServerName (Apache) for your domain.
Error: "Connection refused" on port 80
Make sure the web server is listening on port 80 and that the firewall is not blocking it:
sudo ss -tlnp | grep :80
sudo ufw statusError: "DNS problem: NXDOMAIN"
The domain does not resolve. Check the A record:
dig example.com +shortRate limit exceeded
Let's Encrypt limits issuance to 50 certificates per domain per week and 5 duplicates per week. If you exceed the limit, you must wait. Use --dry-run for testing to avoid using up the limit.
Certificate does not renew
Check the logs:
sudo journalctl -u certbot.timer
sudo certbot renew --dry-run -vMake sure port 80 is accessible from outside (for the HTTP-01 challenge).
Let's Encrypt file structure
/etc/letsencrypt/
├── live/example.com/
│ ├── cert.pem # Сертификат сервера
│ ├── chain.pem # Цепочка промежуточных сертификатов
│ ├── fullchain.pem # cert.pem + chain.pem (используйте этот)
│ └── privkey.pem # Приватный ключ
├── archive/ # Архив старых версий
├── renewal/ # Конфигурация обновления
└── renewal-hooks/ # Скрипты при обновленииUse fullchain.pem and privkey.pem in your web server configuration.
Testing and verification
After installation, check that:
- HTTPS opens — open https://example.com in a browser
- The certificate is valid — there are no browser warnings
- The redirect works — http://example.com redirects to https://
- SSL rating — use SSL Checker for detailed analysis
Additional resources: Complete guide to SSL certificates and Types of SSL certificates.
Conclusion
Let's Encrypt with Certbot lets you obtain and maintain free SSL in just a few minutes. Automatic renewal eliminates routine work. A DV certificate is sufficient for most sites; a wildcard certificate is needed only when you have a large number of subdomains. Follow the steps above, and your site will run over HTTPS at no extra cost.