Let's Encrypt è un'autorità di certificazione gratuita e aperta sviluppata dall'Internet Security Research Group (ISRG). I certificati emessi da Let's Encrypt sono oggi considerati affidabili da quasi tutti i browser.
In questo tutorial, forniremo istruzioni dettagliate su come proteggere il tuo Nginx con Let's Encrypt utilizzando lo strumento certbot su Ubuntu 16.04.
Prerequisiti #
Assicurati di aver soddisfatto i seguenti prerequisiti prima di continuare con questo tutorial:
- Hai un nome di dominio che punta all'IP del tuo server pubblico. In questo tutorial useremo
example.com
. - Hai installato Nginx seguendo Come installare Nginx su Ubuntu 16.04.
Installa Certbot #
Certbot è un'utilità scritta in Python che può automatizzare le attività per ottenere e rinnovare i certificati SSL Let's Encrypt e configurare i server web.
Per prima cosa installa il software-properties-common
pacchetto che fornisce il add-apt-repository
strumento necessario per aggiungere PPA aggiuntivi.
Aggiorna l'indice dei pacchetti e installa software-properties-common
con:
sudo apt update
sudo apt install software-properties-common
Una volta completata l'installazione, aggiungi il repository PPA di certbot al tuo sistema utilizzando il seguente comando:
sudo add-apt-repository ppa:certbot/certbot
Aggiorna l'elenco dei pacchetti e installa il pacchetto certbot:
sudo apt update
sudo apt install certbot
Genera Strong Dh (Diffie-Hellman) gruppo #
Lo scambio di chiavi Diffie–Hellman (DH) è un metodo per lo scambio sicuro di chiavi crittografiche su un canale di comunicazione non protetto. Genera un nuovo set di parametri DH a 2048 bit per rafforzare la sicurezza:
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Se lo desideri, puoi modificare la dimensione fino a 4096 bit, ma in tal caso la generazione potrebbe richiedere più di 30 minuti a seconda dell'entropia del sistema. Ottenere un certificato SSL Let's Encrypt #
Per ottenere un certificato SSL per il nostro dominio utilizzeremo il plugin Webroot che funziona creando un file temporaneo per la convalida del dominio richiesto nel ${webroot-path}/.well-known/acme-challenge
directory. Il server Let's Encrypt effettua richieste HTTP al file temporaneo per convalidare che il dominio richiesto venga risolto nel server su cui viene eseguito certbot.
Per semplificare, mapperemo tutte le richieste HTTP per .well-known/acme-challenge
in una singola directory, /var/lib/letsencrypt
.
I seguenti comandi creeranno la directory e la renderanno scrivibile per il server Nginx.
sudo mkdir -p /var/lib/letsencrypt/.well-known
sudo chgrp www-data /var/lib/letsencrypt
sudo chmod g+s /var/lib/letsencrypt
Per evitare la duplicazione del codice, crea i seguenti due snippet che includeremo in tutti i nostri file di blocco del server Nginx.
/etc/nginx/snippets/letsencrypt.conflocation ^~ /.well-known/acme-challenge/ {
allow all;
root /var/lib/letsencrypt/;
default_type "text/plain";
try_files $uri =404;
}
/etc/nginx/snippets/ssl.confssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 30s;
add_header Strict-Transport-Security "max-age=15768000; includeSubdomains; preload";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
Lo snippet sopra include le cippatrici consigliate da Mozilla, abilita OCSP Stapling, HTTP Strict Transport Security (HSTS) e applica poche intestazioni HTTP incentrate sulla sicurezza.
Una volta creati gli snippet, apri il blocco del server di dominio e includi il letsencrypt.conf
snippet come mostrato di seguito:
server {
listen 80;
server_name example.com www.example.com;
include snippets/letsencrypt.conf;
}
Attiva il blocco del server creando un collegamento simbolico da sites-available
a sites-enabled
:
sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/example.com.conf
Ricarica la configurazione di Nginx per rendere effettive le modifiche:
sudo systemctl reload nginx
Esegui lo script certbot con il plugin webroot e ottieni i file del certificato SSL:
sudo certbot certonly --agree-tos --email [email protected] --webroot -w /var/lib/letsencrypt/ -d example.com -d www.example.com
Se il certificato SSL viene ottenuto con successo, certbot stamperà il seguente messaggio:
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/example.com/privkey.pem
Your cert will expire on 2018-04-23. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. 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
Ora che abbiamo i file del certificato, modifica il blocco del server di dominio come segue:
/etc/nginx/sites-available/example.com.confserver {
listen 80;
server_name www.example.com example.com;
include snippets/letsencrypt.conf;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
include snippets/ssl.conf;
include snippets/letsencrypt.conf;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
include snippets/ssl.conf;
include snippets/letsencrypt.conf;
# . . . other code
}
Con la configurazione sopra stiamo forzando HTTPS e reindirizzando il www
versione del dominio al non www
versione.
Ricarica il servizio Nginx per rendere effettive le modifiche:
sudo systemctl reload nginx
Rinnovo automatico del certificato SSL #
I certificati di Let's Encrypt sono validi per 90 giorni. Per rinnovare automaticamente i certificati prima che scadano, il pacchetto certbot crea un cronjob che verrà eseguito due volte al giorno e rinnoverà automaticamente qualsiasi certificato 30 giorni prima della sua scadenza.
Poiché stiamo utilizzando il plug-in webroot di certbot una volta rinnovato il certificato, dobbiamo anche ricaricare il servizio nginx. Per farlo aggiungi --renew-hook "systemctl reload nginx"
al /etc/cron.d/certbot
file in modo che assomigli a questo:
0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew --renew-hook "systemctl reload nginx"
Per testare il processo di rinnovo, utilizza il certbot --dry-run
interruttore:
sudo certbot renew --dry-run
Se non ci sono errori, significa che il processo di rinnovo è andato a buon fine.