2013-08-05 2 views
3

Я использую 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') 
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 

ответ

3

Попробуйте следующий код:

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

См Setting assert_hostname to False will disable SSL hostname verification

+0

Такая же ошибка, как указано выше. Скорее, похоже, что я использую более старую версию urllib3, 1.5, как показано в Ubuntu. Даже так, что фиксация еще не дошла до «релиза» (последняя версия была 1.6, которая была 3 месяца назад, это слияние было 2 месяца назад) –

+2

@MarcoCeppi На следующей неделе я вышлю новый релиз. У нас просто было несколько крупных нерешенных проблем, которые мне нужно было очистить перед публикацией. Тем не менее, вы можете использовать ведущую ветвь на данный момент, она должна быть стабильной. – shazow

+0

@shazow Спасибо за это, к сожалению, я связан тем, что находится в архивах Ubuntu, поэтому это не повлияет на меня в течение довольно долгого времени. Я принял этот ответ как резолюцию, но я решил переработать нашу инфраструктуру, чтобы обойти эту проблему. –

1

Попробуйте создать экземпляр подключение бассейн таким образом:

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


EDIT (после просмотра вашего редактирования):

Это похоже, что удаленный хост не отправил сертификат (возможно ли это?). Это код (от 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() возвращается пустая строка.

+0

Не работает. Появилось новое исключение, обновленный вопрос –

+0

Это действительно странно. Он делает или должен отправить сертификат. Услуги работают через браузеры. Я имею в виду, это самозаверяющий сертификат, созданный пакетом Debian ssl-certs. –