HTTPS encrypts traffic between a visitor and your website. Let’s Encrypt provides publicly trusted certificates through the ACME protocol, and Certbot can request, install, and renew them for Nginx.
This guide shows how to secure Nginx with Let’s Encrypt on Rocky Linux 9, AlmaLinux 9, RHEL 9, and CentOS Stream 9. It uses Certbot’s recommended snap installation, checks DNS and Nginx before issuance, and tests automatic renewal.
Before Requesting a Certificate
- Use a supported EL9 server with sudo access.
- Own the domain names that will appear on the certificate.
- Point every requested A/AAAA record to this server.
- Make the website reachable over public TCP port 80.
- Back up the Nginx configuration.
- Use a working email address for urgent ACME account notices.
The HTTP-01 validation used in this guide works only on port 80. If policy or the network prevents that, use a DNS-01 client and protect its DNS API credentials. DNS-01 is also required for wildcard names such as *.example.com.
Confirm DNS
dig +short A example.com dig +short A www.example.com dig +short AAAA example.com
Replace the examples with your domain. An AAAA record must reach this Nginx server too. A stale IPv6 record can make validation fail even when IPv4 is correct.
Install and Configure Nginx
sudo dnf update -y sudo dnf install -y nginx sudo systemctl enable --now nginx sudo systemctl status nginx --no-pager
Create a separate server block:
sudo mkdir -p /var/www/example.com/html echo '<h1>example.com is ready</h1>' | sudo tee /var/www/example.com/html/index.html sudo restorecon -Rv /var/www/example.com
sudo nano /etc/nginx/conf.d/example.com.conf
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Do not request names that are missing from server_name. Certbot’s Nginx plugin uses this value to find the correct configuration.
Test Nginx Before Reloading
sudo nginx -t sudo systemctl reload nginx curl -I http://example.com
Fix any Nginx error before continuing. The public HTTP URL must return a useful response. A local curl test alone does not prove that Let’s Encrypt can reach the server.
Allow HTTP and HTTPS Through firewalld
sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload sudo firewall-cmd --list-services
Also check any provider firewall or security group. Let’s Encrypt recommends keeping port 80 open and redirecting visitors to HTTPS after validation.
Install Certbot with Snap
Certbot currently recommends the snap package for most users. On EL9, install snapd from EPEL and enable its socket:
sudo dnf install -y epel-release sudo dnf install -y snapd sudo systemctl enable --now snapd.socket sudo ln -s /var/lib/snapd/snap /snap
Log out and back in if snap paths are not available, then install Certbot:
sudo snap install core sudo snap refresh core sudo snap install --classic certbot sudo ln -s /snap/bin/certbot /usr/local/bin/certbot certbot --version
If a package-manager version of Certbot was installed earlier, remove that conflicting package before using the snap. Never maintain two different certbot executables without knowing which one runs.
Obtain and Install the Let’s Encrypt Certificate
Make one more backup and configuration test:
sudo cp -a /etc/nginx /root/nginx-before-certbot sudo nginx -t
Request the certificate and let the Nginx plugin install it:
sudo certbot --nginx -d example.com -d www.example.com
Enter the email address, read and accept the subscriber agreement, and choose the HTTPS redirect when appropriate. Certbot validates each name, updates the matched Nginx server block, and reloads Nginx.
If you prefer to review and edit Nginx yourself, obtain only the certificate:
sudo certbot certonly --nginx -d example.com -d www.example.com
Verify HTTPS
sudo nginx -t curl -I http://example.com curl -I https://example.com sudo certbot certificates
The HTTP URL should redirect to HTTPS, the HTTPS URL should return the site, and every hostname must be covered by the certificate. Test from a separate network or browser as well.
Test Automatic Certificate Renewal
The Certbot snap installs renewal automation. Do not add the old custom cron line from the previous version of this article. Confirm the timer or snap scheduling and perform a staging renewal test:
systemctl list-timers | grep -i certbot sudo certbot renew --dry-run
A successful dry run is important because short-lived certificates depend on automation. Let’s Encrypt’s default certificates currently have 90-day lifetimes, with shorter profiles available and shorter maximum lifetimes planned for the future. Reliable renewal matters more than manually tracking a fixed date.
Security Checks After Enabling HTTPS
- Redirect normal HTTP requests to HTTPS.
- Keep private keys readable only by privileged services.
- Patch Nginx, Certbot, snapd, and the operating system.
- Review TLS settings after major Nginx or policy changes.
- Add HSTS only after every required subdomain works permanently over HTTPS.
- Back up configuration and application data, but protect private-key backups.
- Monitor certificate expiry independently so failed automation creates an alert.
Troubleshooting Certbot and Nginx
Unauthorized or Challenge Failed
Check public DNS for every name, including IPv6. Confirm port 80 is reachable, no CDN rule blocks the challenge path, and the request reaches this Nginx server.
Certbot Cannot Find the Server Block
Make sure the domain appears exactly in an enabled Nginx server_name and nginx -t succeeds.
Too Many Requests
Stop repeating production requests. Fix DNS or configuration first and use Let’s Encrypt’s staging environment or Certbot dry runs to test without consuming production rate limits.
Renewal Works but Nginx Uses an Old Certificate
Check the certificate paths in the active configuration, run nginx -t, review renewal hooks, and reload Nginx. Do not copy files out of /etc/letsencrypt/live unless your deployment process handles updates correctly.
Frequently Asked Questions
Is a Let’s Encrypt certificate free?
Yes. Let’s Encrypt is a free, automated, public certificate authority. You still pay for your domain, server, administration, and monitoring.
Can HTTP-01 issue a wildcard certificate?
No. Wildcard certificates require DNS-01 validation.
Should port 80 be closed after installation?
Let’s Encrypt recommends keeping it open for general websites and redirecting requests to HTTPS. HTTP-01 renewal also needs port 80.
Conclusion
You have configured a working Nginx domain, installed Certbot, obtained a trusted Let’s Encrypt certificate, redirected HTTP to HTTPS, and tested renewal. Keep the dry-run check and independent expiry monitoring in your server maintenance routine.
For wider protection, follow our Linux server hardening checklist and firewall guide.
Reviewed and updated: August 2026. The workflow was checked against the official Certbot Nginx instructions, Let’s Encrypt’s challenge documentation, and its current certificate lifetime plan.











Comments