Using Let’s Encrypt

Let’s Encrypt provides free SSL certificates for websites. I thought I’d try it out on my personal website,, which is a simple Flask app running on Google App Engine. It is officially “beta” software, so I ran into a few issues, but nothing I couldn’t work through.

First up, I downloaded the client per instructions from the Let’s Encrypt site:

git clone
cd letsencrypt
./letsencrypt-auto --help

I’m using a Mac and noticed my homebrew install was out of date, so I took a quick side track to bring that up to date. If you don’t have homebrew already installed, it will install it for you.

Next up, the command line to create the certificate manually.

./letsencrypt-auto certonly --manual --email -d -d

This will give you details you need to have your web server provide for verification.

Make sure your web server displays the following content at<challenge_token> before continuing:

If you had multiple domains (e.g. and it repeats this info for each before hitting the server to do the validation, so I just took a note of the token and response values for each of the domains. Before I hit “ENTER” for the last time to continue, I made the following updates to my Flask app.

def letsencrypt_check(challenge):
challenge_response = {
return Response(challenge_response[challenge], mimetype='text/plain')

There were also instructions on how to run a web server locally just for the verification if you don’t have the server configured yet, but since I had the website, I just updated my Flask app.

So now that the website was up with the proper challenge/response, I hit ENTER and {magic, magic, magic} out popped certs. They were stored in the /etc/letsencrypt/live/ folder. I copied the fullchain.pem and privkey.pem to my desktop (the /live folder had only root permissions, so made it easier to upload to Google App Engine).

Under my App Engine settings, I selected the “SSL Certificates” section and clicked the “Upload a new certificate” button. Which got me to this screen.

I gave the cert a nice name and clicked the “Choose File” for the PEM encoded X.509 public key certificate and selected the fullchain.pem file. I initially just tried uploading the privkey.pem file in the Unencrypted PEM encoded RSA private key area but (as the text suggests) the key needed to be an RSA private key — not the format that it was currently in. So next step was to convert the privkey.pem to an RSA format. I used OpenSSL to do this.

sudo openssl rsa -inform pem -in privkey1.pem -outform pem

I copied the output and pasted it into the RSA private key box and, boom, https support for my personal website.

Bonus Info!

I also tweaked my Flask app to redirect all http to https. Here’s the “fix” for that.

def before_request():
if request.url.startswith('http://'):
return redirect(request.url.replace('http://', 'https://'), code=301)
One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.