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?

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 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

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 on 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: acme.sh --issue -w /DocumentRootPath/ -d your-domain
  5. Configure TLS/SSL for Apache on RHEL 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

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 on 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

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.

Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin, DevOps engineer, and a trainer for the Linux operating system/Unix shell scripting. Get the latest tutorials on SysAdmin, Linux/Unix and open source topics via RSS/XML feed or weekly email newsletter.

Similar Posts