How to secure Apache with Let’s Encrypt Certificates on RHEL 8

I read that Let’s Encrypt is a free, automated, and open certificate for web server and other usages. How do I secure Apache with Let’s Encrypt Certificates on RHEL 8? How can I set up Let’s Encrypt Certificates on Red Hat Enterprise Linux version 8.x?

Introduction – Let’s Encrypt is a free, automated, and open certificate authority for your website powered by Apache web server. This page shows how to use Let’s Encrypt to install a free SSL certificate for Apache web server. You will learn how to properly deploy Diffie-Hellman on your server to get SSL labs A+ score on an RHEL 8.

How to secure Apache with Let’s Encrypt Certificates on RHEL 8

The procedure is as follows to obtaining an SSL certificate:

  1. Install SSL/TLS module for the Apache HTTP server in RHEL 8: sudo dnf install mod_ssl
  2. Get acme.sh software in RHEL 8: git clone https://github.com/Neilpang/acme.sh.git
  3. Create a new /.well-known/acme-challenge/ directory using: mkdir -p /var/www/html/.well-known/acme-challenge/
  4. Obtain an SSL certificate your domain, run: acme.sh --issue -w /DocumentRootPath/ -d your-domain
  5. Configure TLS/SSL for Apache on Red Hat Linux 8: vi /etc/httpd/conf.d/ssl.conf
  6. Setup a cron job for auto renewal of SSL/TLS certificate
  7. Open port 443 (HTTPS):sudo firewall-cmd --add-service=https

How to install Let’s Encrypt SSL certificate to secure Apache on RHEL 8

Our sample setup is as follows:

How to Install Let's Encrypt SSL Certificate to Secure Apache on RHEL 9

Secure Apache with Let’s Encrypt on RHEL 8

Let us see how to install acme.sh client and use it on a RHEL 8 to get an SSL certificate from Let’s Encrypt.

Step 1 – Install mod_ssl for the Apache

Type the following dnf command:
$ sudo dnf install mod_ssl
How to install mod_ssl on RHEL 8

Step 2 – Install acme.sh Let’s Encrypt client

You need to install wget on RHEL 8, curl, bc, socat and git client on RHEL 8 in order use acme.sh, run:
$ sudo dnf install wget curl bc git socat

Clone the repo

$ cd /tmp/
$ git clone https://github.com/Neilpang/acme.sh.git

Next, install acme.sh client on to your system, run:
$ cd acme.sh/
$ sudo -i
# cd acme.sh/
# ./acme.sh --install

How to setup Let's Encrypt certificates on RHEL with acme.sh
Now we have needed software on the RHEL 8 box. You must close the current terminal or ssh session and reopen again to make the alias take effect. Or type the following source command:
$ sudo source ~/.bashrc
Verify that acme.sh working, run:
# acme.sh --list

Step 3 – Create acme-challenge directory

Type the following mkdir command. Make sure you set D to actual DocumentRoot path as per your needs:
# D=/var/www/html/
# mkdir -vp ${D}/.well-known/acme-challenge/
###---[ NOTE: Adjust permission as per your setup ]---###
# chown -R apache:apache ${D}/.well-known/acme-challenge/
# chmod -R 0555 ${D}/.well-known/acme-challenge/

Also, create a directory to store SSL certificate:
# mkdir -p /etc/httpd/ssl/cyberciti.biz/

Step 4 – Create dhparams.pem file

Run the openssl command:
# cd /etc/httpd/ssl/cyberciti.biz/
# openssl dhparam -out dhparams.pem -dsaparam 4096

How to speed up OpenSSL/GnuPG Entropy For Random Number Generation On Linux

Step 5 – Obtain a SSL/TLS certificate for domain

Issue a certificate for your domain. The syntax is:
# acme.sh --issue -w /path/to/www/htmlRoot/ -d your-domain-example-com -k 2048
# acme.sh --issue -w /path/to/www/htmlRoot/ -d www.cyberciti.biz -k 4096
# acme.sh --issue -w /var/www/html/ -d rhel8.cyberciti.biz -k 4096

Create a free Apache SSL certificate with Let's Encrypt on RHEL 8

Requesting a free Apache SSL certificate with Let’s Encrypt on RHEL 8 (click to enlarge)

Step 6 – Configure Apache to use SSL/TLS

Edit the file named /etc/httpd/conf.d/ssl.conf using a text editor such as vi command:
$ sudo vi /etc/httpd/conf.d/ssl.conf
Append/update as follows:

### Start config for port 443 #
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache         shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout  300
SSLCryptoDevice builtin
 
### Turn on HTTP2 support #
Protocols h2 http/1.1
 
