How to Secure Apache with Let's Encrypt on CentOS 7
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
- 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
- sudo nano /etc/httpd/conf/httpd.conf
Add this line to the end of the file:
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
- 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 </VirtualHost>
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
wwwsubdomain 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:
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
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
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
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
https access or forcing all requests to redirect to
When the installation is successfully finished, you should see a message similar to this:
IMPORTANT NOTES: - If you lose your account credentials, you can recover through e-mails sent to email@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
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
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
- 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
sites-enabled directory should look similar to this:
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
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:
crontab30 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
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.