Python 使用urllib3忽略证书验证
我正在对具有自签名证书的私有服务使用urllib3。有没有办法让urllib3忽略证书错误并发出请求Python 使用urllib3忽略证书验证,python,python-3.x,urllib3,Python,Python 3.x,Urllib3,我正在对具有自签名证书的私有服务使用urllib3。有没有办法让urllib3忽略证书错误并发出请求 import urllib3 c = urllib3.HTTPSConnectionPool('10.0.3.168', port=9001) c.request('GET', '/') 在使用以下各项时: import urllib3 c = urllib3.HTTPSConnectionPool('10.0.3.168', port=9001, cert_reqs='CERT_NONE')
import urllib3
c = urllib3.HTTPSConnectionPool('10.0.3.168', port=9001)
c.request('GET', '/')
在使用以下各项时:
import urllib3
c = urllib3.HTTPSConnectionPool('10.0.3.168', port=9001, cert_reqs='CERT_NONE')
c.request('GET', '/')
出现以下错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3/dist-packages/urllib3/request.py", line 67, in request
**urlopen_kw)
File "/usr/lib/python3/dist-packages/urllib3/request.py", line 80, in request_encode_url
return self.urlopen(method, url, **urlopen_kw)
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 415, in urlopen
body=body, headers=headers)
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 267, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/lib/python3.3/http/client.py", line 1061, in request
self._send_request(method, url, body, headers)
File "/usr/lib/python3.3/http/client.py", line 1099, in _send_request
self.endheaders(body)
File "/usr/lib/python3.3/http/client.py", line 1057, in endheaders
self._send_output(message_body)
File "/usr/lib/python3.3/http/client.py", line 902, in _send_output
self.send(msg)
File "/usr/lib/python3.3/http/client.py", line 840, in send
self.connect()
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 103, in connect
match_hostname(self.sock.getpeercert(), self.host)
File "/usr/lib/python3/dist-packages/urllib3/packages/ssl_match_hostname/__init__.py", line 32, in match_hostname
raise ValueError("empty or no certificate")
ValueError: empty or no certificate
尝试以下方式实例化连接池:
HTTPSConnectionPool(self.host, self.port, cert_reqs=ssl.CERT_NONE)
HTTPSConnectionPool(self.host, self.port, cert_reqs='CERT_NONE')
或者这样:
HTTPSConnectionPool(self.host, self.port, cert_reqs=ssl.CERT_NONE)
HTTPSConnectionPool(self.host, self.port, cert_reqs='CERT_NONE')
资料来源:
编辑(在看到您的编辑后): 看起来远程主机没有发送证书(可能吗?)。 这是引发异常的代码(来自urllib3):
def match_hostname(cert, hostname):
"""Verify that *cert* (in decoded format as returned by
SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 rules
are mostly followed, but IP addresses are not accepted for *hostname*.
CertificateError is raised on failure. On success, the function
returns nothing.
"""
if not cert:
raise ValueError("empty or no certificate")
所以看起来cert
是空的,这意味着self.sock.getpeercert()
返回了一个空字符串 尝试以下代码:
import urllib3
c = urllib3.HTTPSConnectionPool('10.0.3.168', port=9001, cert_reqs='CERT_NONE',
assert_hostname=False)
c.request('GET', '/')
参见我找到了问题的答案。实际上,urllib3文档并没有完全解释如何抑制SSL证书验证。缺少的是对ssl.CERT\u NONE的引用 我的代码有一个布尔值ssl\u verify,用于指示我是否需要ssl验证。代码现在如下所示:
import ssl
import urllib3
#
#
#
if (ssl_verify):
cert_reqs = ssl.CERT_REQUIRED
else:
cert_reqs = ssl.CERT_NONE
urllib3.disable_warnings()
http = urllib3.PoolManager(cert_reqs = cert_reqs)
auth_url = f'https://{fmc_ip}/api/fmc_platform/v1/auth/generatetoken'
type = {'Content-Type': 'application/json'}
auth = urllib3.make_headers(basic_auth=f'{username}:{password}')
headers = { **type, **auth }
resp = http.request('POST',
auth_url,
headers=headers,
timeout=10.0)
在这个问题上,我看到了很多答案,但是,我认为,太多不必要的信息会导致混乱 只需添加
cert\u reqs='cert\u NONE'
参数
import urllib3
http = urllib3.PoolManager(cert_reqs='CERT_NONE')
真奇怪。它确实或应该发回一份证书。这些服务通过浏览器工作。我的意思是,它是由ssl certs Debian包生成的自签名证书。与上面的错误相同。相反,看起来我使用的是Ubuntu中提供的旧版本urllib3,1.5。即使如此,提交到目前为止还没有进入“发布”阶段(上一个版本是1.6,3个月前,合并是2个月前)@MarcoCeppi我将在下周推出一个新版本。我们刚刚解决了几个悬而未决的大问题,我需要在发布之前进行清理。也就是说,现在欢迎您使用master分支,它应该是稳定的。@shazow谢谢您,不幸的是,我受到Ubuntu档案中任何内容的约束,所以这在相当长的一段时间内不会影响我。我已经接受了这个答案作为解决方案,但我最终还是重新使用了我们的基础设施来解决这个问题。@MarcoCeppi为这些问题感到抱歉。:)我会尽力为你加快速度。新版本发布后,
assert_hostname
也是构造函数iirc上的一个参数。因此,您不需要额外的行。如果有人出现:这也可以像urllib3.PoolManager(cert\u reqs='cert\u NONE')