### Redirect all http urls to https #
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L,QSA]
#################################################
# SSL/TLS config for domain rhel8.cyberciti.biz #
#################################################
<VirtualHost rhel8.cyberciti.biz:443>
 
        ### Log files  #
        ErrorLog logs/ssl_error_log
        TransferLog logs/ssl_access_log
        LogLevel warn
        SSLEngine on
 
        ### No more SSL3/2 #
        SSLProtocol             all -SSLv3
        SSLHonorCipherOrder     off
        SSLCompression          off
        SSLSessionTickets       off
        SSLCipherSuite          ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
 
        ### Path to certs #
        SSLCertificateFile      /etc/httpd/ssl/cyberciti.biz/rhel8.cyberciti.biz.cer
        SSLCertificateKeyFile   /etc/httpd/ssl/cyberciti.biz/rhel8.cyberciti.biz.key
 
        #Forward Secrecy & Diffie Hellman ephemeral parameters
        SSLOpenSSLConfCmd DHParameters "/etc/httpd/ssl/cyberciti.biz/dhparams.pem"
 
        # HSTS (mod_headers is required) (15768000 seconds = 6 months)
        Header always set Strict-Transport-Security "max-age=15768000"
        <FilesMatch "\.(cgi|shtml|phtml|php)$">
            SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory "/var/www/cgi-bin">
                SSLOptions +StdEnvVars
        </Directory>
        BrowserMatch "MSIE [2-5]" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0
         CustomLog logs/ssl_request_log \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
 
### OCSP stapling config
SSLUseStapling          on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache        shmcb:/var/run/ocsp(128000)

Save and close the file and exit from vim text editor.

A note about more secure SSL options

Update above config as follows to disable SSL and TLS version 1/1.1:

SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite          ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256

Please see this page for more info.

Step 7 – Install certificate

Type the following command:
# acme.sh --installcert -d rhel8.cyberciti.biz \
--keypath /etc/httpd/ssl/cyberciti.biz/rhel8.cyberciti.biz.key \
--fullchainpath /etc/httpd/ssl/cyberciti.biz/rhel8.cyberciti.biz.cer \
--reloadcmd 'systemctl reload httpd'

Install and secure Apache with Let's Encrypt certificates

Step 8 – Firewalld configuration on RHEL 8 to open HTTPS tcp port 443

Now our Apache up and running with mod_ssl. It is time to open TCP port # 443 (HTTPS) on RHEL 8 box so that clients can connect to it. Update the rules as follows:
$ sudo firewall-cmd --permanent --add-service=https --zone=public
$ sudo firewall-cmd --reload
$ sudo firewall-cmd --list-services --zone=public

How to open HTTPS port 443 using firewalld on RHEL 8

Use a firewalld tool to open https port 443

Verify that port 443 and 80 open and listing state with the help of ss command along with the grep command/egrep command:
$ sudo ss -tulpn
$ sudo ss -tulpn | egrep ':(80|443)'

Step 9 – Test it

Fire a web browser and type your domain such as:
https://rhel8.cyberciti.biz

rhel8.cyberciti.biz HTTPS test

HTTPS based site in action

Test it with SSLlabs test site:
https://www.ssllabs.com/ssltest/analyze.html?d=rhel8.cyberciti.biz
Getting an A+ rating on ssllabs ssltest

Step 10 – acme.sh commands

List all SSL/TLS certificates, run:
# acme.sh --list
Renew a cert for domain named server2.cyberciti.biz
# acme.sh --renew -d rhel8.cyberciti.biz
Please note that a cron job will try to do renewal a certificate for you too. This is installed by default as follows (no action required on your part). To see job run:
# crontab -l
Sample outputs:

38 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

Upgrade acme.sh client:
# acme.sh --upgrade
Getting help:
# acme.sh --help | more

Conclusion

This page showed how to install a free SSL/TSL certificate from Let’s Encrypt to secure communication between Apache and browsers, on an RHEL 8 server. For more info see Apache mod_ssl documents here.

This entry is 2 of 3 in the RHEL 8 LAMP Tutorial series. Keep reading the rest of the series:
  1. How To Install Linux, Apache, MySQL, PHP (LAMP) stack On RHEL 8
  2. How to secure Apache with Let's Encrypt Certificates on RHEL 8
  3. How To Install MariaDB on RHEL 8
This entry is 5 of 13 in the Secure Web Server with Let's Encrypt Tutorial series. Keep reading the rest of the series:
  1. Set up Lets Encrypt on Debian/Ubuntu Linux
  2. Secure Lighttpd with Lets Encrypt certificate on Debian/Ubuntu
  3. Configure Nginx with Lets Encrypt certificate on Alpine Linux
  4. Nginx with Lets Encrypt on CentOS 7
  5. Apache with Lets Encrypt Certificates on RHEL 8
  6. CentOS 8 and Apache with Lets Encrypt Certificates
  7. Install Lets Encrypt certificates on CentOS 8 for Nginx
  8. Forcefully renew Let's Encrypt certificate
  9. OpenSUSE Linux and Nginx with Let's Encrypt Certificates
  10. Configure Nginx to use TLS 1.2 / 1.3 only
  11. Let's Encrypt wildcard certificate with acme.sh and Cloudflare DNS
  12. Nginx with Let's Encrypt on Ubuntu 18.04 with DNS Validation
  13. AWS Route 53 Let's Encrypt wildcard certificate with acme.sh

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 1 comment so far... add one

CategoryList of Unix and Linux commands
Disk space analyzersdf ncdu pydf
File Managementcat tree
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04

Comments on this entry are closed.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum