How to Secure Apache with Let’s Encrypt and Certbot on RHEL 7
Running your Apache web server over plain HTTP exposes your users to traffic interception and degrades trust in modern browsers. Let’s Encrypt provides free, trusted TLS certificates that can be automated entirely on the command line. Certbot is the official Let’s Encrypt client that handles certificate issuance, Apache configuration updates, and automatic renewal. This tutorial walks through every step needed to go from a standard HTTP Apache installation on RHEL 7 to a fully secured HTTPS site, including mod_ssl setup, automatic HTTP-to-HTTPS redirects, and scheduled renewal.
Prerequisites
- RHEL 7 server with Apache (httpd) installed and running
- A registered domain name with DNS A record pointing to your server’s public IP
- Root or sudo access
- Port 80 and 443 open in your firewall
- EPEL repository enabled
Step 1: Enable the EPEL Repository
Certbot for Apache is distributed through the Extra Packages for Enterprise Linux (EPEL) repository. If you have not already enabled it, install it with yum:
sudo yum install -y epel-release
Verify that EPEL is active:
sudo yum repolist | grep epel
You should see a line similar to epel/x86_64 with a package count. If you are using a minimal RHEL 7 subscription and EPEL is not resolving, you can install the release package directly:
sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
Step 2: Install mod_ssl and Certbot
Apache requires mod_ssl to serve HTTPS connections. Install it along with the Apache Certbot plugin:
sudo yum install -y mod_ssl python-certbot-apache
The python-certbot-apache package includes the Certbot core as well as the Apache plugin, which can read and modify Apache configuration files automatically. Confirm the installation:
certbot --version
After installing mod_ssl, a default SSL virtual host configuration is placed at /etc/httpd/conf.d/ssl.conf. Restart Apache to load the new module before proceeding:
sudo systemctl restart httpd
Step 3: Open Firewall Ports
RHEL 7 uses firewalld by default. Allow HTTPS traffic permanently:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Verify the open services:
sudo firewall-cmd --list-services
Step 4: Obtain a Certificate with Certbot
Run Certbot with the Apache plugin. Replace yourdomain.com and www.yourdomain.com with your actual domain names:
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com
Certbot will prompt you for an email address for renewal notices and expiry warnings, ask you to agree to the Terms of Service, and optionally subscribe you to the EFF mailing list. It then contacts the Let’s Encrypt ACME server, performs an HTTP-01 challenge by placing a temporary file under your web root, verifies domain ownership, and downloads the certificate.
At the final prompt, Certbot asks whether to redirect HTTP traffic to HTTPS. Choose option 2 to enable the redirect — this is the recommended choice for all production sites.
Certificates are stored in /etc/letsencrypt/live/yourdomain.com/:
sudo ls -l /etc/letsencrypt/live/yourdomain.com/
# fullchain.pem — certificate + intermediate chain
# privkey.pem — private key
# cert.pem — certificate only
# chain.pem — intermediate chain only
Step 5: Review the ssl.conf Modifications
Certbot modifies /etc/httpd/conf.d/ssl.conf (or creates a new *-le-ssl.conf file) to point Apache at the Let’s Encrypt certificates. Inspect the relevant directives:
sudo grep -E 'SSLCertificate|ServerName|Redirect' /etc/httpd/conf.d/ssl.conf
A typical Certbot-managed SSL virtual host looks like this:
<VirtualHost *:443>
ServerName yourdomain.com
ServerAlias www.yourdomain.com
DocumentRoot /var/www/html
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/yourdomain.com/chain.pem
# Recommended security settings
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM
SSLHonorCipherOrder on
Header always set Strict-Transport-Security "max-age=63072000"
</VirtualHost>
The HTTP-to-HTTPS redirect in your port-80 virtual host should look like:
<VirtualHost *:80>
ServerName yourdomain.com
RewriteEngine on
RewriteCond %{SERVER_NAME} =yourdomain.com [OR]
RewriteCond %{SERVER_NAME} =www.yourdomain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
Step 6: Verify the Configuration and Reload Apache
Always test the Apache configuration syntax before reloading:
sudo apachectl configtest
You should see Syntax OK. Then reload:
sudo systemctl reload httpd
Step 7: Test the Certificate with openssl s_client
Verify the certificate chain and TLS handshake from the command line:
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com < /dev/null
Key things to check in the output:
Verify return code: 0 (ok)— certificate chain validated successfullysubject=/CN=yourdomain.com— certificate is for your domainProtocol: TLSv1.2orTLSv1.3— no legacy protocols
You can also check the expiry date directly:
echo | openssl s_client -connect yourdomain.com:443 2>/dev/null
| openssl x509 -noout -dates
Step 8: Automate Certificate Renewal
Let’s Encrypt certificates expire after 90 days. Certbot installs a systemd timer on some systems, but on RHEL 7 you should verify and configure a cron job. Check if a cron entry already exists:
sudo cat /etc/cron.d/certbot
If no cron entry exists, add one manually with crontab -e as root:
0 2 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload httpd"
This runs at 2:00 AM daily, silently renews any certificate within 30 days of expiry, and reloads Apache afterwards to pick up the new certificate. Test the renewal process without actually renewing:
sudo certbot renew --dry-run
A successful dry run prints Congratulations, all renewals succeeded.
Step 9: Strengthen SSL Settings (Optional but Recommended)
For hardened security, add the following to your SSL virtual host or to /etc/httpd/conf.d/ssl.conf:
# Disable weak protocols
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
# Strong cipher suite (Mozilla Intermediate compatibility)
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:
ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder on
SSLCompression off
SSLSessionTickets off
# HSTS (requires HTTPS to be working reliably first)
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
# OCSP Stapling
SSLUseStapling on
SSLStaplingCache "shmcb:/var/run/ocsp(128000)"
After saving changes, test and reload:
sudo apachectl configtest && sudo systemctl reload httpd
You can score your SSL configuration at SSL Labs to verify you achieve at minimum an A rating.
Securing Apache with Let’s Encrypt and Certbot on RHEL 7 requires only a handful of commands but delivers significant security and trust benefits. With mod_ssl installed, certificates issued via the --apache plugin, and a cron-based renewal job in place, your site will maintain a valid TLS certificate indefinitely with minimal manual intervention. Combined with strong cipher settings and HSTS headers, this configuration meets modern security standards and protects your users against eavesdropping and man-in-the-middle attacks.