代理后面的https GET成功使用wget + TLSv1,但即使ssl协议被强制为TLSv1,也会因请求而失败

时间:2016-09-07 14:28:30

标签: python ssl proxy python-requests pyopenssl

我正在尝试通过https使用来自代理后面的MacOS 10.11.6上的Python 2.7.12和OpenSSL 1.0.2h(全部从Anaconda安装)的请求2.11.1获取文件。根据{{​​3}},服务器支持TLS 1.0,1.1和1.2。此外,如果我明确地将安全协议设置为tlsv1(但是如果我将其设置为不支持的协议,如sslv2),我可以使用wget(链接到OpenSSL 1.0.2h)成功检索文件。但是,如果我尝试将请求使用的安全协议显式设置为TLSv1,TLSv1_1或TLSv1_2,例如,如下所示,

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") 

我遇到以下异常:

/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')],)",)

(不出所料,明确地将协议设置为SSLv2,SSLv3或SSLv23也会导致握手异常。)此外,在尝试通过https获取其他站点时,我没有发现任何异常。知道为什么连接失败了,即使我强迫它使用TLSv1?

1 个答案:

答案 0 :(得分:0)

此问题证明是由于代理拒绝了带有无法识别的用户代理字符串的HTTP标头。通过黑客版本的cntlm将标题中的用户代理显式设置为Mozilla/4.0 (compatible; MSIE 5.5; Windows 98),解决了问题。