I Encrypt, therefore I Am

Posted 28.02.2016 in General, Security, Technology by Kim Halavakoski

In this age of global surveillance and spying, encrypting communications has become the standard. Companies, big and small, are finally taking the necessary steps to encrypt all their traffic traversing the Internet in order to protect their users from the ubiquitous tentacles of the intelligence agencies of the world. Even Google started ranking SSL/TLS protected sites higher than unencrypted sites in 2014, giving organisations additional incentive to encrypt pages.

Another interesting project that aims to make SSL the standard rather than the exception is Lets Encrypt.  Lets Encrypt offers free SSL certificates for everyone, boosting Internet SSL/TLS usage and enabling encryption for everyone who needs it. Heck, why not encrypt your site even if you don’t need explicit encryption? How hard can it be?

In this post I am going to use the LetsEncrypt client to install a brand new and shiny TLS certificate for this blog and setup automatic renewals for the certificate. Please note that LetsEncrypt is still in public beta so don’t blame me if they go tits-up. You have been warned…

Install the client

First we are going to install the Lets Encrypt client which is pretty straightforward and easy. All you need is git and run the following commands from the command line on a Linux box to install letsencrypt to the /opt directory(I prefer /opt for “legacy” reasons(=I am old!) but you can use whatever directory you like, /usr/local for example !)

root@server:~# cd /opt/ 
root@server:/opt# git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
Cloning into '/opt/letsencrypt'...
remote: Counting objects: 32184, done.
remote: Compressing objects: 100% (107/107), done.
remote: Total 32184 (delta 60), reused 0 (delta 0), pack-reused 32077
Receiving objects: 100% (32184/32184), 8.37 MiB | 3.06 MiB/s, done.
Resolving deltas: 100% (22780/22780), done.
Checking connectivity... done.
root@server:/opt# 

This installs a copy of the letsencrypt client in /opt/letsencrypt

Get a certificate

Next we need to run the letsencrypt-auto client to create a certificate. I will here run the client in “standalone” mode because it does not yet support automatic provisioning of Nginx configurations, only Apache. Standalone mode requires that the client runs a webserver for validation purposes on the host during the certificate creation process. This means that any service running on port 80 must be shut-down before running the command. In this case I need to stop nginx running on my host before running the command and creating the certfiicate.

root@server:/opt/letsencrypt# service nginx stop
root@server:/opt/letsencrypt# ./letsencrypt-auto certonly --standalone -d deductivelabs.com -d www.deductivelabs.com
Checking for new version...
Requesting root privileges to run letsencrypt...
   /root/.local/share/letsencrypt/bin/letsencrypt --no-self-upgrade certonly --standalone -d deductivelabs.com -d www.deductivelabs.com

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/deductivelabs.com/fullchain.pem. Your cert
   will expire on 2016-05-28. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
 - If you like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

root@server:/opt/letsencrypt# 
root@server:/opt/letsencrypt# service nginx restart
 * Restarting nginx nginx                                                                                                       [ OK ] 
root@server:/opt/letsencrypt# 

This will place the TLS certificates in the /opt/letsencrypt/live/deductivelabs.com/ directory from where we can use the certificates for the services running on the system, in this case nginx running the Deductive Labs website.

To configure nginx with the new Let Encrypt certificate we need to put the following directives into our nginx configuration. This configuration may vary depending on what your nginx setup looks like. In our case I configured the following ssl directives into the /etc/nginx/sites-available/deductivelabs.com configuration file:

# HTTP Server with redirect from port 80 to 443 since we are now using TLS for our website
server {
    listen         80;
    server_name    deductivelabs.com www.deductivelabs.com;
    return 301 https://$server_name$request_uri;
}

# HTTPS server 
server {
    listen 443;
    server_name    deductivelabs.com www.deductivelabs.com

    # SSL configurations
    ssl on;
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD
5:!DSS;
    ssl_prefer_server_ciphers on;

    ssl_certificate /etc/letsencrypt/live/deductivelabs.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/deductivelabs.com/privkey.pem;

    # enable session resumption to improve https performance
    # http://vincent.bernat.im/en/blog/2011-ssl-session-reuse-rfc5077.html
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 5m;

    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    ssl_dhparam /etc/ssl/certs/dhparam.pem;

    # HTTP Strict Transport Security
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";


# The rest of the nginx configuration removed to save space...

Then restart nginx to start using the new SSL configurations in nginx:

root@server:/opt/letsencrypt# service nginx start

Now we have a new TLS certificate running on our website and additionally configured all HTTP traffic on port 80 redirected to port 443. No more HTTP on this website!

Renew certificates

Letsencrypt certificates are valid for “only” 90 days so the best way to keep the certificates updated at all times is to automate the renewal process. Luckily the system is built for rapid certificate renewals and can easily be automated with some scripts and cron-jobs which can be version-controlled, provisioned, deployed and run from your favourite automation tool: Ansible, Puppet, Chef, etc.

The renewal process is pretty straightforward and only requires that the letsencrypt client is run using the renew argument. This can be tested with –dry-run so go ahead and run that command to see what happens:

root@server:/opt/letsencrypt# ./letsencrypt-auto renew --dry-run

If everything is OK then we can proceed with renewing the certificate:

root@server:/opt/letsencrypt# ./letsencrypt-auto renew

Since the LetsEncrypt certificates are valid for 90 days we’d like to automate the renewal process in order to keep the certificate valid without unnecessary human intervention.

To make the renewal process as smooth as possible we will use the webroot module where the letsencrypt client places validation information in a specified location on the webserver. First we configure nginx to show files from the .well-known directory from the default nginx root directory by adding the following to our nginx configuration:

location ~ /.well-known {
    root /usr/share/nginx/html/;
    allow all;
}

Then we configure a letsencrypt by creating the file /etc/letsencrypt/deductivelabs.com.ini:

rsa-key-size = 4096
email = ops@deductivelabs.com
text = True
authenticator = webroot
webroot-path = /usr/share/nginx/html

This configuration file configured the default RSA key-size, the email to use for the certificates, text-mode to disable ncurses since we are running the renewals from crontab, the authenticator set to webroot and webroot-path configured to nginx default root path where letsencrypt will put the validation information.

Now we will run the letsencrypt client with the renew argument to first simulate a renewal and then run the renewal. Since we just created the certificate it will not be renewed since the renewal only gets done if the certificate end date is less than 30 days:

root@server:/opt/letsencrypt# ./letsencrypt-auto renew --agree-tos --config=/etc/letsencrypt/deductivelabs.com.conf --dry-run
Checking for new version...
Requesting root privileges to run letsencrypt...
   /root/.local/share/letsencrypt/bin/letsencrypt --no-self-upgrade renew --agree-tos --config=/etc/letsencrypt/deductivelabs.com.conf --dry-run
Processing /etc/letsencrypt/renewal/deductivelabs.com.conf
** DRY RUN: simulating 'letsencrypt renew' close to cert expiry
**          (The test certificates below have not been saved.)
Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/deductivelabs.com/fullchain.pem (success)
** DRY RUN: simulating 'letsencrypt renew' close to cert expiry
**          (The test certificates above have not been saved.)
root@server:/opt/letsencrypt# 

root@server:/opt/letsencrypt# ./letsencrypt-auto renew --agree-tos --config=/etc/letsencrypt/deductivelabs.com.conf 
Checking for new version...
Requesting root privileges to run letsencrypt...
   /root/.local/share/letsencrypt/bin/letsencrypt --no-self-upgrade renew --agree-tos --config=/etc/letsencrypt/deductivelabs.com.conf
Processing /etc/letsencrypt/renewal/deductivelabs.com.conf

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/deductivelabs.com/fullchain.pem (skipped)
No renewals were attempted.
root@server:/opt/letsencrypt# 

Now we configure this command to run via crontab every week to ensure that our certificate is kept updated

#
# Lets Encrypt renewal cronjob
#

MAILTO=root

# Renew letsencrypt certificate
0 0 * * 7 /opt/letsencrypt/letsencrypt-auto renew --agree-tos --config=/etc/letsencrypt/deductivelabs.com.conf >> /var/log/letsencrypt/
renew.log 2>&1

Now we have a LetsEncrypt certificate installed and renewals are tried on a weekly basis and renewed automatically when the certificate expiry date is less than 30 days away!

Now that was not too hard was it?

Written by Kim Halavakoski

Kim is a hacker-minded, technology-geek that loves challenges. Having worked in the IT-industry for over a decade in ISP and large-scale financial networks configuring firewalls, networks, security technologies, log management/SIEM, automation, assessing risks and writing policies and governance processes.

Related articles

Kritisk sårbarhet i Microsoft Remote Desktop(RDP)

En kritisk sårbarhet har hittats i Microsofts Remote Desktop Services, eller RDP.  Remote Desktop Services(RDP) - tidigare känd som Terminal Services, används för fjärrstyrning av Microsoft Windows operativsystem. Sårbarheten är…

Meet us at the Maritime Day 9 May, 2019 in Mariehamn

Busy days!  Proud to announce Deductive Labs will be present at the Maritime Day / Sjöfartens Dag 9 May, 2019 in Mariehamn, Finland. The Maritime Day has been organized since…

“Gone phishing”?

Ett phishing mail är ofta utformat att ser ut att vara från en person i ledande position (vd, chef, hr, ekonomi, ...) i företaget eller annan betrodd organisation, som tex.…