Skip to content

Instantly share code, notes, and snippets.

@dyoo
Created July 16, 2017 22:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dyoo/5f45ee08de76cd9119c552dd4f54fc3f to your computer and use it in GitHub Desktop.
Save dyoo/5f45ee08de76cd9119c552dd4f54fc3f to your computer and use it in GitHub Desktop.
Set up HTTPS for Google App Engine using Let's Encrypt

Copied from https://www.jeffgodwyll.com/posts/2016/letsencrypt

Let’s Encrypt is a free, automated, and open certificate authority (CA), run for the public’s benefit. Let’s Encrypt is a service provided by the Internet Security Research Group (ISRG)

About Let's Encrypt

This post won't go into details as to what Let's Encrypt is about. We should probably read the FAQs if we want to learn more.

Until the Google App Engine Team fully automate the process of using Let's Encrypt on Google App Engine or even provide some sort of API to handle certs, we'll probably have to find ways of either automating the process just a little bit or stick to some other easier cert authority.

So to get started, we'll follow the instructions here to install the Let's Encrypt Client[1]. Note that the client is now referred to as certbot, but the letsencrypt command is still available.

The Let's Encrypt Client is a fully-featured, extensible client for the Let's Encrypt CA (or any other CA that speaks the ACME protocol) that can automate the tasks of obtaining certificates and configuring webservers to use them.

Next is to obtain a certificate using the manual plugin like so:

sudo ./letsencrypt-auto -a manual certonly

We'll be prompted for a couple of things, like the domain names we're generating the cert(s) for, and getting our IP logged.

Last but not least, we'll be presented with a challenge, the most crucial part, where we'll be presented with something like this at the let's encrypt console:

Make sure our web server displays the following content at
http://www.example.com/.well-known/acme-challenge/odebEMaSagM3xRblm_hmcPvnpCFdEsTBDrpaHyw6Q_I
before continuing:

odebEMaSagM3xRblm_hmcPvnpCFdEsTBDrpaHyw6Q_I.du6Wm_JOQBK08bH0MzKjuVzNbozezAthZBONRGcghDI
...
...
Press ENTER to continue

This is fairly straightforward. We can choose to serve the challenge text and content from a special directory within our app and ensure they match correspondingly.

For example in our GAE project directory, we could do the following:

mkdir -p well-known/acme-challenge/

echo "odebEMaSagM3xRblm_hmcPvnpCFdEsTBDrpaHyw6Q_I.du6Wm_JOQBK08bH0MzKjuVzNbozezAthZBONRGcghDI" > well-known/acme-challenge/odebEMaSagM3xRblm_hmcPvnpCFdEsTBDrpaHyw6Q_I

This means the challenges will be stored in a directory structure similar to:

.
├── app.yaml
├── main.py
└── well-known
    └── acme-challenge
            └── odebEMaSagM3xRblm_hmcPvnpCFdEsTBDrpaHyw6Q_I

If we happen to be using a different runtime, running a static site on GAE or we just love using yaml, we can as well handle this in our app.yaml:

handlers:
- url: /.well-known/acme-challenge/(.*)
  mime_type: text/plain
  static_files: well-known/acme-challenge/\1
  upload: well-known/acme-challenge/.*

Upload all changes to our live environment and test that we can reach the endpoint:

gcloud app deploy

Head back to our Let's Encrypt console, hit enter to verify the challenge and get the certs generated.

If successful, the certificates will then reside in /etc/letsencrypt/live/<path_to_site>

We'll then convert our privkey.pem into an RSA private key for use in the Google Cloud Developers Console:

opennssl rsa -in privkey.pem -out rsa.pem

Then copy/paste fullchain.pem into the Public Key section of the Google Cloud Developers Console SSL Certificates Section, and rsa.pem into the Private Key section.

Google Cloud Dev Console

Enable https and voilà!

Okay, not exactly done because if you took note from the very beginning I said that's there's a catch :D. You'll have to remember to repeat parts of this every 3 months to ensure you continue to enjoy this.

[1] The best way is probably to donwload a release tarball from the repo and run letsencrypt-auto. This will create and populate a Python virtualenv with the necessary reqs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment