What is this?
This is a bit of process that I use to get TLS keys to use on AppEngine using Let’s Encrypt.
Why’s it matter?
There are a number of quirks in Let’s Encrypt and TLS on AppEngine that make it more difficult to automate the process. This helps ease the problem, as best we can at the moment.
Let’s get started!
First of all, the limitations. In the usual course one would run Let’s Encrypt on the web-server where the certificate will be used. This is not (yet) an option for AppEngine.
The relevant Google Code issue for AppEngine is #12535.
In the mean time, we can use the
process for validating a server.
produces a response to a challenge
that Let’s Encrypt will perform of the web-server to verify that we, the
ones requesting a signed TLS certificate, indeed own the server.
letsencrypt certonly --manual ...
command above will print something like:
Make sure your web server displays the following content at http://www.example.com/.well-known/acme-challenge/KmgmF6qZl6XCHmQMRyb4Uge-lP1-jvFF-C4LhKfxmXk before continuing:
Press ENTER to continue
So the challenge we have to meet to get our signed certificate is to serve the above file and content on our Google App Engine.
Serving the Challenge-Response
To separate out the ACME part of our service from the rest, one can use App Engine’s modules.
By using modules we speed up the deploy process, circumvent any continuous integration, and minimize any exposure across the system.
To set up a module, one needs a
, something like this:
Then one needs a
, something like this:
The directory setup looks like this:
1 2 3 4
dispatch.yaml acme/ acme/module.yaml acme/challenges/
To set up the module and dispatch one must run, once,
1 appcfg.py update module.yaml -A appengine-example-project
1 appcfg.py update_dispatch dispatch.yaml -A appengine-example-project
Getting a new key
So to mostly-automate the process I have created a couple
seen in the next code snippet.
On reflection, I realized I am taking for granted familiarity with Gulp. In
running you’ll need node, a
, but that’s beyond the scope of this article. Nonetheless I hope
the following proves interesting and sufficiently illustrative of the intended
task to be helpful if you are following a similar path.
After making the appropriate changes to the config (which in this task is exposed as a global), one can obtain a signed key by following these steps:
gulp acme:gen -t stage
- Wait for the challenge (i.e. the “
Press Enter to continue
- Run (in another shell)
gulp acme:cr -t stage
- Enter the file-name and challenge and wait for deployment
terminal; the certificate and private key ought to be printed to the terminal
- Copy the certificate and private key into the corresponding fields of a new key in App Engine’s Cloud Console.
I hope the above helps shed some light on what might be a somewhat daunting process.
Obviously it’ll be better when AppEngine and Let’s Encrypt talk directly. That requires some engineering on Google’s side, and while the issue #12535 has been accepted, there’s no indication of a timeline.
In the interim, the above is a not–too–onerous process for the 90 days renewal that ACME requires.