dicembre 4, 2020 · Personal VPS Nginx

Configurazione nuova VPS: installare un certificato SSL nel nostro sito

Capitoli precedenti
- Configurazione nuova VPS: nuovo utente, chiave SSH, firewall.
- Configurazione nuova VPS: NGINX e sito statico.

Per prima cosa bisogna fermare NGINX per liberare le porte esterne, che saranno usate per la verifica dell'effettiva proprietà e disponibilità del dominio.

sudo service nginx stop

A questo punto vogliamo procurarci un certificato SSL per il nostro dominio. E' possibile acquistarlo, o richiederlo gratis su Let's Encrypt. L'efficacia è la stessa, a dispetto di quanto raccontano quelli che i certificati li vendono, quindi procediamo con la seconda opzione. Per richiedere il certificato si può usare certbot, un'applicazione che svolgerà per noi tutte le operazioni. In particolare, la generazione del certificato passa attraverso la verifica dell'effettiva disponibilità del dominio, ragion per cui certbot, dopo aver effettuato la richiesta, apre un server web ad-hoc per consentire a Let's Encrypt di fare la verifica. Il procedimento è completamente automatico. Se abbiamo installato Docker, possiamo lanciare l'immagine ufficiale di certbot senza neppure dover installare alcunché. Se non abbiamo installato Docker, sarà argomento di uno dei prossimi post, quindi niente paura.

sudo docker run -it --rm \
  --name certbot \
  -v "/etc/letsencrypt:/etc/letsencrypt" \
  -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
  -p "80:80" \
  -p "443:443" \
  certbot/certbot certonly
Saving debug log to /var/log/letsencrypt/letsencrypt.log

How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Spin up a temporary webserver (standalone)
2: Place files in webroot directory (webroot)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1
Plugins selected: Authenticator standalone, Installer None
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): <indirizzo_email>

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'to cancel): <miodominio.estensione> <www.miodominio.estensione>
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for miodominio.estensione
http-01 challenge for www.miodominio.estensione
Waiting for verification...
Cleaning up challenges

A questo punto nella cartella /etc/letsencrypt troveremo una struttura del genere:

/etc/letsencrypt/
├── accounts
│   └── ...
├── archive
│   └── <miodominio.ext>
│       ├── cert1.pem
│       ├── chain1.pem
│       ├── fullchain1.pem
│       └── privkey1.pem
├── csr
│   └── ...
├── keys
│   └── ...
├── live
│   ├── <miodominio.ext>
│   │   ├── cert.pem -> ../../archive/<miodominio.ext>/cert1.pem
│   │   ├── chain.pem -> ../../archive/<miodominio.ext>/chain1.pem
│   │   ├── fullchain.pem -> ../../archive/<miodominio.ext>/fullchain1.pem
│   │   ├── privkey.pem -> ../../archive/<miodominio.ext>/privkey1.pem
│   │   └── README
│   └── README
├── renewal
│   └── ...
└── renewal-hooks
    └── ...

La struttura è pensata per contenere tutte le chiavi (pubblica, privata e dell'ente certificatore) nella cartella archive, e averne un link nella cartella live, sottocartella pari al nome del dominio (in questo caso miodominio.ext). Questa struttura serve a fare in modo che, in caso di rinnovo, le nuove chiavi vengano copiate assieme a quelle vecchie (senza sovrascriverle), ma il collegamento sia contestualmente aggiornato e quindi non si debba cambiare nulla nella configurazione dei servizi che fanno uso di queste chiavi.

A questo punto bisogna configurare nginx per mettersi in ascolto sulla porta 443 (HTTPS) e usare i certificati; inoltre, come misura di sicurezza, restiamo in ascolto sulla porta 80 ma dirottiamo le richieste in arrivo alla 443, per forzare l'uso di SSL su tutte le connessioni in ingresso al nostro server. Il file di configurazione, creato nel capitolo precedente, viene modificato come segue:

server{
  listen 80;
  server_name miodominio.ext www.miodominio.ext;
  location / {
    return 301 https://$host$request_uri;
  }
}

server{
  listen 443 ssl;
  server_name miodominio.ext www.miodominio.ext;
  ssl_certificate /etc/letsencrypt/live/miodominio.ext/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/miodominio.ext/privkey.pem;
  location / {
    root /var/www/sito;
  }
}

A questo punto è sufficiente riavviare nginx...

sudo service nginx start

...e il gioco è fatto! Adesso il nostro sito dovrebbe rispondere alla richiesta su https://miodominio.ext, e le richieste verso http dovrebbero essere girate automaticamente all'indirizzo di cui sopra.