DEV Community

Sospeter Mong'are
Sospeter Mong'are

Posted on

Let's Encrypt SSL: A Beginner's Guide to Free HTTPS for Your Website

Introduction

A few years ago, adding HTTPS to your website cost money — sometimes hundreds of dollars per year for an SSL certificate. Many small websites and developers skipped it entirely, leaving their users exposed.

Then in 2016, Let's Encrypt changed everything.

Today, there is no excuse for a website without HTTPS. Let's Encrypt provides free, trusted, automatically renewing SSL certificates to anyone with a domain name. It powers over 300 million websites worldwide and is trusted by every major browser.

This guide explains what SSL is, why it matters, how Let's Encrypt works, and exactly how to install it on an Nginx server running on Ubuntu.


What Is SSL and Why Does It Matter?

SSL (Secure Sockets Layer) — more accurately called TLS (Transport Layer Security) today, though the term SSL stuck — is a protocol that encrypts the connection between a visitor's browser and your web server.

Without SSL, data travels across the internet in plain text. Anyone between the visitor and your server — their ISP, a coffee shop router, a malicious actor on the same network — can read that data. This includes:

  • Login credentials
  • Credit card numbers
  • Personal information
  • Form submissions
  • Session cookies

With SSL, all of that data is encrypted. Even if intercepted, it is unreadable without the decryption key.

The Padlock in the Browser

You have seen it thousands of times — the padlock icon in the browser address bar next to a URL that starts with https://. That padlock means:

  1. The connection between the browser and server is encrypted
  2. The server's identity has been verified by a trusted Certificate Authority
  3. Data cannot be intercepted or tampered with in transit

Without SSL, modern browsers display a "Not Secure" warning in the address bar. This alone drives visitors away and destroys trust in your website.

SSL Is Not Optional Anymore

Beyond security, SSL affects your website in several concrete ways:

Search Engine Rankings: Google confirmed in 2014 that HTTPS is a ranking signal. Two otherwise identical websites — one with HTTPS, one without — the HTTPS site ranks higher.

Browser Warnings: Chrome, Firefox, and Safari all display prominent "Not Secure" warnings on HTTP sites, especially on pages with login forms or payment fields.

HTTP/2: The modern HTTP/2 protocol — which makes websites significantly faster — requires HTTPS in all major browsers. No SSL means no HTTP/2.

User Trust: Studies consistently show that users abandon websites that display security warnings. For any website handling user data, SSL is non-negotiable.


What Is a Certificate Authority?

Your browser doesn't just trust any SSL certificate. It maintains a list of trusted Certificate Authorities (CAs) — organisations that have been vetted and approved to issue certificates.

When you install an SSL certificate, you are essentially telling browsers: "A trusted organisation has verified that I own this domain. You can trust this connection."

Traditionally, Certificate Authorities charged for this service — anywhere from $10 to $1,000+ per year depending on the certificate type. The revenue model made sense: the CA did the work of verifying your identity and browsers trusted their signature.

Let's Encrypt disrupted this entirely. It is a non-profit Certificate Authority — backed by Mozilla, Google, Cisco, and others — that issues certificates for free, automatically, and without any manual verification process.


What Is Let's Encrypt?

Let's Encrypt is a free, automated, open Certificate Authority launched in 2016 by the Internet Security Research Group (ISRG).

Its certificates are:

  • Free — no cost, ever
  • Trusted — recognised by all major browsers and operating systems
  • Automatic — issuance and renewal are fully automated
  • Open — the process is transparent and publicly audited

The only meaningful difference between a Let's Encrypt certificate and a paid certificate is the validation level. Let's Encrypt issues Domain Validated (DV) certificates, which verify you control the domain but do not verify your organisation's legal identity. For the vast majority of websites — blogs, SaaS applications, APIs, portfolios — DV certificates are perfectly sufficient.

If you run a bank or a large e-commerce platform that wants to display your company name in the browser bar, you might want an Extended Validation (EV) certificate from a paid CA. For everything else, Let's Encrypt is the right choice.


How Let's Encrypt Works

Let's Encrypt uses a protocol called ACME (Automatic Certificate Management Environment) to automate the entire certificate lifecycle.

Here is the process, simplified:

Step 1 — Domain Ownership Verification

