简体   繁体   中英

SSL handshake failure (40) between nginx and iOS 11 only

I have an nginx 1.10.3 server running NextCloud and access it from various clients. The certificate is provided by Lets Encrypt and uses a 2048-bit RSA key.

All clients work fine, including web browsers, except those running on iOS 11 on an iPad or iPhone. The working browsers are Firefox 56 on MacOS and Linux, and Safari 11 on MacOS Sierra. The NextCloud client on Linux also works fine. On iOS, GoodReader has no problem accessing NextCloud as a webdav client. But Safari will not access it, claiming it could not access a secure connection to the server. The iOS NextCloud client returns an SSL error when it tries to connect (I presume it uses the same library as Safari to connect).

The error in the nginx log for when iOS (Safari or the NextCloud app) tries and fails to connect is:

SSL_do_handshake() failed (SSL: error:1417A0C1:SSL routines:tls_post_process_client_hello:no shared cipher) while SSL handshaking

I looked at the traffic on the web server and this is the Client Hello for Firefox:

Secure Sockets Layer
SSL Record Layer: Handshake Protocol: Client Hello
    Content Type: Handshake (22)
    Version: TLS 1.0 (0x0301)
    Length: 512
    Handshake Protocol: Client Hello
        Handshake Type: Client Hello (1)
        Length: 508
        Version: TLS 1.2 (0x0303)
        Random
            GMT Unix Time: Aug  8, 2013 06:38:14.000000000 JST
            Random Bytes: eece37d08b453cedc932958165d0b6c530b31a321554c874...
        Session ID Length: 32
        Session ID: c7...
        Cipher Suites Length: 30
        Cipher Suites (15 suites)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
            Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
            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_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)
        Compression Methods Length: 1
        Compression Methods (1 method)
            Compression Method: null (0)
        Extensions Length: 405
        Extension: server_name
            Type: server_name (0x0000)
            Length: 30
            Server Name Indication extension
                Server Name list length: 28
                Server Name Type: host_name (0)
                Server Name length: 25
                Server Name: mydomain.com
        Extension: Extended Master Secret
            Type: Extended Master Secret (0x0017)
            Length: 0
        Extension: renegotiation_info
            Type: renegotiation_info (0xff01)
            Length: 1
            Renegotiation Info extension
                Renegotiation info extension length: 0
        Extension: elliptic_curves
            Type: elliptic_curves (0x000a)
            Length: 10
            Elliptic Curves Length: 8
            Elliptic curves (4 curves)
                Elliptic curve: ecdh_x25519 (0x001d)
                Elliptic curve: secp256r1 (0x0017)
                Elliptic curve: secp384r1 (0x0018)
                Elliptic curve: secp521r1 (0x0019)
        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: SessionTicket TLS
            Type: SessionTicket TLS (0x0023)
            Length: 208
            Data (208 bytes)
        Extension: Application Layer Protocol Negotiation
            Type: Application Layer Protocol Negotiation (0x0010)
            Length: 14
            ALPN Extension Length: 12
            ALPN Protocol
                ALPN string length: 2
                ALPN Next Protocol: h2
                ALPN string length: 8
                ALPN Next Protocol: http/1.1
        Extension: status_request
            Type: status_request (0x0005)
            Length: 5
            Certificate Status Type: OCSP (1)
            Responder ID list Length: 0
            Request Extensions Length: 0
        Extension: signature_algorithms
            Type: signature_algorithms (0x000d)
            Length: 24
            Signature Hash Algorithms Length: 22
            Signature Hash Algorithms (11 algorithms)
                Signature Hash Algorithm: 0x0403
                    Signature Hash Algorithm Hash: SHA256 (4)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Hash Algorithm: 0x0503
                    Signature Hash Algorithm Hash: SHA384 (5)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Hash Algorithm: 0x0603
                    Signature Hash Algorithm Hash: SHA512 (6)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Hash Algorithm: 0x0804
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (4)
                Signature Hash Algorithm: 0x0805
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (5)
                Signature Hash Algorithm: 0x0806
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (6)
                Signature Hash Algorithm: 0x0401
                    Signature Hash Algorithm Hash: SHA256 (4)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Hash Algorithm: 0x0501
                    Signature Hash Algorithm Hash: SHA384 (5)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Hash Algorithm: 0x0601
                    Signature Hash Algorithm Hash: SHA512 (6)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Hash Algorithm: 0x0203
                    Signature Hash Algorithm Hash: SHA1 (2)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Hash Algorithm: 0x0201
                    Signature Hash Algorithm Hash: SHA1 (2)
                    Signature Hash Algorithm Signature: RSA (1)
        Extension: Padding
            Type: Padding (0x0015)
            Length: 71
            Padding Data: 000000000000000000000000000000000000000000000000...

