Save 15% on All Hosting Services

Test your skills and get Discount on any hosting plan

Use code: Skills Get Started
FAQ’s Sections
Linux Security

How to Secure Nginx with Let’s Encrypt SSL on Ubuntu (Complete 2025 Guide)

HTTPS is no longer optional. In 2025, every website needs SSL/TLS encryption — not just to protect user data, but to rank competitively in Google Search and satisfy modern browser security requirements. Let's Encrypt makes this achievable for free, offering trusted, auto-renewing SSL certificates that work seamlessly with Nginx on Ubuntu.

This comprehensive guide walks you through every step: installing Certbot, obtaining a Let's Encrypt SSL certificate, verifying your configuration, and automating renewals — all on an Ubuntu 18.04, 20.04, or 22.04 server running Nginx.

Whether you're managing a VPS Hosting environment or a dedicated web server, this tutorial gives you a production-ready HTTPS setup in under 15 minutes.

Why SSL Matters for Nginx in 2025

Before diving into commands, it's worth understanding exactly what you gain by securing Nginx with Let's Encrypt:

  • Data encryption: HTTPS encrypts all traffic between your server and visitors, preventing man-in-the-middle attacks and eavesdropping.
  • SEO ranking signals: Google has confirmed HTTPS as a ranking factor. Sites without SSL are actively penalized in search results.
  • Browser trust indicators: Chrome, Firefox, and Edge display "Not Secure" warnings for HTTP sites, destroying user confidence and increasing bounce rates.
  • Free and automated: Let's Encrypt issues certificates at no cost, and Certbot handles renewals automatically — eliminating the manual overhead of paid certificates.
  • PCI DSS and compliance: Any site handling payments or personal data is legally required to use encrypted connections.

If your domain is already registered and pointing to your server, you're ready to begin. If you still need a domain, AlexHost offers affordable Domain Registration with instant DNS management.

Prerequisites

Ensure the following conditions are met before proceeding:

RequirementDetails
Operating SystemUbuntu 18.04, 20.04, or 22.04 LTS
Web ServerNginx installed and actively serving your site
Domain NameA registered domain with an A record pointing to your server's public IP
Server AccessSSH access with a user that has sudo privileges
FirewallPorts 80 (HTTP) and 443 (HTTPS) open in UFW or iptables
Root AccessNot strictly required, but sudo access is mandatory

Verify Nginx Is Running

Before installing Certbot, confirm Nginx is active:

sudo systemctl status nginx

You should see active (running) in the output. If Nginx is not installed, run:

sudo apt update && sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx

Open Required Firewall Ports

If UFW is enabled, allow HTTP and HTTPS traffic:

sudo ufw allow 'Nginx Full'
sudo ufw reload
sudo ufw status

The output should show Nginx Full as ALLOW for both IPv4 and IPv6.

Step 1 — Installing Certbot and the Nginx Plugin

Certbot is the official Let's Encrypt client. It automates the entire certificate lifecycle: issuance, installation, and renewal. The python3-certbot-nginx plugin allows Certbot to read your Nginx configuration and modify it automatically.

Update Your Package Index

Always update your package lists before installing new software:

sudo apt update
sudo apt upgrade -y

Install Certbot with the Nginx Plugin

sudo apt install certbot python3-certbot-nginx -y

Verify the Installation

certbot --version

Expected output (version may vary):

certbot 2.x.x

> Note for Ubuntu 18.04 users: If the default APT version of Certbot is outdated, install via Snap for the latest release:

> “`bash

> sudo snap install –classic certbot

> sudo ln -s /snap/bin/certbot /usr/bin/certbot

> “`

Step 2 — Configuring Your Nginx Server Block

Certbot needs to detect your domain in the Nginx configuration to automatically modify it. If you haven't already created a server block for your domain, do so now.

Create a Server Block

Replace yourdomain.com with your actual domain name throughout this guide:

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

Add the following basic configuration:

server {
    listen 80;
    listen [::]:80;

    server_name yourdomain.com www.yourdomain.com;

    root /var/www/yourdomain.com/html;
    index index.html index.htm index.nginx-debian.html;

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

Enable the Server Block

sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/

Test the Nginx Configuration

Always validate your Nginx config before reloading:

sudo nginx -t

Expected output:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Reload Nginx

sudo systemctl reload nginx

Step 3 — Obtaining a Let's Encrypt SSL Certificate

With Nginx configured and Certbot installed, you can now request your SSL certificate.

Run Certbot with the Nginx Plugin

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

Breaking down the flags:

    --nginx — Tells Certbot to use the Nginx plugin for automatic configuration
    -d yourdomain.com — Specifies the primary domain
    -d www.yourdomain.com — Adds the www subdomain to the same certificate (Subject Alternative Name)
    
    Interactive Prompts Explained
    Certbot will guide you through a short setup wizard:
    1. Email Address
    Enter email address (used for urgent renewal and security notices):
    Provide a valid email. Let's Encrypt uses this to notify you of expiring certificates and security issues.
    2. Terms of Service
    Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf
    (A)gree/(C)ancel:
    Type A and press Enter.
    3. EFF Newsletter (Optional)
    Would you be willing to share your email address with the Electronic Frontier Foundation?
    (Y)es/(N)o:
    This is optional. Type N if you prefer not to subscribe.
    4. HTTP to HTTPS Redirect
    Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
    1: No redirect
    2: Redirect - Make all requests redirect to secure HTTPS access
    Always choose option 2. This ensures all visitors are automatically upgraded to HTTPS, eliminating mixed-content issues and improving security posture.
    Successful Output
    If everything is configured correctly, you'll see:
    Successfully received certificate.
    Certificate is saved at: /etc/letsencrypt/live/yourdomain.com/fullchain.pem
    Key is saved at:         /etc/letsencrypt/live/yourdomain.com/privkey.pem
    This certificate expires on YYYY-MM-DD.
    These files will be updated when the certificate renews.
    
    Deploying certificate
    Successfully deployed certificate for yourdomain.com to /etc/nginx/sites-available/yourdomain.com
    Successfully deployed certificate for www.yourdomain.com to /etc/nginx/sites-available/yourdomain.com
    Congratulations! You have successfully enabled HTTPS on https://yourdomain.com and https://www.yourdomain.com
    What Certbot Modified in Nginx
    After running, Certbot automatically appends SSL directives to your server block. Your configuration will now look similar to this:
    server {
        server_name yourdomain.com www.yourdomain.com;
    
        root /var/www/yourdomain.com/html;
        index index.html index.htm;
    
        location / {
            try_files $uri $uri/ =404;
        }
    
        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;
    }
    
    server {
        if ($host = www.yourdomain.com) {
            return 301 https://$host$request_uri;
        }
        if ($host = yourdomain.com) {
            return 301 https://$host$request_uri;
        }
    
        listen 80;
        server_name yourdomain.com www.yourdomain.com;
        return 404;
    }
    Step 4 — Verifying SSL Installation
    After Certbot completes, verify that your SSL certificate is correctly installed and functioning.
    Method 1: Browser Check
    Open your web browser and navigate to https://yourdomain.com. Look for:
    
    Padlock icon in the address bar — confirms an active, trusted SSL connection
    No security warnings — the certificate is valid and trusted by your browser
    HTTPS in the URL — HTTP requests should automatically redirect to HTTPS
    
    Click the padlock icon and select "Certificate" to view the issuer (should show "Let's Encrypt") and expiration date.
    Method 2: SSL Labs Deep Analysis
    For a comprehensive security audit, use Qualys SSL Labs:
    
    Navigate to https://www.ssllabs.com/ssltest/
  • Enter your domain name
  • Click "Submit"
  • A properly configured Let's Encrypt + Nginx setup should score A or A+. If you score lower, SSL Labs will identify the specific weaknesses to address.

    Method 3: Command-Line Verification

    Check the certificate details directly from the terminal:

    sudo certbot certificates

    Output:

    Found the following certs:
      Certificate Name: yourdomain.com
        Serial Number: abc123...
        Key Type: RSA
        Domains: yourdomain.com www.yourdomain.com
        Expiry Date: YYYY-MM-DD HH:MM:SS+00:00 (VALID: 89 days)
        Certificate Path: /etc/letsencrypt/live/yourdomain.com/fullchain.pem
        Private Key Path: /etc/letsencrypt/live/yourdomain.com/privkey.pem

    Method 4: OpenSSL Command

    Verify the certificate chain and expiry using OpenSSL:

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

    Expected output:

    notBefore=Mon Jan  1 00:00:00 2025 GMT
    notAfter=Tue Apr  1 00:00:00 2025 GMT
    issuer=C=US, O=Let's Encrypt, CN=R11

    Step 5 — Setting Up Automatic Certificate Renewal

    Let's Encrypt certificates expire after 90 days. This short validity period is intentional — it limits exposure if a private key is compromised. Certbot handles renewals automatically, but you should verify the automation is working correctly.

    How Certbot Renewal Works

    When you install Certbot via APT or Snap, it automatically creates a systemd timer (or cron job on older systems) that runs twice daily. It checks whether any certificates are within 30 days of expiry and renews them automatically.

    Verify the Systemd Timer

    sudo systemctl status certbot.timer

    Expected output:

    ● certbot.timer - Run certbot twice daily
         Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
         Active: active (waiting) since ...
        Trigger: ...
       Triggers: ● certbot.service

    If the timer is active and enabled, automatic renewal is already configured.

    Test the Renewal Process (Dry Run)

    Before relying on automatic renewal, simulate it to confirm everything works:

    sudo certbot renew --dry-run

    Successful output:

    Simulating renewal of an existing certificate for yourdomain.com and www.yourdomain.com
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Congratulations, all simulated renewals succeeded:
      /etc/letsencrypt/live/yourdomain.com/fullchain.pem (success)
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    If the dry run succeeds, your certificates will renew automatically without any manual intervention.

    Verify the Cron Job (Legacy Systems)

    On older Ubuntu versions that don't use systemd timers, check for the Certbot cron job:

    sudo cat /etc/cron.d/certbot

    You should see a line similar to:

    0 */12 * * * root test -x /usr/bin/certbot -a ! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew

    This runs Certbot twice daily at random intervals to avoid overloading Let's Encrypt servers.

    Manual Renewal (If Needed)

    If you ever need to manually force a renewal:

    sudo certbot renew --force-renewal
    sudo systemctl reload nginx

    > Best practice: After any certificate renewal (manual or automatic), reload Nginx to ensure it picks up the new certificate files:

    > “`bash

    > sudo systemctl reload nginx

    > “`

    > Certbot's renewal hooks handle this automatically in most configurations.

    Configure Renewal Hooks

    To ensure Nginx reloads automatically after every renewal, add a deploy hook:

    sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

    Add the following content:

    #!/bin/bash
    systemctl reload nginx

    Make it executable:

    sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

    Troubleshooting Common Issues

    Error: "Could not bind to IPv4/IPv6"

    Certbot uses port 80 for domain validation. If another process is using port 80, the challenge will fail.

    Solution: Temporarily stop Nginx, obtain the certificate in standalone mode, then restart:

    sudo systemctl stop nginx
    sudo certbot certonly --standalone -d yourdomain.com -d www.yourdomain.com
    sudo systemctl start nginx

    Error: "DNS problem: NXDOMAIN looking up A for yourdomain.com"

    Your domain's DNS records are not yet propagating to Let's Encrypt's validation servers.

    Solution: Verify your A record is correctly set:

    dig yourdomain.com A +short

    The output should return your server's public IP address. DNS propagation can take up to 48 hours, though it typically resolves within 1–2 hours.

    Error: "Too many certificates already issued"

    Let's Encrypt enforces a rate limit of 5 duplicate certificates per week per domain.

    Solution: Use the --staging flag to test your setup without hitting rate limits:

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

    Once testing is complete, revoke the staging certificate and issue a production one.

    Error: "Nginx configuration test failed"

    Certbot modifies your Nginx config. If the resulting config has syntax errors, Nginx won't reload.

    Solution: Manually test and fix the configuration:

    sudo nginx -t
    sudo nano /etc/nginx/sites-available/yourdomain.com
    # Fix any syntax errors, then:
    sudo systemctl reload nginx

    Certificate Not Renewing Automatically

    If you receive expiry warning emails despite having Certbot installed, check the timer status:

    sudo systemctl status certbot.timer
    sudo journalctl -u certbot.service --since "7 days ago"

    Review the logs for errors and address them accordingly.

    Advanced: Hardening Your Nginx SSL Configuration

    The default Let's Encrypt + Certbot configuration is secure, but you can further harden it for an A+ SSL Labs score.

    Enable HTTP/2

    Edit your server block to enable HTTP/2 for improved performance:

    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    Add HSTS (HTTP Strict Transport Security)

    HSTS instructs browsers to always use HTTPS for your domain, even if a user types http://:

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    Disable Weak Protocols and Ciphers

    Add these directives to your nginx.conf or server block:

    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;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    After making changes, always test and reload:

    sudo nginx -t && sudo systemctl reload nginx

    Choosing the Right Hosting for Your Nginx + SSL Setup

    The performance and reliability of your SSL-secured Nginx server depends heavily on the underlying infrastructure. Here's how AlexHost's hosting options align with different use cases:

    • VPS Hosting — Ideal for most websites and applications. Full root access lets you configure Nginx and Certbot exactly as described in this guide. AlexHost VPS plans run on Ubuntu 18.04, 20.04, and 22.04 LTS.
    • Dedicated Servers — Best for high-traffic websites requiring maximum performance, dedicated resources, and full hardware control. Run multiple Nginx virtual hosts, each with its own Let's Encrypt certificate.
    • VPS with cPanel — If you prefer a graphical interface for managing SSL certificates alongside your web hosting, cPanel integrates with Let's Encrypt and handles certificate issuance through its AutoSSL feature.
    • SSL Certificates — For enterprise environments, e-commerce sites, or applications requiring extended validation (EV) or organization validation (OV) certificates, AlexHost offers premium SSL certificates with warranty coverage and dedicated support.

    Conclusion

    Securing Nginx with a Let's Encrypt SSL certificate on Ubuntu is one of the most impactful steps you can take to protect your users, improve your search engine rankings, and build trust with your audience. The entire process — from installing Certbot to enabling automatic renewals — takes less than 15 minutes and costs nothing.

    To recap what you've accomplished in this guide:

    1. ✅ Installed Certbot and the Nginx plugin
    2. ✅ Configured a proper Nginx server block for your domain
    3. ✅ Obtained a trusted Let's Encrypt SSL certificate
    4. ✅ Verified the certificate using browser tools, SSL Labs, and OpenSSL
    5. ✅ Confirmed automatic renewal via systemd timer and dry-run testing
    6. ✅ Applied advanced hardening for an A+ security rating

    With your Nginx server now secured, consider exploring additional layers of protection: a Web Application Firewall (WAF), fail2ban for brute-force protection, and regular security audits. If you're managing multiple domains or applications, AlexHost's VPS Control Panels provide a streamlined interface for managing SSL certificates, virtual hosts, and server configurations without sacrificing the flexibility of a Linux environment.

    Your users deserve a secure connection. Now they have one.