Before issuing a certificate for example.com, Let's Encrypt needs to verify you actually control that domain. It does this through a challenge.

The most common challenge type is the HTTP-01 challenge:

  1. Let's Encrypt tells your server to place a specific file at a specific URL — for example http://example.com/.well-known/acme-challenge/randomtoken
  2. Let's Encrypt then fetches that URL from its servers
  3. If the file is there with the correct content, domain ownership is proven
  4. The certificate is issued

This entire process happens in seconds and is fully automated by Certbot.

Step 2 — Certificate Issuance

Once domain ownership is verified, Let's Encrypt issues a certificate valid for 90 days. This short validity period is intentional — it limits the window of exposure if a certificate is ever compromised, and it forces automation of renewal.

Step 3 — Automatic Renewal

Certbot installs a systemd timer (or cron job) that runs twice daily. It checks whether any certificate is within 30 days of expiring. If so, it automatically renews it — re-running the challenge, obtaining a new certificate, and reloading Nginx — all without any manual intervention.

In practice, your certificates renew themselves every 60-70 days, long before the 90-day expiry.


What Is Certbot?

Certbot is the official client tool for Let's Encrypt, maintained by the Electronic Frontier Foundation (EFF). It is the software you install on your server that:

  • Communicates with Let's Encrypt's ACME servers
  • Handles the domain ownership challenge automatically
  • Obtains and installs the SSL certificate
  • Configures Nginx (or Apache) to use it
  • Sets up automatic renewal

Without Certbot, you would need to manually interact with Let's Encrypt's API. Certbot makes the entire process a single command.


Prerequisites Before Running Certbot

Before you can install an SSL certificate, three things must be true:

1. Your Domain Must Point to Your Server

Let's Encrypt verifies domain ownership by making an HTTP request to your domain. If your domain's DNS is not pointing to your server's IP address, the challenge will fail and no certificate will be issued.

Check your DNS records at your registrar. You need:

Record Type Value
example.com A Your server IP
www.example.com A Your server IP
api.example.com A Your server IP

DNS changes can take anywhere from a few minutes to 48 hours to propagate, depending on your registrar and TTL settings. You can verify DNS has propagated using:

dig example.com +short
Enter fullscreen mode Exit fullscreen mode

Or use an online tool like dnschecker.org.

2. Nginx Must Be Running and Configured

Certbot needs Nginx to be running with a server block configured for your domain. The server block does not need SSL yet — Certbot adds that. It just needs to exist and be active.

3. Port 80 Must Be Open

Certbot uses port 80 (HTTP) to complete the domain challenge. Your firewall must allow incoming traffic on port 80. If you followed the server setup guide in this series, UFW already has port 80 open.


Installing Certbot on Ubuntu with Nginx

Step 1 — Install Certbot

sudo apt install -y certbot python3-certbot-nginx
Enter fullscreen mode Exit fullscreen mode

The python3-certbot-nginx plugin allows Certbot to automatically modify your Nginx configuration to enable SSL — you do not need to edit any config files manually.

Step 2 — Obtain Your First Certificate

sudo certbot --nginx -d example.com -d www.example.com
Enter fullscreen mode Exit fullscreen mode

What the flags mean:

  • --nginx — use the Nginx plugin to automatically configure SSL
  • -d example.com — issue certificate for this domain
  • -d www.example.com — include this as an additional domain on the same certificate

You can include multiple -d flags to cover multiple subdomains on one certificate:

sudo certbot --nginx -d example.com -d www.example.com -d api.example.com
Enter fullscreen mode Exit fullscreen mode

Step 3 — Answer the Prompts

Certbot will ask you a few questions:

Enter email address: you@example.com
Agree to terms of service: Y
Share email with EFF: N (your choice)
Redirect HTTP to HTTPS: 2 (Always redirect — recommended)
Enter fullscreen mode Exit fullscreen mode

Choose option 2 for the redirect. This automatically adds an Nginx rule that sends all HTTP traffic to HTTPS, so visitors who type http://example.com are seamlessly redirected to https://example.com.

Step 4 — What Certbot Does Automatically

