Automatically renewing a lot of Let’s Encrypt certificates

I’ve been experimenting lately with Let’s Encrypt for SSL certificates, contemplating whether it can replace my StartSSL Class 2 wildcards.

For those unfamiliar with Let’s Encrypt, it’s a free certificate authority1 aimed at simplifying the process of making a site available via a secure connection. If you’re reading this on ethitter.com, your browser’s address bar will display a lock icon, the text https, or some other indicator that the connection is secure.

Secure URL

Until Let’s Encrypt launched its public beta in December 2015, acquiring a certificate involved many steps; at times, considerable cost; and terminology many find confusing. Let’s Encrypt intends to address these issues, and effectively does so in at least one way.

Of its many benefits, Let’s Encrypt affords the ability to automate the certificate renewal process via a configuration file, which is, understandably, helpful for a few reasons.

To start, I currently use wildcard certificates, such as *.ethitter.com. Rather than buy certificates for ethitter.com, www.ethitter.comi.ethitter.comcookedby.ethitter.comwhereis.ethitter.com, and so on, I have one certificate that covers all of those variations. Let’s Encrypt, however, doesn’t support wildcard certificates. As a result, if I do adopt Let’s Encrypt in place of StartSSL, I’ll need a way to list every domain I need to secure.

Perhaps more importantly, unlike other certificate providers, Let’s Encrypt‘s certificates are valid for three months. Comparatively, the current StartSSL certificate for ethitter.com is valid for two years (expiring January 2018; details). More-frequent renewals place particular emphasis on automating the process.

Configuration files

Let’s Encrypt creates /etc/letsencrypt to hold the certificates it generates, so that seemed a logical place to store the configuration files I’ll need; to the default directory, I added a configs folder.

In an effort to organize my certificates, I created separate files for different domain types, adding each file to /etc/letsencrypt/configs. The following is one example, which I could’ve named example.ini.

# All flags used by the client can be configured here.

# Use a 4096 bit RSA key instead of 2048
rsa-key-size = 4096

# Uncomment and update to register with the specified e-mail address
email = letsencrypt@example.com

# Uncomment and update to generate certificates for the specified
# domains.
domains = example.com, www.example.com

# Config for command-line re-verification without bothering my nginx setup
webroot = True
webroot-path = /var/www/

# Bypass prompts during CLI renewal
keep-until-expiring = True
agree-tos = True
redirect = True

https://git.ethitter.com/snippets/15

Review the Let’s Encrypt documentation to better understand the configuration options; the important value to highlight is domains–replace this with a list of domains to be included in a single certificate. While I’ve only listed two, each certificate can contain up to 100 domains.

Duplicate the above configuration file for as many certificate sets as you need. Again, I organize mine around the purpose of a group of domains (parked, redirecting, hosting random services, etc), rather than creating separate certificates for every domain.

Now, about automating renewals

Since the certificates are valid for just three months, automating their renewal eliminates any risk that I’ll forget to do so, an oversight that would block visitors’ access to any sites sharing an expired certificate (despite automation, monitoring is also important).

As I’m using several configuration files, I need a script to process each of those in succession; there’s no sense in manually calling each configuration file from its own cron. To this end, I created /etc/letsencrypt/eth-le-autorenew.sh:

#!/bin/sh

printf "LET'S ENCRYPT BULK RENEWAL\n%s\n\n" "$(date)";

for f in /etc/letsencrypt/configs/*.ini;
do
	printf "RENEWING CERTIFICATES FROM '%s':\n\n" "$f";
	/usr/local/src/letsencrypt/letsencrypt-auto certonly --config "$f";
	printf "\n\n";
done

printf "DONE RENEWING. PLEASE RELOAD THE RELEVANT SERVICES.\n";

https://git.ethitter.com/snippets/16

Note that /usr/local/src/letsencrypt is where I happen to have the Let’s Encrypt‘s library; you’ll need to update this to reflect wherever you’ve checked it out to. When ready, make the file executable by running chmod +x /etc/letsencrypt/eth-le-autorenew.sh.

To run the script every Sunday at 5:30, add the following to your server’s crontab:

30 5 * * 0 /etc/letsencrypt/eth-le-autorenew.sh

I wanted an email notifications with the results, so I modified the above to:

30 5 * * 0 /etc/letsencrypt/eth-le-autorenew.sh | mail -s "Let's Encrypt Weekly Renewal" letsencrypt@example.com

In conclusion

This is one way to renew alot of certificates. 😉

ALOT; https://core.trac.wordpress.org/ticket/13237
https://core.trac.wordpress.org/ticket/13237

  1. An organization that provides the trusted verification that makes secure certificates secure.

4 thoughts on “Automatically renewing a lot of Let’s Encrypt certificates”

  1. The weekly notification resembles the following:

    LET'S ENCRYPT BULK RENEWAL
    Sun Mar  6 05:30:01 UTC 2016
    
    RENEWING CERTIFICATES FROM '/etc/letsencrypt/configs/-.ini':
    
    Checking for new version...
    Requesting root privileges to run letsencrypt...
       /root/.local/share/letsencrypt/bin/letsencrypt certonly --config /etc/letsencrypt/configs/-.ini
    
    
    RENEWING CERTIFICATES FROM '/etc/letsencrypt/configs/-.ini':
    
    Checking for new version...
    Requesting root privileges to run letsencrypt...
       /root/.local/share/letsencrypt/bin/letsencrypt certonly --config /etc/letsencrypt/configs/-.ini
    
    
    DONE RENEWING. PLEASE RELOAD THE RELEVANT SERVICES.
  2. Automatically renewing LetsEncrypt certificates is great, but the real value of this article was discovering the alot trac ticket! Hadn’t seen that one yet 🙂

Leave a Reply