FreeNAS Nextcloud plugin – nginx e HTTPS

Come descritto nell’articolo sulla mia configurazione cloud, il webserver della mia istanza Nextcloud non esce fuori dalla rete locale se non attraverso una VPN con OpenVPN.

Idealmente dunque, utilizzare HTTP invece di HTTPS potrebbe sembrare una scelta ragionevole: handshake iniziale più rapido, numero minore di componenti da configurare e intuitivamente performance migliori.

In realtà, HTTPS con HTTP2 (tecnologia costruita su SPDY) garantisce performance migliori in quanto aggiunge la compressione degli header, la parallelizzazione delle richieste e un eventuale push proattivo da parte del webserver che può decidere che certe risorse saranno necessarie al client ancora prima che questi ne faccia richiesta. Non mi credete? Provate voi stessi.

A tutta questa (bella) roba si aggiunge uno strato di sicurezza in più: anche all’interno della mia rete locale le richieste (e le autenticazioni) verso nextcloud saranno cifrate e illeggibili da un aggressore.

Tutto molto bello insomma, non potevo lasciarmelo scappare. Non c’è ragione di usare HTTP invece di HTTPS in tutti i tuoi progetti web.

Il plugin di NextCloud per FreeNAS si basa su nginx, un webserver più moderno e performante del robustissimo Apache.

Configurare nginx per usare SSL e HTTP2 è semplicissimo. Entriamo via SSH nella Jail dedicata a nextcloud con jexec.

1. Verifichiamo se OpenSSL è installato (eventualmente installiamolo usando pkg).

root@nextcloud:/ # openssl version
OpenSSL 1.0.2o-freebsd 27 Mar 2018

2. Verifichiamo se i moduli nginx relativi a SSL (--with-http_ssl_module) e HTTP2 (--with-http_v2_module) sono installati.

root@nextcloud:/ # nginx -V
nginx version: nginx/1.16.0
built with OpenSSL 1.0.2o-freebsd  27 Mar 2018
TLS SNI support enabled
configure arguments: --prefix=/usr/local/etc/nginx --with-cc-opt='-I /usr/local/include' --with-ld-opt='-L /usr/local/lib' --conf-path=/usr/local/etc/nginx/nginx.conf
--sbin-path=/usr/local/sbin/nginx --pid-path=/var/run/nginx.pid --error-log-path=/var/log/nginx/error.log --user=www --group=www --modules-path=/usr/local/libexec/nginx --with-file-aio
--http-client-body-temp-path=/var/tmp/nginx/client_body_temp --http-fastcgi-temp-path=/var/tmp/nginx/fastcgi_temp --http-proxy-temp-path=/var/tmp/nginx/proxy_temp --http-scgi-temp-path=/var/tmp/nginx/scgi_temp --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi_temp --http-log-path=/var/log/nginx/access.log
--with-http_v2_module --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-pcre --with-http_secure_link_module --with-http_slice_module
--with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --without-mail_imap_module --without-mail_pop3_module --without-mail_smtp_module --with-mail_ssl_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-threads --with-mail=dynamic --with-stream=dynamic
root@nextcloud:/ #

3. Generiamo i certificati necessari (Certificate Authority, chiave privata e così via…).
Il CA sarà di tipo self-authority (non legato ad un ente certificatore esterno come potrebbe essere Let’s Encrypt [1]). Nessun problema, semplicemente il browser ci darà un warning (ma noi sappiamo di aver emesso noi quel certificato: possiamo fidarci).

Personalmente ho creato una directory openssl dentro /usr/local/etc/ssl/ nella quale ho salvato i file del mio certificato.

openssl req -new > cert.csr
openssl rsa -in privkey.pem -out key.pem
openssl x509 -in cert.csr -out cert.pem -req -signkey key.pem -days 1095
cat key.pem>>cert.pem
openssl dhparam 2048 -out dhparam.pem

Durante la generazione dei vari certificati vi verranno chieste un paio di password e qualche informazione per descrivere il certificato. Conservate le password con cura.

Occhio che il parametro -days indica i giorni di validità del certificato: 1095 sono 3 anni.

A questo punto sarete già al 50% del lavoro.

4. Raggiungete la cartella di configurazione della vostra istanza web nextcloud.
Di default si trova in /usr/local/etc/nginx/conf.d/

Per non far danni fate una copia di nextcloud.conf e successivamente modificate la configurazione in questo modo:

server {
  listen 443 ssl http2;
  server_name nextcloud.local;
  ssl_certificate /usr/local/etc/ssl/openssl/cert.pem;
  ssl_certificate_key /usr/local/etc/ssl/openssl/key.pem;
  ssl_prefer_server_ciphers on;
  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DHE+AES128:!ADH:!AECDH:!MD5;
  ssl_dhparam /usr/local/etc/ssl/openssl/dhparam.pem;
  add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
...

Tutto il resto del file di configurazione potete lasciarlo immutato.

5. Riavviamo la lettura dei file di configurazione da parte di nginx:

root@nextcloud:/usr/local/etc/nginx/conf.d # service nginx reload
Performing sanity check on nginx configuration:
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
root@nextcloud:/usr/local/etc/nginx/conf.d #

Modifica completata! Se non avete fatto errori potrete loggarvi su https://<nextcloud-ip-address>:443/ 🎉

[1] Non ho potuto usare Let’s Encrypt perché come dicevo il mio webserver è isolato e non possiede un dominio. Se non siete nelle mie condizioni potrete usare CertBot e gestire l’intera catena di certificazione configurando il porting di Certbot per FreeBSD e nginx.

2 commenti » Scrivi un commento

  1. Ciao Emanuele, complimenti per l’articolo! Ho anch’io da poco comprato un microserver HP e installato freenas! grazie alla tua guida sono riuscito a configurare nextcloud con il certificato self signed. Mi chiedevo: tramite servizi come dyndns o altri non è possibile usare let’s Encrypt per avere un certificato valido?
    Grazie
    Ciao
    Christian

    • Ciao Christian, hai già provato a guardare se installando Certbot riesci a interfacciarti in maniera corretta con Let’s Encrypt (nonostante la tua, come la mia, istanza nextcloud non sia raggiungibile dall’esterno)? Personalmente non ho provato ma credo possa essere una strada da percorrere. La domanda però è: perché? Quale vantaggio speri di ottenere (oltre all’eventuale lucchetto in verde)?
      Ciao,
      Emanuele

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.