After you answer the prompts, Certbot:

  1. Contacts Let's Encrypt servers
  2. Places a challenge file in your web root
  3. Let's Encrypt verifies the file
  4. Certificate is issued and saved to /etc/letsencrypt/live/example.com/
  5. Certbot modifies your Nginx config to enable SSL on port 443
  6. Certbot adds the HTTP to HTTPS redirect on port 80
  7. Nginx is reloaded

Your site is now serving HTTPS. The entire process takes under 60 seconds.


What Your Nginx Config Looks Like After Certbot

Before Certbot, your Nginx server block looked like this:

server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com/public;
    ...
}
Enter fullscreen mode Exit fullscreen mode

After Certbot runs, it transforms it into:

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name example.com www.example.com;
    root /var/www/example.com/public;

    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;

    ...your existing config...
}
Enter fullscreen mode Exit fullscreen mode

The first server block catches all HTTP traffic and redirects it to HTTPS. The second handles all HTTPS traffic with your SSL certificate.


Where Certbot Stores Your Certificates

/etc/letsencrypt/
├── live/
│   └── example.com/
│       ├── fullchain.pem    ← Your certificate + intermediate chain
│       ├── privkey.pem      ← Your private key (keep this secret)
│       ├── cert.pem         ← Your certificate only
│       └── chain.pem        ← Intermediate certificates only
├── archive/
│   └── example.com/         ← Historical certificates (all versions)
└── renewal/
    └── example.com.conf     ← Renewal configuration
Enter fullscreen mode Exit fullscreen mode

Important: The files in live/ are actually symbolic links pointing to the latest version in archive/. When Certbot renews your certificate, it creates new files in archive/ and updates the symlinks — so your Nginx config never needs to change.

Never delete anything in /etc/letsencrypt/ unless you know exactly what you are doing.


Automatic Certificate Renewal

This is where Let's Encrypt's real power shows. Certbot installs a systemd timer that runs twice daily:

# Check the timer status
sudo systemctl status certbot.timer
Enter fullscreen mode Exit fullscreen mode

You will see it is active and scheduled to run at random times twice per day. The randomisation prevents all Certbot installations worldwide from hitting Let's Encrypt's servers simultaneously.

When the timer runs, Certbot checks each certificate. If any certificate expires within 30 days, it renews it automatically. In practice your certificates renew around the 60-day mark — well before the 90-day expiry.

Test Renewal Without Actually Renewing

sudo certbot renew --dry-run
Enter fullscreen mode Exit fullscreen mode

This simulates the entire renewal process without actually changing anything. Run this after installation to confirm renewal will work when the time comes.

Expected output:

Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/example.com/fullchain.pem (success)
Enter fullscreen mode Exit fullscreen mode

Managing Multiple Domains

If you host multiple websites on one server, you can have separate certificates for each domain:

# Certificate for your main app
sudo certbot --nginx -d example.com -d www.example.com

# Certificate for your API
sudo certbot --nginx -d api.example.com

# Certificate for another site
sudo certbot --nginx -d anotherdomain.com -d www.anotherdomain.com
Enter fullscreen mode Exit fullscreen mode

Each domain gets its own certificate stored separately in /etc/letsencrypt/live/. Certbot manages renewal for all of them automatically.

List all your certificates:

sudo certbot certificates
Enter fullscreen mode Exit fullscreen mode

Output:

Found the following certs:
  Certificate Name: example.com
    Domains: example.com www.example.com
    Expiry Date: 2026-11-14 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem

  Certificate Name: api.example.com
    Domains: api.example.com
    Expiry Date: 2026-11-14 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/api.example.com/fullchain.pem
Enter fullscreen mode Exit fullscreen mode

Testing Your SSL Installation

After installing your certificate, verify it is working correctly.

Test in Your Browser

Visit https://example.com and click the padlock icon. You should see:

  • Connection is secure
  • Certificate is valid
  • Issued by: Let's Encrypt

Test with SSL Labs

SSL Labs provides a free, detailed SSL analysis of your domain. It checks:

  • Certificate validity
  • Certificate chain
  • Protocol support (TLS 1.2, TLS 1.3)
  • Cipher strength
  • Known vulnerabilities

A properly configured Let's Encrypt certificate with default Certbot settings typically scores A on SSL Labs.

Test from the Command Line

curl -I https://example.com
Enter fullscreen mode Exit fullscreen mode

