SSLError przez proxy w requests i urllib3

Bezpieczne połączenie nie zostało nawiązane: albo program próbował mówić TLS do proxy, które czeka na zwykły HTTP, albo certyfikat strony nie przeszedł weryfikacji.

Zaktualizowano · Redakcja Prokso

W skrócie
  • Błąd wrong version number przez proxy prawie zawsze oznacza schemat https:// w linii proxy HTTP
  • CERTIFICATE_VERIFY_FAILED dotyczy certyfikatu strony: proxy w tunelu CONNECT nie zmienia szyfrowania
  • Pisz http:// dla portu 823, zaktualizuj certifi i nie wyłączaj weryfikacji przez verify=False

Co oznacza błąd

Gdy requests otwiera stronę https przez proxy HTTP, najpierw prosi proxy o otwarcie tunelu metodą CONNECT. Dalej proxy tylko przekazuje bajty, a szyfrowane połączenie powstaje między Twoim kodem a stroną. Dlatego certyfikat, który sprawdza requests, wysłała strona, a nie proxy.

Najczęstszy błąd to linia proxy ze schematem https://. Wtedy urllib3 próbuje nawiązać TLS z samym proxy, a port 823 czeka na zwykły HTTP. W odpowiedzi przychodzi nie TLS i OpenSSL zgłasza [SSL: WRONG_VERSION_NUMBER] wrong version number. W obecnej urllib3 2.x jest to opakowane w ProxyError z podpowiedzią Your proxy appears to only use HTTP and not HTTPS, try changing your proxy URL to be HTTP.

CERTIFICATE_VERIFY_FAILED to inna sytuacja: TLS ze stroną się zaczął, ale łańcuch certyfikatów nie przeszedł weryfikacji. Przez tunel CONNECT przyczyny są takie same jak bez proxy: nieaktualny zestaw certyfikatów głównych, podmiana certyfikatu przez antywirus lub sieć firmową, zmienne REQUESTS_CA_BUNDLE lub CURL_CA_BUNDLE wskazujące na inny plik.

Przyczyny

  • Schemat https:// dla proxy HTTP. Linia https://LOGIN:HASŁO@gw.prokso.com:823 zmusza bibliotekę do szyfrowania połączenia z proxy i pojawia się wrong version number.
  • Schemat http:// na porcie SOCKS5. Port 824 działa tylko w protokole SOCKS5. Żądanie HTTP nie dostanie odpowiedzi HTTP, a treść błędu będzie niezrozumiała.
  • Przechwytywanie HTTPS. Antywirus lub firmowa brama podstawia własny certyfikat i requests zgłasza CERTIFICATE_VERIFY_FAILED, często z tekstem self-signed certificate in certificate chain.
  • Nieaktualny certifi lub inny plik CA. Requests bierze certyfikaty główne z pakietu certifi, a zmienna REQUESTS_CA_BUNDLE może podmienić ten zestaw.
  • Problem z certyfikatem samej strony. Certyfikat wygasł lub został wystawiony na inną domenę. Wtedy błąd wystąpi także bez proxy.

Jak to naprawić

  1. Dla portu 823 i portów 10000–20000 w trybie HTTP pisz schemat http://: 'https': 'http://LOGIN:HASŁO@gw.prokso.com:823'. Klucz 'https' w słowniku oznacza schemat strony, a nie proxy.
  2. Dla SOCKS5 używaj socks5h://LOGIN:HASŁO@gw.prokso.com:824 i zainstaluj zależności SOCKS. Przykłady dla obu protokołów są w instrukcji Python requests, a wszystkie porty i formaty linii w opisie bramy.
  3. Zaktualizuj pakiety poleceniem pip install -U requests certifi i sprawdź, czy nie są ustawione REQUESTS_CA_BUNDLE i CURL_CA_BUNDLE: env | grep CA_BUNDLE.
  4. Jeśli pracujesz w sieci firmowej lub z antywirusem skanującym HTTPS, podaj ścieżkę do ich certyfikatu głównego: verify='/ścieżka/do/ca.pem'.
  5. Nie ustawiaj verify=False. Według dokumentacji requests ten parametr dotyczy tylko certyfikatu strony: nie usunie wrong version number od proxy, a CERTIFICATE_VERIFY_FAILED jedynie ukryje, zostawiając połączenie bez ochrony przed podmianą.

Jak sprawdzić, czy działa

Uruchom requests.get('https://prokso.com/ip', proxies=proxies, timeout=30) z włączoną weryfikacją certyfikatów. Jeśli dostaniesz JSON z IP proxy, tunel i TLS działają. Dla porównania otwórz stronę Mój IP w przeglądarce przez to samo proxy: jeśli tam błędu nie ma, a w kodzie jest, problem leży w ustawieniach Pythona.

Diagnoza w 2 minuty

Najpierw wklej linię do sprawdzania proxy. Jeśli tam proxy działa, przyczyna leży w programie lub jego ustawieniach. Jeśli nie - sprawdź linię z terminala:

curl -v -x "http://LOGIN:HASŁO@gw.prokso.com:823" https://api.ipify.org
  • Wiersz < HTTP/1.1 407 zaraz po CONNECT oznacza, że odpowiada proxy. Nazwa po kodzie, na przykład NO_USER, wskazuje przyczynę.
  • Proxy odpowiedziało na CONNECT kodem 200, a potem przyszedł inny kod - proxy działa, tę odpowiedź dała strona.
  • Brak odpowiedzi, tylko przekroczony czas - połączenie nie dotarło do proxy: sprawdź host, port i sieć.

Instrukcje, w których pojawia się ten błąd

Pytania i odpowiedzi (FAQ)

Czy proxy Prokso może podmienić certyfikat strony?

Nie. W tunelu CONNECT szyfrowanie powstaje między Twoim programem a stroną, a proxy przekazuje już zaszyfrowane dane. Więcej na stronie <a href="/pl/errors/ssl-certificate-errors">błędy SSL i certyfikatów</a>.

Strona jest na https://, więc proxy też musi być https://?

Nie. Schemat adresu strony i schemat linii proxy to różne rzeczy. Strona może być na https://, a połączenie z proxy na porcie 823 zwykłym http://, wewnątrz którego biegnie szyfrowany tunel.

Dlaczego błąd jest tylko w Pythonie, a przeglądarka otwiera stronę?

Przeglądarka ma własny magazyn certyfikatów, a requests korzysta z pakietu certifi lub pliku ze zmiennej REQUESTS_CA_BUNDLE. Zaktualizuj certifi i sprawdź zmienne środowiskowe.

Rezydencjalne $1.59, mobilne $2.50, serwerowe $0.65 za 1 GB

Rejestracja w minutę, dostęp od razu po płatności.

Utwórz konto