Certificati SSL gratis, grazie a Let’s Encrypt

Il titolo sembra uno spot pubblicitario che qualcuno su internet potrebbe usare per attirare clienti e poi scoprire che di gratis non c’è un bel niente. D’altronde, come ho già detto nel mio articolo “cosa sono i certificati SSL“, per ottenere un certificato SSL si deve sostenere un costo che varia a seconda del tipo di certificato. Ma il web è un luogo pieno di possibilità e grazie alla comunità open e a tutti i loro sostenitori è possibile trovare un sistema affidabile, automatico e assolutamente sicuro per ottenere gratuitamente i certificati SSL di tipo Single Domain.

Let’s Encrypt fa tutto questo e lo fa anche molto bene.

Chi è Let’s Encrypt?

Let’s Encrypt è una CA ossia una Certificate Authority. È già nota praticamente a tutti i più diffusi browser internet e quindi la sua chiave pubblica è già disponibile e pronta all’uso (per dubbi consiglio la lettura del mio articolo “cosa sono i certificati SSL“). Le sue sponsorizzazioni sono di tutto rispetto, parliamo di Mozilla, Cisco, OVH, EFF, ma anche brand più noti come Facebook, Google e davvero molti altri.

Come una qualsiasi CA rilascia certificati digitali che permettono di rendere sicura la navigazione sul proprio sito internet, ma lo fa in maniera del tutto automatica e con tempi ridotti a pochi secondi. Questa sua forza però è anche una limitazione perché l’automatismo non può garantire la proprietà del dominio da parte di un’azienda reale e quindi non può emettere certificati Extended Validated.

Sono mossi dalla volontà, ormai condivisa da molti addetti ai lavori, di rendere il web un posto più sicuro, dove tutte le informazioni trasmesse siano cifrate e per questo hanno cercato di rendere il più semplice e immediato possibile un processo che normalmente è dispendioso sia in termini di tempo che di denaro.

Let’s encrypt è affidabile?

La loro affidabilità è del tutto comparabile a quella di qualsiasi altra CA del web, ma con una limitazione. Trattandosi di un servizio offerto gratuitamente non può stipulare con i suoi clienti un’assicurazione che li rimborsi in caso di manomissione o violazione della sicurezza del certificato. A parte questo però l’affidabilità generale di Let’s Encrypt è di assoluto livello.

Ottimo! Ma come funziona?

Come loro stessi dicono, “per ottenere un certificato per il tuo dominio da Let’s Encrypt devi dimostrare di averne il controllo” e per fare questo esistono alcuni metodi che differiscono a seconda del tipo di accesso e controllo che si ha sul proprio sito internet e sul server che lo ospita. Alla base è però sempre presente l’uso di un software basato su protocollo ACME; quello da loro consigliato è certbot.

Si dispone di accesso shell amministrativo al server

Nel caso in cui si abbia un accesso amministrativo alla shell del proprio web server è possibile usare il client certbot ed in pochi passi ottenere il certificato pronto e installato sul server.

Notare che negli esempi riportati si suppone di essere loggati come root (ho usato il # appositamente), nel caso si preferisca restare loggati con un utente standard allora si deve anteporre a tutte le istruzioni il comando “sudo“.

Come installare un certificato SSL con Let’s Encrypt e certbot su Debian 8

Prima di tutto va installato certbot e per farlo dobbiamo aggiungere il backport repository sul server

# echo 'deb http://ftp.debian.org/debian jessie-backports main' | tee -a /etc/apt/sources.list.d/backports.list

Aggiorniamo quindi le informazioni sui pacchetti

# apt-get update

Ora installiamo il pacchetto python-certbot-apache.
Nota bene: siccome stiamo usando backports è consigliato installare solo il pacchetto desiderato e non usare il repository per scopi generici a causa delle minori garanzie di compatibilità offerte dai pacchetti backport. Per evitare rischi si userà quindi il parametro (-t) seguito dal nome specifico del repository backport.

# apt-get install python-certbot-apache -t jessie-backports

Ora certbot è pronto all’uso.

Certbot si basa sostanzialmente sull’uso di alcuni plugin ciascuno dei quali accetta diversi parametri specifici. Nel caso più semplice il plugin “–apache” è in grado di leggere da solo i file di configurazione del server e di proporci la lista dei domini installati sulla macchina tra cui scegliere.

Se abbiamo un server con un singolo dominio avremo quasi certamente editato il file /etc/apache2/sites-available/000-default.conf che sarà simile a questo

<VirtualHost *:80>
 . . .
 ServerName esempio.com
 ServerAlias www.esempio.com
 . . .
</VirtualHost>

Nel caso invece di molti domini sullo stesso server avremo editato il file di configurazione del dominio specifico (lo troviamo nella directory “/etc/apache2/sites-available/“) e potrebbe chiamarsi www.esempio.it e dovrebbe essere simile a questo

<VirtualHost *:80>
 . . .
 ServerName esempio.it
 ServerAlias www.esempio.it
 ServerAdmin webmaster@localhost
 DocumentRoot /var/www/www.esempio.it
 . . .
</VirtualHost>

Certbot leggerà da solo la configurazione di questi file e li modificherà e duplicherà per abilitare le necessarie direttive all’uso dei certificati SSL.

Nel caso la configurazione sia corretta e apache sia regolarmente attivo e funzionante (ricordo che ad ogni modifica di questi file possiamo verificarne la validità usando “apache2ctl configtest” e se tutto ok ricaricarli nel server attivo usando “systemctl reload apache2” o riavviare il server con “systemctl restart apache2“) possiamo procedere con l’installazione del certificato

# certbot --apache

Certbot leggerà la configurazione del server apache e produrrà un output nel quale ci viene chiesto per quale dominio richiedere il certificato

Saving debug log to /var/log/letsencrypt/letsencrypt.log

Which names would you like to activate HTTPS for?
-------------------------------------------------------------------------------
1: esempio.com
2: esempio.it
3: www.esempio.it
4: www.esempio.com
-------------------------------------------------------------------------------
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):

