Errori SSL/TLS su browser molto vecchi che si connettono a Discourse

Dopo aver configurato la mia istanza di Discourse con il supporto predefinito di Let’s Encrypt, ho ricevuto segnalazioni da alcuni utenti secondo cui il loro browser non riesce a stabilire una connessione sicura con Discourse. Uno screenshot ricevuto da un utente indica chiaramente un errore SSL/TLS. Si tratta di un errore lato browser e gli utenti non vedono nemmeno nulla da Discourse.

Dal contesto, sembra che quegli utenti abbiano sistemi operativi o browser piuttosto datati. Inizialmente ho sospettato che il problema fosse il supporto a TLS 1.2, ma l’utente con cui ho verificato sta utilizzando Safari 10.1.2 su macOS (versione sconosciuta) e, secondo Can I use... Support tables for HTML5, CSS3, etc, Safari dovrebbe supportare TLS 1.2 dalla versione 7.

Esiste un’altra ragione, oltre a TLS 1.2, che potrebbe causare a un browser o a un sistema operativo il fallimento nell’instaurare una connessione sicura con un’installazione predefinita di Discourse che utilizza il supporto TLS predefinito tramite Let’s Encrypt? Sto cercando di capire quali domande porre ai miei utenti per individuare il problema e su quale lato dovrebbe essere applicata la correzione.

Come soluzione temporanea: per quanto ne so, l’impostazione predefinita è reindirizzare il traffico da http a https. Esiste un modo per effettuare prima un controllo, qualcosa come “solo se il browser supporta TLS 1.2” o “solo se il browser/sistema operativo è di versione superiore”, altrimenti rimanere su http?

Questo è l’URL, nel caso abbiate idee su come verificare se qualcosa sia configurato in modo errato: https://forum.stadtteilgenossenschaft-wik.de

Puoi testare il tuo sito utilizzando il SSL Server Test. I risultati del test contengono una sezione denominata “Simulazione di handshake” che dovrebbe mostrarti le combinazioni browser/sistema operativo che funzionano o non funzionano.

Con l’ultima immagine Docker, vedo la seguente configurazione TLS:

Puoi inviare i tuoi utenti a https://www.ssllabs.com/ssltest/viewMyClient.html per ottenere maggiori informazioni sulle versioni del loro browser e sistema operativo, nonché sulle versioni TLS supportate.

Grazie per la risposta dettagliata!

Ho eseguito il SSL Server Test e non riesco a trovare nulla di sbagliato nel risultato:

Sono gli stessi che hai indicato nel tuo post, per quanto ne so.

Gli unici fallimenti riguardano vecchi sistemi operativi con versioni di Safari (Safari 8+9) e vecchie versioni di Windows con IE 11. Quest’ultimo mi preoccupa un po’: non dovrebbe IE 11 essere supportato da Discourse e supportare TLS 1.2 di default?

Il test non include inoltre una verifica per Safari 10 sul sistema operativo più vecchio ancora supportato, quindi forse anche quello fallisce…

Per gli utenti con versioni vecchie di Windows, probabilmente è necessario abilitare le cifrature CBC:

La prossima cosa da fare è inviare questi utenti a

per ottenere informazioni su cosa supporta il loro browser. Il modo più semplice per condividere il risultato è probabilmente fargli stampare in PDF e inviarlo a te.

Grazie, ho ricevuto una risposta dal mio utente. Sta utilizzando un iPod Touch molto vecchio:

Capacità SSL/TLS del tuo browser
User Agent: Mozilla/5.0 (iPod; CPU iPhone OS 6_1_6 come Mac OS X) AppleWebKit/536.26 (KHTML, come Gecko) Version/6.0 Mobile/10B500 Safari/8536.25

Supporto dei protocolli

Il tuo user agent ha un buon supporto per i protocolli.

Il tuo user agent supporta TLS 1.2, che è la versione del protocollo consigliata al momento.

Quindi, anche se è vecchio (e sono consapevole che è ben lontano dal sistema operativo e dal browser minimi supportati da Discourse), vorrei consentirgli di collegarsi almeno al sito e vedere come si comporta il suo browser con HTML e JavaScript moderni.

Questo è il rapporto dettagliato sul supporto TLS:

Caratteristiche dei protocolli

Protocolli

TLS 1.3 No
TLS 1.2 Sì
TLS 1.1 Sì
TLS 1.0 Sì
SSL 3 Sì
SSL 2 No

Suite di cifratura (in ordine di preferenza)

TLS_EMPTY_RENEGOTIATION_INFO_SCSV ( 0xff ) -
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 ( 0xc024 ) DEBOLE 256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 ( 0xc023 ) DEBOLE 128
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ( 0xc00a ) DEBOLE 256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA ( 0xc009 ) DEBOLE 128
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA ( 0xc007 ) INSECURO 128
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA ( 0xc008 ) DEBOLE 112
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 ( 0xc028 ) DEBOLE 256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ( 0xc027 ) DEBOLE 128
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ( 0xc014 ) DEBOLE 256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ( 0xc013 ) DEBOLE 128
TLS_ECDHE_RSA_WITH_RC4_128_SHA ( 0xc011 ) INSECURO 128
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA ( 0xc012 ) DEBOLE 112
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 ( 0xc026 ) DEBOLE 256
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 ( 0xc025 ) DEBOLE 128
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 ( 0xc02a ) DEBOLE 256
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 ( 0xc029 ) DEBOLE 128
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA ( 0xc004 ) DEBOLE 128
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA ( 0xc005 ) DEBOLE 256
TLS_ECDH_ECDSA_WITH_RC4_128_SHA ( 0xc002 ) INSECURO 128
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA ( 0xc003 ) DEBOLE 112
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA ( 0xc00e ) DEBOLE 128
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA ( 0xc00f ) DEBOLE 256
TLS_ECDH_RSA_WITH_RC4_128_SHA ( 0xc00c ) INSECURO 128
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA ( 0xc00d ) DEBOLE 112
TLS_RSA_WITH_AES_256_CBC_SHA256 ( 0x3d ) DEBOLE 256
TLS_RSA_WITH_AES_128_CBC_SHA256 ( 0x3c ) DEBOLE 128
TLS_RSA_WITH_AES_128_CBC_SHA ( 0x2f ) DEBOLE 128
TLS_RSA_WITH_RC4_128_SHA ( 0x5 ) INSECURO 128
TLS_RSA_WITH_RC4_128_MD5 ( 0x4 ) INSECURO 128
TLS_RSA_WITH_AES_256_CBC_SHA ( 0x35 ) DEBOLE 256
TLS_RSA_WITH_3DES_EDE_CBC_SHA ( 0xa ) DEBOLE 112
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ( 0x67 ) DEBOLE 128
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 ( 0x6b ) DEBOLE 256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA ( 0x33 ) DEBOLE 128
TLS_DHE_RSA_WITH_AES_256_CBC_SHA ( 0x39 ) DEBOLE 256
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA ( 0x16 ) DEBOLE 112
TLS_ECDHE_ECDSA_WITH_NULL_SHA ( 0xc006 ) INSECURO 0
TLS_ECDHE_RSA_WITH_NULL_SHA ( 0xc010 ) INSECURO 0
TLS_ECDH_ECDSA_WITH_NULL_SHA ( 0xc001 ) INSECURO 0
TLS_ECDH_RSA_WITH_NULL_SHA ( 0xc00b ) INSECURO 0
TLS_RSA_WITH_NULL_SHA256 ( 0x3b ) INSECURO 0
TLS_RSA_WITH_NULL_SHA ( 0x2 ) INSECURO 0
TLS_RSA_WITH_NULL_MD5 ( 0x1 ) INSECURO 0
(1) Quando un browser supporta SSL 2, le sue suite SSL 2-esclusive vengono mostrate solo nella prima connessione a questo sito. Per vedere le suite, chiudi tutte le finestre del browser, poi apri direttamente questa pagina esatta. Non aggiornare.

Dettagli del protocollo

Server Name Indication (SNI) Sì
Rinegoziazione sicura Sì
Compressione TLS No
Biglietti di sessione No
OCSP stapling No
Algoritmi di firma SHA384/RSA, SHA256/RSA, SHA1/RSA, SHA256/ECDSA, SHA1/ECDSA
Gruppi nominati secp256r1, secp384r1, secp521r1
Next Protocol Negotiation No
Application Layer Protocol Negotiation No
Compatibilità handshake SSL 2 No

