Let's Encrypt SSL: Free HTTPS for Your Website with Certbot

Let's Encrypt SSL: Free HTTPS for Your Website with Certbot


If you’re running a website without HTTPS in 2025, you’re putting your users at risk and hurting your search engine rankings. Browsers now flag HTTP sites as “Not Secure,” and Google has been using HTTPS as a ranking signal since 2014. The good news? Let’s Encrypt provides free, automated SSL/TLS certificates, and Certbot makes obtaining and renewing them effortless.

This guide walks you through everything you need to set up free HTTPS on your server using Let’s Encrypt and Certbot — from installation to automatic renewal.

What Is Let’s Encrypt?

Let’s Encrypt is a free, automated, and open Certificate Authority (CA) run by the Internet Security Research Group (ISRG). Since its launch in 2016, it has issued billions of certificates and is trusted by all major browsers.

Key features:

  • Free — No cost, ever.
  • Automated — Certificates can be issued and renewed without manual intervention.
  • Open — The ACME protocol it uses is an open standard.
  • Secure — Certificates are Domain Validated (DV) and use modern cryptographic standards.

Let’s Encrypt certificates are valid for 90 days, which encourages automation and limits damage from compromised keys.

What Is Certbot?

Certbot is the most popular ACME client for Let’s Encrypt. Developed by the Electronic Frontier Foundation (EFF), it automates the process of obtaining, installing, and renewing SSL/TLS certificates.

Certbot supports a wide range of web servers and operating systems, and it can automatically configure HTTPS for you with a single command.

Prerequisites

Before you start, make sure you have:

  • A Linux server (Ubuntu/Debian, CentOS/RHEL, or similar) with root or sudo access
  • A registered domain name pointing to your server’s IP address (A record in DNS)
  • A web server installed — Nginx or Apache
  • Port 80 and 443 open in your firewall

You can verify your DNS is set up correctly:

dig +short yourdomain.com

This should return your server’s public IP address.

Installing Certbot

Ubuntu / Debian

The recommended way to install Certbot is via snap:

# Remove any old certbot packages
sudo apt remove certbot -y

# Install snapd if not already installed
sudo apt install snapd -y

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

# Create a symlink so certbot is in your PATH
sudo ln -s /snap/bin/certbot /usr/bin/certbot

CentOS / RHEL / Fedora

# Install EPEL repository (CentOS/RHEL)
sudo dnf install epel-release -y

# Install Certbot via snap (recommended)
sudo dnf install snapd -y
sudo systemctl enable --now snapd.socket
sudo ln -s /var/lib/snapd/snap /snap
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Verify Installation

certbot --version

You should see something like certbot 2.x.x.

Obtaining a Certificate with Nginx

If you’re running Nginx, Certbot has a built-in plugin that handles everything — obtaining the certificate and configuring Nginx to use it.

Step 1: Make sure Nginx is running

sudo systemctl status nginx

Ensure your Nginx configuration has a server_name directive matching your domain:

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    root /var/www/yourdomain.com/html;
    index index.html;
}

Step 2: Run Certbot

sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Certbot will:

  1. Verify you control the domain (via HTTP-01 challenge)
  2. Obtain the certificate from Let’s Encrypt
  3. Automatically modify your Nginx config to enable HTTPS
  4. Set up a redirect from HTTP to HTTPS

You’ll be prompted for your email address (for renewal notifications) and to agree to the Terms of Service.

Step 3: Verify

Visit https://yourdomain.com in your browser — you should see the padlock icon. You can also test with:

curl -I https://yourdomain.com

Look for the HTTP/2 200 status and check the certificate details:

echo | openssl s_client -servername yourdomain.com -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -dates

Obtaining a Certificate with Apache

For Apache users, the process is similar:

sudo certbot --apache -d yourdomain.com -d www.yourdomain.com

Certbot’s Apache plugin will automatically configure your virtual host with the SSL certificate and set up redirects.

Make sure your Apache virtual host has ServerName set correctly:

<VirtualHost *:80>
    ServerName yourdomain.com
    ServerAlias www.yourdomain.com
    DocumentRoot /var/www/yourdomain.com/html
</VirtualHost>

Standalone Mode (No Web Server)

If you’re not running Nginx or Apache (or you want to handle configuration manually), you can use standalone mode. Certbot will spin up its own temporary web server on port 80:

sudo certbot certonly --standalone -d yourdomain.com -d www.yourdomain.com

Note: Port 80 must be free — stop any running web server first.

The certificate files will be saved to:

/etc/letsencrypt/live/yourdomain.com/
├── fullchain.pem   # Certificate + intermediate chain
├── privkey.pem     # Private key
├── cert.pem        # Certificate only
└── chain.pem       # Intermediate chain only

Wildcard Certificates

Let’s Encrypt supports wildcard certificates (e.g., *.yourdomain.com), but they require DNS-01 validation instead of HTTP-01. This means you need to create a TXT record in your domain’s DNS.

sudo certbot certonly --manual --preferred-challenges dns \
  -d yourdomain.com -d *.yourdomain.com

Certbot will ask you to create a DNS TXT record like:

_acme-challenge.yourdomain.com  TXT  "random-verification-string"

