Search code examples
androidnginxssl

Nginx TLS Handshake Failure (40) for old Android devices


I'm running nginx using the official docker image and I want to enable some endpoints for old Android devices. These devices are running Android 4.3 JB or Android 4.4 KitKat.

From the point of view of the Android devices this exception rises after a http call:

javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb9d6d1a0: Failure in SSL library, usually a protocol error
2023-11-28 13:43:14.941  8763-8763  System.error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0xa3860990:0x00000000)

By capturing the traffic via Wireshark I find the following behavior. Android client sends an SSL Hello with the following Cipher Suites:

enter image description here

The server replies with an Handshake failure 40 error.

enter image description here

So i tought the server doesn't support the client cyper suites. I tried many configurations, I report the last used:

server {

    listen       443 ssl;
    listen  [::]:443 ssl;
    server_name  myserver.com;

    client_max_body_size 40M;

    server_tokens off;

    ssl_certificate       /etc/nginx/certs/fullchain.pem;
    ssl_certificate_key   /etc/nginx/certs/key.pem;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA@SECLEVEL=0;

    access_log  /var/log/nginx/host.access.log  main;

    location /api{
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://mybackend:8080;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    gzip on;
}

As you can see in the Client Hello there are some Chiper Suites that appear also in the nginx ssl configuration.

I tried to switch to old nginx images to see if it can depends from some changing in the defaults. The used version, when writing here, is nginx:1.13.

Update 1

The log error prints the follow line:

2023/11/28 18:52:57 [info] 7#7: *1 SSL_do_handshake() failed (SSL: error:1417A0C1:SSL routines:tls_post_process_client_hello:no shared cipher) while SSL handshaking, client: 185.170.137.233, server: 0.0.0.0:443

Update 2 Here follows the server exposed Cipher Suites enter image description here

Does someone know why some enabled cipher are missing?

Thank you, Nci


Solution

  • I solved like follows. Starting on a newer nginx over debian docker image (nginx:1.23) I edited the openssl system configuration (inside the container) /etc/ssl/openssl.cnf by setting the TLS protocol and the system Chiper Suites

    openssl_conf = default_conf
    
    [default_conf]
    ssl_conf = ssl_sect
    
    [ssl_sect]
    system_default = system_default_sect
    
    [system_default_sect]
    MinProtocol = TLSv1
    CipherString = DEFAULT@SECLEVEL=0
    

    Then the problem was related to the key type of the signed certificate used. I'm using Let's Encrypt with acme.sh as renewal method.

    I forced the renewal by setting --keylength 2048