Installare un certificato Let’s Encrypt da linea di comando

Con Certbot possiamo installare un certificato SSL/TLS di Let’s Encrypt da linea di comando. In questo articolo vedremo come fare e come rinnovare il certificato automaticamente

Ormai da tempo una cricca di gangsta, tra cui Google, al fine di rendere più sicuro il web, spinge i siti a trasmettere informazioni via HTTPS. Per farlo è necessario installare un certificato SSL (in realtà si chiama TLS, ma tant’è). Il certificato permette di dare un’identità ad un sito web, cioè indica che stiamo comunicando in maniera privata con il server, senza che nessuno possa spiare la nostra conversazione. E chi lo garantisce? Un’entità esterna, detta Autorità Certificatrice (CA).

Fino a poco tempo fa, il certificato non era mai gratis, ma oggi esistono veri e propri angeli custodi, come il caro e famoso Let’s Encrypt, che è appunto una CA.

Per installare il certificato viene in aiuto Certbot, con cui è possibile sollevare un certificato TLS da linea di comando in pochi secondi. La maggior parte degli articoli che ho trovato su Internet spiega come installare il certificato da pannelli di gestione del server, come cPanel e Plesk. Sono due click messi in croce. Invece noi vogliamo farlo da linea di comando via SSH per sentirci grandi sistemisti (ma soprattutto perché probabilmente non abbiamo un pannello di gestione del server), per questo motivo ho scritto una guida.

Installare il certificato

Innanzitutto apriamo una finestra da terminale e colleghiamoci in SSH al server. Poi rechiamoci sul sito di Certbot.

Sito di Certbot

Quindi selezioniamo il webserver e il sistema operativo del server dai menù a tendina. Ad esempio Apache e Ubuntu 16.04 xenial. Se non ricordate la versione esatta, presupponendo che siate su una macchina Debian based (come Ubuntu), digitate:

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.1 LTS
Release: 16.04
Codename: xenial

Et voilà.

Selezionando quanto richiesto, vengono mostrati i comandi da eseguire (uno per volta) manualmente sul server. In pratica prendiamo il repository mantenuto da Certbot ed installiamo il bot che si occuperà di creare il certificato.

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install python-certbot-apache
$ sudo certbot --apache

Con l’ultimo comando abbiamo lanciato la procedura per installare il certificato e abbiamo dato implicitamente il consenso di installare le chiavi necessarie al certificato nella configurazione di Apache. Se per qualche ragione non volete che certbot metta le mani nella vostra configurazione, potete aggiungere il comando certonly, che si limiterà a generare l’occorrente senza però installarlo in Apache. Chiaramente è un lavoro che dovreste poi fare a mano.

$ sudo certbot --apache certonly

Nel mio caso, non avendo chissà quali esigenze, ho eseguito il comando senza certonly. Vi verrà chiesto di inserire delle informazioni, come un indirizzo e-mail (per aggiornamenti di sicurezza o richieste urgenti di rinnovo del certificato, di cui parleremo più tardi), di accettare i termini di servizio (e dovete farlo, naturalmente) e il permesso di iscrivervi alla newsletter di Electronic Frontier Foundation (gli autori di Certbot). Passiamo alla roba interessante. Arriverete ad un punto analogo a questo:

Which names would you like to activate HTTPS for?

-------------------------------------------------------------------------------

1: zombieprocess.it

-------------------------------------------------------------------------------

Select the appropriate numbers separated by commas and/or spaces, or leave input

blank to select all options shown (Enter 'c' to cancel): __

Nel mio caso ho inserito 1, corrispondente all’unico dominio presente e premendo invio genero il certificato. Teniamolo a mente, perché ci ritorneremo tra un attimo.

Certbot mi dice che ha creato una nuova configurazione di Apache, relativo alla porta 443 (usata da TLS), nel path di default ovvero /etc/apache2/sites-available/zombieprocess-le-ssl.conf

A questo punto viene chiesto se desideriamo che venga effettuato il redirect da HTTP a HTTPS o meno:

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.

-------------------------------------------------------------------------------

1: No redirect - Make no further changes to the webserver configuration.

2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for

new sites, or if you're confident your site works on HTTPS. You can undo this

change by editing your web server's configuration.

-------------------------------------------------------------------------------

Select the appropriate number [1-2] then [enter] (press 'c' to cancel): __

Prestate attenzione. Forse sapete già che è buona norma farlo, ma probabilmente non è questo il momento più idoneo. Se per qualche motivo l’installazione del certificato dovesse andare male, potreste creare un disservizio ai vostri utenti, perché verrebbe fatto un redirect a HTTPS, che però non è abilitato. Quindi, a meno che il vostro non sia un sito in costruzione, consiglio di specificare l’opzione numero 1.

Se tutto è andato bene vedrete un messaggio positivo e tutte le informazioni utili annesse, come i path in cui sono stati salvati il certificato e le chiavi. Chiaramente, se avete usato certonly dovrete creare voi la configurazione di Apache della porta 443 e inserire i path del certificato e delle chiavi necessari.
Insomma, ora dovrebbe funzionare già tutto, ma se siete giunti a questo punto e le cose non sono andate bene non disperate. È stato così anche per me. Infatti, andando su https://www.zombieprocess.it, il browser mi dice che la connessione non è sicura e l’errore è piuttosto banale. Il mio sito viene forzato ad avere quel www davanti, ma io ho sollevato il certificato per zombieprocess.it, non per www.zombieprocess.it. Facciamo una verifica veloce con curl:

$ curl --head https://www.zombieprocess.it

curl: (51) SSL: certificate subject name (zombieprocess.it) does not match target host name 'www.zombieprocess.it'

Ecco l’errore. Invece, provando a farlo sull’indirizzo corretto otteniamo:

$ curl --head https://zombieprocess.it

HTTP/1.1 301 Moved Permanently

Date: Sat, 23 Dec 2017 22:46:11 GMT

Server: Apache/2.4.18 (Ubuntu)

Location: https://www.zombieprocess.it/

Content-Type: text/html; charset=UTF-8

Riceviamo un 301, che significa che il server ha effettuato un redirect automatico a www (ed è giusto che sia così). Tutto come ci aspettavamo, insomma. Se ben ricordate, allo step in cui Certbot ci chiedeva di scegliere il dominio, ci veniva dato solo quello di secondo livello come unica opzione. E dunque? Per specificare il sottodominio ci viene in aiuto l’opzione -d:

sudo certbot --apache -d www.zombieprocess.it

Un paio di secondi e avremo un nuovo certificato bello e funzionante. Questa volta, l’operazione va a buon fine. Anche se di fatto non usate direttamente il dominio principale, per via del redirect, consiglio comunque di mantenere il certificato, altrimenti potreste avere problemi con il redirect alla versione con WWW.

Impostare il rinnovo automatico

È giunto il momento di parlare di rinnovo. Tutti i certificati hanno una scadenza, ma rinnovarli è semplicissimo, basta usare il comando renew. L’opzione –dry-run permette di fare una simulazione.

sudo certbot renew --dry-run

Purtroppo il certificato di Let’s Encrypt dura solo 3 mesi, perciò dovremmo fare quest’operazione con una certa cadenza. È impensabile per chiunque sano di mente farlo a manina, perciò, da grandi informatici che vogliono automatizzare tutto, inseriremo un cron job, che serve proprio per dire al server di pianificare un’azione con cadenza regolare, senza l’intervento umano. I sistemi Debian-based (quindi anche Ubuntu), hanno l’applicativo cron, di cui è possibile consultare il manuale digitando:

man cron

Nella descrizione leggiamo che cron è inserito nella directory speciale init.d, che contiene tutti gli applicativi eseguiti all’avvio del sistema. Quindi cron resta sempre attivo e ogni minuto controlla nei file crontab se ci sono job da eseguire.

Crontab di fatto è un file di testo con un formato preciso:

<min> <ora> <gio> <mes> <gds> <comando>

Dove:

  • min: minuti, da 0 a 59
  • ora: autoesplicativo, da 0 a 23
  • mes: mese, da 1 a 31
  • gds: giorno della settimana, da 0 (domenica) a 6 (sabato). Si può usare la virgola per indicare più giorni
  • comando: l’azione che vogliamo eseguire

Mettiamoci all’opera. Editiamo un file crontab digitando:

$ crontab -e

Aggiungiamo righe come queste (sta volta senza –dry-run, perché non vogliamo una simulazione):

3 4 * * 0 /usr/bin/certbot renew

5 6 * * 0 /usr/bin/certbot renew

Stiamo dicendo di fare il rinnovo del certificato tutti i giorni alle 04:03 e alle 06:05. Sembrerà strano tentare di rinnovare il certificato per ben due volte al giorno, invece di prendercela comoda (insomma, abbiamo tre mesi a disposizione), ma è Let’s Encrypt in primis che consiglia di farlo. La ragione è che, in realtà, facciamo dei “tentativi” di rinnovo, di cui la maggior parte non andrà a buon fine. Infatti, il rinnovo vero e proprio viene fatto a pochi giorni di distanza dalla scadenza effettiva. La documentazione consiglia anche di scegliere orari a caso, e così ho fatto, incentrandoli di notte, per non impegnare il server durante le ore con più traffico.

Salivamo il file. Mi preme dire che non c’è bisogno di mettere sudo davanti al comando. Ve lo dico perché ho visto soluzioni in cui si specificava la password… in chiaro. È un erroraccio da non fare mai!

Ci resta ancora una cosa da fare: il redirect, ricordate? Ora che siamo sicuri che tutto funziona possiamo farlo. Basta modificare il file di configurazione del virtual host sulla porta 80 (cioè per il sito in HTTP) e impostare il redirect sulla porta 443 (cioè HTTPS):

<VirtualHost *:80>

RewriteEngine On

RewriteCond %{HTTPS} off

RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI}

...

Riavviamo Apache:

sudo service apache2 restart

E abbiamo finito… quasi. Ricordate di seguire tutte le buone norme per una corretta migrazione ad HTTPS. Aggiungete la versione HTTPS come proprietà nella Search Console (Dashboard > selezionate la proprietà con HTTPS > ingranaggio > Impostazioni sito > scegliere) e indicatela come preferita. Indicate il cambio di protocollo anche nel pannello di Google Analytics (Dashboard > Amministratore > Impostazioni proprietà > selezionare HTTPS sotto URL predefinito), altrimenti potreste avere statistiche non rilevate. Infine, se usate WordPress, consiglio il plugin Really Simple SSL, che vi aiuta a forzare le risorse del vostro sito ad HTTPS, importante anche per evitare il triangolino giallo invece del lucchetto verde.

Questo è tutto e rendiamo ancora grazie a Let’s Encrypt, che permette di muovere il web verso una forma più sicura in pochi passaggi.

L'autore

Ciao, sono Antonio D'Amore e sono un ingegnere informatico con la passione del web. Amo l'ambiente start-up e imparare ogni giorno cose nuove