Un po 'di contesto:
Ho questo endpoint dietro un ALB AWS. Faccio terminazione SSL presso l'ALB. Con mia sorpresa, osservando la metrica client_tlsnegotiation_error_count per l'ALB, ho notato una notevole quantità di tentativi di connessione falliti a causa di errori di negoziazione TLS - forse circa il 5% del traffico totale ma questa stima potrebbe essere errata con un margine considerevole.
I client sono per lo più una sezione media degli attuali dispositivi mobili in uso negli Stati Uniti.
L'ALB è configurato con il criterio TLS predefinito fornito da Amazon:
| ssl-enum-ciphers:
| TLSv1.0:
| ciphers:
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| compressors:
| NULL
| cipher preference: server
| TLSv1.1:
| ciphers:
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| compressors:
| NULL
| cipher preference: server
| TLSv1.2:
| ciphers:
| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
| TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
| TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| compressors:
| NULL
| cipher preference: server
|_ least strength: A
Sfortunatamente, gli ALB non forniscono log degli errori, quindi non sono stato in grado di identificare direttamente il motivo per cui alcuni client hanno fallito la negoziazione SSL.
Ho invece spinto la terminazione SSL più in profondità nello stack, nel frontend Nginx, e ho sostituito l'ALB con un semplice ELB basato su TCP. Ora le connessioni alla porta 443 vengono inoltrate direttamente a Nginx per la negoziazione SSL.
Ho configurato Nginx con le stesse identiche versioni e cifrari del protocollo come l'ALB:
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA';
ssl_prefer_server_ciphers on;
Ho verificato con nmap e ottengo lo stesso elenco ssl-enum-ciphers di Nginx.
Ora nel log degli errori di Nginx ottengo molte righe come questa:
SSL_do_handshake() failed (SSL: error:140A1175:SSL routines:ssl_bytes_to_cipher_list:inappropriate fallback) while SSL handshaking
Ancora non molto informativo, quindi ho eseguito tcpdump sulla porta 443 sulle istanze Nginx. Come previsto, c'è una certa quantità di errori SSL come questo:
Secure Sockets Layer
TLSv1 Record Layer: Alert (Level: Fatal, Description: Inappropriate Fallback)
Content Type: Alert (21)
Version: TLS 1.0 (0x0301)
Length: 2
Alert Message
Level: Fatal (2)
Description: Inappropriate Fallback (86)
Nello stesso flusso TCP c'è questo pacchetto Client Hello:
Secure Sockets Layer
TLSv1 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 165
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 161
Version: TLS 1.0 (0x0301)
Random
GMT Unix Time: Jun 7, 2050 12:50:05.000000000 PST
Random Bytes: da03ff7045a5f76e78edf61c097c75e4e141df6649ef1861...
Session ID Length: 0
Cipher Suites Length: 28
Cipher Suites (14 suites)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA (0xc007)
Cipher Suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011)
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)
Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)
Cipher Suite: TLS_RSA_WITH_RC4_128_SHA (0x0005)
Cipher Suite: TLS_RSA_WITH_RC4_128_MD5 (0x0004)
Cipher Suite: TLS_FALLBACK_SCSV (0x5600)
Compression Methods Length: 1
Compression Methods (1 method)
Compression Method: null (0)
Extensions Length: 92
Extension: renegotiation_info
Type: renegotiation_info (0xff01)
Length: 1
Renegotiation Info extension
Renegotiation info extension length: 0
Extension: server_name
Type: server_name (0x0000)
Length: 27
Server Name Indication extension
Server Name list length: 25
Server Name Type: host_name (0)
Server Name length: 22
Server Name: [REDACTED]
Extension: Extended Master Secret
Type: Extended Master Secret (0x0017)
Length: 0
Extension: SessionTicket TLS
Type: SessionTicket TLS (0x0023)
Length: 0
Data (0 bytes)
Extension: Application Layer Protocol Negotiation
Type: Application Layer Protocol Negotiation (0x0010)
Length: 26
ALPN Extension Length: 24
ALPN Protocol
ALPN string length: 5
ALPN Next Protocol: h2-16
ALPN string length: 8
ALPN Next Protocol: spdy/3.1
ALPN string length: 8
ALPN Next Protocol: http/1.1
Extension: ec_point_formats
Type: ec_point_formats (0x000b)
Length: 2
EC point formats Length: 1
Elliptic curves point formats (1)
EC point format: uncompressed (0)
Extension: elliptic_curves
Type: elliptic_curves (0x000a)
Length: 8
Elliptic Curves Length: 6
Elliptic curves (3 curves)
Elliptic curve: secp256r1 (0x0017)
Elliptic curve: secp384r1 (0x0018)
Elliptic curve: secp521r1 (0x0019)
È un po 'sconcertante perché lo scambio di messaggi crittografici utilizza TLS 1.0 che il server sicuramente supporta e il client dovrebbe essere molto probabile che supporti anche.
Ho visto discussioni online che affermano che la presenza della suite di crittografia TLS_FALLBACK_SCSV è un'indicazione che questa connessione fallita è correlata a misure di sicurezza anti-POODLE e la comunicazione è probabile che venga ritentata di nuovo. È corretto?
Per la maggior parte, quello che sto cercando di fare è trovare le risposte a queste domande:
-
È così male? Se sì, perché? (quali sono le cose di cui i client hanno bisogno che l'endpoint non sta fornendo)
-
Se non è male, allora perché otteniamo questo flusso costante di errori SSL?
È un po 'difficile cercare il file di acquisizione e provare a correlare l'handshake SSL non riuscito con altre connessioni riuscite, perché gli IP di origine sono mascherati dall'ELB. Potrebbe esserci un modo per fare affidamento sull'intestazione del protocollo PROXY per identificare gli IP, ma dovrò capire come farlo.