Traffico HTTP sicuro grazie a Let’s Encrypt

0

letsencrypt-logo

Quando si tratta di erogare siti web, in questo periodo, è sempre più importante prestare attenzione alla sicurezza, non solo dei propri sistemi che erogano, ma anche dei propri visitatori. Questa tematica è molto sentita in questo periodo al punto che molti stanno intraprendendo azioni volte ad ottenere una navigazione web solo sicura: da alcuni browser che stanno valutando di iniziare ad utilizzare solo protocolli sicuri, agli stessi motori di ricerca (come Google) che garantiscono un ranking migliore ai siti disponibili tramite protocollo https.

Già, perchè quando parliamo di web sicuro, stiamo parlando del protocollo https: uno strato di sicurezza fornito da certificati SSL che incapsula il protocollo HTTP utilizzato per il traffico internet.

Nonostante i più diffusi webserver (Apache ed Nginx, per citarne un paio) offrano da tempo immemore la possibilità di erogare siti tramite https, molti optavano per i protocolli in chiaro per diversi motivi:

  • Il costo dei certificati: acquistare un certificato può essere molto dispendioso, le cifre variano tra qualche decina fino a diverse centinaia di euro
  • La manutenzione: i certificati SSL hanno una scadenza, e questo comporta una certa gestione da parte dell’amministratore di sistema; da verificare le scadenze, ai rinnovi, alla sostituzione dei file sul webserver.

Let’s Encrypt nasce per venire incontro al desiderio di un web sicuro con effort -e costi- minimi. Si tratta di una Certification Authority (CA) aperta che eroga certificati gratuitamente ed automaticamente.

Riesce a rimanere gratuita grazie alle sponsorizzazione ed alla durata limitata dei certificati che emette (attualmente, i certificati vengono erogati con durata di tre mesi). Questa limitazione è però rapidamente superata dall’estrema automazione che garantiscono i tool, anch’essi open, che forniscono, e che sono in grado di emettere semplicemente e rinnovare autonomamente certificati.

Ma vediamo insieme quanto è semplice configurare il proprio webserver per erogare pagine in https.

Installazione

Installare Let’s Encrypt è tanto semplice quanto l’esecuzione di un singolo comando git. Avremo bisogno, per prima cosa, di installare il client git:

~# apt-get install git
Reading package lists... Done
Building dependency tree 
Reading state information... Done ... Setting up git-man (1:2.7.4-0ubuntu1) ... Setting up git (1:2.7.4-0ubuntu1) ...

Una volta installato git, possiamo clonarci il repository pubblico GitHub di Let’s Encrypt, anche qui si tratta di un singolo comando:

~# cd /usr/local
/usr/local# git clone https://github.com/letsencrypt/letsencrypt
Cloning into 'letsencrypt'...
remote: Counting objects: 41866, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 41866 (delta 1), reused 0 (delta 0), pack-reused 41864
Receiving objects: 100% (41866/41866), 11.75 MiB | 535.00 KiB/s, done.
Resolving deltas: 100% (29850/29850), done.
Checking connectivity... done.
/usr/local# cd letsencrypt
/usr/local/letsencrypt#

Ora abbiamo tutto quello che ci serve per iniziare a richiedere i nostri certificati.

Richiedere un nuovo certificato

Per richiedere un certificato tramite Let’s Encrypt sono necessarie alcune premesse. Sarà necessario:

  • Avere una entry a DNS pubblica che risolva l’ip con il quale ci presentiamo su Internet
  • Avere un webserver (questo non è necessario per richiedere un certificato, ma sarà per necessario erogare un sito tramite https)
  • Avere la porta 443 non utilizzata in fase di richiesta dei certificati

Prendiamo, ad esempio, la entry a DNS www.miamammausalinux.org. Questo viene risolto con l’ip pubblico della nostra rete:

/usr/local# nslookup www.miamammausalinux.org
Server:         127.0.1.1
Address:        127.0.1.1#5

Non-authoritative answer:
Name:   www.miamammausalinux.org
Address: 46.4.105.174

E l’apache è attualmente configurato per erogare il sito in http:


        ServerName www.miamammausalinux.org
...

Verifichiamo infine che la porta 443 sia attualmente a disposizione:

/usr/local# netstat -anp | grep \:443\ 
/usr/local#

Tutte le premesse ci sono, possiamo procedere dunque a richiedere un nuovo certificato:

/usr/local/letsencrypt# ./letsencrypt-auto certonly --standalone

Questo comando, la prima volta che verrà lanciato, installerà (sempre tramite il comando di gestione dei propri repository, sia esso apt o yum) le dipendenze necessarie:

root@ubuntuvm:/usr/local/letsencrypt# ./letsencrypt-auto certonly --standalone
Bootstrapping dependencies for Debian-based OSes...
Hit:1 http://it.archive.ubuntu.com/ubuntu xenial InRelease
Hit:2 http://it.archive.ubuntu.com/ubuntu xenial-updates InRelease
Hit:3 http://it.archive.ubuntu.com/ubuntu xenial-backports InRelease
Get:4 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB]
Fetched 102 kB in 3s (31,4 kB/s)
Reading package lists... Done
Reading package lists... Done
Building dependency tree
Reading state information... Done
augeas-lenses is already the newest version (1.4.0-0ubuntu1).
augeas-lenses set to manually installed.
ca-certificates is already the newest version (20160104ubuntu1).
ca-certificates set to manually installed.
gcc is already the newest version (4:5.3.1-1ubuntu1).
gcc set to manually installed.
libaugeas0 is already the newest version (1.4.0-0ubuntu1).
libaugeas0 set to manually installed.
python is already the newest version (2.7.11-1).
python set to manually installed.
...

Terminato, procederà presentando un’interfaccia ncurses (a terminale) chiedendo alcuni dati:

letsencrypt-step1

Ovviamente leggiamo ed accettiamo i termini di uso del servizio:

letsencrypt-step2

Infine ci verrà chiesta la lista di domini di cui vogliamo generare il certificato. Se in futuro dovessimo generare altri certificati, ci ritroveremo direttamente in questo passaggio:

letsencrypt-step3

L’operazione continuerà ed i nostri certificati saranno generati e scaricati in locale. Si chiude l’applicazione con il seguente messaggio:

IMPORTANT NOTES:
 - If you lose your account credentials, you can recover through
   e-mails sent to [email inserita al primo passaggio].
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.

Se andiamo a vedere il contenuto della directory /etc/letsencrypt vedremo questa struttura:

/etc/letsencrypt# ls -l
totale 28
drwx------ 3 root root 4096 nov 29 15:24 accounts
drwx------ 6 root root 4096 dic  1 13:47 archive
drwxr-xr-x 2 root root 4096 dic  1 13:47 csr
drwx------ 2 root root 4096 dic  1 13:47 keys
drwx------ 5 root root 4096 dic  1 13:47 live
-rw-r--r-- 1 root root 1389 nov 29 15:24 options-ssl-apache.conf
drwxr-xr-x 2 root root 4096 dic  1 13:47 renewal

Ed infine, ecco i certificati che sono stati generati:

/etc/letsencrypt# cd live/www.miamammausalinux.org/
/etc/letsencrypt/live/www.miamammausalinux.org# ls -l
totale 0
lrwxrwxrwx 1 root root 35 nov 29 16:32 cert.pem -> ../../archive/www.miamammausalinux.org/cert1.pem
lrwxrwxrwx 1 root root 36 nov 29 16:32 chain.pem -> ../../archive/www.miamammausalinux.org/chain1.pem
lrwxrwxrwx 1 root root 40 nov 29 16:32 fullchain.pem -> ../../archive/www.miamammausalinux.org/fullchain1.pem
lrwxrwxrwx 1 root root 38 nov 29 16:32 privkey.pem -> ../../archive/www.miamammausalinux.org/privkey1.pem

Non resta dunque che configurare il nostro webserver.

Configurazione di Apache

Qui la configurazione è decisamente semplice, vi ricordate il VirtualHost che gestiva il traffico http (porta 80)?


        ServerName www.miamammausalinux.org
...

Copiamo il blocco ed incolliamolo subito prima di quello già presente. Andremo ora aspecificare il VirtualHost per la risposta alla porta https, la 443:


        ServerName www.miamammausalinux.org
...

Rimane tutto uguale, se non che dobbiamo istruire apache sull’utilizzo dell’ssl, e su come reperire i certificati.
Aggiungiamo quindi, subito sotto la voce ServerName, le seguenti entry:

SSLEngine On
SSLCertificateFile      /etc/letsencrypt/live/www.miamammausalinux.org/fullchain.pem
SSLCertificateKeyFile   /etc/letsencrypt/live/www.miamammausalinux.org/privkey.pem

Se volete, potete anche modificare le entry relative ai log al fine di avere separati i log del traffico sicuro e di quelli in chiaro (basta editare le righe CustomLog ed ErrorLog all’interno di questo VirtualHost).

Una volta salvata la nuova configurazione, assicuriamoci che il modulo SSL sia attivo:

/etc/apache2# a2enmod ssl
Considering dependency setenvif for ssl:
Module setenvif already enabled
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Module socache_shmcb already enabled
Module ssl already enabled

E riavviamo il nostro webserver:

/etc/apache2# systemctl restart apache2
/etc/apache2# systemctl status apache2
● apache2.service - LSB: Apache2 web server
   Loaded: loaded (/etc/init.d/apache2; bad; vendor preset: enabled)
  Drop-In: /lib/systemd/system/apache2.service.d
           └─apache2-systemd.conf
   Active: active (running) since ven 2016-12-02 15:25:38 CET; 5s ago
...

Ora, possiamo notare che la porta 443 è in ascolto, e che è gestita da Apache:

/etc/apache2# netstat -anp | egrep 443.*LISTEN
tcp6       0      0 :::443                  :::*                    LISTEN      6443/apache2

Tentando dunque di collegarsi al sito sito tramite il protocollo https, possiamo vedere che la comunicazione sicura è attiva e funzionante:

letsencrypt-blog

Possiamo ora garantire ai nostri utenti una navigazione protetta verso il nostro sito.

Rinnovo certificati

Come dicevamo all’inizio, una delle comodità di Let’s Encrypt è quella di poter riuscire a gestire autonomamente il rinnovo dei certificati. L’operazione è molto semplice e consiste nell’inserire a crontab un comando (fornito esso stesso da letsencrypt) che si occupa di leggere tutti i certificati che abbiamo generato, verificarne la validità e, nel caso fosse necessario, rinnovarli.

Il comando è il seguente, ed è possibile lanciarlo a mano per verificarne l’output:

/etc/apache2# /usr/local/letsencrypt/certbot-auto renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/www.miamammausalinux.org.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/www.miamammausalinux.org/fullchain.pem (skipped)
No renewals were attempted.

Come vediamo, avendo appena generato il certificato, questo non richiede il rinnovo. La stessa cosa non sarà vera tra tre mesi. Aggiungiamo quindi un job nella crontab di sistema per far verificare la validità dei certificati a Let’s Encrypt. Scegliamo noi la frequenza, ad esempio una volta alla settimana, il Lunedì, alle 02:30 del mattino:

~# grep let /etc/crontab
# Aggiornamento certificati let's encrypt
30 02   * * 1   root    /usr/local/letsencrypt/certbot-auto renew >/dev/null 2>&1

Questo ci garantirà dei certificati sempre freschi per i nostri utenti.

Cosa fare dopo?

Le operazioni sono terminate. Se vogliamo possiamo forzare gli utenti ad utilizzare la connessione sicura tramite una redirect, per assicurarci che tutti possano godere del nuovo ambiente.

Procediamo quindi a modificare il VirtualHost di Apache per rimandare gli utenti al sito https:


        ServerName www.miamammausalinux.org
        Redirect / https://www.miamammausalinux.org/

Ricarichiamo le configurazioni di Apache:

/etc/apache2# systemctl reload apache2
/etc/apache2#

Ed, ovviamente, assicuriamoci che il tutto stia funzionando tramite una semplice curl:

~# curl -I http://www.miamammausalinux.org
HTTP/1.1 302 Found
Date: Fri, 02 Dec 2016 14:45:39 GMT
Server: Apache/2.4.7 (Ubuntu)
Location: https://www.miamammausalinux.org/
Connection: close
Content-Type: text/html; charset=iso-8859-1
~#

Come vediamo il webserver risponde con un messaggio 302 (HTTP Redirect) e l’indirizzo che si andrà ad utilizzare (leggibile nell’header http Location) è il nostro stesso sito con protocollo https.

Conclusioni

Come abbiamo visto, grazie a Let’s Encrypt, la gestione dei certificati è incredibilmente semplice e gratuita e non ci sono più scuse per non fornire anche questa soluzione ai propri utenti. Inoltre, questo garantisce anche una copertura maggiore per il futuro, rendendoci di fatto pronti ad affrontare browser particolarmente zelanti, ed a garantire un buon ranking nei principali motori di ricerca.

Utente Linux/Unix da più di 20 anni, cerco sempre di condividere il mio know-how; occasionalmente, litigo con lo sviluppatore di Postfix e risolvo piccoli bug in GNOME. Adoro tutto ciò che può essere automatizzato e reso dinamico, l’HA e l’universo container. Autore dal 2011, provo a condividere quei piccoli tips&tricks che migliorano il lavoro e la giornata.