Snippet 0x0D: Let's Encrypt - 5 min guide to set up cronjob based certificate renewal
Contents
Let’s Encrypt was officially released to the open public today. That means the Internet can finally get free, trusted SSL/TLS certificates. This quick guide shows how to set up Let’s Encrypt with auto-renewal through a cronjob – using the simp_le client, an alternative client developed by one of the same authors who develop the official client.
Updates
Feb 2016: The new version of simp_le requires a -f account_key.json argument. I’ve updated the post accordingly.
Feb 2017: Unfortunately, the original simp_le project has been abandoned by the original author. This fork still works fine though. I have changed all the links, and it should just work.
1. Install the simp_le client
On your web server, clone the simp_le client and install it in a sensible directory (e.g. /opt/simp_le). Then run the installation steps as provided in the README.md:
Install client and symlink it
# Clone
$ cd /opt
$ git clone https://github.com/zenhack/simp_le/
$ cd simp_le
# Install
$ ./bootstrap.sh
$ ./venv.sh
$ ln -s $(pwd)/venv/bin/simp_le /usr/local/sbin/simp_le
2. Generate a keypair and retrieve signed certificate
Once the installation is done, everything else is super easy. All you need is a location for your keys and certificates, as well as the publicly available document root for your website. I store my certificates and keys in /srv/cert, with a subfolder for each domain, e.g. /srv/cert/example.com, and my document root is at /srv/www/example.com/html.
Create certificate signed by Let’s Encrypt
$ cd /srv/cert/example.com
$ simp_le \
-d example.com:/srv/www/example.com/html \
-f key.pem -f cert.pem -f fullchain.pem -f account_key.json
2015-12-04 01:31:52,131:INFO:simp_le:157: Creating new account key
2015-12-04 01:31:56,529:INFO:requests.packages.urllib3.connectionpool:756: Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
...
2015-12-04 01:31:58,568:INFO:requests.packages.urllib3.connectionpool:207: Starting new HTTP connection (1): example.com
2015-12-04 01:31:58,588:INFO:simp_le:803: example.com was successfully verified by the client
...
2015-12-04 01:32:04,570:INFO:simp_le:409: Saving key.pem
2015-12-04 01:32:04,570:INFO:simp_le:370: Saving fullchain.pem
This command automatically generates a keypair, creates a certificate request and gets that signed by Let’s Encrypt. It also verifies your domain ownership by creating a file in the document root at http://example.com/.well-known/.... So let’s look at the key and certificate:
Certificate and private key file
$ ls
account_key.json cert.pem fullchain.pem key.pem
3. Configure your web server
Now configure the SSL/TLS certificate in your web server. For me, that’s Apache. The configuration for the virtual host looks like this:
Configuring the Apache virtual host
$ cat /etc/apache2/sites-enabled/example.com
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /srv/cert/example.com/cert.pem
SSLCertificateKeyFile /srv/cert/example.com/key.pem
SSLCertificateChainFile /srv/cert/example.com/fullchain.pem
DocumentRoot "/silv/www/example.com/html"
ServerName example.com
// ...
</VirtualHost>
And finally, restart Apache with service apache2 restart and you can access your website via HTTPS! Easy, right?
4. Automating certificate renewal via cronjob
The wonderful thing about the simp_le client is that the command for the initial creation and the renewal is the same, so you can run the exact same command as above in a script from a cronjob. I created a script called /srv/bin/cert-renew to do just that:
Script to check/renew the certificates every night
$ cat /srv/bin/cert-renew
#!/bin/bash
cd /srv/cert/example.com
simp_le -d example.com:/srv/www/example.com/html -f key.pem -f cert.pem -f fullchain.pem -f account_key.json \
&& service apache2 reload
cd /srv/cert/example.xyz
simp_le -d example.xyz:/srv/www/example.xyz/html -f key.pem -f cert.pem -f fullchain.pem -f account_key.json \
&& service apache2 reload
This will renew the certificates for two domains (if necessary) and reload Apache if the certificate has been renewed. Note that Apache will not be reloaded if the certificate has not been altered.
The matching cronjob looks like this:
Cronjob to run renewal script every night
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
43 1 * * * /srv/bin/cert-renew || true
That’s it! Now every night at 1:43am, your certificates are checked and renewed if necessary.
A. About this post
I’m trying a new section for my blog. I call it Code Snippets. It’ll be very short, code-focused posts of things I recently discovered or find fascinating or helpful. I hope this helps.