How to Install Certbot and Automate Let’s Encrypt Renewals on RHEL 7
Securing your web server with a trusted TLS certificate is no longer optional — it is a baseline requirement for any production site. Let’s Encrypt provides free, automated, and domain-validated certificates, and Certbot is the official command-line client that manages the entire lifecycle: issuance, verification, installation, and renewal. On RHEL 7, Certbot is distributed through the EPEL (Extra Packages for Enterprise Linux) repository because it is not included in the default Red Hat channels. This guide walks through every step of installing Certbot, obtaining certificates using multiple challenge modes, integrating with both Nginx and Apache, and fully automating renewals so that certificates never expire unexpectedly.
Prerequisites
- RHEL 7 server with root or sudo access
- A registered domain name with DNS A (and optionally AAAA) records pointing to the server’s public IP address
- Port 80 and/or 443 open in firewalld and any upstream network firewall
- Nginx or Apache already installed and serving at least a basic virtual host (required for webroot and plugin modes)
- Internet access from the server to Let’s Encrypt ACME servers
Step 1: Enable the EPEL Repository
Certbot and its plugins are packaged in EPEL. If you have a subscription, EPEL can be enabled directly; otherwise, install the EPEL release package manually.
# Option A — servers with Red Hat subscription
sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
# Option B — verify EPEL is now active
sudo yum repolist enabled | grep epel
After enabling EPEL, clear the yum cache so the new repository metadata is fetched on the next install operation.
sudo yum clean all
sudo yum makecache fast
Step 2: Install Certbot and Web Server Plugins
Install the core Certbot package plus the plugin for whichever web server you are running. Both can be installed simultaneously without conflict.
# Core certbot only (standalone / webroot modes)
sudo yum install -y certbot
# Apache plugin
sudo yum install -y python-certbot-apache
# Nginx plugin
sudo yum install -y python-certbot-nginx
# Verify installed version
certbot --version
The Apache and Nginx plugins can automatically edit your virtual host configuration files to add TLS directives and redirect HTTP to HTTPS. If you prefer to manage configuration manually, installing only the core certbot package is sufficient.
Step 3: Obtain a Certificate — Standalone Mode
Standalone mode spins up a temporary HTTP server on port 80 to answer the ACME HTTP-01 challenge. This requires that your web server is stopped (or port 80 is free) during issuance. It is ideal for initial setup before a web server is configured.
# Stop the web server first if it is running
sudo systemctl stop httpd # Apache
sudo systemctl stop nginx # Nginx
# Obtain certificate
sudo certbot certonly --standalone -d example.com -d www.example.com
--email [email protected] --agree-tos --non-interactive
# Restart the web server
sudo systemctl start httpd
Certificates are saved under /etc/letsencrypt/live/example.com/. The files of interest are fullchain.pem (certificate + intermediates) and privkey.pem (private key).
Step 4: Obtain a Certificate — Webroot Mode
Webroot mode places a challenge file inside your existing document root and lets your running web server serve it. This means the web server does not need to be stopped.
# Ensure the .well-known directory is accessible
# Apache — add to your VirtualHost or .htaccess:
# Alias /.well-known/acme-challenge/ /var/www/html/.well-known/acme-challenge/
sudo certbot certonly --webroot
-w /var/www/html
-d example.com -d www.example.com
--email [email protected] --agree-tos --non-interactive
For Nginx, ensure the document root is correctly set and that no rewrite rules block access to /.well-known/acme-challenge/. Add the following location block if necessary:
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /var/www/html;
allow all;
}
Step 5: Obtain a Certificate Using the Apache or Nginx Plugin
The web server plugins handle both certificate issuance and automatic configuration updates in a single command. They are the most convenient option when the web server is already running with a properly configured virtual host.
# Apache — issues cert and modifies /etc/httpd/conf.d/ automatically
sudo certbot --apache -d example.com -d www.example.com
# Nginx — issues cert and modifies /etc/nginx/conf.d/ automatically
sudo certbot --nginx -d example.com -d www.example.com
After running the plugin, inspect the modified configuration to verify that SSLCertificateFile, SSLCertificateKeyFile, and redirect directives have been added correctly.
Step 6: List and Inspect Certificates
The certbot certificates subcommand provides a clear summary of every certificate managed by Certbot on the system.
sudo certbot certificates
Sample output:
Found the following certs:
Certificate Name: example.com
Domains: example.com www.example.com
Expiry Date: 2026-08-14 12:34:56+00:00 (VALID: 89 days)
Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem
Private Key Path: /etc/letsencrypt/live/example.com/privkey.pem
Step 7: Test Renewal with a Dry Run
Before configuring automated renewal, always perform a dry run to confirm that the renewal process succeeds without actually modifying any files.
sudo certbot renew --dry-run
A successful dry run outputs Congratulations, all renewals succeeded. If errors appear, they typically indicate a connectivity issue, a misconfigured web root, or a firewall blocking port 80.
Step 8: Automate Renewal with a Cron Job
Certbot only renews certificates that are within 30 days of expiry, so running the renew command twice daily is safe and recommended by Let’s Encrypt.
# Edit the root crontab
sudo crontab -e
# Add the following two lines:
0 2 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload httpd"
0 14 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload httpd"
Adjust the --post-hook command to systemctl reload nginx if you are running Nginx. The post-hook is executed only when at least one certificate was actually renewed, preventing unnecessary service reloads.
Step 9: Automate Renewal with a systemd Timer
On RHEL 7 with systemd, a timer unit is a more integrated alternative to cron. Create both a service unit and a timer unit.
# /etc/systemd/system/certbot-renew.service
[Unit]
Description=Certbot Renewal
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --post-hook "systemctl reload httpd"
# /etc/systemd/system/certbot-renew.timer
[Unit]
Description=Run Certbot twice daily
[Timer]
OnCalendar=*-*-* 02,14:00:00
RandomizedDelaySec=3600
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now certbot-renew.timer
sudo systemctl list-timers certbot-renew.timer
Step 10: Deploy Hook Scripts for Post-Renewal Actions
Certbot looks for executable scripts in /etc/letsencrypt/renewal-hooks/deploy/ and runs them after every successful renewal. This is the recommended way to handle tasks like copying certificates to custom paths or restarting additional services.
# Example deploy hook: /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh
#!/bin/bash
systemctl reload httpd
systemctl reload postfix
logger "certbot: certificates renewed and services reloaded"
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh
Hook directories are also available for pre-renewal (/etc/letsencrypt/renewal-hooks/pre/) and post-renewal failure scenarios (/etc/letsencrypt/renewal-hooks/post/).
Conclusion
With Certbot installed from EPEL, certificates issued for your domains, and automated renewal running via cron or a systemd timer, your RHEL 7 server now maintains valid Let’s Encrypt certificates indefinitely without manual intervention. The combination of dry-run testing, deploy hooks, and service reloads ensures that each renewal is applied cleanly and that dependent services pick up the new certificate immediately. Regularly review certbot certificates and monitor your renewal logs in /var/log/letsencrypt/letsencrypt.log to catch any issues before a certificate actually expires.