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 which 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 client and how to use it to manage certificates on your cloud server running nginx.

Installing Let’s Encrypt client

Getting an HTTPS server setup can be a hassle. Let’s Encrypt aims to greatly simplify the task by automating obtaining certificates and configuring web servers to use them. The client is fully-featured and extensible for the Let’s Encrypt Certificate Authority, or any other CA that uses the ACME protocol, that allows managing certificates with simple commands.

Note that the client is currently in beta and may contain bugs. It’s recommended to make a backup of your server before continuing.

The client is available through the project’s GitHub repository. If you don’t have git installed yet, you can get it with one of the two following commands depending on your OS.

sudo apt-get install git
sudo yum install git

There is no need to configure git if you don’t require it for anything other than downloading repositories. Instead, just change to the directory where you wish to put the Let’s Encrypt client into and fetch it with

git clone https://github.com/letsencrypt/letsencrypt

Then change into the newly downloaded directory

cd letsencrypt

Obtaining a certificate works using the letsencrypt-auto wrapper script provided with the client. It installs all of its own dependencies and updates the client code automatically, therefore you’ll need to run the client on an account with sudo privileges. Use the command below to see the accepted subcommands and flags.

./letsencrypt-auto --help

Given that the help command works, you are ready to continue on with obtaining and installing a certificate.

Obtaining a certificate

Let’s Encrypt validates the domain it’s 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 or install certificates. While Let’s Encrypt is being developed further they intend to provide a plugin for nginx which will automate installing certificates, but at this time the plugin is still experimental, instead it’s recommended to use the webroot method.

The webroot plugin automates obtaining certificates from the CA and saves them on the host. To use this plugin on the command line, you’ll need to run the client with the certonly subcommand then add –webroot flag with the path to the root and lastly specify at least a single domain. Replace the <domain name> in the configuration with your server’s domain name and <root folder> with the directory you web server files reside, commonly either /usr/share/nginx/html or /var/www/html.

sudo ./letsencrypt-auto certonly --webroot -w <web root folder> -d <domain names>

This starts the script in an interactive mode asking a couple of questions to obtain the certificate correctly.

  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.

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 using the client script, make sure you are trying to register a domain or subdomain that currently resolves to that host. Also, check that you have the administrative privileges to run the commands and that you are pointing to the correct web root.

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 will take 1-3 minutes using the 2048-bit key after which it can be used with nginx in the next part.

Configuring nginx

With the certificate issued, you will need to configure nginx to use it to accept HTTPS connections. Depending on your choice of OS the server configuration files are commonly either located under folder conf.d or sites-available. On Ubuntu and other Debian-based systems, you can find the default configuration at the latter, open it for edit with the following command.

sudo nano /etc/nginx/sites-available/default

Systems with CentOS or other Red Hat variants have the same configuration file usually under conf.d/default.conf, open it with the command below.

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

The default configuration sets up a single site listening for HTTP connections. Keep the server listening on port 80 as is for now, but edit or add in an HTTPS server section to the end of the file like the example configuration below. Set the <domain name> and <root folder> in the configuration the same as when obtaining 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';
   location / {
      root <web root folder>;
      index index.html index.htm;
   }
}

Then save the file and exit the editor.

To have the changes take an effect, you’ll need to restart nginx.

sudo service nginx restart

Now open your domain in a web browser using https://<your domain>, 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.

Qualys SSL Labs test

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 your HTTP server segment. Again replace the <domain name> with your web servers 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 again.

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

Renewing a certificate

At the end of the certificate obtaining script output, you’ll see the certificate’s expiration date which is usually 3 months from the day you installed it. Renewing a certificate is as easy as installing it again using the same values as before.

In almost all circumstances, renewal should be performed with the certonly subcommand after which reloading your web server configuration should be enough to deploy the renewed certificate, for example:

./letsencrypt-auto certonly --webroot -w <web root folder> -d <domain names>

Then answer the questions the client asks to renew and replace the certificate.

Once the renewal is complete simply reload your web service to update the configuration using the following command.

sudo nginx -s reload

Your certificate is now again valid for another 3 months.

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

Let’s Encrypt intends to provide renewal scripts later down the line to automate this process, but in the meanwhile, you can create your own along the lines of the example below.

#!/bin/sh
if ! ~/letsencrypt/letsencrypt-auto certonly -tvv --keep --webroot -w <web root folder> -d <domain names> > /var/log/letsencrypt/renew.log 2>&1 ; then
   echo Automated renewal failed:
   cat /var/log/letsencrypt/renew.log
   exit 1
fi
nginx -s reload

The example script runs the renewal while directing the output to a log file and then checks if it was successful or not, and finally reloads nginx to complete the renewal. Once your renewal script works, you can automate it with a Cron job.

Revoking a certificate

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

./letsencrypt-auto revoke --cert-path /etc/letsencrypt/live/<domain name>/cert.pem

The process won’t give a confirmation upon completion, but if you perform it again you’ll 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.