21

自己署名証明書を持つプライベート サービスに対して 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')
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

を使用cURLして、サービスから期待される応答を得ることができます

$ curl -k https://10.0.3.168:9001/
Please read the documentation for API endpoints
4

4 に答える 4

17

次のコードを試してください:

import urllib3
c = urllib3.HTTPSConnectionPool('10.0.3.168', port=9001, cert_reqs='CERT_NONE',
                                assert_hostname=False)
c.request('GET', '/')

assert_hostname を False に設定すると SSL ホスト名の検証が無効になるを参照してください。

于 2013-08-05T15:45:52.620 に答える
7

この質問には多くの回答がありますが、私見ですが、混乱を招く可能性のある不要な情報が多すぎます。

cert_reqs='CERT_NONE'パラメータを追加するだけ

import urllib3
http = urllib3.PoolManager(cert_reqs='CERT_NONE')
于 2021-02-16T08:20:03.420 に答える
2

この方法で接続プールをインスタンス化してみてください。

HTTPSConnectionPool(self.host, self.port, cert_reqs=ssl.CERT_NONE)

またはこの方法:

HTTPSConnectionPool(self.host, self.port, cert_reqs='CERT_NONE')

ソース: https://github.com/shazow/urllib3/blob/master/test/with_dummyserver/test_https.py


編集(編集を見た後):

リモート ホストが証明書を送信していないようです (可能ですか?)。これは、例外を発生させた (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()

于 2013-08-05T15:34:37.027 に答える