[openssl-users] SSL error “inappropriate fallback” and TLS_FALLBACK_SCSV

Florin Andrei florin at andrei.myip.org
Thu Jun 1 01:58:16 UTC 2017

A bit of context:

I have this endpoint behind an AWS ALB. I do SSL termination at the ALB. 
To my surprise, when looking at the client_tlsnegotiation_error_count 
metric for the ALB, I've noticed a substantial amount of failed 
connection attempts due to TLS negotiation errors - perhaps around 5% of 
total traffic but this estimate could be wrong by a substantial margin.

The clients are mostly an average cross-section of current mobile 
devices in use these days in the US.

The ALB is configured with the default TLS policy that Amazon provides:

     | 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

Unfortunately, ALBs do not provide error logs, so I could not directly 
identify why some clients are failing the SSL negotiation.

Instead, I've pushed SSL termination deeper into the stack, to the Nginx 
frontend, and replaced the ALB with a plain TCP-based ELB. Now 
connections to port 443 are forwarded directly to Nginx for SSL 

I've configured Nginx with the exact same protocol versions and ciphers 
like the ALB:

     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
     ssl_prefer_server_ciphers on;

I've verified with nmap and I get the same ssl-enum-ciphers list from 

Now in the Nginx error log I get lots of lines like this:

     SSL_do_handshake() failed (SSL: error:140A1175:SSL 
routines:ssl_bytes_to_cipher_list:inappropriate fallback) while SSL 

Still not very informative, so I've run tcpdump on port 443 on the Nginx 
instances. As expected, there's some amount of SSL errors like this:

     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)

In that same TCP stream there's this Client Hello packet:

     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)
                     GMT Unix Time: Jun  7, 2050 12:50:05.000000000 PST
                     Random Bytes: 
                 Session ID Length: 0
                 Cipher Suites Length: 28
                 Cipher Suites (14 suites)
                     Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 
                     Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 
                     Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 
                     Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 
                     Cipher Suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 
                     Cipher Suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA 
                     Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA 
                     Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA 
                     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 
                     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)

It's a little puzzling because the exchange of crypto messages uses TLS 
1.0 which the server definitely supports, and the client should be very 
likely to support too.

I've seen discussions online saying that the presence of the 
TLS_FALLBACK_SCSV cipher suite is an indication that this failed 
connection is related to anti-POODLE security measures, and the 
communication is likely to be retried again. Is that correct?

For the most part, what I'm trying to do is find the answers to these 

1. Is this bad? If yes, why? (what are the things that the clients need 
that the endpoint is not providing)

2. If it's not bad, then why do we get this constant stream of SSL 

It's a little difficult to search the capture file and try to correlate 
the failed SSL handshake with other, successful connections, because the 
source IPs are masked by the ELB. There might be a way to rely on the 
PROXY protocol header to identify IPs, but I'll have to figure out how 
to do that.

Florin Andrei

More information about the openssl-users mailing list