How to Secure Nginx with Let’s Encrypt on Ubuntu

Secure Nginx with Let's Encrypt — install a free, auto-renewing SSL certificate on Ubuntu using Certbot in just a few steps.

If your website is still running on plain HTTP, you’re leaking data, losing search rankings, and scaring off visitors with a “Not Secure” warning in their browser bar. The fix takes about five minutes and costs nothing. In this guide, you’ll learn how to secure Nginx with Let’s Encrypt — installing a free, auto-renewing SSL certificate on an Ubuntu server using Certbot.

Introduction

Why You Need SSL

SSL/TLS certificates encrypt the connection between your visitor’s browser and your server. Without one:

  • Data is exposed in plain text — anything typed into a form (passwords, payment details, contact info) can be intercepted.
  • Browsers actively warn users. Chrome, Firefox, and Edge all flag HTTP-only sites as “Not Secure,” which tanks trust and conversions.
  • Google uses HTTPS as a ranking signal. An unencrypted site is at a built-in SEO disadvantage compared to HTTPS competitors.
  • Modern web features require it. Service workers, HTTP/2, and many browser APIs simply won’t work over plain HTTP.

What Is Let's Encrypt?

Let’s Encrypt is a free, automated, open Certificate Authority run by the nonprofit Internet Security Research Group (ISRG). Instead of paying $50–200/year for a certificate from a traditional CA, Let’s Encrypt issues one to you for free — and the Certbot tool automates both the issuance and renewal process, so you never have to manually renew a cert again.

Prerequisites

Before you start, make sure you have;

  • An Ubuntu server with Nginx already installed and running. If you haven’t set this up yet, check out my guide on spinning up an Ubuntu server on AWS EC2.
  • A registered domain name (e.g., example.com) with an A record pointed at your server’s public IP address. Certbot verifies domain ownership over HTTP/HTTPS, so this DNS propagation must be complete before you begin.
  • Root or sudo access to the server via SSH.
  • Port 80 (HTTP) and Port 443 (HTTPS) open — either through ufw on the server or your cloud provider’s security group/firewall (e.g., AWS Security Groups).

Step 1: Install Certbot

Ubuntu’s default package repository includes Certbot along with the Nginx plugin, so a single apt command handles the install:

				
					sudo apt update
sudo apt install certbot python3-certbot-nginx -y
				
			

Verify the install:

				
					certbot --version
				
			

Step 2: Check and Confirm Your Nginx Server Block

Certbot needs a valid Nginx server block with the correct server_name to know which domain to issue the certificate for. Open your site’s config file:

				
					sudo nano /etc/nginx/sites-available/yourdomain.com
				
			

Make sure it looks something like this, with your actual domain in server_name:

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

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

    location / {
        try_files $uri $uri/ =404;
    }
}
				
			

Save and exit, then test the config for syntax errors before reloading:

				
					sudo nginx -t
sudo systemctl reload nginx
				
			

If nginx -t doesn’t return syntax is ok and test is successful, fix the errors before moving on — Certbot won’t be able to modify a broken config.

Step 3: Allow HTTPS Through the Firewall

If you’re using ufw (Ubuntu’s default firewall), you need to allow Nginx traffic on both HTTP and HTTPS.

Check your current firewall status:

				
					sudo ufw status
				
			

If Nginx is only listed under “Nginx HTTP,” update it to allow both ports:

				
					sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'
sudo ufw status
				
			

Nginx Full opens both port 80 and 443, while removing the old HTTP-only rule avoids duplicate entries.

On AWS EC2 or another cloud host: Also double-check your Security Group / firewall rules in the cloud console allow inbound traffic on port 443 — ufw alone won’t help if the cloud-level firewall is blocking it.

Step 4: Obtain the SSL Certificate

Now for the main event. Run Certbot with the Nginx plugin:

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

Certbot will walk you through a few prompts:

  1. Email address — used for renewal and security notifications.
  2. Terms of Service agreement.
  3. Optional: share your email with the EFF (your choice).
  4. Redirect HTTP to HTTPS? — choose yes (recommended) so all traffic is automatically forced onto the secure connection.

Once complete, Certbot confirms the certificate was issued and installed, and tells you where it’s stored (typically /etc/letsencrypt/live/yourdomain.com/).

Visit https://yourdomain.com in your browser to confirm the padlock icon appears.

How NGINX With Let's Encrypt Configuration Works

This is the part most tutorials skip — understanding what Certbot actually did to your server helps you troubleshoot later.

  1. Domain validation (ACME challenge). Certbot uses the ACME protocol to prove you control the domain. With the Nginx plugin, it temporarily serves a verification file through your existing server block on port 80 (or spins up a temporary one), which Let’s Encrypt’s servers fetch to confirm ownership.
  2. Certificate generation. Once validated, Let’s Encrypt issues a certificate (valid for 90 days) and Certbot downloads it to /etc/letsencrypt/live/yourdomain.com/, along with the private key and full certificate chain.
  3. Nginx config modification. Certbot’s Nginx plugin directly edits your server block, adding:
				
					listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
				
			

If you chose the HTTP→HTTPS redirect, it also adds a second server block on port 80 that redirects all traffic to https://. Your original config file is preserved with a .bak extension before any changes are made, so you can always roll back manually if needed.

Automatic renewal. Let’s Encrypt certificates expire every 90 days. The Certbot snap package installs a systemd timer (certbot.timer) that runs twice daily and silently renews any certificate within 30 days of expiry — no action needed from you. You can confirm it’s active with:

				
					sudo systemctl status certbot.timer
				
			

Test that renewal will work without actually renewing anything:

				
					sudo certbot renew --dry-run
				
			

If this dry run succeeds, your SSL setup is effectively maintenance-free from here on.

Verifying Your SSL Setup

Once installed, it’s worth confirming your configuration is solid, not just “working”:

  • Run your domain through SSL Labs’ SSL Test to check your grade (aim for A or A+).
  • Confirm http://yourdomain.com redirects to https://yourdomain.com.
  • Check the certificate expiry and issuer by clicking the padlock icon in your browser.
Common Issues
  • “Failed authorization procedure” — usually means DNS hasn’t propagated yet, or port 80 is blocked by the firewall/security group. Double-check both before retrying.
  • Certbot can’t find a server block — make sure server_name in your Nginx config exactly matches the domain you’re requesting a certificate for.
  • Mixed content warnings after enabling HTTPS — check your site for hardcoded http:// links to images, scripts, or stylesheets and update them to https:// or protocol-relative URLs.
Wrapping Up

You’ve now got a free, auto-renewing SSL certificate securing your Nginx server — no manual renewal, no yearly certificate fees, and a nice trust boost for both visitors and search engines. In upcoming posts, I’ll cover setting up a custom domain on AWS and hardening your Nginx configuration further with security headers.

Project content
Create Website for Blog and tutorial and Developer news
Created by you
Add PDFs, documents, or other text to reference in this project.
Content

ON THIS PLACE