Inseriti i numeri separati da virgola corrispondenti ai domini dei quali si vuole richiedere il certificato si da INVIO e si avvia il processo di generazione e autoinstallazione dei certificati nel server. Ci verrà chiesta una casella di posta per eventuali notifiche e il ripristino di chiavi perse e ci verrà domandato se vogliamo che il sito sia accessibile sia in http che in https. Salvo particolari esigenze è consigliabile selezionare solo https.

A lavoro terminato troveremo:

  • i nuovi certificati nella directory /etc/letsencrypt/live
  • nella directory /etc/apache2/sites-available/ i file di configurazione dei domini selezionati modificati per inoltrare la navigazione sempre all’https
  • all’interno della directory /etc/apache2/sites-available/ un nuovo file di configurazione con un nome simile a questo www.esempio.it-le-ssl.conf per ciascun dominio selezionato, contenente tutte le direttive per l’accesso al sito in https e l’uso dei certificati opportuni
  • la nuova configurazione già caricata e funzionante nel server web

Un test fatto a questo indirizzo ci confermerà la qualità del certificato installato

https://www.ssllabs.com/ssltest/analyze.html?d=www.esempio.it
Procedura alternativa

La procedura appena descritta si basa sulla presenza del server web attivo e funzionante, ed una verifica dell’effettiva presenza del dominio sul nostro server web basata su protocollo ACME e TLS-SNI-01 challenge (verifica in https), ma se ci troviamo in circostanze particolari è possibile richiedere il certificato usando il plugin “standalone” di certbot. In questa maniera, per la verifica del possesso del dominio, certbot tenta di instaurare tra il server Let’s Encrypt e la macchina locale una connessione sfruttando la porta 80 o la 443, ma può essere certbot a rispondere su queste porte e non apache. Per questo motivo l’eventuale presenza di apache attivo disturba l’operazione (usualmente lavora proprio su queste porte) e quindi deve essere spento e riacceso al termine.

Chiariamo bene come funziona la verifica del dominio

La verifica dell’effettiva presenza del dominio sul server richiedente il certificato è il punto nodale del rilascio dei certificati Single Domain. Per questo certbot contatta (in maniera del tutto cifrata) Let’s Encrypt e si fa dare un token monouso (una stringa di caratteri casuali tipo noQZ8AneuP1DEaq3HFFFzgVH0styP82W0ihcz4tf4Og) che viene inserito in un file con lo stesso nome e posizionato all’interno della directory fisica del sito puntato dal dominio.
A questo punto Let’s Encrypt contatta il nostro server ad un indirizzo che solo lei può conoscere, del tipo: http://www.esempio.it/.well-known/acme-challenge/noQZ8AneuP1DEaq3HFFFzgVH0styP82W0ihcz4tf4Og oppure https://www.esempio.it/.well-known/acme-challenge/noQZ8AneuP1DEaq3HFFFzgVH0styP82W0ihcz4tf4Og.
Se riesce a leggere il file e il token inserito corrisponde a quello rilasciato allora la verifica va a buon fine e viene autorizzato il rilascio del certificato.

La verifica su http (mediante l’uso della porta 80 detta HTTP-01 challenge) o su https (mediante l’uso della porta 443 detta TLS-SNI-01 challenge) dipende dai parametri passati a certbot:

  • HTTP-01 challenge su porta 80 se non imposto –preferred-challenges oppure se imposto “–preferred-challenges http
  • TLS-SNI-01 challenge su porta 443 se imposto “–preferred-challenges tls-sni

Il comando per ottenere i certificati installati su apache usando il plugin standalone e una verifica HTTP-01 challenge è

# certbot --installer apache --authenticator standalone -d www.esempio.it --pre-hook "systemctl stop apache2" --post-hook "systemctl start apache2"

L’output a video che si ottiene è simile a questo

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
Running pre-hook command: systemctl stop apache2
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for www.esempio.it
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0001_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0001_csr-certbot.pem
Running post-hook command: systemctl start apache2
Created an SSL vhost at /etc/apache2/sites-available/www.esempio.it-le-ssl.conf
Deploying Certificate to VirtualHost /etc/apache2/sites-available/www.esempio.it-le-ssl.conf
Enabling available site: /etc/apache2/sites-available/www.esempio.it-le-ssl.conf

Please choose whether HTTPS access is required or optional.
-------------------------------------------------------------------------------
1: Easy - Allow both HTTP and HTTPS access to these sites
2: Secure - Make all requests redirect to secure HTTPS access
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

Slezionando 2 otteniamo

Redirecting vhost in /etc/apache2/sites-available/www.esempio.it.conf to ssl vhost in /etc/apache2/sites-available/www.esempio.it-le-ssl.conf

-------------------------------------------------------------------------------
Congratulations! You have successfully enabled https://www.esempio.it

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=www.esempio.it
-------------------------------------------------------------------------------

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
 /etc/letsencrypt/live/www.esempio.it/fullchain.pem. Your
 cert will expire on 2018-04-17. To obtain a new or tweaked version
 of this certificate in the future, simply run certbot again with
 the "certonly" option. To non-interactively renew *all* of your
 certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

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

E con questo possiamo dire di aver concluso.

Il nostro certificato ora è attivo e per le impostazioni scelte siamo certi che accedendo al sito verremo sempre dirottati alla versione in https.

Rinnovo del certificato

I certificati rilasciati da Let’s Encrypt hanno una durata di 90 giorni dopodiché va eseguito questo comando per il rilascio di un nuovo certificato

# certbot renew

Se lo eseguiamo adesso il software verificherà semplicemente la scadenza avvisandoci che non è necessario rinnovare alcun certificato

Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/www.esempio.it.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal

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

Siccome la procedura di rinnovo del certificato viene presa in carico solo quando mancano 30 giorni alla scadenza, possiamo automatizzare il tutto con crontab

# crontab -e

Se ci viene chiesto scegliamo l’editor che preferiamo e poi inseriamo questa riga

. . . 
30 2 * * 1 /usr/bin/certbot renew >> /var/log/le-renew.log

Ogni lunedì (giorno 1 della settimana) alle ore 02:30 verrà eseguito il renew del certificato e il suo output loggato nel file /var/log/le-renew.log.

Non si dispone di un accesso shell

Se non si dispone di un accesso shell ci si potrebbe trovare nel caso più semplice dato che il pannello di gestione del nostro dominio potrebbe darci la possibilità di scegliere Let’s Encrypt come CA per la generazione del certificato. In questo caso basterebbe lanciare la procedura e in pochi secondi avremmo il nostro sito perfettamente funzionante in https.

In alternativa si dovrebbe chiedere al proprio maintainer di fare la procedura al posto nostro o di aggiungere Let’s Encrypt tra quelli disponibili, ma è una possibilità piuttosto remota.

L’unico altro modo è quello di scaricare certbot sul proprio computer e avviarlo in modalità manuale facendogli generare un certificato per il nostro sito che poi dovremo caricare sul server tramite un’apposita funzione che dovremmo trovare nell’interfaccia di gestione del dominio. L’operazione manuale non è difficile ma prevede comunque di poter dimostrare il controllo del dominio. Per farlo esistono due opzioni: una mediante l’uso di una connessione HTTP che dovrà puntare ad uno specifico file che dovremo mettere in una sottodirectory della root del sito e l’altra mediante l’aggiunta di un record TXT nella configurazione del DNS.

Per eseguire certbot in maniera manuale si usa questo comando

certbot certonly --manual

e da qui vanno seguite passo passo tutte le sue indicazioni.

Link utili
  • Si consiglia di vedere questa pagina perché contiene tutte le opzioni di installazione dei certificati Let’s Encrypt fatte mediante certbot.
  • Questo link invece permette di monitorare lo stato dei server Let’s Encrypt.