Expected output:

HTTP/2 200
server: nginx
...
Enter fullscreen mode Exit fullscreen mode

The HTTP/2 200 confirms both HTTPS and HTTP/2 are working.


Common Problems and Solutions

Challenge Failed — Domain Not Pointing to Server

Error:

Challenge failed for domain example.com
Enter fullscreen mode Exit fullscreen mode

Cause: DNS is not pointing to your server yet, or DNS has not propagated.

Solution:

# Check what IP your domain resolves to
dig example.com +short

# It must match your server IP
curl ifconfig.me
Enter fullscreen mode Exit fullscreen mode

Wait for DNS propagation and try again.

Port 80 Is Blocked

Error:

Connection refused on port 80
Enter fullscreen mode Exit fullscreen mode

Cause: Your firewall is blocking HTTP.

Solution:

sudo ufw allow http
sudo ufw status
Enter fullscreen mode Exit fullscreen mode

Nginx Configuration Error

Error:

nginx: configuration file test failed
Enter fullscreen mode Exit fullscreen mode

Solution:

sudo nginx -t
Enter fullscreen mode Exit fullscreen mode

Fix whatever error it reports before running Certbot again.

Certificate Already Exists

If you run Certbot for a domain that already has a certificate, it will ask whether to renew, expand, or reinstall. Choose:

  • Renew — get a fresh certificate for the same domains
  • Expand — add new domains to the existing certificate
  • Reinstall — reinstall the existing certificate without changes

Rate Limits

Let's Encrypt has rate limits to prevent abuse:

Limit Value
Certificates per domain per week 5
Duplicate certificates per week 5
Failed validations per hour 5

In practice you will never hit these limits in normal use. They only matter if you are repeatedly requesting certificates for the same domain due to testing or errors.

If you do hit a rate limit, you must wait before trying again. To avoid this during testing, use Let's Encrypt's staging environment:

sudo certbot --nginx --staging -d example.com
Enter fullscreen mode Exit fullscreen mode

Staging certificates are not trusted by browsers but have much higher rate limits. Use staging to test your setup, then run without --staging for the real certificate.


Revoking a Certificate

If your private key is ever compromised, revoke the certificate immediately:

sudo certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem
Enter fullscreen mode Exit fullscreen mode

Then obtain a new certificate:

sudo certbot --nginx -d example.com
Enter fullscreen mode Exit fullscreen mode

The Bigger Picture — HTTPS Everywhere

Let's Encrypt's mission is to make HTTPS universal. Before it existed, the friction and cost of SSL certificates meant that millions of websites transmitted user data in plain text. Today there is no technical or financial barrier to HTTPS.

If you are building a web application, an API, or any internet-facing service, HTTPS is not a feature — it is a baseline requirement. Let's Encrypt removes every excuse not to have it.


Quick Reference — Certbot Commands

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

# Obtain certificate for a domain
sudo certbot --nginx -d example.com -d www.example.com

# List all certificates
sudo certbot certificates

# Test renewal (dry run)
sudo certbot renew --dry-run

# Force renewal immediately
sudo certbot renew --force-renewal

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

# Delete a certificate
sudo certbot delete --cert-name example.com

# Check renewal timer
sudo systemctl status certbot.timer

# Test staging (no rate limits)
sudo certbot --nginx --staging -d example.com
Enter fullscreen mode Exit fullscreen mode

Summary

Here is everything covered in this guide:

  • SSL encrypts the connection between your visitor and server — it is mandatory for any modern website
  • Let's Encrypt is a free, trusted, automated Certificate Authority that issues 90-day certificates
  • Certbot is the tool that talks to Let's Encrypt, installs your certificate, configures Nginx, and renews automatically
  • Domain ownership is verified via the HTTP-01 challenge — Let's Encrypt checks a file on your server
  • Certificates auto-renew every 60 days via a systemd timer — zero manual work required
  • Always run certbot renew --dry-run after setup to confirm renewal works
  • Use --staging for testing to avoid rate limits
  • SSL Labs gives you an independent grade of your SSL configuration

When your domain is pointed to your server and Nginx is configured, running Let's Encrypt takes less than two minutes. There is genuinely no reason to run any website without it.

Top comments (0)