使用带有 TLS 的请求不提供 SNI 支持

问题描述 投票:0回答:7
我正在使用请求与 django 应用程序进行通信,但是

当我尝试时

requests.get('https://mysite.com', verify=True)

我收到错误:

主机名“mysite.com”与“*.myhost.com”、“myhost.com”都不匹配

但是,当我查看浏览器或

http://www.digicert.com/help/时,证书看起来不错。

我的主机表示这是请求缺乏 SNI 支持(Github 似乎证实了这一点

https://github.com/kennethreitz/requests/issues/749)。有没有人找到使用请求的解决方法?

python ssl ssl-certificate python-requests sni
7个回答
132
投票
当前版本的 Requests 应该可以很好地支持 SNI。

再往下看GitHub问题你可以看到要求:

  • pyOpenSSL
  • ndg-httpsclient
  • pyasn1
尝试安装这些软件包,然后再试一次。

编辑:从 Requests v2.12.1 开始,不再需要 ndg-httpsclient 和 pyasn1。所需软件包的完整列表现在是:

  • pyOpenSSL
  • idna

22
投票
为了让我得到可接受的答案,我必须按以下顺序安装一堆其他软件包:

    yum 安装 libffi-devel
  • 百胜安装 gcc
  • yum 安装 openssl-devel
  • pip 安装 urllib3
  • pip 安装 pyopenssl
  • pip 安装 ndg-httpsclient
  • pip 安装 pyasn1

12
投票
像这样安装请求模块。这将安装安全包附加功能。

pip install requests[security]


    


5
投票
@Lukasa 的答案对于当前(来自 github)的请求是正确的。除了他提到的 pip 依赖项之外,请记住在您的系统中添加 OpenSSL。

如果出于部署原因,您更喜欢 pip 中的 1.2.3 等稳定的请求版本,您可以对该版本进行猴子修补以与 SNI 一起使用,如下所示:

import requests def fileno(self): return self.socket.fileno() def close(self): return self.connection.shutdown() requests.pyopenssl.WrappedSocket.close = close requests.pyopenssl.WrappedSocket.fileno = fileno
    

5
投票
或者您可以只使用 Python 2.7.9 及更高版本:

“Python 3.4 的整个 ssl 模块已向后移植到 Python 2.7.9。请参阅 PEP 466 了解理由。”

https://www.python.org/downloads/release/python-279/


2
投票
复制我的答案

使用 IP 地址访问 https 站点

在 MAC High Sierra 和 Python 3.6.4 上,我尝试了解决方案:

requests toolbelt:HostHeaderSSLAdapter 1st,不幸的是,它对我不起作用,然后我尝试了 forcediphttpsadapter,终于可以用了。

作者在自述文件部分解释了所有内容,并提供了示例脚本,可以轻松遵循。

1.通过

pip install requests[security] forcediphttpsadapter

安装库

2.运行示例脚本:

import requests from forcediphttpsadapter.adapters import ForcedIPHTTPSAdapter session = requests.Session() session.mount("https://example.com", ForcedIPHTTPSAdapter(dest_ip='1.2.3.4')) response = session.get( '/some/path', headers={'Host': 'example.com'}, verify=False)

注意:在某些情况下,您可能需要从网址中删除前缀:“www”。


0
投票
我一直收到这个错误...

ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1006)
使用 python 3.11.5 和 requests 2.31.0。将 requests lib 降级到 2.28.2 后,当使用 verify=False 时,一切都按预期工作。

© www.soinside.com 2019 - 2024. All rights reserved.