Bouke van der Bijl

Getting TLS certs locally because why not

Jan 2021

I have the domain bouke.dev that I use for serving local content—for example, to run Jekyll on my machine. I have set up the DNS to point *.bouke.dev and bouke.dev to 127.0.0.1. Because I was bored I decided to serve it over TLS as well, here’s how to do that:

  1. Install Lego: go get -u github.com/go-acme/lego/v4/cmd/lego
  2. Figure out how to configure it for your DNS Provider by reading the docs
  3. Run lego from your home directory, e.g. lego --accept-tos -d '*.bouke.dev' -d 'bouke.dev' -m <email> --dns namecheap run

You should now have valid certificates under ~/.lego/certificates. For example, I have one called ~/.lego/certificates/_.bouke.dev.crt.

Renewal

You should consider certificates unreliable, unless you have a renewal process in place! So, I created the following file in ~/bin/update-cert:

#!/usr/bin/env bash
cd $HOME
export NAMECHEAP_API_KEY=...
export NAMECHEAP_API_USER=...
exec lego --accept-tos -d '*.bouke.dev' -d 'bouke.dev' -m <email> --dns namecheap renew

Don’t forget to make it executable with chmod +x ~/bin/update-cert. Then just add it to your crontab by running crontab -e and adding:

@daily $HOME/bin/update-certs

Now lego will run daily, and keep your certificate nice and fresh. Cool!

Sharing is caring

This process can also be used for certificates that need to be shared with other people. You can set-up a monthly scheduled job with GitHub Actions or Google Cloud Scheduler that runs something like this:

lego --accept-tos --domains=example.dev --email=certs@example.com --dns=gcloud --pem --path=lego run
gcloud secrets versions add projects/xxx/secrets/star-company-dev-cert --data-file=lego/certificates/_.company.dev.pem

And now you can have a certificate that can be used by anyone who has access to the secret. Or if you don’t care that much you could even commit it directly to the repository automatically, since it’s just for local development anyways.