Free SSL certificates without placing a file on your server using AWS Route53

Emil Ong
Haus Engineering Blog
3 min readMar 31, 2016

This article shows you how to get a free Let’s Encrypt certificate for your domain when it’s not convenient for you to place a file on your HTTP server for the challenge and you use Route53 as your DNS provider.

For the impatient

If you already know what all this means and/or you just want to get on with it, here you go:

Prerequisites

  1. You have Ruby installed.
  2. You have your AWS credentials set up in your environment (either using the AWS CLI’s aws configure command or in environment variables).
  3. You have a Route53 hosted zone in place for your domain.

Getting the certificate

  1. Download the letsencrypt.sh client.
  2. Download tache’s Route53 hook.rb.
  3. Run the following:
$ gem install aws-sdk pry awesome_print domainatrix
$ chmod +x <path-to>/hook.rb
$ <path-to>/letsencrypt.sh -c -d your-domain.example.com -t dns-01 -k <path-to>/hook.rb

4. Install the cert from certs/your-domain.example.com/cert.pem into your server, provider, whatever.

5. Automate the letsencrypt.sh call above and installation and run it every 90 days (probably a bit less).

What just happened?

Let’s Encrypt is an awesome project that signs TLS certificates for free. They’re helping make the web a safer place. :) However, most of their support is for http-01 challenges, which means making a file available for verification on your server, which is not always an easy thing to do.

Verification and challenges

Let’s Encrypt and other TLS certificate authorities will not just sign any certificate for anyone who asks otherwise, this defeats the point of TLS. :D They need you to prove you own the domain. You can do this a number of ways, but placing a file in a place that no one else is likely to guess the contents and/or URL of is one way. This is essentially the http-01 challenge approach. In most practical circumstances only the owner of the domain should be able to place such a file on demand.

If for some reason this is difficult to do, another possibility is to place a TXT DNS entry for the domain with a challenge value that’s unlikely to be guessed and generated on demand. This is the approach of the dns-01 challenge.

Let’s Encrypt Clients

Let’s Encrypt is primarily a service for signing certificates that pass one of the challenges above, but they also provide a client implementation for their service. The service itself, as of March 2016, does support dns-01 challenges, but their client does not as of yet. The 3rd-party letsencrypt.sh client does, so that’s why we’re using it here.

letsencrypt.sh supports both the http-01 and dns-01 challenges, but needs hooks in place to take the actions to perform the challenges. If you’re using Route53, you need a hook that creates the TXT entry when receiving the challenge, thus the hook.rb.

tache (who created an updated version of asimihsan’s hook to support subdomains) used Ruby to do this, thus the gem installs above.

Automation and renewal

Let’s Encrypt certificates are only valid for 90 days, so you’ll need to update them regularly, thus the final step above.

Conclusion

This procedure is obviously a bit hacky at the moment, but it Works For Me, so I hope it’s useful for anyone else in the same boat.

If you’re not using Route53, you might be able to do the same thing using on of the other hook implementations produced by the community.

Thanks to Let’s Encrypt, the contributors of letsencrypt.sh, tache, and asimihsan for making this possible!

If you’re interested in working with us, discussing issues like these and others, please check out our jobs page and get in touch!

--

--