Setting up a Lets Encrypt Certificate on Heroku

By Josh Wright on September 2016 in tips

 

Update (April 2017)

Heroku now has first-class support for Let's Encrypt so installing it is as easy as clicking "Configure SSL" and following their instructions.

I'll leave the original blog post in case it helps people on other hosts:

Original Post

This guide will walk you through creating a free "Lets Encrypt" SSL certificate and getting it installed on your NodeJS Heroku website.

The instructions are basically the same for rails, php, java, etc so if youre on a different platform then these instructions will still be useful.

In this guide, well use the domain www.5favorites.net as an example.

References:

Step 1) Preparing Your Website

Make sure your website is setup and ready for SSL: - Website is up and running (e.g. on https://five-favorites.herokuapp.com) - Custom domain is setup (e.g. http://www.5favorites.net) - Im also assuming youre on a Mac with Homebrew installed

Step 2) Install certbot

Open your Terminal app and run:

brew install certbot

Step 3) Generate Your Certificate

Lets Encrypt prefers that you run their installer on your server. Thats not possible with Heroku, so youll create it locally then install it.

Run this command in Terminal:

sudo certbot certonly --manual

Certbot will walk you through creating a certificate:

  • Email Address
  • Agree to Terms of Service
  • Domain (e.g. www.5favorites.net)

Step 4) Verify Your Site

Now Certbot wants to verify that you control your domain. Theyll ask you to post a string at a specific URL before you continue. For example, my instructions look like:

Make sure your web server displays the following content at
http://www.5favorites.net/.well-known/acme-challenge/sjkhfkjsdhfjkdshfkjhsdkfjhdskfhskdjhfkjsdhf before continuing:

KJLShjsfhjlsefhljaehFUSDFHULIOEUSLUHFDSLHFU.SDJ-KJDk-LKJSFJksjkfi-SDLFKJS:KFJDjkdjDFJSK

So if youre using express, you could setup a route like this:

app.get("/.well-known/acme-challenge/sjkhfkjsdhfjkdshfkjhsdkfjhdskfhskdjhfkjsdhf", function(req, res){ res.send("KJLShjsfhjlsefhljaehFUSDFHULIOEUSLUHFDSLHFU.SDJ-KJDk-LKJSFJksjkfi-SDLFKJS:KFJDjkdjDFJSK"); });

Deploy this to your server, then press [ENTER] to continue setting up your certificate (in terminal).

Now you should see a "Congratulations!" message.

Step 5) Install the Certificate

After the "Congratulations!" message, certbot should show you where you certificate was saved. For example, mine says:

Your certificate and chain have been saved at
/etc/letsencrypt/live/www.5favorites.net/fullchain.pem. Your cert
will expire on 2016-12-26.

Now we need to turn on the SSL plugin on Heroku. Within your Heroku app directory, run:

heroku addons:create ssl:endpoint

Then upload your new certificate:

NOTE: The first path in this command is for your fullchain.pem. The second path is to your privkey.pem which should be in the same directory, just a different filename.

sudo heroku certs:add --type sni /etc/letsencrypt/live/www.5favorites.net/fullchain.pem /etc/letsencrypt/live/www.5favorites.net/privkey.pem

Step 6) Update Your DNS

Originally our custom domain was setup (http only) with a record that looked like:

CNAME www => five-favorites.herokuapp.com

Now that we have an SSL certificate, heroku has a different endpoint. That new endpoint is listed after you add your cerficiate so you need to change your CNAME to the new target. For example, mine is:

CNAME www => www.5favorites.net.herokudns.com

Step 7) Verify HTTPS

This may take a few hours to propagate. Once its done, you should be able to visit your site using SSL:

https://www.5favorites.net

Id also recommend that you use a free online service (like DigiCert) to verify whether your certificate is installed correctly and has the full chain of trust, etc.