Il cielo sopra il Carlino in https grazie a Let's Encrypt

In un anticipo di pulizie primaverili, ho deciso di consolidare i miei server e spostare sul mio server casalingo i siti ancora rimasti su un hosting condiviso.

Una delle cose che mi sembravano importanti da fare in questo trasloco è dare un certificato SSL a tutti i miei siti in modo da poterli navigare in https. Solitamente ho sempre gestito questa cosa in modo artigianale e solo per i siti che uso a scopo unicamente personale (ad esempio ownCloud), generando un certificato e installandolo sui miei client. Il risultato è appena funzionale. Il motivo principale per non adottare un vero certificato è che i certificati costano.

Da alcune settimane è in beta un servizio che fornisce un certificato gratuito riconosciuto da tutte le certification authority: Let's Encrypt. Non solo è gratuito, è anche automatico, nel senso che c'è uno script che consente di generare il certificato e di aggiornarlo periodicamente. La durata dei certificati di Let's Encrypt è infatti di 90 giorni e sarebbe impossibile gestirli manualmente.

Mi sono cimentato dunque nell'utilizzare un certificato per Il cielo sopra il Carlino per testarne il funzionamento. Spoiler: è stato davvero molto facile e l'intera procedura non ha preso più di 20 minuti, compreso documentare i vari passaggi.

Nel mio caso utilizzo un web server nginx su Ubuntu 14.04. A quanto pare Let's Encrypt non è ancora pacchettizzato per questo sistema operativo, quindi ho cercato una guida specifica per il mio assetto. Potete provare a cercare alternative nella documentazione ufficiale.

Ho cominciato con il clone della repository git:

$ sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt

Alla base del metodo di assegnazione del certificato c'è l'identificazione del server che viene fatta dall'autorità tramite una chiamata particolare al web server su cui vogliamo installare il certificato. Ci sono vari modi per fare questo. Quello che userò è spegnere nginx e lanciare un serverino standalone fornito da Let's Encrypt. Infatti non c'è ancora il plugin per nginx.

$ sudo service nginx stop
$ cd /opt/letsencrypt
$ ./letsencrypt-auto certonly --standalone

L'ultimo comando è uno script che aggiorna una serie di pacchetti tramite il gestore di pacchetti del sistema operativo e avvia l'installazione vera e propria.

Bisogna fornire la propria email (che comunque non comparirà nel certificato) e accettare le condizioni di utilizzo. Per le condizioni ho dovuto copiarmi il link a mano, per cui lo riporto per comodità: https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf.

Per ora ho registrato soltanto ilcielosoprailcarlino.gamea.me, ma si possono inserire più domini nello stesso certificato. Sembra che non sia prevista la possibilità di certificare domini tramite wildcard (ad esempio tutti i terzi livelli di gamea.me), data la facilità con cui è possibile richiedere nuovi certificati.

Il certificato è stato generato senza problemi:

IMPORTANT NOTES:

  • If you lose your account credentials, you can recover through
    e-mails sent to *********.

  • Congratulations! Your certificate and chain have been saved at
    /etc/letsencrypt/live/ilcielosoprailcarlino.gamea.me/fullchain.pem.
    Your cert will expire on 2016-04-29. To obtain a new version of the
    certificate in the future, simply run Let's Encrypt again.

  • Your account credentials have been saved in your Let's Encrypt
    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 Let's
    Encrypt so making regular backups of this folder is ideal.

  • 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

Faccio quindi il backup come suggerito:

$ sudo rsync -Paz /etc/letsencrypt/ ~/Backup/letsencrypt

Ora bisogna far utilizzare il nuovo certificato a nginx. Ecco la mia configurazione:

server {
	listen 443 ssl;
	server_name ilcielosoprailcarlino.gamea.me;

	ssl_certificate /etc/letsencrypt/live/ilcielosoprailcarlino.gamea.me/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/ilcielosoprailcarlino.gamea.me/privkey.pem;
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
	ssl_prefer_server_ciphers on;
	ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

	root /usr/share/nginx/html;
	index index.html index.htm;

	location / {
		proxy_pass http://localhost:2368;
	}
}

server {
    listen 80;
    server_name ilcielosoprailcarlino.gamea.me;
    return 301 https://$host$request_uri;
}

Riavvio nginx:

$ sudo service nginx restart

Ed ecco il risultato!

Obiettivo fra 3 mesi: configurare il rinnovo automatico e fare una donazione per sostenere questa iniziativa davvero importante!


EDIT: Per verificare la bontà della configurazione di nginx si può usare SSL Server Test come suggerito da poluz nei commenti. Nel mio caso Avevo un voto C perché risultava ancora attivo SSL 3.0, nonostante non fosse elencato nella configurazione. Utilizzando il comando

$ openssl s_client -connect ilcielosoprailcarlino.gamea.me:443 -ssl3

viene fuori che c'era un altro virtual host in ssl con le impostazioni di default di nginx che prevedono anche SSL 3.0, per cui bisogna prestare attenzione a inserire ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ovunque. L'indizio per la soluzione viene da ServerFault.

Ora il risultato è una bella B. C'è ancora spazio per migliorare!