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:
| Requirement | Details |
|---|---|
| Operating System | Ubuntu 18.04, 20.04, or 22.04 LTS |
| Web Server | Nginx installed and actively serving your site |
| Domain Name | A registered domain with an A record pointing to your server's public IP |
| Server Access | SSH access with a user that has sudo privileges |
| Firewall | Ports 80 (HTTP) and 443 (HTTPS) open in UFW or iptables |
| Root Access | Not strictly required, but sudo access is mandatory |
Verify Nginx Is Running
Before installing Certbot, confirm Nginx is active:
sudo systemctl status nginxYou 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 nginxOpen Required Firewall Ports
If UFW is enabled, allow HTTP and HTTPS traffic:
sudo ufw allow 'Nginx Full'
sudo ufw reload
sudo ufw statusThe 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 -yInstall Certbot with the Nginx Plugin
sudo apt install certbot python3-certbot-nginx -yVerify the Installation
certbot --versionExpected 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.comAdd 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 -tExpected output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successfulReload Nginx
sudo systemctl reload nginxStep 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.comBreaking 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/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 certificatesOutput:
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.pemMethod 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 -issuerExpected 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=R11Step 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.timerExpected 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.serviceIf 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-runSuccessful 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/certbotYou 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 renewThis 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.shAdd the following content:
#!/bin/bash
systemctl reload nginxMake it executable:
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.shTroubleshooting 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 nginxError: "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 +shortThe 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.comOnce 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 nginxCertificate 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 nginxChoosing 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:
- ✅ Installed Certbot and the Nginx plugin
- ✅ Configured a proper Nginx server block for your domain
- ✅ Obtained a trusted Let's Encrypt SSL certificate
- ✅ Verified the certificate using browser tools, SSL Labs, and OpenSSL
- ✅ Confirmed automatic renewal via systemd timer and dry-run testing
- ✅ 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.
on All Hosting Services