Automated TLS With Let's Encrypt

Let's Encrypt
I've been excited ever since first hearing the news that Internet Society, Mozilla, EFF and others had gotten together to create an easy, free, open system for issuing TLS (aka SSL) certificates. Today the service is finally open for public beta and of course I switched all my domains immediately. Here's how I did it.


First, grab the client from Github. If packages are available for your platform, you could use that instead I suppose.

Run the script named "letsencrypt-auto" to complete setup. On my box it verified a bunch of system packages, such as python, and set up some kind of virtual environment. This command must be run as root.

How it works

Here's how the process works. You run the letsencrypt client and tell it which domains you want to create certificates for. The client talks to the API server out in The Cloud&tm; which turns around and connects back to the web server for the domain you specified. That's how it verifies you are who you say you are. If everything checks out, the client creates a certificate request, the server signs it and sends it back. Certificates are stored in /etc/letsencrypt.

One important point to keep in mind is that the Let's Encrypt server will only connect back to you on ports 80 and 443. This can be a problem if for example you're already running a webserver. There are some ways around this though; see below.

Manual operation

I didn't have any luck with the plugin which automatically updates your Apache config with TLS settings, so I went with the "certonly" option instead. For your first manual run, I recommend shutting down your web server and letting the client bind to ports 80 and 443.

# ./letsencrypt-auto certonly

The client will use an ncurses interface to walk you through the process. You have to agree to the terms and conditions. Then enter your domain name and contact email address, in case you need key recovery (or skip it if you like living on the edge). Wait a minute or two and you'll get a message like this:

- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/ Your cert will
expire on 2016-03-02. To obtain a new version of the certificate in
the future, simply run Let's Encrypt again.

To complete the process, simply update your web server configs to point to the PEM files in /etc/letsencrypt/live/

SSLCertificateFile /etc/letsencrypt/live/
SSLCertificateKeyFile /etc/letsencrypt/live/
SSLCACertificateFile /etc/letsencrypt/live/

Automating the process

The client accepts a number of command line parameters to simplify the process. You can view all of them with the "--help all" option. Here's an example of requesting a new certificate.

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

If you want to put that in a config file, the client supports that as well. Create a file something like this:

authenticator = webroot
webroot-path = /var/www/html
domains =,

And then point the client to your config:

# ./letsencrypt-auto --config /etc/letsencrypt/

From there, it's pretty simple to throw it in a cron job and never worry about it again.

Known Issues

I found a few problems as I was setting this up.

Binding to port 80

The client wants to bind to port 80 and that's a hassle. The solution is to use your existing web server to handle the challenge response to the API server. This is done with the "webroot" authenticator.

#./letsencrypt-auto certonly -d --webroot --webroot-path /var/www/html

The client will create a directory named ".well-known/acme-challenge" in that path and create a file with a unique name inside of it. Piece of cake.

Apache .htaccess files

Drupal's default .htaccess file breaks the webroot authenticator. Your results may vary with other access files. As mentioned


1 Comment


Added SSLCACetificateFile to the Apache config. Without it, Android certificate validation was failing.

Subscribe to Comments for "Automated TLS With Let's Encrypt" Subscribe to - All comments