Let’s Encrypt is a non-profit certificate authority run by Internet Security Research Group (ISRG) that provides X.509 certificates for Transport Layer Security (TLS) encryption at no charge. The certificate is valid for 90 days, during which renewal can take place at any time. The offer is accompanied by an automated process designed to overcome manual creation, validation, signing, installation, and renewal of certificates for secure websites. It launched on April 12, 2016.

In this article, we will show you how you can install Let’s Encrypt Certificate for Apache web server and configure the certificate to renew automatically on CentOS 8.

Installing Apache

Apache is available in the default CentOS repositories.

# dnf install httpd mod_ssl

Enable and start the Apache service.

# systemctl enable httpd
# systemctl start httpd

Install Certbot

# wget https://dl.eff.org/certbot-auto
# mv certbot-auto /usr/local/bin/certbot-auto
# chmod 0755 /usr/local/bin/certbot-auto

Generate a new set of 2048 bit DH parameters to strengthen the security.

# openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Obtaining a Let’s Encrypt SSL certificate

To obtain an SSL certificate for the domain we’re going to use the Webroot plugin that works by creating a temporary file for validating the requested domain in the ${webroot-path}/.well-known/acme-challenge directory. The Let’s Encrypt server makes HTTP requests to the temporary file to validate that the requested domain resolves to the server where certbot runs.

To make the setup more simple we’re going to map all HTTP requests for .well-known/acme-challenge to a single directory, /var/lib/letsencrypt.

# mkdir -p /var/lib/letsencrypt/.well-known
# chgrp apache /var/lib/letsencrypt
# chmod g+s /var/lib/letsencrypt

Create two configurations files

#  nano /etc/httpd/conf.d/letsencrypt.conf

Alias /.well-known/acme-challenge/ "/var/lib/letsencrypt/.well-known/acme-challenge/"
<Directory "/var/lib/letsencrypt/">
    AllowOverride None
    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
    Require method GET POST OPTIONS
</Directory>

And the second one.

# nano /etc/httpd/conf.d/ssl-params.conf

SSLCipherSuite EECDH+AESGCM:EDH+AESGCM
# Requires Apache 2.4.36 & OpenSSL 1.1.1
SSLProtocol -all +TLSv1.3 +TLSv1.2
SSLOpenSSLConfCmd Curves X25519:secp521r1:secp384r1:prime256v1
# Older versions
# SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder On
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff
# Requires Apache >= 2.4
SSLCompression off
SSLUseStapling on
SSLStaplingCache "shmcb:logs/stapling-cache(150000)"
# Requires Apache >= 2.4.11
SSLSessionTickets Off

SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem"

Reload the Apache configuration

# systemctl reload httpd

Run certbot script with the webroot plugin and fetch the SSL certificate files.

# /usr/local/bin/certbot-auto certonly --agree-tos --email [email protected] --webroot -w /var/lib/letsencrypt/ -d example.com -d www.example.com

Creating Virtual Host 

By default, Apache is configured to load all configuration files that ends with .conf from the /etc/httpd/conf.d/ directory.

# nano /etc/httpd/conf.d/example.com.conf

<VirtualHost *:80>
  ServerName example.com
  ServerAlias www.example.com

  Redirect permanent / https://example.com/
</VirtualHost>

<VirtualHost *:443>
  ServerName example.com
  ServerAlias www.example.com

  Protocols h2 http:/1.1

  <If "%{HTTP_HOST} == 'www.example.com'">
    Redirect permanent / https://example.com/
  </If>

  DocumentRoot /var/www/example.com/public_html
  ErrorLog /var/log/httpd/example.com-error.log
  CustomLog /var/log/httpd/example.com-access.log combined

  SSLEngine On
  SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

</VirtualHost>

Test Let’s Encrypt SSL Certificate

Test your SSL certificate for problems and its security ratings by going to the below URL. 
https://www.ssllabs.com/ssltesthttps://www.sslshopper.com/ssl-checker.html

Renew Let’s Encrypt Certificate

Let’s Encrypt certificate is valid for 90 days from the date of issuance, and it needs to be renewed before it expires.

Run the following command to create a new cronjob which will renew the certificate and restart Apache.

# echo "0 0,12 * * * root python3 -c 'import random; import time; time.sleep(random.random() * 3600)' && /usr/local/bin/certbot-auto -q renew --renew-hook \"systemctl reload httpd\"" | sudo tee -a /etc/crontab > /dev/null

You can also simulate the certificate renewal process with the below command to ensure the renewal goes smooth.

# /usr/local/bin/certbot-auto renew --dry-run

In this guide, we demonstrated how you can use certbot to install and configure the Let’s Encrypt certificate on Apache webserver running on a CentOS 8 system.