Skip to content

How I got Let’s Encrypt setup and operating on CentOS

Dear Reader,

WARNING: Here there be techy-stuff. Mere mortals, tread lightly.
Translation: I am not responsible if you hose your website trying to implement what I describe here.

letsencrypt

 

The web has been given a wonderful gift by the name of Let’s Encrypt. A free way to get an SSL certificate for your website. Many hosting services are already incorporating Let’s Encrypt in their control panels. Soon there will be no good reason for every website not to be encrypted.

Encryption vs. Verification

Before I go any further, let’s talk about the two things that an SSL certificate can provide for your website.

Encryption

The first thing that an SSL certificate gives you is encryption. For the uninitiated, this means that before your server sends a single byte of content, it negotiates a secure channel with the client. THEN it sends the content. This is what Let’s Encrypt is all about, securing the web.

Previously, you had to purchase an SSL certificate to get encryption. Granted, the price has come way down in the past few years. The last one I actually purchased was for Voices of the ElePHPant and it was only $8 a year! Still, that is a barrier for some people. So Let’s Encrypt provides a way for everyone to get encrypted websites for free.

Verification

The other thing that some commercial SSL certificate do is provide verification. To get one of the more expensive SSL certificates – e.g. not the $8/year ones – you have to prove who you or your business are. The company issuing the SSL certificate will ask you a lot of questions, you may even have to provide a DUNS to be verified. This helps prevent against fraud on the web and is very important to e-commerce sites, banking sites, and any site where you want to ensure the user that they are seeing the site for the company they THINK they are.

Let’s Encrypt does not provide Verification. If verification is important to your users, don’t use Let’s Encrypt. On the other hand, verification is not real important to sites like this blog, so Let’s Encrypt is a great option.

Doing the Deed

Let’s Encrypt provides wonderful documentation and a lot of automation if you are running Debian. If you aren’t – like me – or if you have a non-standard Apache setup, then you have to do a few extra steps.

So I am going to describe what I do when I set up a new SSL certificate from Let’s Encrypt, and how I keep them renewed automatically.

The following assumes you have installed Let’s Encrypt on your server. I simply cloned the Let’s Encrypt GitHub repo so that I can keep up to date. Twitter follower Nick Le Mouton also pointed out that Let’s Encrypt is also EPEL and that you can use yum to install it as well.

Step 1: Get the certificate

I have a script to manage this for me. I manually edit it before I run it each time, changing the domain name. Since I don’t purchase more than one domain per month these days – I’m on a domain name diet – this is easier for me than remembering parameters.

 

The Certificate Script

<code>
#!/bin/bash
#
# makeCert.sh
# This script requests a cert the first time. This is not the auto renew script.
#
# Set DOMAIN before running
#
DOMAIN=example.com
SITE=$DOMAIN
 
#
# Make sure this is set correctly
#
ENCRYPTDIR=/opt/letsencrypt
 
#
# Once it is working, you shoudn't have to change anything below here.
#
cd $ENCRYPTDIR
 
 
#
# How many dots are in the $SITE. If more than 1 then it is a subdomain 
# so don't register www as well.
#
FILESEPS=$(echo $SITE | awk 'BEGIN { FS="."} {print NF}')
 
if [ $FILESEPS -le 2 ]; then
       DOMAIN="$SITE -d www.$SITE "
else
        DOMAIN="$SITE"
fi
 
#
# Requst the cert
#
./letsencrypt-auto certonly \
          --agree-tos \
          -d $DOMAIN \
          -a webroot \
          --webroot-path /var/www/$SITE/public_html \
          --server https://acme-v01.api.letsencrypt.org/directory
</code>

 

All of my websites sit in /var/www on my servers. If you have a different scheme, you will have to adjust.

Update Apache

Ok, that gets my initial SSL certificate. Since I can’t use any of the automation, I have to manually update my apache conf files. How you do this is up to you. Since you are reading this because you have a non-standard setup, it is not possible for me to tell you exactly what you need to do. Honestly, if you don’t know, you probably shouldn’t be reading this in the first place. The important part is that you add these lines to your site’s apache conf file, where ever that may be.

The important part is that you add these lines to your site’s apache conf file, where ever that may be.

<code>
   SSLEngine on
   SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
   SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
   SSLCACertificateFile /etc/letsencrypt/live/example.com/chain.pem 
</code>

Once you’ve done that, restart apache.

Step 2: Get the renewals

Let’s Encrypt SSL certificates are only good for 90 days. So you will have to renew them at least once a quarter. Thankfully, renewal is not difficult. I have a bash script that I run once a morning. I won’t tell you when but pick a non-standard hour and minute so we aren’t all hitting it at say 1:15 AM.

You run this once a day for a couple of reasons.

First, we are not renewing the certs every day, we are only checking to see if they need renewing. It is a much lighter touch and doesn’t even involve hitting their API unless you actually do need to renew.

