HTTPS con NGINX

Tra le tante scelte architetturali fatte per la nostra app, senza dubbio quella di rendere le connessioni sicure è la più importante.
Chiudere le nostre API con un certificato è stato un must dal primo giorno.
Vedere poi montato il certificato su un web server Nginx e il lucchetto chiuso sul browser è stata una vera emozione.

Senza una vera esperienza su certificati e standard HTTPS, siamo entrati su https://www.cheapestssls.com/ e abbiamo acquistato il prodotto COMODO Essential SSL.

COMODO SSL

Una volta registrato sul provider di SSL i valori necessari per la registrazione del dominio, è stato necessario creare sul server le chiavi pubbliche e private, e infine generare il certificato di sign in.

Per creare una nuova chiava a 2048-bit RSA apri il terminale e digita:

openssl genrsa -aes256 -out my-private-encrypted.key 2048

L'operazione di generazione della chiave privata, ti chiederà una frase che dovrai ricordare per le prossime volte.

Il prossimo step, consiste nel decriptare la chiava privata, che ti permetterà di generare un certificato di accesso.
Per decriptare la tua chiave privata digitare il comando:

openssl rsa -in my-private-encrypted.key -out my-private-decrypted.key

Ora genera il certificato di richiesta di accesso con il comando:

openssl req -new -sha256 -key my-private-decrypted.key -out mydomain.com.csr

Il provider che abbiamo utilizzato, richiedeva di sottomettere il contenuto del certificato per procedere.
Per copiare il contenuto del file csr nella clipboard eseguire il comando:

clip < mydomain.com.csr 

Tornate sul pannello di controllo del vostro provider e incollate il contenuto del vostro csr, scegliete il web server più adatto a voi e continuate.

Dovo aver terminato il pagamento e dopo aver atteso qualche ora, vi dovrebbe arrivare una mail con all’interno un file da pubblicare sul vostro dominio. Questo servirà al vostro provider per validare il permesso di scrittura sul server web.

In seguito il vostro provider invierà una mail con allegato uno zip contenente i file necessari per la pubblicazione dell’ssl, nel dettagio dovreste avere:

  • 1 file .ca-bundle (contenente tutti i certificati root e intemedi)
  • 1 file .crt (contenente il vostro certificato di autenticazione)

A questo punto dobbiamo combinare i due certificati, il risultante sarà il certificato che dovremmo esporre sul web server.
Utilizziamo il comando cat per accodare i due certificati.

cat www_yourdomain_com.crt www_yourdomain_com.ca-bundle > ssl-bundle.crt

Copiamo il nostro certificato .crt sul nostro server, ad esempio sotto la cartella /etc/ssl

NGINX

Settiamo infine il nostro webserver nginx: andiamo nel file di configurazione e impostiamo l’ssl.

server {
    listen 443;
    server_name mysite.com;

    ssl on;
    ssl_certificate /etc/ssl/certs/ssl-bundle.crt;
    ssl_certificate_key /etc/ssl/private/mysite.key;

    #enables all versions of TLS, but not SSLv2 or 3 which are weak and now deprecated.
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    #Disables all weak ciphers
    ssl_ciphers ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

    ssl_prefer_server_ciphers on;
}

Notare che ssl_certificate, è il nostro certificato generato poco fa, ssl_certificate_key invece è la chiave privata utilizzata per il certificato.

É possibile includere la password del certificato nella chiave privata, utilizzando il comando

cp ssl_certificate_key ssl_certificate_key.old

openssl rsa -in ssl_certificate_key.old -out ssl_certificate_key
[enter the passphrase]

Questo per evitare che ad ogni riavvio di Nginx, venga richiesta la password della chiave privata.

Come ultima cosa verifichiamo la bontà del nostro SSL utilizzando in web tool: https://www.ssllabs.com/ssltest/index.html

Grazie a Zaerl che mi ha consigliato questo link, le nostre API sono arrivate ad un livello A di certificazione SSL.

Aggiornamento 16/12/2015

Weak Diffie-Hellman and the Logjam Attack

Al fine di aumentare la sicurezza e prevenire un Logjam Attack, occorre includere nella configurazione del nostro server http di Nginx, il parametro Diffie-Hellman.

Per prima cosa occorre generare la chiave tramite OpenSSL:

openssl dhparam -out dhparam.pem 2048

Aggiungiamo quindi la chiave appena creata alle configurazioni di Nginx

ssl_dhparam {path to dhparams.pem}

Riavviamo il server e ritestiamo il livello di SSL.
Alcuni link utili per capire meglio il problema