Gestione del contenuto misto

Test del contenuto misto
Immagini Passive Sì
CSS Attivo Sì
Script Attivo Sì
XMLHttpRequest Attivo Sì
WebSockets Attivo Sì
Frame Attivo Sì
(1) Questi test potrebbero causare un avviso di contenuto misto nel tuo browser. È previsto.
(2) Se vedi un test fallito, prova a ricaricare la pagina. Se l’errore persiste, ti preghiamo di contattarci.

Scusa per la formattazione, l’utente ha copiato e incollato per me l’HTML del testo ricco e parte di esso si perde quando incollato su Discourse. Cercherò di capire come correggere la formattazione più tardi.

Come ho detto, vorrei consentirgli di stabilire almeno una connessione sicura in modo che veda qualcosa e dovrebbe essere possibile dato che il browser supporta TLS 1.2. Ma immagino che dovrei abilitare alcune configurazioni meno sicure per TLS 1.2 affinché il suo browser sia supportato. Non conosco abbastanza i dettagli di TLS per confrontare l’output di quel rapporto con ciò che il server supporta e cosa dovrei cambiare. Puoi dirmi cosa manca e cosa dovrei cambiare?

Ho un’idea approssimativa di cosa intendi, ma non ho la minima idea di come farlo. Puoi indicarmi qualche documentazione che spieghi come modificare la configurazione TLS del contenitore Docker di Discourse per abilitarle?

Non credo che Safari 6 funzionerà, anche se risolvi i problemi TLS aggiungendo suite di crittografia aggiuntive.

Puoi aggiungere le suite di crittografia mancanti sovrascrivendo il file di configurazione di nginx. Aggiungi il seguente frammento (non testato, ma dovrebbe funzionare) alla sezione hooks di app.yml e modifica il valore di ssl_ciphers a tuo piacimento.

  after_ssl:
    - replace:
        filename: "/etc/nginx/conf.d/discourse.conf"
        from: /ssl_ciphers .*/
        to: ssl_ciphers <your_complete_cipher_list>;

A proposito: sto cercando di aggiungere il supporto per i certificati a curva ellittica a Discourse, il che lo renderebbe funzionante per IE11 senza configurazioni aggiuntive.

iOS 6?! L’ultima versione è stata rilasciata all’inizio del 2014! Sono passati oltre 5 anni!

Lo so, sono stato sorpreso quanto te. Non mi aspetto che lo supportiate, ma vorrei che l’utente potesse ottenere almeno un po’ di HTML e vedere cosa funziona e cosa no.

Grazie @gerhard, ho apportato la modifica che hai descritto a /var/discourse/containers/app.yml (spero fosse il file app.yml corretto) e poi ho eseguito /var/discourse/launcher rebuild app come indicato nei commenti di app.yml.

Ho quindi rieseguito il test su ssllabs.com, ma sembra che il risultato non sia cambiato: https://www.ssllabs.com/ssltest/analyze.html?d=forum.stadtteilgenossenschaft-wik.de&s=68.183.214.228&hideResults=on

Non sono sicuro di come verificare se la modifica alla configurazione abbia effettivamente funzionato (ma non ha influenzato il risultato del test) o se la modifica alla configurazione non abbia funzionato.

Oh, non ho letto correttamente il tuo post, @gerhard. Se ho capito bene, la configurazione che hai fornito rende esplicite le cifre utilizzate, ma il valore che hai usato è sostanzialmente lo stesso di quello predefinito, giusto? Quindi dovrei comunque estenderla con altre cifre che potrebbero essere supportate dai browser più vecchi.

Sì, esattamente. Non volevo pubblicare una soluzione per aggiungere cifrari deboli alla configurazione. Dovrai risolvere questo problema da solo. :wink:

Ma se stai apportando queste modifiche, tieni d’occhio la pull request che ho menzionato prima. Se viene unita, IE11 funzionerà immediatamente.

Capisco, non vuoi rendere troppo facile per qualcuno configurare il proprio ambiente in modo insicuro. Rispetto questo approccio e non pubblicherò anch’io il codice completo.

