Vai al contenuto principaleVai al footer
tools
|
16 marzo 17

Https everywhere: perché non metterlo su tutti i progetti?

Il 2017 sembra dare molto peso ai siti che supportano l'Https, in particolare Google darà un po' di visibilità in più ai siti 'sicuri' mentre i principali browser faranno comparire una notifica di 'Pagina non sicura' quando rileveranno dei login sotto http. Vediamo come configurare l'Https sulle differenti architetture per siti web.

Update Marzo 2017

Heroku ha integrato il servizio Let's Encrypt nella sua architettura, quindi la sezione Heroku è stata rivisitata

Nei seguenti esempi si suppone di voler ottenere un certificato ssl per il dominio www.example.com.

SNI: Server Name Indication

Nel protocollo ssl standard, un pacchetto contenente delle informazioni criptate arriva al server tramite un indirizzo IP. Il server utilizza il certificato ssl associato a all'istanza del server su quell'indirizzo IP e stabilisce la connessione. La comunicazione è sicuramente criptata, ma potremmo essere arrivati a quell'IP tramite un altro nome di dominio.

Il classico esempio è quando abbiamo un certificato ssl per www.example.com e permettiamo anche a example.com di raggiungere il server. Digitando quest'ultimo ci troveremo di fronte ad un alert:

.

Ora, se sei un nerd stile me, apri il certificato, noti che il problema era solo un errata configurazione dei DNS e prosegui, ma un utente medio che visita il portale della propria banca magari si farà qualche problema e chiuderà la finestra.

Supponiamo quindi che il nostro sistema preveda un'unica istanza di server in ascolto su un certo indirizzo IP con un unico certificato ssl da fornire. N domini significherebbero N indirizzi IP, cosa non sempre realizzabile, almeno finché non avremo IPV6 ovunque.

Per ovviare a questo limite i tutti browser recenti hanno implementato un nuovo protocollo: l'SNI. In questa nuova modalità il browser manda in chiaro l'hostname a cui vuole connettersi. Nel sistema standard l'hostname sta negli header della richiesta, che sono criptati. A questo punto possiamo avere anche molti server in ascolto con hostname differenti sullo stesso indirizzo IP: avere in chiaro l'hostname ci permette di ricevere il certificato corretto.

Tutto molto bello, tranne per una piccola cosa: i browser più vecchi non sanno gestire questo tipo di ssl (ma stiamo parlando di browser per symbian e browser per Blackbarry OS7 o precedente.)

##Cloudflare

Cloudflare offre una soluzione universale per la gestione di certificati SSL (in particolare si potrà utilizzare come alternativa a tutti i casi che affronteremo in questo articolo).

Cloudflare è una CDN che viene utilizzata per effettuare un caching delle pagine. Per configurarla è necessario che il record DNS di www.example.com punti verso le macchine della CDN. Poi si istruisce la CDN su quale sia l'indirizzo del server che ospita il nostro sito/applicazione.

Il gioco sta tutto qui: essendo il nome di dominio collegato direttamente alla CDN sarà lei stessa a doverci fornire il certificato ssl.

Supponendo di voler mettere una CDN davanti ad un sito hostato su Amazon S3 sono necessari i seguenti step:

  1. Trasferire la gestione del DNS a Cloudflare (bisogna andare nella dashboard del register del dominio e settare come server DNS quelli di Cloudflare
  2. Nel pannello di configurazione DNS di Cloudflare settiamo la normale regola DNS verso il server (record A o CNAME verso il server effettivo)
  3. Nel pannello Crypto di Cloudflare abilitare l'Https verso il client.

Dal momento che abbiamo spostato la gestione DNS del nostro dominio su Cloudflare, abbiamo dato la garanzia di essere gli effettivi amministratori del dominio, condizione sufficiente per poter ricevere un certificato ssl.

A questo punto abbiamo un certificato valido dal browser a Cloudflare, lui internamente gestisce la comunicazione con il server originale.

Come si può notare non è stato fatto alcun intervento lato server, e questo è il grande vantaggio di questa architettura. Il problema principale di questa architettura è la necessità di trasferire a Cloudflare la gestione del DNS, cosa che, in particolare quando il dominio non è di propria proprietà, è molto difficile realizzare.

Siti Statici su Amazon S3

Amazon S3 offre la funzionalità di hostare nei suoi bucket pagine HTML, permettendo di avere una sorta di server web per file statici. Nel caso di Cantiere, generiamo i siti statici tramite Middleman e il nostro CMS per siti statici DatoCMS.

Il mondo di AWS comprende un servizio di Certification Authority che rilascia certificati ssl da utilizzare internamente alla piattaforma: Amazon Certificate Manager.

Per generare un certificato è sufficiente fornire il nome del dominio. Mentre Cloudflare da per scontato che sia l'admin del dominio a settare il DNS resolver, Amazon non possiede informazioni a priori per la certificazione: l'autenticazione dell'admin del dominio avviene tramite una email mandata ad un set di indirizzi noti (admin@example.com, administrator@example.com) e a quelli dell'Admin rilevabili dal servizio whois. All'interno di questa mail c'è un link di attivazione: seguite il link e Certificate Manager considererà questo HIT come prova di essere admin del dominio.

Ottenuto il certificato, non sarà possibile utilizzarlo con S3 direttamente. Dobbiamo quindi attivare una distribuzione di AWS Cloudfront, il servizio di CDN interno.

Una volta che è stata creata la distribuzione impostiamo l'url pubblico del bucket (mybucket.s3-website-eu-west1.amazonaws.com) come Origin, nella sezione General scegliamo il certificato precendentemente creato da Certificate Manager e in Behaviour impostiamo una Policy (a meno di esigenze particolari, la Policy HTTP => HTTPS va più che bene).

Rispetto a Cloudflare, qui abbiamo il vantaggio di non dover essere i gestori del dominio. È sufficiente che l'admin segua il link nella mail per ottenere un certificato valido, ma la cosa, anche se contenuto, ha un certo costo; Cloudflare offre il servizio nel piano Free, Cloudfront invece ha sempre un costo proporzionale alla banda trasferita.

Server personale

Nel caso in cui si abbia la necessità di avere un server personale (ad esempio DigitalOcean o Linode) possiamo sfruttare il protocollo ACME tramite il servizio LetsEncrypt.

Acme è un protocollo che automatizza la generazione e il rinnovo dei certificati ssl. Il meccanismo è molto banale:

  1. Il client richiede al server ACME una richiesta per ottenere un certificato per un dominio.
  2. ACME risponde alla richiesta con un challenge, composto da un filename e un contenuto.
  3. Il client predispone il server affinché al path richiesto da ACME sia presento il contenuto atteso.
  4. Il client dice ad ACME di verificare la richiesta.
  5. ACME va all'indirizzo www.example.com/filename e controlla se il contenuto è quello voluto.
  6. Se la verifica avviene con successo, il client richiede il certificato e ACME fornisce un certificato completo (certificato, chiave privata, chain e fullchain).

Come si può notare client e server potrebbero benissimo essere sia la stessa macchina che due macchine differenti. L'unica garanzia che ACME vuole è che il richiedente del certificato dimostri di avere accesso in scrittura sulla macchina associata al dominio da certificare.

Una guida completa alla configurazione su un server è disponibile a questo link.

Nel caso di server personale questo permette di avere fisicamente dei certificati ssl senza tutte le problematiche associate ai classici Certificatori (costi, complessità nell'autenticazione del gestore del dominio). Ovviamente sarà nostra cura gestire lo scheduling della procedura di rinnovo, ma avendo già accettato di farsi carico della sistemistica di un server personale il costo di gestione dei certificati, a mio parere, è esiguo.

Heroku Platform

La piattaforma Heroku è sempre stata un punto di riferimento per il deploy delle applicazioni Rack. Niente oneri sistemistici: ogni app ha un repository git, si imposta questo repository come remote e con un push si deploya l'applicazione (Heroku spacchetta il repo e tira su tutto l'occorrente per eseguire quel tipo di app).

L'ssl su Heroku è stato da sempre oggetto di dibattito. Essendo una piattaforma Cloud non è dato sapere a priori l'indirizzo IP della macchina, dato che viene gestito dalla loro infrastruttura. A differenza di Cloudflare o AWS, non fornivano un meccanismo automatizzato di certificazione e tutto era protetto dal loro certificato che copre i domini *.herokuapp.com.

Le soluzioni erano solo 2:

  1. Cloudflare davanti ad Heroku
  2. Comprarsi un certificato da terze parti e abilitare il plugin Heroku che forniva l'Endpoint necessario a fornire quel certificato ssl (alla modica cifra di 20$/mese, più il prezzo del certificato).

Da qualche mese è stato abilitato il supporto SNI gratuitamente sulla piattaforma (a patto che si utilizzi un Dyno a pagamento), rendendo possibile utilizzare dei certificati di terze parti gratuitamente.

Combinato con Let's Encrypt e l'ausilio di alcuni plugin (il tool Sabayou per applicazioni generiche o la gemma Letsencrypt-rails-heroku per le applicazioni Rails), è stato possibile integrare nell'archiettura dell'applicazione un sistema di certificazione automatico.

Parlo al passato in quanto pochi giorni fa (21 Marzo 2017) Heroku ha annunciato di aver integrato nella loro piattaforma un servizio di certificazione automatizzata sfruttando proprio Let's Encrypt, senza l'ausilio di tool esterni.

E' sufficiente abilitare il servizio tramite la dashboard dell'app o con il comandi

heroku certs:auto:enable --app nome-app

per abilitare il servizio.

Adesso basta aggiungere i domini di cui abbiamo bisogno tramite il comando

heroku domains:add www.example.com --app app-name
heroku domains:add example.com --app app-name

ed il servizio provvederà a richiedere a Let's Encrypt il certificato corretto.

Configurazione DNS

L'unica cosa di cui tenere conto è la seguente: dal momento che si decide di utilizzare un certificato custom dobbiamo cambiare l'impostazione del DNS. Prima il DNS aveva questa regola

www.example.com. CNAME my-app.herokuapp.com.

ma questa configurazione fornirà sempre il certificato wildcard per tutti i sottodomini herokuapp.com (*.herokuapp.com).

Affinché Heroku serva il nuovo certificato ssl, bisogna utilizzare questa regola

www.example.com. CNAME www.example.com.herokudns.com.

Https Everywhere

Come abbiamo visto esistono diversi meccanismi per avere delle connessioni sicure che non hanno costo di acquisto di certificati e costi veramente bassi in termini di risorse temporali per configurare gli ambienti.

A questo punto la domanda è diventata "Perché non dovrei mettere sotto HTTPS tutti i miei progetti"? :)