Improving your website security through encryption, even on the most basic servers, can increase your visitors’ trust in your site and your ability to run it. Setting up encryption on your web host has generally been complicated and expensive, which often deters administrators whose web applications might not depend on user input. Let’s Encrypt aims to change this by making implementing encryption on any website easier. They are an open and free project that allows obtaining and installing of certificates through simple, automated, commands.

Let's Encrypt Project Logo

Let’s Encrypt is a new Certificate Authority capable of issuing certificates cross-signed by IdentTrust, which allows their end certificates to be accepted by all major browsers.  This guide outlines the steps for installing their certbot client version 0.11.1 and how to use it to manage certificates on your CentOS 7 server running nginx.

Installing Let’s Encrypt client

Let’s Encrypt greatly simplifies server management by automating obtaining certificates and configuring web services to use them. The client is fully-featured and extensible for the Let’s Encrypt Certificate Authority or any other CA that supports the ACME protocol.

On CentOS, the client is available in the Extra Packages for Enterprise Linux (EPEL) which you will need to first install and update.

sudo yum install epel-release
sudo yum update

You will also need to have nginx installed and running. Of course, if you are adding certificates onto a previously configured web host this would already be installed.

sudo yum install nginx
sudo systemctl start nginx

Then install the certbot client itself with the following command.

sudo yum install certbot

Once installed, you can use the next command to see test the client is working correctly.

certbot --help

Given that the help command works, the client is good to go. Next, check that your firewall is configured correctly with the instructions below.

Allow HTTP/S at firewall

CentOS 7 has enabled by default relatively strict firewall rules which do not allow HTTP or HTTPS connections to the host. The Let’s Encrypt client requires access to authenticate the domain name and will fail with the default rules.

If you are installing the certificates on a previously configured web host, the required rules are probably already set. Confirm the firewall rules with the --list-services command and continue in the next section with obtaining the certificates.

Enable connections for HTTP and HTTPS services using the following command.

sudo firewall-cmd --permanent --add-service=http --add-service=https

Then reload the firewall rules to apply the changes.

sudo firewall-cmd --reload

You can check that the rules were added successfully with the command below.

sudo firewall-cmd --list-services
dhcpv6-client http ssh https

You should see at least the four services enabled as shown above. With the firewall configured, you can continue on with obtaining and installing certificates.

Obtaining a certificate

Let’s Encrypt validates the domain it is installed on similarly to a traditional CA process by identifying the server administrator via a public key. The client generates a new key pair when interacting with the Let’s Encrypt servers for the first time, and then aims to prove to the CA that the host has control over a particular domain by at least one of the two following ways:

  • Provisioning a DNS record under the domain in question
  • Provisioning an HTTP resource under a well-known URI on the domain

On top of one of the two challenges, the client also must sign a nonce with its private key to prove it controls that key pair.

To help the Let’s Encrypt client accomplish these tasks it supports a number of plugins that can be used to obtain and install certificates. While Let’s Encrypt does not yet support automated installation on nginx, the certificates can be easily obtained using the certonly command together with the --webroot plugin.

The --webroot plugin automates obtaining certificates from the CA and is compatible with any web server software. To use this plugin on the command line, you will need to run the client with the path to the root directory and specify at least one domain like shown in the example below. Replace the <domain_name> in the command with your server’s domain name and <web_root> with the directory you web server files reside, commonly either /usr/share/nginx/html or /var/www/html.

sudo certbot certonly --webroot -w <web_root> -d <domain_names>

The command starts an interactive configuration script that asks a couple of questions to help with managing certificates.

  1. On the first installation on any specific host, you’ll need to enter a contact email.
  2. Then go through the Let’s Encrypt Terms of Service and select Agree if you accept the terms and wish to use the service.
  3. Choose whether you wish to share your email address with the Electronic Frontier Foundation (EFF) for updates on their work.

If the client was successful at obtaining a certificate you can find a confirmation and certificate expiration date at the end of the client output.

In case you are having problems with the client, make sure you are trying to register a domain or subdomain that currently resolves to your server. Check that you have the administrative privileges to run the commands and that you are pointing to the correct web root.

Configuring nginx

Once you have the certificate and chain saved on the server, you will next need to configure nginx to accept HTTPS connections using the new certificates.

Diffie-Hellman Ephemeral algorithm

The Diffie-Hellman algorithm is a way of generating a shared secret between two parties in such a way that the secret cannot be seen by observing the communication. It is a useful technique to create an encryption key between a server and a client, that then use the shared key to encrypt their traffic. Ephemeral Diffie-Hellman (DHE) differs from the static Diffie-Hellman by generating a temporary key for every connection and never using the same key twice. This enables Forward Secrecy which means that even if the server long-term private key gets leaked, previous communication remains secure.

Generate a strong DHE parameter using the command below.

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

The process takes but a moment with 2048-bit key length. You can also use 4096-bit length for higher security but generating a longer parameter will be considerably slower. Afterwards, the output can be used with nginx in the next part.

Setting up the configuration

With CentOS or other Red Hat variants, the nginx default configuration file is usually under /etc/nginx/conf.d/default.conf. Open it to edit with the command below.

sudo vi /etc/nginx/conf.d/default.conf

The example configuration below sets up a single site listening for HTTPS connections. Set the <domain_name> and <web_root> in the configuration the same as with the certificate.

# HTTPS server
server {
   listen 443 ssl;
   server_name <domain_name>;
   ssl_certificate /etc/letsencrypt/live/<domain_name>/fullchain.pem;
   ssl_certificate_key /etc/letsencrypt/live/<domain_name>/privkey.pem;
   ssl_session_cache shared:SSL:10m;
   ssl_session_timeout 5m;
   ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
   ssl_prefer_server_ciphers on;
   ssl_dhparam /etc/ssl/certs/dhparam.pem;
   ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
   add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
   location / {
      root <web_root>;
      index index.html index.htm;
   }
}

Then save the file and exit the editor.

To have the changes take effect, you will need to restart nginx.

sudo systemctl restart nginx

Now open your domain in a web browser using https://<domain_name>, when it loads you will know the installation is working properly.

You can evaluate the server encryption performance with Qualys SSL Labs test site. Enter your domain name into the text field and click the Submit button. The test will take a moment, but when completed it provides some useful information on different areas of your server encryption security as well as an overall rating.

Qualys SSL Labs nginx test

Note that as Let’s Encrypt is still in development they have set certain rate limits for issuing certificates to protect the service against both accidental and intentional abuse. You can check further details at the Let’s Encrypt documentation.

Redirect unencrypted connections

Optionally you can add a redirection from your HTTP connections to the encrypted HTTPS by editing the same configuration file as you did before. Make sure you have the 3 lines shown below in an HTTP server segment. Again replace the <domain_name> with your web server’s domain. The rest of that segment can remain as is.

server {
   listen 80;
   server_name <domain_name>;
   return 301 https://$server_name$request_uri;
}

Then save the file, exit the editor and reload nginx.

sudo nginx -s reload

Now you should always land on the encryption enabled https:// part of your site even with links pointing to the http://<domain_name> address.

Renewing a certificate

At the end of the certificate obtaining script, the output shows the certificate’s expiration date which is usually 3 months from the day it was issued. Renewing a certificate is just as easy as obtaining one.

The client will only renew certificates close to their expiry date, but you can test that the renewal works using the --dry-run parameter to simulate the process.

sudo certbot renew --dry-run

To actually renew certificates, simply leave out the simulation parameter.

sudo certbot renew

Once the renewal is complete, reload your web service to update the configuration to include the new certificates using the following command.

sudo nginx -s reload

Your certificate is now again valid for another 3 months.

Considering the duration of the certificates, you might wish to automate the renewal with a short script like the example below and make it executable.

sudo vi /etc/cron.daily/letsencrypt-renew
#!/bin/sh
if certbot renew > /var/log/letsencrypt/renew.log 2>&1 ; then
   nginx -s reload
fi
exit
sudo chmod +x /etc/cron.daily/letsencrypt-renew

The example script runs the renewal while directing the output to a log file, then reloads nginx if the process was successful to complete the renewal.

You can then automate the script using Crontab. Open the root user crontab for edit with the command underneath.

sudo crontab -e

Include a line similar to the example below in the crontab file, then save and exit.

01 02,14 * * * /etc/cron.daily/letsencrypt-renew

Let’s Encrypt recommends setting the automated renewal script to run twice a day on a random minute within the hour. The above example runs on 02:01 and 14:01 but you can select any time slot you wish.

Revoking a certificate

If you wish to remove a certificate from your server it can be revoked using the subcommand with the client. The command below can be used to revoke a particular certificate. Replace the <domain_name> with the domain which certificate you wish to revoke.

sudo certbot revoke --cert-path /etc/letsencrypt/live/<domain_name>/cert.pem

The process does not give a confirmation upon completion, but if you perform it again you will get a message that the certificate has already been revoked.

Other plugins

In most cases simply installing and renewing your certificates as instructed above are enough, but the Let’s Encrypt client also supports some additional plugins for managing your certificates. For example, if you do not have a web service configured yet while obtaining a new certificate you can use the --standalone plugin with certonly subcommand.

This guide focuses on installing the certificate on nginx using the --webroot plugin, though Let’s Encrypt also works just as well with other web servers software. Let’s Encrypt has built in support to issue and install certificates automatically for servers running Apache. Check out our guide for How to Install Let’s Encrypt on Apache2 to learn more. You can also find out about other supported options in the documentation for Let’s Encrypt.