Using certbot to add Let's Encrypt certificate on Heroku
July 26, 2020
Ever since Google announced in 2017 that they would be prioritizing sites with HTTPS for SEO, I knew I had to make sure this blog had the necessary setup. I initially procrastinated a bit because I thought I was going to have to do some research to find the latest and greatest in terms of trusted certificate authorities. Once I decided to put this in place my research wasn’t long at all.
Enter Let’s Encrypt, a
free, automated, and open certificate authority… provided by the ISRG.
Well that gives me peace of mind. Further investigation then pointed me to
free, open source software tool for automatically using Let’s Encrypt certificates on manually-administrated websites to enable HTTPS.
Nice 😌, that’s perfect.
Let’s get started. Assuming you have Homebrew installed, then:
brew install certbot
Generate the certificate for your website, fill in everything it asks you (I had to use sudo in front of this command even though it seems to Just Work™ for other people in the interwebz; not sure why but hey, it works 🤷🏻♂️):
sudo certbot certonly --manual -d <www.your-domain.com>
Note that I put the fully qualified domain name above. This does not issue wildcard certificates.
Now, it’ll ask you to create a new file to verify you actually own the domain. Something like this:
Create a file containing just this data: <some-characters>.<more-characters> And make it available on your web server at this URL: http://<www.your-domain.com>/.well-known/acme-challenge/<some-characters> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Press Enter to Continue
In another terminal tab, create the file and commit it:
echo "<some-characters>.<more-characters>" > source/.well-known/acme-challenge/<some-characters> git add -A source/.well-known git commit -m 'Add SSL certificate'
Make it available in your app:
git remote add heroku email@example.com:<your-app-name>.git git push heroku master
Back in the
certbotprompt, press Enter. You should see something like this:
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/<www.your-domain.com>/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/<www.your-domain.com>/privkey.pem Your cert will expire on <YYYY-MM-DD>. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
On to the Heroku part of the puzzle. Make sure you have the heroku CLI installed:
brew tap heroku/brew brew install heroku # Or if you already have it, might as well upgrade it: brew upgrade heroku/brew/heroku
List your certificates (you should have nothing here the first time):
heroku certs:info -a <your-app-name>
Add your new certificate:
sudo heroku certs:add /etc/letsencrypt/live/<www.your-domain.com>/fullchain.pem /etc/letsencrypt/live/<www.your-domain.com>/privkey.pem -a <your-app-name>
You’re good to go! You are now a certified ~~hacker~~ domain owner 🔒
Renewing your certificate
Something interesting happened to me here, probably because I manually generated the certificate via
certbot renew didn’t work. Thankfully, I found an easy solution - just run through steps 2–7 from before and then:
List your certificates (you should have something expiring soon here):
heroku certs:info -a <your-app-name> # Fetching SSL certificate <certificate-name> info for ⬢ <your-app-name>... done # Certificate details: # Common Name(s): <www.your-domain.com> # Expires At: 2020-07-31 04:40 UTC # Issuer: /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 # Starts At: 2020-05-02 04:40 UTC # Subject: /CN=<www.your-domain.com> # SSL certificate is verified by a root authority.
Update your certificate (yep - it’ll be on the same path as the previous one but I swear it will be the new one!):
sudo heroku certs:update /etc/letsencrypt/live/<www.your-domain.com>/fullchain.pem /etc/letsencrypt/live/<www.your-domain.com>/privkey.pem -a <your-app-name> # Resolving trust chain... done # ▸ Potentially Destructive Action # ▸ This command will change the certificate of endpoint diplodocus-55595 from ⬢ <your-app-name>. # ▸ To proceed, type <your-app-name> or re-run this command with --confirm <your-app-name> # > (type in your-app-name) # Updating SSL certificate diplodocus-55595 for ⬢ <your-app-name>... done # Updated certificate details: # Common Name(s): <www.your-domain.com> # Expires At: 2020-10-24 19:51 UTC # Issuer: /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 # Starts At: 2020-07-26 19:51 UTC # Subject: /CN=<www.your-domain.com> # SSL certificate is verified by a root authority.
Done! You are, once again, certified 🏅