Ultimately, the TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) cipher is chosen for Firefox.

Here is the Client Hello for the iPad via Safari:

Secure Sockets Layer
SSL Record Layer: Handshake Protocol: Client Hello
    Content Type: Handshake (22)
    Version: TLS 1.0 (0x0301)
    Length: 239
    Handshake Protocol: Client Hello
        Handshake Type: Client Hello (1)
        Length: 235
        Version: TLS 1.2 (0x0303)
        Random
            GMT Unix Time: Jul 20, 2002 17:04:33.000000000 JST
            Random Bytes: 8f8602de9622cf56d70fa8d863a3c8d7154eb23ce19b625b...
        Session ID Length: 0
        Cipher Suites Length: 40
        Cipher Suites (20 suites)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)
            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_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
            Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)
            Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
            Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
            Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)
            Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)
            Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
            Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
        Compression Methods Length: 1
        Compression Methods (1 method)
            Compression Method: null (0)
        Extensions Length: 154
        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: 30
            Server Name Indication extension
                Server Name list length: 28
                Server Name Type: host_name (0)
                Server Name length: 25
                Server Name: mydomain.com
        Extension: Extended Master Secret
            Type: Extended Master Secret (0x0017)
            Length: 0
        Extension: signature_algorithms
            Type: signature_algorithms (0x000d)
            Length: 20
            Signature Hash Algorithms Length: 18
            Signature Hash Algorithms (9 algorithms)
                Signature Hash Algorithm: 0x0403
                    Signature Hash Algorithm Hash: SHA256 (4)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Hash Algorithm: 0x0804
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (4)
                Signature Hash Algorithm: 0x0401
                    Signature Hash Algorithm Hash: SHA256 (4)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Hash Algorithm: 0x0503
                    Signature Hash Algorithm Hash: SHA384 (5)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Hash Algorithm: 0x0805
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (5)
                Signature Hash Algorithm: 0x0501
                    Signature Hash Algorithm Hash: SHA384 (5)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Hash Algorithm: 0x0806
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (6)
                Signature Hash Algorithm: 0x0601
                    Signature Hash Algorithm Hash: SHA512 (6)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Hash Algorithm: 0x0201
                    Signature Hash Algorithm Hash: SHA1 (2)
                    Signature Hash Algorithm Signature: RSA (1)
        Extension: status_request
            Type: status_request (0x0005)
            Length: 5
            Certificate Status Type: OCSP (1)
            Responder ID list Length: 0
            Request Extensions Length: 0
        Extension: next_protocol_negotiation
            Type: next_protocol_negotiation (0x3374)
            Length: 0
        Extension: signed_certificate_timestamp
            Type: signed_certificate_timestamp (0x0012)
            Length: 0
            Data (0 bytes)
        Extension: Application Layer Protocol Negotiation
            Type: Application Layer Protocol Negotiation (0x0010)
            Length: 48
            ALPN Extension Length: 46
            ALPN Protocol
                ALPN string length: 2
                ALPN Next Protocol: h2
                ALPN string length: 5
                ALPN Next Protocol: h2-16
                ALPN string length: 5
                ALPN Next Protocol: h2-15
                ALPN string length: 5
                ALPN Next Protocol: h2-14
                ALPN string length: 8
                ALPN Next Protocol: spdy/3.1
                ALPN string length: 6
                ALPN Next Protocol: spdy/3
                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: ecdh_x25519 (0x001d)
                Elliptic curve: secp256r1 (0x0017)
                Elliptic curve: secp384r1 (0x0018)

