Getting a free TLS certificate from Let's Encrypt

Certified

Automating Renewal

The Let's Encrypt certificates are designed to expire in three months. This expiration ensures the certificates are "always fresh" and, after a breach, they cannot be used for long.

This short lease period means you might want to automate renewal to save yourself the trouble of repeating the installation process.

For the first renewal, I recommend letting cron take care of it, but then do a check to ensure that all went well. I scripted a proof-of-concept renewal script that I run every week (Listing 2). In addition, I have a second script that alerts me on certificates that are about to expire. The script in Listing 2 does the job, but please post better scripts as you make them. The script will probably work if:

  • Your Hiawatha configuration is working for the domains you are serving (so your websites are reachable and the web server can write to the webroot directory)
  • You have manually verified Let's Encrypt works
  • You have adjusted all lines that say #adjust with settings relevant for your network
  • You are root when you run the script (it can run as a user but you should adjust the tmp file)

Listing 2

Automated Renewal

01 #!/bin/bash
02 # hanscees@hanscees.com version 27-03-2016
03 #This script will renew one or multiple Let's Encrypt domains
04 # by default it uses the staging server. Adjust to use life Let's Encrypt server
05 # Let me know if you built a better script
06
07 WEBROOT="/var/www/backends/"
08 #we will get certificates for the following domains
09 DOMAINS="www.test-backend.com www.backend.com www.backend.net" #adjust
10 EMAILADMIN="hanscees@hanscees.con" #adjust
11
12 LECROOT="/etc/letsencrypt/live"
13 mkdir /root/letsencrypt #justincase
14
15 #lets get certs
16 echo "will get the certs now" & sleep 3
17 for i in `echo $DOMAINS` ; do
18 echo "getting certs for  $i"
19
20 #If certs do not exist yet
21 FILE="$LECROOT/$i/cert.pem"
22 if [ ! -f "$FILE" ]
23 then
24         echo "$FILE does not exists, so lets get certificates"
25         cd /root/letsencrypt
26         #using staging server? Adjust if neccesary
27         ./letsencrypt-auto certonly -a webroot --webroot-path $WEBROOT -d $i --server \
28         https://acme-staging.api.letsencrypt.org/directory
29         #./letsencrypt-auto certonly -a webroot --webroot-path $WEBROOT -d $i --server \
30         https://acme-v01.api.letsencrypt.org/directory
31         sleep 33 # can take a while
32 else
33         echo "there is already a certificate, lets test its age"
34         sleep 3
35
36         #only get certs if the current certs arent very youngh: age test
37         if test `find "$LECROOT/$i/cert.pem" -mtime +71`
38         then
39                 echo "certificates exist and are rather old"
40                 # so lets get new ones
41                 cd /root/letsencrypt
42                 #using staging server? Adjust if neccesary
43                 ./letsencrypt-auto certonly -a webroot --webroot-path $WEBROOT -d $i \
44                 --server https://acme-staging.api.letsencrypt.org/directory
45                 #./letsencrypt-auto certonly -a webroot --webroot-path $WEBROOT -d $i \
46                 --server https://acme-v01.api.letsencrypt.org/directory
47                 sleep 33 # can take a while
48         else
49                 echo " certificates exist, but apparently are very fresh, do not get new ones"
50                 sleep 3
51                 # notify and exit this loop iteration, continuing with the next
52                 echo "certificate $i not refreshed, they are very new so no problem" |
53                 mail -s no-need-refresh-cert-$i $EMAILADMIN
54                 continue
55         fi # age test
56
57 fi # does cert file exist
58
59
60 #if all is well we have a new certificate, but we need to adjust it to hiawatha pem format
61 #check if pems are indeed new, or skip, could be an error right?
62 #cd $LECROOT/$i
63 if test `find "$LECROOT/$i/cert.pem" -mmin +3600`
64 then
65         # certificates are old, not refreshed, has been an error
66         # notify and exit this loop iteration, continuing with the next
67         echo "certificate $i not refreshed, send fire department" | mail -s problem-cert-$i $EMAILADMIN
68         continue
69 else
70         # certs are fresh, so lets make a new pem  #adjust for non-hiawatha webserver
71         echo "certs $i are in lets make a pem"
72         cat $LECROOT/$i/privkey.pem $LECROOT/$i/cert.pem $LECROOT/$i/chain.pem > $LECROOT/$i/hiawatha-hc.pem
73         chown www-data:www-data  $LECROOT/$i/hiawatha-hc.pem
74         chmod 440 $LECROOT/$i/hiawatha-hc.pem
75         echo "pemfile is $LECROOT/$i/hiawatha-hc.pem"
76 fi
77 done
78
79 # todo, built in some test?
80 /etc/init.d/hiawatha restart #adjust
81
82 echo "letsencrypt certificates $DOMAINS update just ran, sending email to $EMAILADMIN"
83 echo "letsencrypt certificates $DOMAINS update just ran, please check your websites" |
84 mail -s "letsencrypt-update-$DOMAINS" $EMAILADMIN

To create the script, enter

mkdir /root/scripts
vi /root/scripts/updatecerts

and copy the lines in Listing 2 to the updatecerts file. Then, change the permissions for the file with the following:

chmod +x /root/scripts/updatecerts

Make the necessary modifications to the lines labeled #adjust, and run the script with:

/root/scripts/updatecerts

If you want to run this script from cron every 4 weeks or so, add a line like the following to cron:

cron crontab -e
30 03 01 */2 * /root/scripts/updatecerts >> /var/log/cron.log 2>&1

If you will be using this script, I strongly recommend you run it a few times manually using the stage area!

To check if your certificates will expire within 4 weeks, you can run the script shown in Listing 3.

Listing 3

expire-check

01 #!/bin/bash
02 # hanscees@hanscees.com version 28-12-2015
03
04 DOMAINS="www.test-backend.com www.thisisagreatwebsite.com"   #adjust
05 EMAILADMIN="hanscees@hanscees.con"    # adjust
06
07 LECROOT="/etc/letsencrypt/live"
08 for i in `echo $DOMAINS` ; do
09 #checkend is seconds. 1 week = 604800 sec 4 weeks 2419200 16 weeks = 9676800
10   if openssl x509 -checkend  2419200 -noout -in $LECROOT/$i/cert.pem
11   then
12     echo "Certificate is good for another 4 weeks!"
13   else
14     echo "Certificate $i will expire within 4 weeks! (or is invalid/not found)"
15     echo "Certificate $i will expire within 4 weeks! (or is invalid/not found)" |
16     mail -s "TLS certificate $i will expire act now" $EMAILADMIN
17 fi
18 done #end forloop

Conclusion

In this article, I described how to get a free trusted TLS certificate on a Linux web server and also how you

might automate the process, because you will need to refresh your certificates. Have fun setting up many TLS-protected websites with Let's Encrypt.

Infos

  1. Let's Encrypt: https://letsencrypt.org/
  2. Let's Encrypt "How It Works": https://letsencrypt.org/how-it-works/
  3. Turnkey Linux: https://www.turnkeylinux.org/
  4. Hiawatha web server: https://www.hiawatha-webserver.org/
  5. Let's Encrypt terms of service: https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf
  6. Other how-tos by Hans-Cees: https://www.hanscees.com/ (guess who signed the certificate?)

The Author

Hans-Cees Speel works as manager and security officer for youth health organizations in the Netherlands. In his spare time, he has a lot of fun tinkering with cheap but effective proof-of-concept security controls. To tinker is to learn! His first encounter with Linux was on single-floppy-disk firewalls.

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus