Opened 7 years ago

Closed 7 years ago

#1267 closed defect (invalid)

TLS 1.0 handshake fails on upstream when TLS1.2 is enabled

Reported by: abarre@… Owned by:
Priority: minor Milestone:
Component: nginx-module Version: 1.11.x
Keywords: TLS proxy Cc: tech@…
uname -a: Linux worker01-integration 3.13.0-101-generic #148-Ubuntu SMP Thu Oct 20 22:08:32 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.11.8
built with OpenSSL 1.0.2k 26 Jan 2017
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -fPIC -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-openssl=/openssl-1.0.2k --with-http_stub_status_module --with-http_gunzip_module --with-http_v2_module --with-threads --with-file-aio --add-module=/tmp/ngx_http_enhanced_memcached_module --add-module=/tmp/headers-more-nginx-module --add-module=/tmp/lua-nginx-module --add-module=/tmp/ngx_devel_kit --add-module=/tmp/lua-upstream-nginx-module

Description

Proxification to server accepting TLSv1 fails when TLSv1.2 is activated

We discover this problem when proxifying to www.groupama.fr which is a website that support only TLSv1 but don't support TLSv1.1 or TLSv1.2
(see https://www.ssllabs.com/ssltest/analyze.html?d=www.groupama.fr)

We had to change our nginx configuration in order to establish TLS connection to this server on TLSv1:

location / {

  • proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2; (fails)

+ proxy_ssl_protocols TLSv1 TLSv1.1; (work)
...

The Error message when TLSv1.2 is enabled : peer closed connection in SSL handshake while SSL handshaking to upstream

We don't understand why nginx don't try to establish a connection to TLSv1 when TLSv1 TLSv1.1 and TLSv1.2 are activated.

Change History (1)

comment:1 by Maxim Dounin, 7 years ago

Resolution: invalid
Status: newclosed

The problem is the the server in question rejects SSL handshake by closing a connection instead of responding with maximum supported version as per SSL/TLS protocol version negotiation mechanism. Dump of an openssl s_client -connect www.groupama.fr:443 connection attempt:

17:47:37.484273 IP 192.168.33.82.62100 > 91.223.125.129.443: Flags [S], seq 3294370312, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 889378967 ecr 0,sackOK,eol], length 0
17:47:37.563493 IP 91.223.125.129.443 > 192.168.33.82.62100: Flags [S.], seq 709795882, ack 3294370313, win 1460, options [mss 1452,nop,wscale 0,nop,nop,TS val 0 ecr 0,nop,nop,sackOK], length 0
17:47:37.563653 IP 192.168.33.82.62100 > 91.223.125.129.443: Flags [.], ack 1, win 4140, options [nop,nop,TS val 889379046 ecr 0], length 0
17:47:37.564127 IP 192.168.33.82.62100 > 91.223.125.129.443: Flags [P.], seq 1:309, ack 1, win 4140, options [nop,nop,TS val 889379046 ecr 0], length 308
17:47:37.641121 IP 91.223.125.129.443 > 192.168.33.82.62100: Flags [F.], seq 1, ack 309, win 65227, options [nop,nop,TS val 69595584 ecr 889379046], length 0
...

Note that the server sent FIN after receiving ~ClientHello packet, without trying to respond anything. It's up to the server operators to find out why it behaves incorrectly and closes connection instead of properly responding per specification. The "Handshake Simulation" section on SSL Labs may help to identify the cause, it lists various clients which will fail to connect the server.

Note well that some browsers to work around similar interoperability problems often try to reconnect to the server in such situations, with maximum supported protocol downgraded to an older version, and due to this such misbehaving servers often appear "working" when tested from browsers. This is not what nginx does though, so you have to set proxy_ssl_protocols if you want to proxy requests to such misbehaving server. Or, better yet, fix the misbehaving server to properly implement SSL / TLS version negotiation.

Note: See TracTickets for help on using tickets.