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 secure Apache with Let’s Encrypt Certificates on RHEL 8
The procedure is as follows to obtaining an SSL certificate:
- Install SSL/TLS module for the Apache HTTP server in RHEL 8: sudo dnf install mod_ssl
- Get acme.sh software on RHEL 8: git clone https://github.com/Neilpang/acme.sh.git
- Create a new /.well-known/acme-challenge/ directory using: mkdir -p /var/www/html/.well-known/acme-challenge/
- Obtain an SSL certificate your domain: acme.sh --issue -w /DocumentRootPath/ -d your-domain
- Configure TLS/SSL for Apache on RHEL 8: vi /etc/httpd/conf.d/ssl.conf
- Setup a cron job for auto renewal of SSL/TLS certificate
- 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
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
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
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'
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
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
Test it with SSLlabs test site:https://www.ssllabs.com/ssltest/analyze.html?d=rhel8.cyberciti.biz
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.