Second, if you run it once every 90 days and it fails, your certs will expire before your next run. Even every 30 days is a risk. If you run it every day and you have a cert nearing expiration, if for some reason you can’t reach the API on day 1, you get more chances.

The Renewal Script

<code>
#!/bin/bash
#
# renewCerts.sh
# This script checks every cert on this server and if necessary, renews it.
#
 
#
# Configure
#
ROOTDIR=/etc/letsencrypt/live
WEBROOT=/var/www
ENCRYPTDIR=/opt/letsencrypt
 
#
# Loop and renew
#
cd $ENCRYPTDIR
 
for SITE in $(ls -1 $ROOTDIR); do
 
        FILESEPS=$(echo $SITE | awk 'BEGIN { FS="."} {print NF}')
 
        if [ $FILESEPS -le 2 ]; then
                DOMAIN="$SITE -d www.$SITE "
        else
                DOMAIN="$SITE"
        fi
 
        ./letsencrypt-auto certonly \
          --agree-tos \
          --keep-until-expiring \
          -d $DOMAIN \
          -a webroot \
          --webroot-path $WEBROOT/$SITE/public_html \
          --server https://acme-v01.api.letsencrypt.org/directory
done
 
 
#
# Restart Apache
#
systemctl restart httpd
 
</code>

The script above will most likely be run either as root or by using sudo as it has to restart apache automatically.

The big change is --keep-until-expiring. This tells the Let’s Encrypt script to check the cert and if it’s expiration date is greater than 30 days out, don’t bother with it. If it’s less than 30 days, the script will go ahead and request a new SSL certificate.

Gotchas

There is only one gotcha I have found in doing things this way. If you have more than 3 subdomains, and you have certs for all of them individually – like I do – you can only request 3 SSL certificates per 24 hour period for any given domain. The answer to this is actually very easy, stagger the dates on your certificates. You can have as many as you want as long as more than 3 of them don’t expire on the same day.

Wrap-up

I developed these scripts right when the Let’s Encrypt public beta opened. As the project matures, all of this may not be necessary. Before implementing these scripts, check the Let’s Encrypt docs to see if things have changed.

Until next time,
I <3 |<
=C=

p.s. I hate to say this but I am going to. Change example.com in all of the above scripts to your domain name. An SSL certificate for example.com won’t do you much good. :)

35 thoughts on “How I got Let’s Encrypt setup and operating on CentOS

  1. Hi Cal,

    Thanks for the post. I think letsencrypt is a great way to easily setup SSL nowadays.

    You say that Let’s Encrypt does not provide Verification. But this is not quite true. What LetsEncrypt does is domain verification. This is the same verification that many (cheap) SSL certificates like Comodo Essential SSL do, only they have automated the process.

    The difference is that normally you need to verify the domain through email. LetsEncrypt does this through the ACME specification, which allows you to use the domain itself by creating a temporary file on it, just like you can do with google to verify that you own the domain. There are actually different ways of verification in the ACME spec, for instance through DNS TXT records, which is great when domains are not publicly available (and thus letsencrypt cannot validate).

    However, letsencrypt does not verify on organisation or via an extended validation process. (Even though this would technically not hard to automate either). This means that letsencrypt certificates can never give you the “green bar”, but note that this does not affect encryption levels. A common misconception is that green bar websites are better encrypted than non-green bar sites, which is not true: they are only validated in a better way.

    You also mentioned you can only create up to 3 certificates a day. Another way to do this, (I think this also works with multiple different domains and not only with subdomains), is to add multiple “-d” options to letsencrypt. This will “extend” the current certificate with the given names (this is called Subject Alternate Name or SAN). I haven’t verified it properly, but I think it does not affect your rate limit (although other limits may apply). A good thing to try out, especially when you have multiple subdomains running.

    Finally, setting up a SSL certificate is only one part of the story: Always make sure you configure your web server properly (disabling SSLv2 and SSLv3, setting up correct ciphers etc). Sites like https://cipherli.st, https://www.ssllabs.com and https://securityheaders.io/ can help you to set this up and verify the results.

    Regards,
    Josh

  2. Hi Joshua!

    No, Let’s Encrypt – and even the cheap SSL certificates – do not do corporate verification. Yes, Let’s Encrypt verifies that you have access to the web directory, but that’s not really verification. The more expensive certifications put you through a much more rigorous – and human involved – process to prove not only that you have access tot eh web root but that you are the company that you say you are. That is what I am saying when I say that Let’s Encrypt does not do verification. It doesn’t even do the basics that cheap SSL certificates do.

    Yes, you can use the -d option, in the scripts, I do that automatically for domains that do not have a sub-domain. However, for renewals, I spin through the /etc/letsencrypt/live directory to find the certificates to check. If you are going to get all your domains on the same certificate, you have to find a different way to identify them.

    If you are going to do that – and there is nothing wrong with it – then you will need to maintain a list of the certificates to check for renewal. That’s not that hard to do, it just wasn’t the way I went. :)

    Thanks for taking the time to write, always great to hear from you. :)

    Cheers!
    =C=

Comments are closed.