SNI su Apache 2.4

L’adozione di https sta diventando sempre più importante per la tutela della privacy degli utenti e per la sicurezza delle comunicazioni.

Uno dei fattori che più hanno limitato la diffusione di questo protocollo risiede nella caratteristica della sessione TLS che, fino a poco tempo fa obbligava ad avere un solo certificato PKI per una coppia IP:porta.

In altre parole, sulla porta 443 di un server con un solo indirizzo IP non era possibile creare dei virtual host basati sul nome in https così come vengono creati normalmente sulla porta 80 in http. Questo perché TLS, benché agisca a livello Application del modello ISO/OSI, è di fatto un trasporto di un altro protocollo del medesimo livello.

Quindi, al momento di stabilire una sessione TLS il server http non sa a quale dei server virtuali il client vuole connettersi perché la sessione TLS viene stabilita prima che inizi il dialogo http tra client e server; per questo motivo non era possibile presentare una chiave diversa a seconda del virtual host richiesto dal client.

La soluzione è stata quella di includere l’estensione Server Name Indication (SNI) del protocollo TLS, definita per la prima volta in RFC4366. SNI permette al client di presentare il nome del server a cui si vuole connettere nelle prime fasi di handshake del protocollo TLS in modo tale da consentire al server di scegliere la chiave corretta da utilizzare.

In quanto “estensione” del protocollo TLS esistente, non tutti i client la supportano, queste sono le versioni dei browser che supportano SNI:

  • Mozilla Firefox 2.0 e successivi
  • Opera 8.0 e successivi con TLS 1.1 abilitato
  • Internet Explorer 7.0 e successivi su Windows Vista e successivi (non su Windows XP)
  • Google Chrome
  • Safari 3.2.1 e successivi su MacOS 10.5.6 e successivi

A livello server se si utilizza OpenSSL è necessario avere almeno la versione 0.9.8f, ma questo non dovrebbe essere un problema se la distribuzione che state utilizzando utilizza Apache 2.4.

Prima di abilitare SNI è necessario scegliere il comportamento del server nel caso in cui si colleghi un client che non supporta SNI oppure venga presentato un hostname non previsto nella configurazione. Il controllo avviene attraverso il parametro SSLStrictSNIVHostCheck. Se il parametro è disabilitato (default) il server fornisce al client il primo degli host virtuali definito nella configurazione (considerato da Apache l’host virtuale di default). Se il parametro è abilitato Apache restituisce al client un errore 4xx e viene scritta questa riga nel log:

[error] No hostname was provided via SNI for a name based virtual host

Per eseguire i test è meglio utilizzare certificati auto-emessi; con Apache e Linux l’operazione per creare questo tipo di certificati è molto semplice:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /path/sito.key -out /path/sito.crt

Una volta risposto alle domande del caso, verranno creati due file da utilizzare in questo modo nella configurazione di Apache

SSLCertificateFile /path/sito.crt
SSLCertificateKeyFile /path/sito.key

Non ci sono limiti al numero di certificati che si possono creare. Ovviamente i browser diranno che il certificato non è riconosciuto dalla PKI, ma potete tranquillamente proseguire e fare tutte le prove del caso, che risulteranno affidabili, a meno, ovviamente, della verifica del certificato.

Ora che abbiamo tutti gli strumenti possiamo procedere ad assemblare una configurazione con più certificati SSL che rispondono sulla medesima porta 443 del medesimo IP.

Apache 2.4 ha reso obsoleto il parametro NameVirtualHost, che è considerato implicito se si utilizzano più host virtuali sulla medesima coppia IP:porta.

Per definire un host virtuale si includono le definizioni relative all’host all’interno di un container <VirtualHost a.b.c.d:443> dove al posto di a.b.c.d si indica l’indirizzo IP del server. Tra i parametri obbligatori ci sono ServerName per specificare il nome dell’host virtuale, ServerPath per indicare la directory che contiene i file del sito e, ovviamente la coppia SSLCertificateFile e SSLCertificateKeyFile.

Un metodo brutale, ma efficace, può essere di moltiplicare la definizione esistente del sito https cambiando nome, chiavi, log e altri parametri opportuni. Prima di andare in produzione vale comunque la pena di comprendere il significato di ogni tipo di parametro per evitare sorprese spiacevoli o comportamenti non desiderati.

Una volta riavviato Apache dovrebbe essere possibile accedere agli host virtuali ciascuno con la propria chiave SSL.

È bene eseguire tutti i test del caso prima di passare un sito in https.

Innanzi tutto il sito potrebbe includere risorse esterne con URL http diversi dal sito medesimo, la qual cosa provoca una segnalazione nel browser che avvisa l’utente della minor sicurezza del sito in quanto alcuni contenuti non sono cifrati.

In seconda istanza, bisogna considerare che i contenuti https non vengono salvati nella cache su disco; alcuni browser mantengono una cache in memoria, ma vale, ovviamente, solo per quella sessione. In un sito con molti contenuti grafici statici e con le pagine che si differenziano principalmente per i testi (tipicamente un blog) questo potrebbe portare ad una penalizzazione della performance percepita dall’utente.

Autore: Luigi Rosa

Consulente IT, sviluppatore, SysAdmin, cazzaro, e, ovviamente, geek.

6 pensieri riguardo “SNI su Apache 2.4”

  1. utilizzo Firefox 34 su Debian 8 e, quando scrollo il tuo sito fino in fondo, la sezione “Seguimi su Twitter” sfarfalla e fa saltare la visualizzazione su al tag cloud

    1. Succedeva anche a me e credevo fosse un problema solamente mio. Deve essere Twitter che non gradisce molto essere l’ultimo widget, vedi se adesso a te fa ancora lo stesso scherzo.

Spazio per un commento