Search code examples
pythonsslproxypython-requestspyopenssl

https GET behind proxy succeeds with wget + TLSv1, but fails with requests even if ssl protocol is forced to TLSv1


I'm trying to get a file via https using requests 2.11.1 with Python 2.7.12 and OpenSSL 1.0.2h (all installed from Anaconda) on MacOS 10.11.6 from behind a proxy. According to SSLLabs, the server supports TLS 1.0, 1.1, and 1.2. Moreover, I can successfully retrieve the file with wget (linked to OpenSSL 1.0.2h) if I explicitly set the secure-protocol to tlsv1 (but not if I set it to unsupported protocols like sslv2). However, if I try to explicitly set the secure protocol used by requests to TLSv1, TLSv1_1, or TLSv1_2, e.g., as follows,

from requests_toolbelt import SSLAdapter
import requests
import ssl

s = requests.Session()
p = ssl.PROTOCOL_TLSv1
s.mount('https://', SSLAdapter(p))
r = s.get("https://anaconda.org/conda-forge/matplotlib/2.0.0b3/download/osx-64/matplotlib-2.0.0b3-np111py27_5.tar.bz2") 

I encounter the following exception:

/Users/lebedov/anaconda2/lib/python2.7/site-packages/requests/adapters.pyc in send(self, request, stream, timeout, verify, cert, proxies)
    495         except (_SSLError, _HTTPError) as e:
    496             if isinstance(e, _SSLError):
--> 497                 raise SSLError(e, request=request)
    498             elif isinstance(e, ReadTimeoutError):
    499                 raise ReadTimeout(e, request=request)

SSLError: ("bad handshake: Error([('SSL routines', 'SSL3_GET_RECORD', 'wrong version number')],)",)

(Less surprisingly, explicitly setting the protocol to SSLv2, SSLv3, or SSLv23 also results in handshake exceptions.) Also, I don't observe any exception when attempting to get other sites via https. Any idea why the connection fails with requests even when I force it to use TLSv1?


Solution

  • This issue proved to be due to the proxy rejecting HTTP headers with unrecognized user-agent strings. Explicitly setting the user-agent in the headers to something like Mozilla/4.0 (compatible; MSIE 5.5; Windows 98) via a hacked version of cntlm solved the problem.