Let's Encrypt Complete Guide 2025: Free SSL Certificates

October 15, 2025 By SSL Checker Pro Team 8 min read

Let's Encrypt has revolutionized web security by providing free, automated SSL/TLS certificates to millions of websites. This comprehensive guide covers everything you need to know about using Let's Encrypt in 2025, from basic installation to advanced automation and wildcard certificates.

What is Let's Encrypt?

Let's Encrypt is a free, automated, and open Certificate Authority (CA) that provides SSL/TLS certificates at no cost. Launched in 2016, it has issued over 3 billion certificates and secured more than 300 million websites worldwide.

Key Features

  • 100% Free: No cost for certificates, renewals, or support
  • Automated: ACME protocol enables automatic issuance and renewal
  • Secure: Industry-standard encryption, trusted by all major browsers
  • Transparent: All certificates logged in Certificate Transparency logs
  • Open: Open source tools and protocols
  • Wildcard Support: Free wildcard certificates for subdomains

Installing Certbot

Ubuntu/Debian

# Update package list
sudo apt update

# Install Certbot
sudo apt install certbot python3-certbot-nginx

# Or for Apache
sudo apt install certbot python3-certbot-apache

CentOS/RHEL

# Enable EPEL repository
sudo yum install epel-release

# Install Certbot
sudo yum install certbot python3-certbot-nginx

# Or for Apache
sudo yum install certbot python3-certbot-apache

Using Snap (Recommended)

# Install snapd
sudo apt install snapd

# Install Certbot via snap
sudo snap install --classic certbot

# Create symlink
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Obtaining Your First Certificate

Automatic Configuration (Nginx)

# Automatic Nginx configuration
sudo certbot --nginx -d example.com -d www.example.com

# Certbot will:
# 1. Obtain certificate
# 2. Configure Nginx automatically
# 3. Set up HTTPS redirect
# 4. Enable automatic renewal

Automatic Configuration (Apache)

# Automatic Apache configuration
sudo certbot --apache -d example.com -d www.example.com

# Certbot handles everything automatically

Manual Certificate Only

# Get certificate without auto-configuration
sudo certbot certonly --webroot \
    -w /var/www/html \
    -d example.com \
    -d www.example.com \
    --email admin@example.com \
    --agree-tos \
    --non-interactive

# Certificates saved to:
# /etc/letsencrypt/live/example.com/fullchain.pem
# /etc/letsencrypt/live/example.com/privkey.pem

Wildcard Certificates

DNS-01 Challenge Required

Wildcard certificates require DNS validation. Install DNS plugin for your provider:

# Cloudflare
sudo apt install python3-certbot-dns-cloudflare

# Create credentials file
mkdir -p ~/.secrets
cat > ~/.secrets/cloudflare.ini << EOF
dns_cloudflare_api_token = YOUR_API_TOKEN
EOF
chmod 600 ~/.secrets/cloudflare.ini

# Request wildcard certificate
sudo certbot certonly \
    --dns-cloudflare \
    --dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
    -d example.com \
    -d *.example.com \
    --email admin@example.com \
    --agree-tos

Supported DNS Providers

Provider Plugin Installation
Cloudflare certbot-dns-cloudflare apt install python3-certbot-dns-cloudflare
AWS Route53 certbot-dns-route53 apt install python3-certbot-dns-route53
Google Cloud DNS certbot-dns-google apt install python3-certbot-dns-google
DigitalOcean certbot-dns-digitalocean apt install python3-certbot-dns-digitalocean

Automatic Renewal

Testing Renewal

# Dry run (test without actually renewing)
sudo certbot renew --dry-run

# If successful, automatic renewal is configured

Renewal Configuration

# Check systemd timer status
sudo systemctl status certbot.timer

# Enable timer if not active
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer

# Manual renewal (if needed)
sudo certbot renew

# Force renewal
sudo certbot renew --force-renewal

Renewal Hooks

# Create post-renewal hook
sudo nano /etc/letsencrypt/renewal-hooks/post/reload-services.sh

#!/bin/bash
systemctl reload nginx
systemctl reload apache2
echo "Services reloaded after certificate renewal"

# Make executable
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/reload-services.sh

Manual Nginx Configuration

# /etc/nginx/sites-available/example.com

# HTTP to HTTPS redirect
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

# HTTPS configuration
server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    
    # SSL certificates
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # SSL configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    
    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    
    # Security headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
    root /var/www/html;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

# Enable site
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Manual Apache Configuration

# /etc/apache2/sites-available/example.com-ssl.conf


    ServerName example.com
    ServerAlias www.example.com
    
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]



    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
    
    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite HIGH:!aNULL:!MD5
    SSLHonorCipherOrder on
    
    # OCSP Stapling
    SSLUseStapling on
    SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
    
    # Security headers
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    
    
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    


# Enable modules and site
sudo a2enmod ssl rewrite headers
sudo a2ensite example.com-ssl
sudo apache2ctl configtest
sudo systemctl reload apache2

Rate Limits

⚠️ Let's Encrypt Rate Limits

  • Certificates per Domain: 50 per week
  • Duplicate Certificates: 5 per week
  • Failed Validations: 5 per account per hostname per hour
  • Accounts per IP: 10 per 3 hours
  • Pending Authorizations: 300 per account

Use staging environment for testing to avoid hitting limits!

Using Staging Environment

# Test with staging server (doesn't count against rate limits)
sudo certbot certonly --staging \
    --nginx \
    -d example.com \
    -d www.example.com

# Once working, get production certificate
sudo certbot certonly \
    --nginx \
    -d example.com \
    -d www.example.com

Advanced Features

Multiple Domains (SAN)

# Single certificate for multiple domains
sudo certbot certonly --nginx \
    -d example.com \
    -d www.example.com \
    -d blog.example.com \
    -d shop.example.com \
    -d api.example.com

Certificate Expansion

# Add new domain to existing certificate
sudo certbot certonly --nginx \
    -d example.com \
    -d www.example.com \
    -d blog.example.com \
    -d newdomain.example.com \
    --expand

Certificate Revocation

# Revoke certificate
sudo certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem

# Revoke and delete
sudo certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem --delete-after-revoke

Troubleshooting

Common Issues

Port 80 Not Accessible

# Check if port 80 is open
sudo netstat -tlnp | grep :80

# Check firewall
sudo ufw status
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Test from external
curl -I http://example.com/.well-known/acme-challenge/test

DNS Not Propagated

# Check DNS
dig example.com +short
nslookup example.com

# Wait for DNS propagation (up to 48 hours)
# Use DNS checker: https://dnschecker.org/

Webroot Not Found

# Verify webroot path
ls -la /var/www/html/.well-known/acme-challenge/

# Create if missing
sudo mkdir -p /var/www/html/.well-known/acme-challenge/
sudo chown -R www-data:www-data /var/www/html/.well-known/

Best Practices

Security Recommendations

  • Always use fullchain.pem (includes intermediates)
  • Enable OCSP stapling for better performance
  • Implement HSTS with preload
  • Use TLS 1.2 and 1.3 only
  • Configure strong cipher suites
  • Set up automatic renewal monitoring
  • Test renewal process regularly

Monitoring and Alerts

#!/bin/bash
# Monitor certificate expiration

DOMAIN="example.com"
ALERT_DAYS=14

EXPIRY=$(echo | openssl s_client -servername $DOMAIN -connect $DOMAIN:443 2>/dev/null | \
         openssl x509 -noout -enddate | cut -d= -f2)

EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)
CURRENT_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $CURRENT_EPOCH) / 86400 ))

if [ $DAYS_LEFT -lt $ALERT_DAYS ]; then
    echo "WARNING: Certificate expires in $DAYS_LEFT days"
    # Send email/slack notification
fi

Conclusion

Let's Encrypt has made SSL/TLS certificates accessible to everyone, removing cost barriers and simplifying deployment. By following this guide, you can secure your website with free, trusted certificates and maintain them with automated renewal. The combination of Certbot's automation and Let's Encrypt's reliability makes HTTPS deployment straightforward and maintainable.

Verify Your Let's Encrypt Certificate

Use our free tools to check your installation: