Automated generation of Letsencrypt certificates on heroku

Earlier today, Heroku announced SSL Beta, a way to provide SSL on your heroku-hosted app for a much lower cost than it used to be. This is an awesome feature, entirely in line with all the changes SSL for over the past year.

With the rise of free SSL certificates, every website can now properly secure it’s requests, and the fact that you can do that on Heroku too is truly amazing.

Off to the praises and back to nerding now. Letsencrypt certificates expire every 3 months, which means we don’t want to renew them manually (and automation is a good thing anyway).

During the Heroku SSL private beta, I’ve been looking into automating the generation of a letsencrypt certificate and assigning it to an heroku app. This isn’t a big challenge per-se, though it needed a bit of gymnastic in order to do the letsencrypt validation.

Without any further ado, I now present you sabayon (an OSS project with a pastry as a name. So French right?).
Sabayon is a small Go app that you can use under the Heroku free tier in parallel of your current app which needs SSL.

With the help of the Heroku Scheduler add-on, it will fetch the expiration date of your certificate once every day, and renew it 1 month before expiration.

How does it work?

When you or the scheduler executes the sabayon command, it will do the following:

  • Request a certificate with letsencrypt for all the domains configured in the sabayon app.
  • Set config vars on your app with the key/token pair letsencrypt gives us for each domain.

This is where you need to do a bit of work.
Your main app needs to be able to serve the letsencrypt challenge based on those key/token pair.

The sabayon README provides a couple examples. Update your app’s code so that it is able to serve all requests on path /.well-known/acme-challenge/$ACME_TOKEN with $ACME_KEY as the content.

If you need multiple domains for that certificate, sabayon will set the key/pair tokens as $ACKE_TOKEN_X and $ACME_KEY_X, where X is an iterator. You then need to match the right key with the right token.
All the examples in the sabayon README handle that case.

Once you’ve done this, we can go back to the automated process.

  • Sabayon will let letsencrypt know it can perform the validation.
  • If the validation does pass, it will receive a certificate and private key.
  • Sabayon will use Heroku’s Platform API to configure that certificate and private key.
Sabayon will never store your certificate and private anywhere but on the Heroku Platform.
Whenever renewing your certificate, a new private key will be generated as well.

You then only have to configure your app’s DNS to the endpoint specified by the heroku ssl command. For more information (and to see how to enable the new SSL on your app), you can see the Heroku SSL Beta documentation.

In order to finish automating your certificates renewal, you need to Setup and configure the scheduler add-on.

Pour finir

I won’t say again how awesome SSL has become in the past year. I think you get the point by now.

Sabayon has been tested on a few herokai personnal apps such as Codetriage. It is definitely open to contributions though. And you can report issues using as GitHub issues.