Come creare un certificato TLS SSL self-signed per Apache o NGINX con Linux CentOS Come creare un certificato SSL auto-firmato (self-signed) per NGINX o Apache con Linux CentOS 7.x per accettare richieste HTTPS su porta TCP 443

How to create a self-signed TLS SSL certificate for Apache or NGINX to accept HTTPS requests on port 443

In questo articolo illustreremo come creare un certificato TLS / SSL auto-firmato e configurarlo all’interno di un web server Apache o Nginx per consentire connessioni sicure e crittografate.

La prima parte del tutorial è dedicata a una breve introduzione del concetto di HTTPS, seguita da un approfondimento dei protocolli di sicurezza SSL e TLS; nella seconda parte parleremo di come utilizzare lo strumento openssl per procedere alla creazione del certificato TLS / SSL auto-firmato; ovviamente, qualora abbiate già acquistato (o intenzione di acquistare) un certificato TLS / SSL da una Certification Authority, potrete passare direttamente alla terza e ultima parte, dedicata alla Configurazione del certificato TLS / SSL su Apache e/o Nginx.

Introduzione

La sigla HTTPS è un acronimo/crasi di HyperText Transfer Protocol over Secure Socket Layer: si tratta di un protocollo di comunicazione sicura utilizzabile da due sistemi (peer-to-peer o client-server) che hanno l’obiettivo di scambiarsi informazioni tra loro. La porta utilizzata convenzionalmente è la TCP 443. La principale differenza tra HTTPS e il “cugino” HTTP (HyperText Transfer Protocol) sta nel fatto che il primo, a differenza del secondo, consente lo scambio di informazioni attraverso una connessione criptata tramite un protocollo crittografico asimmetrico come il Transport Layer Security (TLS) o il suo predecessore, Secure Sockets Layer (SSL).

L’utilizzo di HTTPS in luogo del semplice HTTP garantisce alla connessione una serie di caratteristiche di sicurezza estremamente importanti, tra cui:

  • Protezione delle informazioni e quindi anche della privacy delle parti comunicanti, nel rispetto dei criteri di riservatezza e confidenzialità.
  • Garanzia dell’integrità dei dati scambiati tra le parti comunicanti.
  • Verifica e autenticazione del trasmittente, ovvero del sito web visitato, o di entrambe le parti, nei casi di autenticazione duplex (vedi sotto).

Fino ai primi anni 2000 l’utilizzo del protocollo HTTPS era limitato ai siti di e-commerce, alle connessioni inter-aziendali e a una serie di servizi corporate ed enterprise che trattavano dati particolarmente sensibili o riservati: la maggior parte dei siti web non ne faceva uso, anche e soprattutto per via delle risorse hardware necessarie per effettuare le attività di encrypt e decrypt richieste nel corso della connessione. A partire dalla metà dei 2000 e, soprattutto, dal 2010 in poi il protocollo HTTPS ha iniziato ad avere una larga diffusione, anche per merito dei browser e dei motori di ricerca, che ne hanno promosso e incoraggiato l’utilizzo in vari modi. I risultati di questa adozione ad ampio spettro sono estremamente positivi: l’utilizzo diffuso delle connessioni HTTPS garantisce l’autenticità delle pagine web visitate, aumenta la sicurezza degli account utente e protegge i dati che transitano sul web da accessi non autorizzati.

Transport Layer Security

Prima di affrontare l’utilizzo di openssl e dei relativi comandi terminal necessari per generare il certificato è opportuno spendere qualche parola sui protocolli di sicurezza TLS e SSL,così da comprendere al meglio perché è importante dotarsi di questo tipo di protezione.

TLS, acronimo per Transport Layer Security e il suo predecessore SSL, o Secure Sockets Layer, sono protocolli crittografici che garantiscono un elevato livello di sicurezza delle comunicazioni attraverso una rete di computer: il loro utilizzo include tutte le principali connessioni TCP oggi utilizzate attraverso internet e non solo: web browsing, e-mail, invio di fax attraverso internet, messaggistica istantanea, protocolli VoIP, e molti altri.

Una connessione TLS è contraddistinta dalle seguenti fasi principali:

  • Negoziazione: in questa fase il server e il client stabiliscono quale protocollo di data-encryption utilizzare per la comunicazione sicura, il protocollo per lo scambio delle chiavi e l’algoritmo di autenticazione, nonché il Message Authentication Code (MAC).
  • Scambio delle chiavi e autenticazione: in questa fase il server e il client si scambiano le informazioni relative alle chiavi crittografiche rispettivamente utilizzate, necessarie per decifrare correttamente i dati trasmessi e ricevuti. Sia l’algoritmo per lo scambio delle chiavi che quello per l’autenticazione sono normalmente algoritmi a chiave pubblica oppure (come nel caso del TLS-PSK) utilizzano una Pre-Shared Key, ovvero una chiave precondivisa.
  • Cifratura simmetrica e autenticazione dei messaggi: in questa fase, l’integrità dei messaggi è garantita da un algoritmo di hash che usa un costrutto HMAC per il protocollo TLS o una funzione pseudorandom non standard per il protocollo SSL.

Lo scopo principale di questi protocolli è duplice:

  • Proteggere i dati in-transit e garantire la loro integrità attraverso algoritmi di data-encryption estremamente complessi e difficili da decifrare, anche a seguito di eventuali accessi non autorizzati (ottenuti mediante l’utilizzo di tecniche di attacco quali eavesdropping, tampering, man-in-the-middle, etc.).
  • Garantire la reale identità della fonte di trasmissione – ad esempio un sito web – attraverso la certificazione di un ente formalmente autorizzato a fornire questo servizio, ovvero una Certification Authority: questa verifica viene effettuata mediante l’analisi del contenuto del certificato e il controllo dell’intera catena di certificazione.

Come si può facilmente vedere, il primo aspetto riguarda la sicurezza e la protezione dei dati in senso stretto, mentre il secondo consente di verificare che il trasmittente sia chi dichiara di essere.

Autenticazione unilaterale, duplex, PSK e SRP

Nelle tipiche connessioni browser-server l’autenticazione TLS avviene in modo unilaterale, con il server web che si autentica presso il client ma non viceversa: questo significa che il client ha modo di conoscere e verificare l’identità del server a cui si connette pur restando anonimo.

Il protocollo TLS supporta anche un’autenticazione bilaterale, tipicamente utilizzata in quegli scenari dove entrambi i peer oggetto della connessione (client e server, due webservice che comunicano tra loro, o altra situazione analoga) hanno necessità di autenticarsi in modo sicuro scambiandosi i relativi certificati. Questa tecnica di autenticazione, nota come autenticazione duplex (Duplex Authentication) e richiede ovviamente che anche il client possieda un proprio certificato digitale ed è normalmente utilizzata solo in scenari di connessioni aziendali o con enti pubblici. Un perfetto esempio di Duplex Authentication è quella prevista dalle specifiche tecniche del Sistema di Interscambio di Agenzia delle Entrate per il servizio SDICoop, basato per l’appunto sulla comunicazione tra due web service.

In assenza di un’autenticazione bilaterale si possono utilizzare il protocollo TLS-PSK (Pre-Shared Key), di cui abbiamo già avuto modo di parlare, oppure il protocollo SRP (Secure Remote Password): entrambi consentono di effettuare un’autenticazione sicura in assenza di un certificato lato client.

Green Bar

Per riassumere quanto detto finora, possiamo dire che il certificato TLS consente di garantire sia la cifratura dei dati che la verifica del trasmittente. Nel momento in cui entrambe queste verifiche danno esito positivo il browser indica all’utente che la connessione è sicura mostrando l’icona di un lucchetto verde o un altro messaggio visivo analogo, a seconda del browser e delle caratteristiche del certificato stesso:

Come creare un certificato TLS SSL self-signed per Apache o NGINX con Linux CentOS

Questo tipo di evidenza visiva è detta green lock e garantisce l’utente che il proprio browser ha verificato con successo che la connessione è protetta da un certificato “genuino”, ovvero rilasciato all’azienda proprietaria del sito.

[type=”alert”]IMPORTANTE: E’ opportuno precisare che tali verifiche non consentono di determinare che il sito a cui ci si sta connettendo sia intrinsecamente sicuro: è infatti del tutto possibile che un sito, benché protetto da un certificato genuino, possa contenere materiale potenzialmente pericoloso o veicolare contenuti fraudolenti. Per spiegare lo stesso concetto con una metafora, potremmo dire che le verifiche su cui si basa il green lock riguardano la sicurezza della serratura e la corrispondenza tra l’indirizzo della casa e il suo proprietario effettivo, ma non entrano nel merito di quello che possiamo trovare oltre la porta d’ingresso.[/type]

Certificati Auto-Firmati

Con il termine auto-firmato (o self-signed, in lingua inglese) ci si riferisce a un certificato generato dal proprietario del sito o servizio a cui ci si sta connettendo anziché da una autorità di certificazione attendibile: in altre parole, si tratta di un certificato che consente la piena crittografia dei dati trasmessi ma che non fornisce alcuna garanzia della reale identità della fonte di trasmissione, in quanto emesso dal diretto interessato e non da una “terza parte” autorizzata.

Inutile dire che, vista l’impossibilità di garantirne l’attendibilità del certificato in modo oggettivo, qualsiasi certificato self-signed non sarà mai accompagnato da un green lock. Al contrario, la quasi totalità dei browser moderni reagisce a questo tipo di certificati visualizzando una serie di warning visuali all’utente, informandolo dei rischi che corre rispetto a un sito SSL realmente sicuro:

Come creare un certificato TLS SSL self-signed per Apache o NGINX con Linux CentOS

Si tratta di un warning che, a prima vista, può apparire esagerato: che un sito HTTPS protetto da un certificato self-signed è comunque notevolmente più sicuro di un sito HTTP, visto che i dati trasmessi e ricevuti vengono comunque criptati. Se però consideriamo che le connessioni HTTPS sono generalmente considerate sicure e affidabili dall’utente medio, è facile comprendere come la premura da parte del browser di avvisarci immediatamente che c’è qualcosa che non va sia pienamente giustificata.

L’utente posto di fronte a questo avviso è costretto a prendere atto del fatto che l’identità del server a cui sta cercando di connettersi, a dispetto quanto la URL potrebbe far pensare, non è garantita da nessuno: può quindi scegliere di continuare consapevolmente la connessione oppure di rinunciare, a seconda della fiducia riposta nel server stesso.

Quando ha senso utilizzare un Certificato Self-Signed?

Veniamo dunque alla domanda più importante di questa lunga introduzione: quando ha senso utilizzare un certificato SSL auto-firmato? La risposta può essere dedotta facilmente da quanto chiarito nell’ultimo paragrafo: in tutti i casi in cui abbiamo necessità di garantire una connessione criptata a un server accessibile solo a un ristretto numero di utenti autorizzati, ovvero a noi stessi o colleghi-compagni-amici-chiunque altro che non abbia motivo di “dubitare” del suddetto server.

Gli scenari tipici in cui questo tipo di certificato può essere utilizzato senza problemi includono tutti quei siti e servizi amministrativi con una GUI web-based chiusi al pubblico e aperti soltanto ad alcune specifiche utenze amministrative. Al contrario, installare un certificato auto-firmato su qualsivoglia sito o servizio aperto al pubblico avrebbe ben poco senso, visto che la mancanza di green lock e la presenza dei warning di cui sopra suonerebbero come un campanello d’allarme per tutti gli utenti.

Creare un certificato SSL Auto-Firmato

Ora che abbiamo messo a fuoco il perimetro d’uso ideale di un certificato SSL self-signed, vediamo come è possibile crearlo e configurarlo su un web server di tipo Apache e/o Nginx. Gli esempi riportati in questo paragrafo sono relativi a una macchina Linux CentOS ma possono essere utilizzati su tutte le principali distribuzioni Linux (e persino su sistemi Windows, utilizzando il porting di openssl per Windows).

La prima cosa da fare è creare una cartella di tipo  sul nostro server, che sarà utilizzata per memorizzare la chiave privata relativa al certificato SSL/TLS. La riservatezza di questo file sarà essenziale, quindi è opportuno proteggere la cartella appena creata da qualsivoglia accesso non autorizzato nel seguente modo:

Una volta fatto questo, possiamo utilizzare il tool openssl – incluso in tutte le principali distribuzioni Linux – per creare il certificato e la relativa chiave con un singolo comando terminal:

Come si può vedere, mentre la chiave sarà creata nella cartella che abbiamo creato pochi istanti fa, il certificato vero e proprio verrà generato nella directory di sistema , che dovrebbe già esistere sul server (e contenere una serie di certificati ad uso interno) ed essere già dotata di tutti i permessi di accesso necessari.

Ecco una breve spiegazione degli switch che abbiamo utilizzato:

  • req – è il comando per la generazione della richiesta di emissione del certificato (CSR, ovvero Certificate Signing Request).
  • x509 – identifica lo standard di formato del certificato (X.509).
  • days – definisce il numero di giorni di validità del certificato.
  • newkey – indica la volontà di creare una chiave privata.
  • rsa:2048 – indica la volontà di creare una chiave privata utilizzando il RSA key processor a 2048 bit.
  • keyout – il percorso completo dove sarà creata la chiave privata (solitamente un file con estensione .key).
  • out – il percorso completo dove sarà creato il certificato (solitamente un file con estensione .crt).

