+(91)70149-37521Subscribe Now

Secure Nginx with Let’s Encrypt on Rocky Linux 9 and EL9

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 […]

Secure Nginx with Let's Encrypt

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

Leave a Reply

Your email address will not be published. Required fields are marked *

Subscribe to Our Newsletter

Get free how-to tutorials and over 700+ courses. Seo tips, create a wordpress, or learn a new skill.