Killring

Rick Dillon's Weblog

How to use Let's Encrypt with Dreamhost

Background

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.

Acme Tiny is 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 acme_tiny’s small 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 private keys.

Overview

There are five steps to the process:

  1. Install acme_tiny
  2. Generate account key, private key, and certificate signing request
  3. Create location to host challenge files
  4. Obtain signed certificate
  5. 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.

Install acme_tiny

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 Encrypt uses. acme_tiny will take care of generating the right file for you, but you need to tell it where to put the file.

The official 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 the same.

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 official 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:

  1. Private key
  2. Certificate signing request
  3. Signed certificate
  4. Intermediate certificate

Your configuration can work without the intermediate certificate, but it means the certificate chain will be incomplete. You can simply cut and paste domain.key, domain.csr and signed.crt into the first three fields. Then, go obtain the intermediate certificate from Let’s Encrypt’s site, 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.

Good enough!