使用TLS请求不会提供SNI支持

时间:2013-09-02 17:43:28

标签: python ssl ssl-certificate python-requests sni

我正在使用请求与django app进行通信,但

当我尝试

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)。有没有人找到使用请求的解决方法?

6 个答案:

答案 0 :(得分:125)

当前版本的请求应该与SNI一样好。 Further down the GitHub issue您可以看到要求:

尝试安装这些软件包然后再试一次。

编辑:自请求v2.12.1起,不再需要ndg-httpsclient和pyasn1。现在所需包的完整列表:

  • pyOpenSSL
  • IDNA

答案 1 :(得分:22)

为了让我得到公认的工作答案,我必须按顺序安装一堆其他软件包:

  • yum install libffi-devel
  • yum install gcc
  • yum install openssl-devel
  • pip install urllib3
  • pip install pyopenssl
  • pip install ndg-httpsclient
  • pip install pyasn1

答案 2 :(得分:9)

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

pip install requests[security]

答案 3 :(得分:6)

或者您可以使用Python 2.7.9及更高版本:

“整个Python 3.4的ssl模块已被反向移植到Python 2.7.9。请参阅PEP 466以获得理由。”

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

答案 4 :(得分:4)

@Lukasa答案与当前(来自github)请求是正确的。请记住在系统中添加OpenSSL,与他提到的pip依赖关系不同。

如果出于部署原因,你更喜欢稳定的请求版本,比如1.2.3 in pip,你可以修补一个与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 :(得分:1)

Accessing https sites with IP address

复制我的答案

在MAC High Sierra和Python 3.6.4上,我尝试了解决方案:requests toolbelt:HostHeaderSSLAdapter首先,不幸的是,它对我不起作用,然后我尝试了 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”。