The response given to iOS in the network traffic is:

Secure Sockets Layer
TLSv1.2 Record Layer: Alert (Level: Fatal, Description: Handshake Failure)
    Content Type: Alert (21)
    Version: TLS 1.2 (0x0303)
    Length: 2
    Alert Message
        Level: Fatal (2)
        Description: Handshake Failure (40)

Unfortunately what specifically failed in the handshake is not clear to me because I haven't been able to find any more detailed information. The exact cipher chosen by the server for Firefox is listed as supported by iOS, but the SSL handshake not only doesn't choose it but fails to choose any option.

Adding further weirdness, a run of the site through SSL Labs gives, alongside an A+ rating, the following results for the handshake test for Safari:

Safari 6/iOS 6.0.1    RSA 2048 (SHA256)  TLS 1.2       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA     ECDH secp521r1  FS
Safari 7/iOS 7.1      RSA 2048 (SHA256)  TLS 1.2       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA     ECDH secp521r1  FS
Safari 7/OS X 10.9    RSA 2048 (SHA256)  TLS 1.2       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA     ECDH secp521r1  FS
Safari 8/iOS 8.4      RSA 2048 (SHA256)  TLS 1.2       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA     ECDH secp521r1  FS
Safari 8/OS X 10.10   RSA 2048 (SHA256)  TLS 1.2       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA     ECDH secp521r1  FS
Safari 9/iOS 9        RSA 2048 (SHA256)  TLS 1.2 > h2  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256  ECDH secp521r1  FS
Safari 9/OS X 10.11   RSA 2048 (SHA256)  TLS 1.2 > h2  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256  ECDH secp521r1  FS
Safari 10/iOS 10      RSA 2048 (SHA256)  TLS 1.2 > h2  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256  ECDH secp521r1  FS
Safari 10/OS X 10.12  RSA 2048 (SHA256)  TLS 1.2 > h2  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256  ECDH secp521r1  FS

So apparently SSL Lab's model of Safari is happy with my server, but the real Safari on iOS is not.

This is the SSL cipher configuration for the nginx server:

ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:
  ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA256:
  ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:
  ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA:
  ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:
  DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:
  DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:
  DHE-RSA-AES256-SHA256";

It was taken from here . I have also tried a configuration from theMozilla SSL configuration generator . The "modern" profile was this:

ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:
  ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:
  ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:
  ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:
  ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';

This gave the same result of a handshake failure.

Letting nginx use the default for ssl_ciphers results in iOS connecting to the server. But, when I checked the TCP dump, I found that it had chosen the cipher TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d) , which does not provide forward secrecy Naturally, SSL Labs also gives the site an A- rating when the server is using the default cipher selections, due to some browsers choosing ciphers without forward secrecy. But even in this situation, SSL Labs' Safari 10/iOS 10 handshake test gives RSA 2048 (SHA256) TLS 1.2 > h2 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ECDH secp521r1 FS for its result, so I'm stumped as to why iOS 11 is behaving so differently.

Any help in resolving this bizarre situation is greatly appreciated.

I have found the source of the problem. The server was constrained to only accept secp521r1 for the elliptical curve (the ssl_ecdh_curve setting). I don't remember why it was set like that; some guide in the past told me to do so and I blindly complied.

Adding an additional curve of lower strength, secp384r1 , allows iOS to make a successful handshake and communicate using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA384 . ssl_ecdh_curve is now set to secp521r1:secp384r1 .

I'm not sure what changed between iOS 10 and 11 to cause this. My best guess, from digging through the OpenSSL code and some further research , is that iOS 11 is trying to comply with Suite B . Suite B restricts the curves to P-256 and P-384. But that's just an amateur's guess.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM