Free SSL for Rails and Nginx using Let's Encrypt

Add a free SSL certificate to your Rails app using Nginx and Let's Encrypt



Overview

Let's Encrypt is a wonderful new Certificate Authority that provides free, automated SSL Certificates. It's supported by some of the best companies in the world and promotes the idea that all websites should be protected by SSL.

They're doing that by offering free SSL certificates that you can use on any site. They're short lived so they last 3 months, and you setup a cron job in order to attempt to renew them periodically. Let's get started!

Install the Let's Encrypt client

First off, we're going to SSH into our server:

Next, we're going to grab a copy of the Let's Encrypt client from Github:

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

Then we need to run the script to install it:

./letsencrypt-auto

Creating a Let's Encrypt SSL Cert

We can create a cert using the following command. Note that you'll need to change a few things:

  • example.com should be replaced with your domain
  • [email protected] should be replaced with your email address on the domain
  • /home/deploy/myapp/current/public should be replaced with the path to your Rails app
sudo /home/deploy/.local/share/letsencrypt/bin/letsencrypt certonly --webroot --webroot-path /home/deploy/myapp/current/public --renew-by-default --email [email protected] --text --agree-tos -d example.com -d www.example.com

Another thing we need to do to get an A+ rating on our SSL security is to create our own Diffie-Hellman group. The reason for this is that it protects us from the Logjam Attack. It's pretty simple. We just need to use OpenSSL to generate a Diffie-Hellman group which we will later add to our Nginx SSL config.

cd ~
openssl dhparam -out dhparams.pem 2048

Configure Nginx

Now that we've registered our SSL cert and created our Diffie-Hellman group, we can modify your Nginx config to add SSL.

Add the following lines to your server block for your app and be sure to change example.com to your domain.

        listen 443 ssl;

        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_dhparam /home/deploy/dhparams.pem;

Once you've updated your Nginx config you can run the following command to reload Nginx.

sudo nginx -s reload

Now open up your site in your browser to verify that you can access it over SSL!

Setup Renewal Cron Job

Since Let's Encrypt is designed for short-lived SSL certificates, we need to setup the renewal script to run periodically to try to renew the SSL cert. We'll add this to the root user's cron job so that it can attempt to update the cert every Monday at 2:30am.

Run this command to open up the crontab:

sudo crontab -e

Add this line to the bottom which will denotes when to run and which script to run.

30 2 * * 1 /home/deploy/.local/share/letsencrypt/bin/letsencrypt renew

Save and close the file.

Conclusion

That's really it! Nothing more to it. It's incredibly easy and simple to setup an SSL cert using Let's Encrypt. You can find out more information at the Let's Encrypt website.