Il comando, una volta eseguito, chiederà all’utente di rispondere alle domande seguenti, necessarie per generare correttamente la CSR:

  • Country Name (2 letter code) [XX]: il codice ISO 3166-1 (due lettere) della country, ovvero del paese di origine del certificato. Ad esempio: US
  • State or Province Name (full name) []: il nome dello stato o della provincia. Ad esempio: Massachusetts
  • Locality Name (eg, city) [Default City]: il nome della città. Ad esempio: Boston
  • Organization Name (eg, company) [Default Company Ltd]: il nome dell’azienda (o della persona) che sta creando il certificato. Ad esempio: My Company, Inc.
  • Organizational Unit Name (eg, section) []: il settore, ramo, categoria merceologica o area di attività dell’azienda che crea il certificato. Ad esempio: Information Technology
  • Common Name (eg, your name or your server’s hostname) []: il dominio o hostname su cui si desidera installare questo certificato. Ad esempio: example.com
  • Email Address []: l’indirizzo e-mail dell’amministratore di sistema. Ad esempio: ftp-admin@example.com

I campi vanno compilati correttamente, prestando particolare attenzione al Common Name: è necessario che il valore impostato all’interno di quel campo corrisponda a un domain name associato al server (o che risolva su un indirizzo IP associato al server) su cui andremo ad installare il certificato.

Creare un file dhparam.pem

Per incrementare la sicurezza  dell’handshaking TLS effettuato tra il nostro server e i client ad ogni connessione è opportuno spendere qualche altro minuto del nostro tempo per creare un file dhparam.pem, ovvero un gruppo moltiplicativo Diffie-Hellman.

Per farlo, digitare questo comando:

L’operazione durerà alcuni minuti, durante i quali il server provvederà a generare il gruppo: al termine dell’attività, il file dhparam.pem sarà generato nella cartella /etc/ssl/certs/ , pronto per essere utilizzato nella nostra configurazione.

Il funzionamento del file dhparam.pem, così come la sua utilità in termini di sicurezza, è spiegato ottimamente in questa riposta sul sito security.stackexchange.com e nella documentazione di openssl.

Configurazione di Apache

Installare il nostro certificato self-signed su Apache è estremamente semplice: dobbiamo soltanto aggiungere i seguenti parametri di configurazione all’interno dell’elemento <VirtualHost> relativo al sito o servizio web all’interno del file    :

Volendo cogliere l’occasione per impostare un redirect di tutto il traffico non-HTTPS su HTTPS, è possibile aggiungere le linee seguenti:

Per impostare redirect più complessi, ad esempio solo limitatamente ad alcune sotto-cartelle del sito, consigliamo di leggere questo articolo (paragrafo ISAPI REWRITE 3, che presenta una sintassi compatibile con Apache).

Configurazione di Nginx

Ecco come modificare il file di configurazione   per far sì che il nostro sito web example.com possa accettare connessioni HTTP con il certificato creato nei paragrafi precedenti:

L’ultimo blocco di direttive contiene una serie di impostazioni che aumentano notevolmente la sicurezza delle connessioni HTTPS negoziate da Nginx: questi parametri sono consigliati da un articolo di Remy van Elst pubblicato su Cipherli.st, un sito di divulgazione specializzato sul tema della sicurezza informatica. Per approfondire le scelte che hanno portato alla loro definizione, consigliamo la lettura integrale dell’articolo: Strong SSL Security on Nginx.

IMPORTANTE: Le impostazioni suggerite dall’articolo su Cipherli.st garantiscono un ottimo livello di sicurezza: tuttavia, potrebbero risultare controproducenti qualora il vostro sito web abbia necessità di garantire un elevato livello di compatibilità con browser di vecchia (o vecchissima) generazione. In quel caso, potete scaricare un set di istruzioni più “compatibile” (ma leggemente meno sicuro) facendo click sul pulsante Yes, give me a ciphersuite that works with legacy / old software.

Anche nel caso di Nginx, qualora avessimo la necessità di impostare un redirect di tutto il traffico non-HTTPS su HTTPS, potremmo aggiungere le linee seguenti:

Conclusioni

Per il momento è tutto: ci auguriamo che questo articolo possa aiutare utenti e amministratori di sistema a far luce sui certificati SSL e a configurare i propri server web in modo sicuro ed efficace. Alla prossima e… felice configurazione!

[NGINX]

 

About Ryan

IT Project Manager, Web Interface Architect e Lead Developer di numerosi siti e servizi web ad alto traffico in Italia e in Europa. Dal 2010 si occupa anche della progettazione di App e giochi per dispositivi Android, iOS e Mobile Phone per conto di numerose società italiane. Microsoft MVP for Development Technologies dal 2018.

View all posts by Ryan

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.