Today, Let’s Encrypt opened up a public beta test of their service that provides a highly automated mechanism for obtaining an SSL certificate. This is very exciting because it has the potential to usher in a new era of free, ubiquitous encrypted internet connections. Unfortunately, the default client requires things that may not be available on, for example, a shared host. That client needs to manipulate the server process, which requires root access, and also installs certificates directly on the machine. Most shared hosts make neither of these actions available. Let’s Encrypt adheres to the Automated Certificate Management Environment specification, though, so other, lighter weight, clients can be used.
a small (~200 SLOC) python script that performs all the necessary
functions to negotiate with the Let’s Encrypt CA to obtain a signed
certificate for your website. One of the virtues of
size is that you can read the code yourself and see what it is doing.
This is nice, since the script will have access to and be handling your
There are five steps to the process:
- Generate account key, private key, and certificate signing request
- Create location to host challenge files
- Obtain signed certificate
- Install the certificate
In these examples, I will use my domain,
killring.org as the example
domain. Of course, you would replace that with your own domain before
running these commands.
git clone https://github.com/diafygi/acme-tiny.git
Generate keys and CSR
openssl genrsa 4096 > account.key openssl genrsa 4096 > domain.key openssl req -new -sha256 -key domain.key -subj "/CN=killring.org" > domain.csr
Create location to host challenge files
How does Let’s Encrypt know that it’s giving you a certificate for a
domain you own? Some certificate authorities use DNS, but many have you
host a specific file at the domain. This is the approach that Let’s
acme_tiny will take care of generating the right file
for you, but you need to tell it where to put the file.
acme_tiny documentation suggests altering your web server
configuration to set up a route to host the files. If you have a
mechanism to host static files on your site, an even simpler solution is
to simply make the correct directory. This may not work for everyone,
but since https://killring.org is hosted as a static site, it’s by far
the simplest approach and worked great for me:
mkdir -p killring.org/.well-known/acme-challenge
This command works in my configuration because the equivalent of
/var/www on Dreamhost is a directory with the name of the domain it is
hosting. Your configuration might vary in the details, but the gist is
No matter the details, this directory is the location we’ll give the
script where it can place the challenge files. If you have a dynamic
site that can’t host files in that subdirectory of your domain, you’ll
either need to reconfigure your app or your server to route that URL to
a directory where you can tell the script to host the files. The
acme_tiny readme has more information about doing this for
nginx (the official client only works for Apache, so this is
particularly relevant for users running dynamic apps on nginx).
Obtain the signed certificate
This is the easy part! Here goes:
python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir killring.org/.well-known/acme-challenge/ > ./signed.crt
This command will reach out to Let’s Encrypt’s servers and supply the URL where the challenge files can be found along with the CSR. If everything matches up, the CA will respond with a signed certificate that we can install on our web host.
Install the certificate
Here’s another place where the scripts differ from what some shared hosts allow: the scripts expect you to be able to copy the signed certificate into the web server’s configuration directory. This works great on a dedicated EC2 or Google Compute Cloud instance, but not so well on a shared hosting plan on, for example, Dreamhost.
For Dreamhost, I opened up the web control panel and navigated into secure hosting options for my domain. I selected manual configuration, at which point there were four form fields I could provide:
- Private key
- Certificate signing request
- Signed certificate
- Intermediate certificate
Your configuration can work without the intermediate certificate, but it
means the certificate chain will be incomplete. You can simply cut and
signed.crt into the first three
fields. Then, go obtain the intermediate certificate from Let’s
paste it in to the final field, and submit the form. In my case, it took
about five minutes for everything to update, and Dreamhost took care of
installing them and restarting the server process so that they would be
served to clients correctly.
After lining it all up, SSL Labs report card gives the site an A.