/ / Jak wyłączyć sprawdzanie nazwy hosta w żądaniach python - python, ssl, python-request

Jak wyłączyć żądania sprawdzania nazwy hosta python - python, ssl, python-request

Korzystam z żądań, aby połączyć się z interfejsem API RESTful. Serwer, z którym chciałbym skorzystać, korzysta z protokołu ssl z certyfikatem samokopiującym.

cafile = "gateway.pem"
r = requests.get(request, auth=("admin", "password"), verify=cafile)

problem polega na tym, że otrzymuję SSLError nazwy hostaniedopasowanie. powinien istnieć sposób na wyłączenie sprawdzania nazwy hosta bez wyłączania sprawdzania poprawności certyfikatu, tak jak w wielu implementacjach Java, ale nie mogę znaleźć sposobu na wykonanie tego w żądaniach w Pythonie.

Ślad stosu:

Traceback (most recent call last):
File "<pyshell#43>", line 1, in <module>
r = requests.get(request, auth=("admin", "password"), verify="gateway.pem")
File "C:Python27libsite-packagesrequests-2.0.0-py2.7.eggrequestsapi.py", line 55, in get
return request("get", url, **kwargs)
File "C:Python27libsite-packagesrequests-2.0.0-py2.7.eggrequestsapi.py", line 44, in request
return session.request(method=method, url=url, **kwargs)
File "C:Python27libsite-packagesrequests-2.0.0-py2.7.eggrequestssessions.py", line 357, in request
resp = self.send(prep, **send_kwargs)
File "C:Python27libsite-packagesrequests-2.0.0-py2.7.eggrequestssessions.py", line 460, in send
r = adapter.send(request, **kwargs)
File "C:Python27libsite-packagesrequests-2.0.0-py2.7.eggrequestsadapters.py", line 358, in send
raise SSLError(e)
SSLError: hostname "10.76.92.70" doesn"t match u"lital.com"

Jak to zrobić?

Odpowiedzi:

8 dla odpowiedzi № 1

Żądania nie pozwalają na to bezpośrednio, jednak można zapewnić niestandardowy adapter transportu, który korzysta z funkcji urządzenia bazowego urllib3. Korzystanie z adapterów transportowych jest opisane w dokumentacji wniosków.

Ten kod nie jest testowany, ale powinien działać.

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager


# Never check any hostnames
class HostNameIgnoringAdapter(HTTPAdapter):
def init_poolmanager(self, connections, maxsize, block=False):
self.poolmanager = PoolManager(num_pools=connections,
maxsize=maxsize,
block=block,
assert_hostname=False)


# Check a custom hostname
class CustomHostNameCheckingAdapter(HTTPAdapter):
def cert_verify(self, conn, url, verify, cert):
#      implement me
host = custom_function_mapping_url_to_hostname(url)
conn.assert_hostname = host
return super(CustomHostNameCheckingAdapter,
self).cert_verify(conn, url, verify, cert)

Szczegółowo assert_hostname param działa w następujący sposób: Gdyby None użyj nazwy hosta z adresu URL, jeśli False pomiń sprawdzanie nazwy hosta, jeśli ciąg niestandardowy sprawdza poprawność względem tego ciągu.


4 dla odpowiedzi nr 2

Jestem trochę spóźniony na przyjęcie, ale requests_toolbelt wygląda na to, że może pomóc, jeśli zainstalujesz wersję 0.7.0 lub nowszą (moje Ubuntu 16.04 ma tylko 0.6.0): https://toolbelt.readthedocs.io/en/latest/adapters.html#hostheaderssladapter

Z linku:

Example usage:
>>> s.mount("https://", HostHeaderSSLAdapter())
>>> s.get("https://93.184.216.34", headers={"Host": "example.org"})

1 dla odpowiedzi nr 3

Czy zajrzałeś do SSLContext.check_hostname parametr? Powinieneś być w stanie ustawić go na False i nie powinien sprawdzać nazwy hosta:

context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
context.load_default_certs()

Jedynym ograniczeniem jest to, że działa to tylko w Pythonie 3.4 i nowszych.

Odniesienie: https://docs.python.org/3/library/ssl.html#ssl.SSLContext.check_hostname


-2 dla odpowiedzi № 4

http://docs.python-requests.org/en/latest/user/advanced/#ssl-cert-verification

verify słowo kluczowe jest flagą, a nie do dostarczania pliku certyfikatu. Podałeś tam niepisany ciąg, który rozwiązuje True w kontekście logicznym.

Posługiwać się cert= słowo kluczowe, aby podać ścieżkę do plików certyfikatu lub wyłączyć weryfikację za pomocą verify=False.

EDYTOWAĆ: chociaż dokumentacja mówi, że można przekazać ścieżkę urzędu certyfikacji verify=, ale nie ma przykładów. Byłoby pomocne zobaczyć cały otrzymywany ślad.


-3 dla odpowiedzi № 5

Jeśli jest to tylko do testowania, po prostu dodaj wpis w / etc / hosts do swojego lokalnego systemu (zakładając, że masz dostęp).