Ecco cosa ho ottenuto finora: ho identificato le suite crittografiche mancanti per supportare browser e sistemi operativi più vecchi, consultando ad esempio Qualys SSL Labs - Projects / User Agent Capabilities: Safari 6 / iOS 6.0.1 (e analoghe per altri). Poiché le suite crittografiche del client sono elencate in ordine di preferenza, ho semplicemente scelto quella in cima alla lista, assicurandomi di supportarla, assumendo che se il server supporta almeno una delle suite elencate, ciò dovrebbe essere sufficiente. Ecco le suite crittografiche che ho identificato:

  • ECDHE-ECDSA-AES256-CBC-SHA384 per Safari 6-8
  • ECDHE-RSA-AES256-CBC-SHA384 per IE 11 su Win 7/8.1/Phone 8.1 Update (secondo @supermathie)
  • ECDHE-RSA-AES128-CBC-SHA256 per IE 11 su Win Phone 8.1

Ho preso questi valori e li ho aggiunti alla fine dell’elenco di ssl_ciphers, separati da due punti, assumendo che “fine dell’elenco” significhi “meno preferito, verrà utilizzato solo se il client non supporta nulla di meglio”. Ho quindi eseguito /var/discourse/launcher rebuild app per applicare la nuova configurazione e ho rieseguito il test su SSL Server Test (Powered by Qualys SSL Labs) dopo aver svuotato la cache. Ma i risultati non sono cambiati.

Mi aspettavo che ora fosse funzionante sia per i test falliti di IE 11 sia per Safari 6-8, ma l’handshake continua a fallire. Quindi devo aver tralasciato qualcosa.

Inoltre, uno dei miei utenti utilizza un iPhone con iOS 9/Safari 9 e per loro la connessione fallisce anch’essa. Ma secondo i risultati del test di SSL Labs, quella connessione dovrebbe già funzionare nativamente (come si può anche vedere nel risultato di @gerhard sopra).

Quindi devo aver tralasciato due cose:

  1. Perché la connessione non funziona ancora dopo aver aggiunto il supporto per le suite crittografiche?
  2. Perché SSL Labs dice che funziona per iOS 9 + Safari 9, ma in realtà non funziona per il mio utente?

Per quanto riguarda il punto 1: non sono ancora sicuro di aver applicato correttamente la configurazione. Oltre al test SSL Labs, esiste un altro modo per verificare quali suite crittografiche il server supporta, per vedere se la modifica alla configurazione è stata effettivamente applicata correttamente?

Dopo aver esaminato più da vicino il risultato di SSLLab, penso che questo non funzioni.

Questo è il risultato che vedo su SSLLabs per il mio server dopo aver applicato la configurazione e ricostruito:

Secondo la mia comprensione, dovrebbe elencarne molti di più, dato che la configurazione include molte altre opzioni. Significa che questa modifica alla configurazione non ha funzionato?

Penso che i nomi dei cipher scelti siano errati. Mapping OpenSSL cipher suite names to IANA names è una risorsa utile per mappare i cipher elencati dallo SSL Server Test con i nomi utilizzati da OpenSSL (nginx).

Nei miei test ho aggiunto :ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA e, dopo una ricostruzione, il test appare così:

Forse c’è un bug nel test? :man_shrugging: Non ho una versione così vecchia di Safari per i test. Supportiamo solo Safari 10+. Sei sicuro che l’errore sia ancora dovuto a un problema TLS?

Grazie, ci proverò!

Ho dato un’occhiata più approfondita ai file di configurazione di Discourse e ho trovato templates/web.ssl.template.yml. Qual è la differenza tra apportare questa modifica alle cifre tramite il file app.yml e modificare direttamente l’elenco di ssl_ciphers in templates/web.ssl.template.yml?

Il template è sottoposto a controllo versione, mentre app.yml non lo è. Avrai problemi nell’aggiornare il repository se modifichi il template.

Grazie, questo era il problema e correggere i nomi fa sì che l’handshake funzioni per tutti i browser testati nell’elenco di SSLLabs. Grazie mille per la tua pazienza!

Ora sono curioso di sapere cosa vedono i miei utenti una volta superato l’errore HTTPS con i loro vecchi browser. :smiley: