Requests failing to connect to a TLS server

I'm having an issue tracking down why requests fails to connect to a specific host.

The following works just fine via curl, or browser:

curl https://banking4.anz.com

However if I use requests:

requests.get('https://banking4.anz.com')

I get:

SSLError: ("bad handshake: SysCallError(-1, 'Unexpected EOF')",)

On the wire, I see only the client hello and the server disconnects immediately, so it doesn't seem like any ssl or cipher incompatibility. (I'd expect an SSL-layer error for those) What else could be an issue in this case?

I'm on python 3.6.1 with requests 2.14.2 (with security extras).


This server is broken in multiple ways.

For one, it only understands DES-CBC3-SHA which is considered insecure and not included in the default cipher set used by requests. Additionally it looks like that it only checks a limited number of offered ciphers in the ClientHello and thus will not see that DES-CBC3-SHA is offered by the client if too much other offers are before this cipher.

A quick workaround for this broken server is to only offer the only cipher the server supports:

import requests
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'DES-CBC3-SHA'
requests.get('https://banking4.anz.com')

But note that this sets the default cipher list of requests to an insecure value. Thus this method should not be used if you want to connect to other sites within your application. Instead have a look at this more complex solution of using your own HTTPAdapter with specific cipher settings for the broken site.