Vai al contenuto principaleVai al footer
Code
|
08 maggio 16

Certificati Ssl con Let's Encrypt

Per alcuni progetti, la gestione dei certificati ssl è una procedura onerosa sia in termini di costo fisico del certificato, sia della gestione manuale della pratica (richiesta, autenticazione, pagamento, invio). Può quindi capitare che il budget non sia sufficiente a coprire anche questa necessità. Let's Encrypt è una possibile soluzione che ci permette di ottenere in maniera automatica e gratuita, dei certificati ssl validabili dai browser!

Update 19 Maggio 2016

Nell'ultimo mese la beta di let's encrypt è passata a release ufficiale, quindi l'articolo è stato aggiornato con i nuovi comandi

La gestione dei certificati ssl

Per rendere sicure le comunicazioni tra client e server nell'ambito web (in origine era pensato per le transazioni bancarie) il protocollo di comunicazione HTTP venne ampliato grazie all'introduzione della crittografia asimmetrica dando vita all'SSL.

L'SSL è un layer sopra lo stack Tcp/Ip che cifra i messaggi scambiati tramite i protocolli di livello applicativo (Http, Ftp, ecc) tramite un meccanismo a chiave asimmetrica. Qui, un possibile tentativo di attacco di tipo Man in the middle, è evitato poiché, anche se vengono intercettati, i pacchetti risulteranno illeggibili.

Nel caso della tecnologia web, sono i server a gestire direttamente la comunicazione cifrata, rimanendo in ascolto su una porta (solitamente la porta 443).

La verifica del certificato ssl

Quando un client effettua una connessione sicura verso un server web, il server fornisce un certificato associato ad un nome di dominio da cui inizia la fase di autenticazione. Alla fine di questa procedura il client avrà la garanzia che nessuno potrà leggere il contenuto dei messaggi scambiati con il server.

Ma chi assicura il client riguardo la reale identità del server? In questo caso entrano in gioco le certification authority.

Questi enti sono gli unici che forniscono ai server le chiavi firmate. In questo modo i client, interrogandoli durante la fase di autenticazione, possono sapere se quel certificato è autentico o meno.

Nel caso in cui sia autentico, verrà visualizzato nella barra del browser un lucchetto verde, ad indicare che la connessione è sicura.

Se invece il certificato non viene generato dalla CA, ma in maniera autonoma (i cosiddetti self-signed) allora la connessione sarà sempre cifrata, ma non avremmo garanzia dell'identità del server. In questo caso, vedremo un lucchetto rosso.

Per avere un certificato da bollino verde, fino a poco tempo fa era necessario fare richiesta alle CA le quali richiedono tutta una serie di procedure (talvolta addirittura telefonate dirette all'intestatario del dominio da autenticare) al fine di fornire un certificato ssl valido.

Let's Encrypt!

Let's Encrypt è una certificate authority che fornisce un meccanismo gratuito ed automatizzato di generazione di certificati ssl.

Il meccanismo è abbastanza semplice: installando un client sul server che gestisce il dominio da verificare, si attiva una fase di autenticazione al termine del quale si viene a generare un certificato valido. A questo punto basta configurare il server web ad utilizzare quelle chiavi ed il gioco è fatto

Configurazione su Nginx

Facciamo un esempio di configurazione su un server ubuntu 14.04 con nginx come server web.

Per prima cosa, installiamo let's encrypt e creiamo le cartelle per le configurazioni:

$ cd /root
$ git clone https://github.com/certbot/certbot
$ cd certbot && ./certbot-auto --os-packages-only
mkdir -p /var/www/letsencrypt

oppure, su Ubuntu 16.04 LTS, direttamente da aptitude

$ sudo apt-get install certbot

Ora, nel file di configurazione nginx del dominio, aggiungiamo la seguente direttiva

location ^~ /.well-known {
  alias /var/www/letsencrypt/.well-known;
}

Questa directory è utilizzata da let's encrypt per rendere disponibile all'ente certificatore ACME un file codificato atto a confermare la propria identità e la capacità di amministrare il dominio da certificare.

Riavviamo il server.

Adesso possiamo lanciare il comando e, se l'identità del server viene riconoscuita dalla CA, ci verrà fornito un certificato ssl valido.

  $ /root/certbot/certbot-auto certonly --webroot -w /var/www/letsencrypt -d mydomain.example.com --no-interactive --agree-tos --email admin@example.com

Al termine del programma, se tutto è andato a buon fine, troveremo installate al percorso /etc/letsencrypt/live/mydomain.example.com/ il certificato e la chiave privata.

Non ci rimane che editare nuovamente il file di configurazione di nginx e configurare l'https con le chiavi appena generate.

# Si reindirizzano tutte le richieste http verso l'https
server {
  listen *:80;
  server_name mydomain.example.com;
  return 301 https://mydomain.example.com:443$request_uri;
}

server {

  listen *:443 ssl;

  server_name mydomain.example.com
  ssl on;
  ssl_certificate /etc/letsencrypt/live/mydomain.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/mydomain.example.com/privkey.pem;

  location ^~ /.well-known {
    alias /var/www/letsencrypt/.well-known;
  }
  .
  ...
}

e riavviare il server.

Adesso visitando l'url *https://mydomain.example.com * vedremo comprarire il lucchetto verde.

Automatizzare il renew del certificato

Il certificato ottenuto ha una scadenza prestabilita, solitamente 90 giorni, al termine del quale non sarà più verificato.

Per rinnovare il certificato si utilizza un'altro comando:

  $ /root/certbot/certbot-auto certonly --webroot -w /var/www/letsencrypt -d mydomain.example.com --no-interactive --keep-until-expiring

che rinnova il certificato relativo al dominio fornito se mancano meno di 30 giorni alla scadenza di quello attuale.

A questo punto possiamo schedulare una procedura di rinnovo automatica: inseriamo queste righe dentro al file '/etc/cron.daily/renew'

#! /bin/bash
/root/certbot/certbot-auto certonly --webroot -w /var/www/letsencrypt -d mydomain.example.com --no-interactive --keep-until-expiring
service nginx restart

e magicamente quando saremo a 30 giorni dalla scadenza, avremmo un certificato nuovo di zecca.

Volendo si può ridurre la frequenza a un tentativo di rinnovo settimanale, ma eviterei quello mensile, perché nell'ipotesi sfortunata (conoscete la legge di Murphy, vero?) nel caso di fallimento dello script per qualunque motivo potreste ritrovarvi con un lucchetto rosso sulla vostra homepage.

Infine potrebbe capitare che abbiate la necessità di rinnovare instantaneamente il certificato. In quel caso sostuituite l'opzione '--keep-until-expiring' con l'opzione '--renew-by-default' che non effettua il controllo dei 30 giorni alla scadenza ma lo rinnova immediatamente (attenzione a non abusarne: l'api dell'ACME permette di ottenere un massimo di 7 certificati ogni settimana)

Come qualcuno avrà notato, si utilizza sempre lo script certbot-auto (che installa tutti i pacchetti necessari) invece che l'eseguibile certbot installato sulla macchina. Il motivo è semplice: al momento stanno iniziando ad uscire i pacchetti da repository per vari sistemi operativi, con i relativi aggiornamenti delle dipendenze, quindi l'uso del repository git sta iniziando a generare warning circa la mancanza di aggiornamenti. certbot-auto provvederà nel caso ad aggiornare qualche dipendenza (ovviamente se voleve aggiornare completamente dovete fare un update manuale del repository git).

Piccola considerazione

FINALMENTE!!!

Sempre più siti si stanno spostando sull'HTTPs per garantire la privacy delle informazioni trasmesse. Il dover pagare dei certificati abbastanza profumatamente (si parla anche di un centinaio di € annuali) iniziava quasi a odorare di pizzo, in quanto requisito ormai fondamentale.

L'unica insicurezza che personalmente noto è il fatto che, durante la fase di autenticazione del dominio dal certbot, un attacco Man-in-the-middle possa intercettare la richiesta di un nuovo certificato. Ma dato che la procedura dura tipo 5-6 secondi ogni 2 mesi circa, credo che stiamo parlando di una probabilità remota quanto il generare una stringa casuale e ritrovarsi con un certificato valido.