Add this record in your DNS provider’s dashboard, wait for propagation, then press Enter to continue.

Automating DNS Challenges

For automated wildcard renewals, use a DNS plugin. For example, with Cloudflare:

sudo snap install certbot-dns-cloudflare

# Create credentials file
sudo mkdir -p /etc/letsencrypt
sudo cat > /etc/letsencrypt/cloudflare.ini << EOF
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN
EOF
sudo chmod 600 /etc/letsencrypt/cloudflare.ini

# Obtain wildcard cert
sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d yourdomain.com -d *.yourdomain.com

DNS plugins are available for many providers: Cloudflare, DigitalOcean, Route53, Google Cloud DNS, and more. Check the Certbot DNS plugins documentation for a full list.

Automatic Renewal

Let’s Encrypt certificates expire after 90 days, so automatic renewal is essential. Certbot sets this up automatically when installed via snap.

Verify the Renewal Timer

sudo certbot renew --dry-run

If the dry run succeeds, your certificates will renew automatically. Certbot’s snap installation creates a systemd timer that checks for renewal twice daily:

systemctl list-timers | grep certbot

Manual Renewal (if needed)

sudo certbot renew

This checks all your certificates and renews any that are within 30 days of expiration.

Post-Renewal Hooks

You may need to reload your web server after a certificate is renewed. Add a deploy hook:

sudo certbot renew --deploy-hook "systemctl reload nginx"

Or make it permanent by creating a renewal hook script:

sudo cat > /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh << 'EOF'
#!/bin/bash
systemctl reload nginx
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

Hardening Your SSL Configuration

Getting a certificate is just the start. You should also configure your web server for strong security. Here’s a recommended Nginx SSL configuration:

server {
    listen 443 ssl http2;
    server_name yourdomain.com www.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    # Strong SSL settings
    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 (be careful — this is hard to undo)
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 1.1.1.1 8.8.8.8 valid=300s;

    # Other security headers
    add_header X-Content-Type-Options nosniff always;
    add_header X-Frame-Options DENY always;
    add_header Referrer-Policy strict-origin-when-cross-origin always;

    root /var/www/yourdomain.com/html;
    index index.html;
}

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

Test Your SSL Configuration

Use the free SSL Labs Server Test to check your configuration. Aim for an A+ rating.

You can also test from the command line:

# Check supported TLS versions
nmap --script ssl-enum-ciphers -p 443 yourdomain.com

# Quick certificate check
curl -vI https://yourdomain.com 2>&1 | grep -A5 "Server certificate"

Managing Certificates

List All Certificates

sudo certbot certificates

This shows all certificates managed by Certbot, including their expiration dates and domains.

Revoke a Certificate

If a certificate is compromised or no longer needed:

sudo certbot revoke --cert-path /etc/letsencrypt/live/yourdomain.com/cert.pem

Delete a Certificate

sudo certbot delete --cert-name yourdomain.com

Troubleshooting Common Issues

”Connection refused” or challenge fails

  • Make sure port 80 is open: sudo ufw allow 80/tcp
  • Ensure your domain’s DNS A record points to the correct server IP
  • Check that no other service is using port 80: sudo lsof -i :80

”Too many requests” rate limit

Let’s Encrypt has rate limits:

  • 50 certificates per registered domain per week
  • 5 duplicate certificates per week
  • 5 failed validations per hostname per hour

Use the staging environment for testing:

sudo certbot --nginx --staging -d yourdomain.com

Staging certificates won’t be trusted by browsers, but they don’t count against rate limits.

Certificate renewal fails

# Check renewal config
cat /etc/letsencrypt/renewal/yourdomain.com.conf

# Test renewal manually
sudo certbot renew --cert-name yourdomain.com --dry-run

# Check logs
sudo cat /var/log/letsencrypt/letsencrypt.log

Let’s Encrypt Alternatives

While Let’s Encrypt is the most popular choice, there are other free and paid options:

ProviderFree?WildcardValidityAutomation
Let’s EncryptYesYes (DNS-01)90 daysCertbot, ACME
ZeroSSLYes (3 certs)Paid only90 daysACME compatible
Google Trust ServicesYesYes90 daysACME compatible
Buypass GoYesNo180 daysACME compatible
SSL.comPaidYes1 yearManual or ACME

Since ZeroSSL and Google Trust Services support the ACME protocol, you can even use Certbot with them by specifying a different server:

# Using Google Trust Services
sudo certbot certonly --nginx \
  --server https://dv.acme-v02.api.pki.goog/directory \
  -d yourdomain.com

Summary

Setting up HTTPS with Let’s Encrypt and Certbot is one of the easiest wins for any website operator. Here’s the quick checklist:

  1. Install Certbot via snap (sudo snap install --classic certbot)
  2. Obtain a certificate (sudo certbot --nginx -d yourdomain.com)
  3. Verify auto-renewal (sudo certbot renew --dry-run)
  4. Harden your SSL config (TLS 1.2+, HSTS, OCSP stapling)
  5. Test with SSL Labs for an A+ rating

With free certificates, automatic renewal, and strong community support, there’s no excuse to run a website without HTTPS in 2025. Your users — and Google — will thank you.