Skip to content

Latest commit

 

History

History
412 lines (264 loc) · 14.9 KB

SSL-certificate-step-by-step-setup-instructions.md

File metadata and controls

412 lines (264 loc) · 14.9 KB

letsencrypt-760x320

Step-by-Step Setup Instructions for Let's Encrypt Free SSL

Note: These instructions are only applicable to web apps with a custom domain name.

Why?

You have a custom domain for your Heroku app and now you want an SSL Certificate to Secure/Encrypt all communications between users and your app.

What?

Let's Encrypt offers a Free Automated SSL Certificate Service brought to you by the non-profit Internet Security Research Group (ISRG). see: https://letsencrypt.org/about/

### Instructions Valid for Apps Written in Any Language/Framework!

The instructions in this tutorial/guide are applicable to an app written in any language or framework. You will temporarily deploy a Node.js http-server to your Heroku app which will allow Let's Encrypt to verify that you "own" the app/domain.

Note: No Node.js knowledge is assumed or required. You won't be writing a single line of JS code.

Once you have set up SSL you can deploy what ever kind of app you like. (in our case the app is written in Elixir/Phoenix! ... node.js is just an easy way to get this working in a generic way.)

How?

"certbot" is the script that automates the certificate creation process.

Step 1: Clone this Repository to get the Setup Code

git clone https://github.com/dwyl/learn-heroku.git
cd learn-heroku

Step 2: Set Git Remote

Check what your current origin remote is:

git remote -v

git-remote

Set it to what ever the git url is for the app you are setting up SSL for. e.g:

git remote set-url origin [email protected]:healthlocker/healthlocker.git

Push your current branch to the GitHub repo:

git push --set-upstream origin letsencrypt-temporary-server

Step 3: Temporarily Change the Branch Heroku Deploys from

ssl1

Change it to the name of your branch e.g:

ssl2

It should look something like this:

ssl-deploy-from-diff-branch-disable-ci-check remember to (temporarily) dissable the checkbox Wait for CI to pass before deploy
(we have no tests for this temporary server!).

Step 4: Install certbot

certbot installation instructions for various platforms: https://letsencrypt.org/getting-started

brew install certbot

bew-install-certbot

(it might take a few minutes to install on a slower internet connection... be patient...)

Step 4: Run certbot Command (Manual Setup)

Once you've installed certbot run the following command:

sudo certbot certonly --manual

Remember to use both the domain a www subdomain. (separated by a space) e.g:

example.com www.example.com

Our app was:

healthlocker.uk www.healthlocker.uk

Follow the steps and pay close attention!

When you reach the screen that looks like this:

certbot-instructions

DON'T continue until you have completed Step 5.

Instructions printed by certbot: (for reference ONLY see below for sub-set of instructions)

mkdir -p /tmp/certbot/public_html/.well-known/acme-challenge
cd /tmp/certbot/public_html
printf "%s" WgFpodyij_PDzkU0MZ3CzKCI05hjLOcq2tP-1rs6ko0.kURQ5HbILtRXEwJA2QI4W5TdBkjnZNqH2_RHORvmN6w > .well-known/acme-challenge/WgFpodyij_PDzkU0MZ3CzKCI05hjLOcq2tP-1rs6ko0

# run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()"

You wont be able to run shell commands on a Heroku instance so we need to use a temporary node.js server to achieve our objective.

In your current working directory (on your localhost) run the following command to create the .well-known/acme-challenge directory:

Step 4.1 Create the .well-known/acme-challenge Directory (if it doesn't exist)

mkdir -p .well-known/acme-challenge

Step 4.2 Create a File for the Token Verification

Now copy-paste the printf command from the certbot instructions: they should look something like this:

printf "%s" WgFpodyij_PDzkU0MZ3CzKCI05hjLOcq2tP-1rs6ko0.kURQ5HbILtRXEwJA2QI4W5TdBkjnZNqH2_RHORvmN6w > .well-known/acme-challenge/WgFpodyij_PDzkU0MZ3CzKCI05hjLOcq2tP-1rs6ko0

The tokens will be specific to you so make sure you get the correct tokens. (there is one token per domain)

Step 4.3: Commit Your Changes (the token file) and Push to GitHub

Make a commit on your local branch so you can push to github (and trigger the heroku build)

git add .
git commit -m 'add letsencrypt verification file'
git push

That will deploy the file you created in Step 4.2 to Heroku.

Step 5: Visit the Endpoint in your Browser to Confirm it Worked:

Visit your app in a web browser to confirm the deploy worked. e.g: http://example.com/.well-known/acme-challenge

The url for our app was: http://healthlocker.uk/.well-known/acme-challenge

click-on-filename-to-test

It should download a text file to your computer when you visit the endpoint in the browser.

Step 6: Continue with the Certbot process

Hit the enter key in the terminal window to continue the certbot process:

certificate-success

If if it worked, you should see something like that output in your terminal. If not scroll down to Trouble-Shooting section below

Step 7: Conclude the process on Heroku

You're amost there, this is the easy part!

Step 7.1: GOTO Heroku "Settings" Tab and Click "Configure SSL"

Navigate to the settings section of your app on Heroku Dashboard e.g:

navigate-to-the-settings-on-heroku

Scroll down to the "Domains and certificates" section and click on "Configure SSL" button:

scroll-down-to-domains-and-certificates-section

Step 7.2: Click the link to Paste the File Contntes

Click on the link to paste the certificate:
click-to-paste-the-contens

Step 7.3: Copy the Pulbic Certificate from your Machine

Recall from above that the certificate generated by certbot was saved to /etc/letsencrypt/live/healthlocker.uk/ (your domain will be different)

You can copy the contents of the file (without "leaking" it) by running the following command in your terminal:

sudo cat /etc/letsencrypt/live/healthlocker.uk/fullchain.pem | pbcopy

Note: sudo is required because the certbot runs as admin
for explanation of the pbcopy command see:
http://superuser.com/questions/113529/how-can-i-load-a-files-contents-into-the-clipboard

Step 7.4: Paste the Pulbic Certificate

Paste the Public Key (cert.pem you copied above) into the <textarea> on Heroku:

paste-contens-of-cert pem-in-browser

Click on the "Continue" button.

Step 7.5: Copy-Paste the Private Certificate

Repeat steps 7.2 to 7.4 for the Private Certificate:

sudo cat /etc/letsencrypt/live/healthlocker.uk/privkey.pem | pbcopy

paste-contents-of-private-key

Step 7.6 Complete the "Configure SLL" Process

You should have already previously set up the DNS settings (else step 5 would not have worked!)

update-dns-settings

Make sure you delete the Heroku SSL Addon (if you had it enabled...)

delete-heroku-SSL-addon

Step 7.7 Confirm the Certificate was Added

Confirm that the certificate was successfully added to the app on Heroku:

confirm-certificate-accepted-by-heroku

Step 7.8 Visit your Custom Domain in your Browser over HTTPS

e.g: https://www.healthlocker.uk

boom-ssl-enabled

Step 8: Clean up (Restore the Default Deployment Branch and Build Pack)

Restore the default branch for deployment on Heroku:

heroku-deploy-from-master-branch

Certificate Renewal

Following the instructions in this guide: https://certbot.eff.org/docs/using.html#renewing-certificates

1. Temporarily Disable Any "Buildpacks"

Visit the Settings tab for your App in Heroku.
Scroll down to the Buildpacks section.
Make a note of any buildpacks you In the case of our Elixir/Phoenix app these were:

image

We copy-paste these into some sort of notepad (so that we can restore them later)

2. Repeat Steps 1 - 7 Above to Renew the Certificate.

Here's a quick summary of the steps:

  1. Re-run the certbot CLI tool.
  2. Copy-paste the printf command (step 4.2 above)
  3. git add . && git commit -m 'adds letsencrypt verification token'
  4. git push the letsencrypt-temporary-server branch of learn-heroku (to your project's github repo)
  5. Push the

3. Copy the Cert into Clipboard

sudo cat /etc/letsencrypt/keys/0002_key-certbot.pem | pbcopy

sudo cat /etc/letsencrypt/live/healthlocker.uk/fullchain.pem | pbcopy





Trouble-Shooting (if it doesn't work!)

The first time I tried to run the certbot command, nothing worked! E.g: the Build failed on Heroku, the cert process failed (see below). This is a catalog of the Trouble-Shooting we did.

As always, if you get stuck, ask a question we will try our best to help!

heroku-activity-log-fail

because we are using an Elixir "Build Pack" for the app (so deploying a node app won't work!):

elixir-build-pack

So I made a note of the buildpack urls:

heroku-no-buildpack

After I delete the build pack and push another commit, it passes:

build success

Failed to continue with certbot process ...

When I attempted to continue it failed:

certbot failed

Output

Waiting for verification...
An unexpected error occurred:
ConnectionError: ('Connection aborted.', error("(60, 'ETIMEDOUT')",))
Please see the logfiles in /var/log/letsencrypt for more details.

IMPORTANT NOTES:
 - If you lose your account credentials, you can recover through
   e-mails sent to [email protected].
 - Your account credentials have been saved in your Certbot
   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 Certbot so
   making regular backups of this folder is ideal.

I deleted all the files created in the process and started from scratch ...

Failed again:
fail again

Re-trace your steps and make sure you followed the instructions exactly. Also, timing matters. if you take a break between steps you will get a "Time Out Error"... We initially got it wrong, but after re-running the command it works as expected.

If you get a Certificate Warning in Step 7.8

If you visit your domain e.g: https://www.healthlocker.uk and takes ages to load and then displays a Certificate warning:

chrome-security-warning-details

If we inspect the details of the warning we see that the browser is getting an incorrect cert.

firefox-ssl-warning

I updated the DNS Settings to:

healthlocker-dns-settings

And then we got this error: heroku-cert-wrong-domain

So I re-ran certbot command for both domains healthlocker.uk www.healthlocker.uk: get-certificate-for-multiple-domains

After running certbot another time, it worked. 🚀

## Background Reading