My ssl certificate expired the other day and I had to replace it.

The old certificate and provider

It was with startcom … I have no complaints about startcom but one person for whom I host email could not install custom certificates on his iphone, so I had to pick an ssl provider that is supported by his phone.

The new certificate provider: letsencrypt

So we went with letsencrypt.org, as it is the current major provider of free ssl certificates. It is backed (founded, really) by the Electronic Frontier Foundation (EFF) — a big plus in letsencrypt’s favour.

First impressions researching letsencrypt

My first impression with letsencrypt was that I would have to install an installer, which I would then run as root and it would install something else and that is what would create, download and install the certificates and keep them up to date.

I could not find this software in my OS distribution. I try to keep the amount of non-officially packaged software I install on my system to a minimum, so I always look for packages of stuff I want to install among the distro packages. With Devuan, (and formerly Debian), that is not usually a problem as they package an enormous number of programs and libraries and other stuff. But, there were no officially packaged clients among the ones I looked at, namely

  • certbot
  • getssl
  • letsencryptshell

but I’m getting ahead of myself here.

When I cannot get a distro package, and if it is a python library, then I look in the cheese shop (“python package index” — the python equivalent of CPAN (Comprehensive Perl Archive Network) for perl or CTAN (Comprehensive TeX Archive Network) for TeX) — no luck there either, sadly.

One thing I wasn’t too sure of from reading the certbot documentation was what URL the verificator was going to try to visit. They documented what they thought would be the path to your web site on your server, because they planned to edit that themselves. But, not so helpful if your web site is dynamic. Again, getting ahead of the story … but wanted to include a mention of this in this section.

I didn’t want a fully automated solution … I did not immediately see that the letsencrypt certificates could be installed “manually” because the paragraph that says that was buried in the “without shell access” part of the “let’s get started” page, and it was also separated from the list of alternate ACME clients (which was in the “with shell access” section).

Looking for an appropriate solution

It seems that the EFF wanted to make the SSL certificate thing a lot easier to use, and they created a multi-level set of solutions:

  • ACME protocol
  • server and client software that implement the ACME protocol
  • a certificate authority service

The bottom level is the ACME protocol, which specifies in detail a series of steps to take for the certificate provider to check if the requestor really controls the resource for which the certificate is being issued. The letsencrypt organization (which is a consortium of quite a few organizations) actually hosts a Certificate Authority (CA) server which uses the ACME protocol and some server software to provide the CA service. They provide a client that uses the protocol and talks to the server — the client is called certbot. The client is what the people who want certificates would run to get a certificate.

Looking at certbot

I had a look at certbot, and it is a fair size. It is modular, but it wasn’t immediately apparent to me which parts I needed and which I did not. Neither was it super apparent what I would have to do to run it in “manual” mode — they are much more focused on the automated use. So, I looked at the list of alternative clients that letsencrypt provides, here. There is an impressive list of alternatives, usually several choices for each programming language — and there were choices for a lot of languages.

Looking at getssl

I next looked at getssl, an all-bash solution. It was a bit bigger than I had hoped for. If I’m going to run someone else’s program as root I’d like to look at it. If it is big, then it takes too long to look at it.

Looking at letsencryptshell

Finally I looked at a python solution, letsencryptshell:

I really like this solution and this is what I used. I stopped looking at solutions once I tried this one. This one did exactly what I wanted. It automated the creation of the keys/csr, and the sending of it to letsencrypt, and it let me change my web site and dns to answer the challenge. Then it provided me a command to start the challenge verification — once that succeeded, then I could give one more command to download the certificate. It showed me what it was doing every step of the way — mainly it was http requests and responses and it showed me the exact http requests and responses. So when things did not succeed, I could see exactly why and fix it quickly.

For instance, I was able to quickly determine that the page with the challenge response should not contain any html markup. I had assumed that their challenge-response parser would be able to pick out the random challenge-response string from the page — but no, even with minimal html markup it rejected it. But it was easy to see when I could see the requests and responses. I could see that the server was receiving the proper response, so that left the only thing that could be wrong was the markup. No guessing. Well, not much anyway, and my first guess was correct. That’s always nice.

Best of all, the documentation and example were minimal and showed me exactly what I needed to see, so that I knew what I had to do to my web site and dns server so that they would pass the challenge. I was also able to get the certificate, so that I could install it into dovecot (which certbot didn’t seem to have a solution for — not that I wanted someone else’s program to run as root on my server and do things like install certificates in them and restart them). One thing I wasn’t too sure of from reading the certbot documentation was what URL the verificator was going to try to visit. They documented what they thought would be the path to your web site on your server, because they planned to edit that themselves. But, if your web site is dynamic … good luck figuring out what you have to do from their documentation. From the letsencryptshell documentation it was quite clear.

Thank you letsencrypt!

A nice thing about letsencrypt is that they provide a practice site, so if you want to practice before actually making a request, you can do it — and get the bugs out of your request before you make a real request. This can be important if you have a lot of certificates, as the requests are rate-limited. So you don’t have to waste any of your real certificate requests on fixing up your process.

Letsencrypt has a nice balance between making you practice installing /updating your certificates often so you don’t forget, and giving you a certificate that lasts a while. Their certificates last three months. Actually, I suppose most people will forget since they will use the automated version … I will try to do it manually for a little while and see how it goes.

We should all thank the letsencrypt organization for providing this service. We all need to be doing most of our communications in encrypted form and they are putting the infrastructure out there so we can do that. So, thank you for the protocol, the CA service and all the kicks in the butt to get going!

Next steps

Now that my imap email is fixed up with a new certificate, I should probably update the certificates on my web sites, which I let lapse a while ago. I’ll get to that a bit later. I wanted to blog about this first! I know, my priorities are skewed. Too bad.

I should think about trying to package letsencryptshell up for PyPi (python package repository — aka the Cheese Shop) and/or Devuan. It seems it is a manageable package for doing that — a smallish python library. We’ll see if I can do that or if someone beats me to it.

Last note — when I’m ready to automate this thing on my server completely, I will probably evaluate both letsencryptshell and certbot. Certbot does look interesting and probably does what I want — I just could not figure it out right away.