Jan 112016
 

Let’s Encrypt is a non-profit organization that is lowering the bar in getting people to encrypt their websites. They are lowering the bar in two ways, first by making it easy and api driven to obtain and renew the certificates and second by making it entirely free. Note, these are Domain Validation certs not Extended Validation or Organization Validation certs, those you still should buy from a reputable company like DigiCert.
Understanding the importance of encrypting the web is Step 1 here. Go google search to convince yourself of that and then come back to get some free certs on your websites.
This method of using let’s encrypt described below will probably get much easier for non-technical people as their software matures. However, I’m completely happy with it as it will grab the certs only, not mess with my nginx/apache configs, work with multiple vhosts, and renew every 60 days. The first thing someone may balk at when looking into the Let’s Encrypt certs is that they give out certs that expire in 90 days and recommend renewing every 60. This isn’t what most people are used to but once you have it configured you will do nothing to make this happen and they briefly review the decision to use ninety-day lifetimes on their certificates as well.

Installing Let’s Encrypt & Obtaining a Certificate

First you will want to git clone their repository so ensure you have git installed and clone it:

apt-get install git
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt/

Later to ensure you are using the latest version you will just run a git pull within the letsencrypt directory to pull down their latest changes.

At this point you need to simply run ./letsencrypt-auto with the parameters you want to get your cert.  It’s very helpful to know that ./letsencrypt-auto --help all will give you all the options and parameters you can use.
In my case I have a site like vigilcode.com that has a separate vhost for blog.vigilcode.com and forum.vigilcode.com and is also available at www.vigilcode.com. You can specify all of these in one command.

./letsencrypt-auto certonly --webroot -w /var/www/vigilcode.com --email youremail@yourdomain.com -d vigilcode.com -d www.vigilcode.com -d blog.vigilcode.com -d forum.vigilcode.com

This will put the certs in directories under /etc/letsencrypt/live/vigilcode.com since vigilcode.com was the first domain parameter. If you have a completely different domain as a vhost as well then simply run another command for that site like:

./letsencrypt-auto certonly --webroot -w /var/www/anothersite.com --email youremail@yourdomain.com -d www.anothersite.com -d anothersite.com

and letsencrypt will put those certs into /etc/letsencrypt/live/www.anothersite.com/

An example of a simple nginx config for “anothersite.com” that would redirect any normal http traffic to https and point to these letsencrypt certs is

server {
    listen 80;
    listen [::]:80;
    server_name www.anothersite.com anothersite.com;
    return 301 https://$server_name$request_uri;
}

server {
    # SSL configuration
    #
    listen 443 ssl;
    listen [::]:443 ssl;
    #
    gzip off;
    #
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_session_timeout 5m;
    ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:!aNULL:!eNULL:!MD5:!EXP:!PSK:!SRP:!DSS;
    ssl_certificate       /etc/letsencrypt/live/www.anothersite.com/fullchain.pem;
    ssl_certificate_key   /etc/letsencrypt/live/www.anothersite.com/privkey.pem;

    root /var/www/anothersite.com;

    index index.html;

    server_name www.anothersite.com anothersite.com;

    if ($request_method !~ ^(GET|HEAD|POST)$ )
    {
            return 405;
    }

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
    }
}

This config should give you an easy A in the Qualys SSL Labs Server Test which I strongly recommend you run against your site to ensure you always have an A. I assume if I turn on HSTS I’d get an A+ out of it but didn’t want to enable that yet.

With the above I did encounter Insecure Platform Warnings in the output. To solve I wanted to switch to use Pyopenssl and then modify the client to use it as well.

apt-get install python-pip
pip install pyopenssl ndg-httpsclient pyasn1

and then added 2 lines to client.py per this diff:

git diff acme/acme/client.py
diff --git a/acme/acme/client.py b/acme/acme/client.py
index 08d4767..9481a50 100644
--- a/acme/acme/client.py
+++ b/acme/acme/client.py
@@ -11,6 +11,7 @@ import OpenSSL
 import requests
 import sys
 import werkzeug
+import urllib3.contrib.pyopenssl

 from acme import errors
 from acme import jose
@@ -19,6 +20,7 @@ from acme import messages


 logger = logging.getLogger(__name__)
+urllib3.contrib.pyopenssl.inject_into_urllib3()

Configuring Automatic Renewals

I found a nice script in the letsencrypt forums that accomplished most of what I wanted. I made a few edits so also uploaded my modified version of it here in case the forum copy disappeared.

If you look at the script the basic renewal command is ${LEBIN} certonly --renew-by-default --config "${LECFG}" --domains "${DOMAINS}"
The only pieces that is missing from our original command is that we were using the webroot authentication method and specifying the webroot path. Since I have a different webroot for some different virtual hosts I want to put them in their own .ini file. So instead of specifying a static .ini file in his script I changed it to be a variable matching the cert name

Line 125: LECFG="/etc/letsencrypt/${CERT_NAME}.ini"

Now I’d create /etc/letsencrypt/www.anotherdomain.com.ini and /etc/letsencrypt/vigilcode.com.ini
and give it an email = line and then also specify the webroot and webroot path as in:

authenticator = webroot
webroot-path = /var/www/vigilcode.com

Then you can just pop this into a crontab with crontab -e

10 2 * * 6 /root/scripts/auto_le_renew.sh vigilcode.com
15 4 * * 6 /root/scripts/auto_le_renew.sh www.anotherdomain.com

These will run every Saturday morning so when I wake up I’d have the success or fail message once the renewal is triggered.

 Leave a Reply

(required)

(required)