We hope you find this tutorial helpful. In addition to guides like this one, we provide simple cloud infrastructure for developers. Learn more →

How to Secure Apache with Let's Encrypt on CentOS 7

Posted Jan 26, 2016 46.1k views Let's Encrypt Security Apache CentOS


This tutorial will show you how to set up a TLS/SSL certificate from Let’s Encrypt on a CentOS 7 server running Apache as a web server. Additionally, we will cover how to automate the certificate renewal process using a cron job.

SSL certificates are used within web servers to encrypt the traffic between server and client, providing extra security for users accessing your application. Let’s Encrypt provides an easy way to obtain and install trusted certificates for free.


In order to complete this guide, you will need:

  • A CentOS 7 server with a non-root sudo user, which you can set up by following our Initial Server Setup guide
  • The Apache web server installed with one or more domain names properly configured

For the purpose of this guide, we will install a Let’s Encrypt certificate for the domain example.com. This will be referenced throughout the guide, but you should substitute it with your own domain while following along.

When you are ready to move on, log into your server using your sudo account.

Step 1 — Create a Virtual Host for your Domain

The Apache plugin for the certbot Let’s Encrypt client greatly simplifies the process of generating and installing SSL certificates for domains hosted with Apache. However, at the time of this writing, it is required that you have your domains organized into virtual hosts, each one in a separate configuration file.

If your domain is already configured as a virtual host in a separate configuration file, you can skip to the next step.

Create the Directory Structure

We will start by creating a new directory structure to hold your virtual host files inside the Apache configuration directory, /etc/httpd. We will follow the standard structure introduced by Debian based distributions, which makes it easier to enable and disable sites that are configured as virtual hosts within Apache.

Access the Apache configuration directory with:

  • cd /etc/httpd

First, create the directory that will hold all sites available on this server:

  • sudo mkdir /etc/httpd/sites-available

Next, create the directory that will have the currently active (enabled) websites hosted on this server. This directory will contain only symbolic links to the virtual host files located inside /etc/httpd/sites-available.

  • sudo mkdir /etc/httpd/sites-enabled

Now we need to tell Apache how to find the virtual host files. To accomplish this, we will edit Apache's main configuration file and add a line declaring an optional directory for additional configuration files. Using your favorite command line text editor, open the file /etc/httpd/conf/httpd.conf:

  • sudo nano /etc/httpd/conf/httpd.conf

Add this line to the end of the file:

IncludeOptional sites-enabled/*.conf

Save and close the file when you are done adding that line.

Create a New Virtual Host File

The next step is to create the virtual host configuration file. Using your favorite command line text editor, create a new file under /etc/httpd/sites-available. We will be naming the file example.com.conf, but you can choose the name of your choice. It is important, however, that the file ends with the .conf extension.

  • sudo nano /etc/httpd/sites-available/example.com.conf

Add the following contents to the file, replacing example.com with your own domain:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/html
    ErrorLog /var/log/apache/example.com/error.log

Save the file and exit. Below, you can find a brief explanation of each configuration option used for this example:

  • ServerName: your main domain name.
  • ServerAlias (optional): an alias for your main domain. It is a common practice to add the www subdomain as an alias of the main domain.
  • DocumentRoot: the location where the website files should be found. With the default Apache configuration on CentOS 7, the main document root is typically /var/www/html, but you can change this value if you want to place your website files in a different location on the server.
  • ErrorLog (optional): a custom location for logging errors specific to this virtual host. If you don’t specify this option, errors will be logged to the default Apache error log: /var/log/httpd/error_log .

Enabling the Virtual Host

The virtual host file is now created, but we still need to tell Apache that we want this website to be enabled. In order to accomplish that, we need to create a symbolic link inside sites-enabled pointing to the new virtual host configuration file. Run:

  • sudo ln -s /etc/httpd/sites-available/example.com.conf /etc/httpd/sites-enabled/example.com.conf

This way, whenever you want to disable a virtual host, you can simply remove the link inside sites-enabled and reload the Apache service, keeping the original virtual host file inside sites-available for any future needs.

If your domain was previously configured as the main Apache website inside the httpd.conf file, it is important that you remove the old configuration from that file, in order to avoid unexpected behavior when generating your SSL certificate.

Open the file /etc/httpd/conf/httpd.conf and search for the directives ServerName and ServerAlias. If they are set to the same domain you configured as a virtual host, you should comment them out by adding a # sign at the beginning of the line:

  • sudo nano /etc/httpd/conf/httpd.conf

# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
# If your host doesn't have a registered DNS name, enter its IP address here.
#ServerName example.com:80
#ServerAlias www.example.com

Next, create the log directory you specified in the virtual host file if it is not already present:

  • sudo mkdir -p /var/log/apache/example.com

Test to make sure that your configuration files do not contain any syntax errors:

  • sudo apachectl configtest

If everything is okay, restart Apache so the changes take effect:

  • sudo systemctl restart httpd

For a detailed guide on how to set up Apache virtual hosts on CentOS 7, check this link.

Step 2 — Install the Server Dependencies

Before we can install the certbot Let’s Encrypt client and generate the SSL certificate, we need to install access to the EPEL repository. We will also need to install the mod_ssl module to correctly serve encrypted traffic.

To enable access to the repository and add support for SSL, type:

  • sudo yum install epel-release mod_ssl

Your server should now be ready to grab the certbot Let's Encrypt client.

Step 3 — Download the Let’s Encrypt Client

Next, we will download the certbot Let’s Encrypt client from the EPEL repository:

  • sudo yum install python-certbot-apache

The certbot client should now be installed and ready for use.

Step 4 — Set Up the SSL Certificate

Generating the SSL Certificate for Apache using the certbot Let’s Encrypt client is quite straightforward. The client will automatically obtain and install a new SSL certificate that is valid for the domains provided as parameters.

To execute the interactive installation and obtain a certificate that covers only a single domain, run the certbot command with:

  • sudo certbot --apache -d example.com

If you want to install a single certificate that is valid for multiple domains or subdomains, you can pass them as additional parameters to the command. The first domain name in the list of parameters will be the base domain used by Let’s Encrypt to create the certificate, and for that reason we recommend that you pass the bare top-level domain name as first in the list, followed by any additional subdomains or aliases:

  • sudo certbot --apache -d example.com -d www.example.com

For this example, the base domain will be example.com.

After the dependencies are installed, you will be presented with a step-by-step guide to customize your certificate options. You will be asked to provide an email address for lost key recovery and notices, and you will be able to choose between enabling both http and https access or forcing all requests to redirect to https.

When the installation is successfully finished, you should see a message similar to this:

 - If you lose your account credentials, you can recover through
   e-mails sent to user@example.com.
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/example.com/fullchain.pem. Your cert
   will expire on 2016-04-21. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
 - Your account credentials have been saved in your Let's Encrypt
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Let's
   Encrypt so making regular backups of this folder is ideal.
 - If you like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

The generated certificate files should be available on /etc/letsencrypt/live.

Reorganizing your Virtual Hosts

The Apache plugin for the certbot Let’s Encrypt client creates a new virtual host file for enabling https access for your domain. This is done automatically by the client when you generate your certificate using the Apache plugin. However, the file is created inside sites-enabled, a directory that should contain only links for the actual virtual host files that are located inside the sites-available directory.

To keep your virtual host files organized and consistent with defaults, it is a good idea to move this new virtual host file to the sites-available directory and create a symbolic link inside sites-enabled:

  • sudo mv /etc/httpd/sites-enabled/example.com-le-ssl.conf /etc/httpd/sites-available/example.com-le-ssl.conf
  • sudo ln -s /etc/httpd/sites-available/example.com-le-ssl.conf /etc/httpd/sites-enabled/example.com-le-ssl.conf

Your sites-enabled directory should look similar to this:

ls -la /etc/httpd/sites-enabled
lrwxrwxrwx 1 root root   48 Jan 25 12:37 example.com.conf -> /etc/httpd/sites-available/example.com.conf
lrwxrwxrwx 1 root root   55 Jan 25 12:44 example.com-le-ssl.conf -> /etc/httpd/sites-available/example.com-le-ssl.conf

Restart Apache to apply the changes:

  • sudo systemctl restart httpd

Checking your Certificate Status

You can verify the status of your SSL certificate with the following link (don’t forget to replace example.com with your base domain):


You should now be able to access your website using a https prefix.

Step 5 — Set Up Auto Renewal

Let’s Encrypt certificates are valid for 90 days, but it’s recommended that you renew the certificates every 60 days to allow a margin of error. The certbot Let's Encrypt client has a renew command that automatically checks the currently installed certificates and tries to renew them if they are less than 30 days away from the expiration date.

To trigger the renewal process for all installed domains, you should run:

  • sudo certbot renew

Because we recently installed the certificate, the command will only check for the expiration date and print a message informing that the certificate is not due to renewal yet. The output should look similar to this:

Processing /etc/letsencrypt/renewal/example.com.conf

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/example.com/fullchain.pem (skipped)
No renewals were attempted.

Notice that if you created a bundled certificate with multiple domains, only the base domain name will be shown in the output, but the renewal should be valid for all domains included in this certificate.

A practical way to ensure your certificates won’t get outdated is to create a cron job that will periodically execute the automatic renewal command for you. Since the renewal first checks for the expiration date and only executes the renewal if the certificate is less than 30 days away from expiration, it is safe to create a cron job that runs every week or even every day, for instance.

Let's edit the crontab to create a new job that will run the renewal command every week. To edit the crontab for the root user, run:

  • sudo crontab -e

Include the following content, all in one line:

30 2 * * 1 /usr/bin/certbot renew >> /var/log/le-renew.log

Save and exit. This will create a new cron job that will execute the certbot renew command every Monday at 2:30 am. The output produced by the command will be piped to a log file located at /var/log/le-renewal.log.

For more information on how to create and schedule cron jobs, you can check our How to Use Cron to Automate Tasks in a VPS guide.


In this guide, we saw how to install a free SSL certificate from Let’s Encrypt in order to secure a website hosted with Apache, on a CentOS 7 server. We recommend that you check the official Let’s Encrypt blog for important updates from time to time.


Creative Commons License