Auto-renew letsencrypt certificates

Let's Encrypt is a great project
that aims to increase security in the web by making it easy and cheap
(free, in fact) to obtain SSL certificates.
Part of their aim is to make sure web servers are configured correctly.

This article describes how to use
acme_tiny.py,
a small Python script that implements the ACME protocol to get a certificate for your domains.
Please see the acme_tiny.py documentation on how to set it up and
how to get the authentication key for the Let's Encrypt server.

Creating a key and a Certificate Signing Request

One cool thing about Let's Encrypt is that they allow more than one domain
per certificate. You can add any number of domains in the
SAN section.
For this you need to enumerate all domains in the subjectAltName value in the
[SAN] section of the openssl configuration file, e.g. this:

The following command creates a secret key and a
CSR.
You'll need to change the values in the -subj option to your location and your details.
Use the primary domain as the CN.
If the -subj option is not used then openssl will query those
values interactively.

Submitting the CSR to the Let's Encrypt CA

The acme_tiny.py command needs the Let's Encrypt account key,
the CSR and a webroot directory (acme-dir to submit the
request).
The webroot directory is the path on your file system to the
top-level directory of your website, plus the directory .well-known/acme-challenge,
in other words, the path that maps to the URL
http://example.com/.well-known/acme-challenge on your server.

For each domain in the SAN list
the acme_tiny.py script will store a file in the
webroot directory to prove that you control that domain.

Note that each domain you submit must be accessible both from the internet and from the
computer where the acme_tiny.py script is run.

Automating it all

The following script automates the process described above.
To use the script, change the variables country, state,
town and email and call it with a list of domains you
want to include in the certificate, separated by space.