Jeśli choć raz otwierałeś panel klienta w serwisie proxy, widziałeś ten obrazek: ten sam adres, ten sam login, a obok dwa porty. Jeden podpisany HTTP, drugi SOCKS5. Wiele osób wybiera na chybił trafił albo z przyzwyczajenia. Tymczasem za tymi dwiema linijkami stoją dwa różne protokoły, które inaczej wyglądają na poziomie bajtów, inaczej widzą twój ruch i inaczej zachowują się w realnych klientach. Ten przewodnik rozbiera różnicę do ostatniego bajtu i kończy się praktycznymi tabelami wyboru.

Wprowadzenie: dlaczego jedno proxy jest wydawane w dwóch trybach i to nie marketing

Zacznijmy od uczciwej odpowiedzi na pytanie z tytułu. Kiedy Proxeon wydaje ci adres z dwoma portami, za nimi stoi ta sama maszyna, ten sam wychodzący adres IP i to samo konto. Różnica nie polega na tym, dokąd trafia ruch. Różnica polega na tym, w jakim języku twój klient rozmawia z serwerem proxy na pierwszym odcinku drogi: od twojej aplikacji do pośrednika.

Proxy HTTP rozmawia w języku HTTP. Przyjmuje żądania HTTP, czyta je, rozumie, co chcesz pobrać, i sam idzie po zasób. Potrafi cachować, dodawać nagłówki, odpowiadać kodami statusu. Dla wszystkiego, co nie jest HTTP, ma jeden uniwersalny trik: metodę CONNECT, która zamienia go w głupią rurę.

SOCKS5 w ogóle nie wie, czym jest HTTP. To protokół na poziomie sesji: klient mówi „połącz mnie z takim hostem i portem”, proxy otwiera połączenie TCP i od tego momentu po prostu przekłada bajty tam i z powrotem. Jest mu obojętne, co jest w środku: TLS, IMAP, SSH, protokół bazy danych czy twój własny binarny format.

Dlaczego nie można zostawić tylko jednego trybu? Bo mają różną kompatybilność. Połowa firmowego i desktopowego oprogramowania obsługuje tylko proxy HTTP przez ustawienia systemowe. Znaczna część bibliotek sieciowych i praktycznie cały ruch nie-webowy czuje się wygodniej w SOCKS5. Wydawanie obu trybów na jednym IP oznacza, że wybierasz narzędzie pod klienta, a nie dopasowujesz klienta do narzędzia.

Czego dowiesz się z tego artykułu:

  • jak wygląda żądanie do proxy HTTP na poziomie tekstu i czym różni się od zwykłego żądania do strony;
  • co dokładnie proxy widzi i może zmienić w trybie przezroczystym HTTP;
  • jak działa metoda CONNECT i co pozostaje widoczne dla pośrednika po ustanowieniu tunelu;
  • bajtowy uścisk dłoni SOCKS5, schematy uwierzytelniania i trzy typy adresów ATYP;
  • dlaczego wybór między domeną a IP w żądaniu SOCKS5 wpływa na geolokalizację i prywatność DNS;
  • porównanie pod kątem protokołów nie-HTTP, UDP, narzutu, cachowania i logowania;
  • tabelę „zadanie, protokół, dlaczego” i rozbiór kompatybilności w popularnych klientach i bibliotekach.

Mechaniki komendy UDP ASSOCIATE i różnicy między schematami socks5 i socks5h w curl i Pythonie nie rozbieramy tu szczegółowo: tym tematom poświęcone są osobne materiały na blogu Proxeon, do których linki pojawią się w odpowiednich miejscach.

Podstawy: gdzie proxy żyje w stosie sieciowym

Żeby rozmowa o protokołach miała sens, ustalmy terminy. Jest ich niewiele.

Trzej uczestnicy i dwa połączenia

W każdym układzie z proxy są trzy strony: klient (twoja przeglądarka, skrypt, program pocztowy), serwer proxy (pośrednik) i serwer docelowy (origin). Między nimi są dwa niezależne połączenia TCP. Pierwsze: klient do proxy. Drugie: proxy do serwera docelowego. Serwer docelowy widzi tylko drugie połączenie i, co za tym idzie, tylko adres IP proxy.

Wszystko, o czym mówimy w tym artykule, dotyczy wyłącznie pierwszego połączenia. Właśnie tam mieszka różnica między HTTP i SOCKS5. Drugie połączenie w obu przypadkach wygląda tak samo: zwykły TCP od proxy do hosta docelowego.

Poziomy modelu i dlaczego to ważne

Przydatna analogia: wyobraź sobie firmę kurierską. Proxy HTTP w trybie przezroczystym przypomina kuriera, który otwiera twoją paczkę, czyta adres i zawartość, w razie potrzeby przepakowuje i może nawet odpowiedzieć sam, jeśli na magazynie ma kopię. SOCKS5 przypomina kuriera, któremu podajesz adres, a paczkę oddajesz zapieczętowaną. Nie wie i nie chce wiedzieć, co jest w środku.

Mówiąc w terminach modelu sieciowego, proxy HTTP działa na poziomie aplikacji: rozumie semantykę żądania. SOCKS5 działa na poziomie sesji: operuje pojęciami „host”, „port”, „połączenie” i nie wznosi się wyżej.

Gdzie następuje rozwiązywanie nazw

Osobny koncept, który przewija się przez cały materiał: rozwiązywanie DNS. Kiedy odwołujesz się do example.com, ktoś musi zamienić nazwę na adres IP. Może to zrobić twój klient lokalnie, a może proxy po swojej stronie. Od tego zależy, czyjej infrastruktury DNS używasz, jaką odpowiedź regionalną dostaniesz od CDN i czy informacja o odwiedzanych domenach wycieka do sieci lokalnej. Zapamiętaj ten punkt, wróci i w sekcji o HTTP, i w sekcji o SOCKS5.

Uwierzytelnianie

I proxy HTTP, i SOCKS5 potrafią sprawdzać login i hasło, ale robią to inaczej. HTTP używa nagłówka Proxy-Authorization i kodu odpowiedzi 407. SOCKS5 używa osobnego podprotokołu z numerem metody 0x02. Jest też alternatywa niezależna od protokołu: autoryzacja po adresie IP klienta, gdy proxy wpuszcza wszystkich, którzy przyszli z wcześniej zatwierdzonego adresu. W Proxeon dostępne są oba warianty, a wybór między nimi wpływa na to, jak łatwo podłączyć klienty, które nie potrafią przekazywać danych uwierzytelniających.

Proxy HTTP: żądanie z absolutnym URI, co proxy widzi i może zmienić

Zwykłe żądanie HTTP do strony wygląda tak:

GET /catalog/items?page=2 HTTP/1.1
Host: shop.example

Zwróć uwagę: w linii żądania jest tylko ścieżka. Host jest przekazywany osobnym nagłówkiem. Taki format nazywa się origin-form. Kiedy klient wie, że rozmawia nie ze stroną, a z proxy, zmienia format na absolute-form: w linię żądania trafia pełny URI.

GET http://shop.example/catalog/items?page=2 HTTP/1.1
Host: shop.example
Proxy-Authorization: Basic dXNlcjpwYXNz
User-Agent: my-parser/1.0
Accept: text/html

Po co duplikować host? Historycznie forma absolutna pojawiła się wcześniej niż nagłówek Host i była jedynym sposobem, by powiedzieć proxy, dokąd iść. Współczesny standard HTTP/1.1 wymaga od proxy umiejętności przyjmowania formy absolutnej, a od klientów zwracających się do proxy używania właśnie jej. Nagłówek Host przy tym zostaje dla kompatybilności i dla serwera docelowego, któremu proxy prześle żądanie już w origin-form.

Co widzi proxy HTTP

W trybie przezroczystym (bez szyfrowania między klientem a stroną docelową) proxy widzi absolutnie wszystko, co jest w żądaniu i odpowiedzi:

  • metodę, pełny URL, łącznie z parametrami query;
  • wszystkie nagłówki żądania: User-Agent, Cookie, Authorization, Referer;
  • ciało żądania w całości: formularze, JSON, wgrywane pliki;
  • status odpowiedzi, nagłówki odpowiedzi i ciało odpowiedzi.

To nie efekt uboczny. To fundamentalna cecha architektury: żeby przekazać żądanie, proxy musi je sparsować. A skoro je sparsował, może z nim zrobić wszystko.

Co proxy HTTP może zmienić

Standard dzieli nagłówki na end-to-end (przechodzące przez całą trasę) i hop-by-hop (przeskok po przeskoku). Nagłówki hop-by-hop dotyczą jednego konkretnego połączenia i muszą być usunięte przez proxy przed przekazaniem. Należą do nich Connection, Keep-Alive, Proxy-Authorization, Proxy-Authenticate, TE, Trailer, Transfer-Encoding, Upgrade. Właśnie dlatego twój login i hasło do proxy nie lecą na stronę docelową: nagłówek Proxy-Authorization jest zgodnie ze standardem zdejmowany na proxy.

Poza obowiązkowym czyszczeniem proxy może:

  • dodać nagłówek Via z nazwą swoją i wersją protokołu; standard tego wymaga, ale w praktyce anonimowe proxy go pomijają;
  • dodać X-Forwarded-For z rzeczywistym IP klienta; tak robią firmowe proxy, i tak nigdy nie powinno robić proxy, które kupujesz do pracy z zewnętrznymi zasobami;
  • oddać odpowiedź ze swojego cache, nie odwołując się do serwera docelowego, jeśli odpowiedź jest oznaczona jako cacheowalna;
  • zmienić kodowanie ciała, dodać lub zdjąć kompresję, przepisać linki w HTML;
  • odrzucić żądanie własną odpowiedzią, na przykład 403 lub 407.

Odpowiedź 407 Proxy Authentication Required zasługuje na osobne wspomnienie. Jeśli proxy wymaga autoryzacji, a klient jej nie przesłał, proxy odpowiada statusem 407 i nagłówkiem Proxy-Authenticate, gdzie wymienia obsługiwane schematy. Dobre klienty po tym powtarzają żądanie z Proxy-Authorization. Złe klienty pokazują użytkownikowi niezrozumiały błąd. Stąd typowy problem przy konfiguracji: aplikacja „nie widzi proxy”, gdy w rzeczywistości po prostu nie umie obsłużyć 407.

Rozbieramy na praktyce

Najprostszy sposób, by zobaczyć to wszystko na własne oczy: curl z kluczem -v.

curl -v -x http://user:pass@gate.proxeon.net:8080 http://httpbin.org/get

W wyjściu zobaczysz linię w postaci GET http://httpbin.org/get HTTP/1.1 i nagłówek Proxy-Authorization. To właśnie forma absolutna.

To samo żądanie ręcznie przez socket w Pythonie, żeby nie zostało żadnej magii:

import socket, base64

creds = base64.b64encode(b"user:pass").decode()
req = (
"GET http://httpbin.org/get HTTP/1.1\r\n"
"Host: httpbin.org\r\n"
f"Proxy-Authorization: Basic {creds}\r\n"
"Connection: close\r\n\r\n"
)
s = socket.create_connection(("gate.proxeon.net", 8080))
s.sendall(req.encode())
print(s.recv(65535).decode(errors="replace"))

Nie ma tu ani jednej biblioteki do proxy. Tylko socket i poprawnie złożony łańcuch. Proxy HTTP w trybie przezroczystym jest tak proste, że można je napisać w jeden wieczór, i w tym jednocześnie jego siła i słabość.

Gdzie rozwiązuje się nazwa w trybie HTTP

W formie absolutnej klient przekazuje proxy nazwę hosta taką, jaka jest. Rozwiązywanie wykonuje proxy. Klient nie musi znać adresu IP serwera docelowego i lokalne zapytanie DNS nie jest wykonywane. To wygodne, ale prowadzi nas do głównego ograniczenia: opisany schemat działa tylko dla niezaszyfrowanego HTTP. Dla HTTPS forma absolutna jest bezużyteczna, bo połączenie TLS musi być ustanowione między klientem a serwerem docelowym, a proxy nie może wejść w środek, nie łamiąc certyfikatu. Dlatego właśnie wymyślono CONNECT.

Metoda CONNECT: zamiana proxy HTTP w tunel TCP

CONNECT to metoda HTTP, która prosi proxy nie o przekazanie żądania, ale o ustanowienie połączenia TCP z podanym hostem i portem, a następnie o stanie się przezroczystą rurą. Żądanie wygląda tak:

CONNECT shop.example:443 HTTP/1.1
Host: shop.example:443
Proxy-Authorization: Basic dXNlcjpwYXNz
Proxy-Connection: Keep-Alive

Zwróć uwagę na format celu: tylko host i port, bez schematu i ścieżki. To authority-form żądania, trzeci z formatów po origin-form i absolute-form.

Jeśli proxy się zgadza, odpowiada:

HTTP/1.1 200 Connection established

Tekst po kodzie może być dowolny, klienty kierują się tylko na 2xx. Od tego momentu HTTP się kończy. Wszystko, co klient pisze do socketu, proxy bajt w bajt przekazuje serwerowi docelowemu, i odwrotnie. Klient zaczyna uścisk dłoni TLS prosto w tym sockecie, jak gdyby był podłączony do serwera bezpośrednio.

Co pośrednik widzi po CONNECT

Tu zaczyna się najciekawsze. Proxy, które przed chwilą było wszechwidzące, nagle ślepnie. Po udanym CONNECT proxy wie:

  • nazwę hosta i port z linii CONNECT; to jedyna informacja semantyczna, jaką otrzymało;
  • czas ustanowienia i zamknięcia połączenia;
  • objętość przekazanych bajtów w obie strony;
  • zawartość TLS ClientHello, jeśli wewnątrz tunelu jest TLS: tam w otwartej postaci przekazywane jest SNI (nazwa serwera), lista obsługiwanych szyfrów, rozszerzenia; współczesne rozszerzenie Encrypted Client Hello ukrywa też SNI, ale jego wsparcie nie jest jeszcze powszechne;
  • nic z poziomu HTTP: ani URL, ani nagłówków, ani ciasteczek, ani ciała.

Innymi słowy, po CONNECT proxy HTTP widzi dokładnie tyle samo, co SOCKS5. Host, port, czasy, objętości. Różnica w widoczności między oboma protokołami istnieje tylko dla niezaszyfrowanego ruchu HTTP, a tego w 2026 roku w realnych zadaniach zostało bardzo mało.

CONNECT nie musi prowadzić do HTTPS

Częsty błąd myślenia: CONNECT jest potrzebny tylko dla HTTPS. W rzeczywistości standard nie ogranicza zawartości tunelu. Przez CONNECT można ustanowić połączenie z serwerem IMAP na porcie 993, z SSH na porcie 22, z dowolną usługą TCP. Pytanie tylko, czy pozwala na to konfiguracja proxy. Wiele publicznych i firmowych proxy HTTP pozwala na CONNECT tylko na porty 443 i czasem 80, żeby zapobiec nadużyciom. Proxeon pozwala na CONNECT na dowolne porty, ale jeśli twój soft umie SOCKS5, dla protokołów nie-HTTP pozostaje on bardziej naturalnym wyborem, o czym niżej.

Przykład: TLS przez CONNECT ręcznie

Narzędzie openssl umie samo przejść przez proxy HTTP:

openssl s_client -proxy gate.proxeon.net:8080 -connect shop.example:443 -servername shop.example

A tak to wygląda w Pythonie ze standardową biblioteką, bez zewnętrznych zależności:

import http.client, ssl

conn = http.client.HTTPSConnection("gate.proxeon.net", 8080,
 context=ssl.create_default_context())
conn.set_tunnel("shop.example", 443,
headers={"Proxy-Authorization": "Basic dXNlcjpwYXNz"})
conn.request("GET", "/")
resp = conn.getresponse()
print(resp.status, resp.getheader("server"))

Metoda set_tunnel robi dokładnie to, co opisano wyżej: wysyła CONNECT, czeka na 200, potem opakowuje socket w TLS. Zauważ, że kontekst TLS sprawdza certyfikat właśnie shop.example, a nie proxy. Proxy w tym schemacie nie może podłożyć certyfikatu, nie wywołując błędu u klienta.

CONNECT w HTTP/2 i HTTP/3

W HTTP/2 metoda CONNECT się zachowała, ale działa wewnątrz jednego multipleksowanego połączenia: każdy tunel to osobny strumień. To pozwala trzymać dziesiątki tuneli przez jedno połączenie TCP z proxy i oszczędzać na uściskach dłoni. Rozszerzony CONNECT (z pseudo-nagłówkiem :protocol) jest używany dla WebSocket po HTTP/2. W HTTP/3 na bazie QUIC pojawiła się specyfikacja CONNECT-UDP, która formalnie pozwala tunelować UDP przez proxy HTTP. Jednak w bibliotekach klienckich to na razie egzotyka, a w praktyce, jeśli potrzebujesz UDP przez proxy, będziesz patrzeć w stronę SOCKS5.

Czego CONNECT nie umie

  • Cachować: zawartość tunelu jest nieprzezroczysta.
  • Modyfikować nagłówków: po prostu ich nie widać.
  • Multipleksować kilku hostów docelowych przez jeden tunel w HTTP/1.1: jeden CONNECT równa się jednemu połączeniu TCP.
  • Przekazywać UDP w HTTP/1.1 i HTTP/2.

SOCKS5: uścisk dłoni, uwierzytelnianie i ATYP

SOCKS5 jest opisany w RFC 1928, a jego schemat uwierzytelniania loginem i hasłem w RFC 1929. Obie specyfikacje mieszczą się na kilku stronach i to jedna z zalet protokołu: zaimplementować go od zera nie jest trudno, więc implementacji jest dużo i rzadko rozjeżdżają się w interpretacji.

SOCKS5 to protokół binarny. Żadnego tekstu, tylko bajty o stałej strukturze. Przeanalizujmy pełną wymianę dla komendy CONNECT.

Krok 1: powitanie i wybór metody uwierzytelniania

Klient wysyła wersję i listę metod uwierzytelniania, które obsługuje:

05 02 00 02
VER=5 NMETHODS=2 METHODS: 00 (bez uwierzytelniania), 02 (login/hasło)

Serwer wybiera jedną metodę i odpowiada dwoma bajtami:

05 02
VER=5 METHOD=02 (serwer wymaga loginu i hasła)

Jeśli serwer odpowie 05 FF, oznacza to „żadna z zaproponowanych metod nie pasuje” i klient musi zamknąć połączenie. Dokładnie tak wygląda na poziomie bajtów sytuacja, gdy zapomniałeś podać hasło, a proxy Proxeon jest skonfigurowane na autoryzację loginem.

Krok 2: uwierzytelnianie według RFC 1929

Jeśli wybrano metodę 02, klient wysyła:

01 04 75 73 65 72 04 70 61 73 73
VER=1 ULEN=4 UNAME="user" PLEN=4 PASSWD="pass"

Zwróć uwagę: wersja podprotokołu to tu 01, a nie 05. To częste źródło błędów w samodzielnie pisanych klientach. Serwer odpowiada:

01 00
VER=1 STATUS=00 (sukces; każda inna wartość oznacza odmowę)

Login i hasło są przekazywane otwartym tekstem. Jeśli między tobą a proxy jest niezaufana sieć, warto o tym pamiętać. W praktyce połączenie z proxy idzie zwykle własnym kanałem dostawcy, a sprawa rozwiązuje się na poziomie transportu lub zamianą na autoryzację po IP.

Krok 3: żądanie połączenia

Teraz najważniejsza wiadomość:

05 01 00 03 0C 73 68 6F 70 2E 65 78 61 6D 70 6C 65 01 BB
VER=5 CMD=01 (CONNECT) RSV=00 ATYP=03 (domena)
LEN=12 ADDR="shop.example" PORT=0x01BB (443)

Pole CMD przyjmuje trzy wartości: 01 CONNECT (wychodzące połączenie TCP), 02 BIND (oczekiwanie na połączenie przychodzące, praktycznie nieużywane), 03 UDP ASSOCIATE (utworzenie retransmitera UDP). Mechanikę UDP ASSOCIATE i jej pułapki rozebraliśmy w osobnym artykule o UDP w SOCKS5, tu tylko zanotujmy: to jedyny z dwóch protokołów, który ma UDP w standardzie.

ATYP: domena kontra IP

Pole ATYP określa, w jakiej postaci klient przekazał adres docelowy:

  • 0x01 IPv4: kolejne 4 bajty to adres;
  • 0x03 nazwa domenowa: jeden bajt długości, potem nazwa bez zeru kończącego;
  • 0x04 IPv6: kolejne 16 bajtów to adres.

Wydawałoby się, że to szczegół techniczny. W rzeczywistości to jedna z najważniejszych decyzji, jaką podejmuje klient, i oto dlaczego.

Jeśli klient używa ATYP=0x01 lub 0x04, to znaczy, że sam wykonał rozwiązywanie DNS przed wysłaniem żądania. Twoja maszyna zwróciła się do swojego serwera DNS, dostała adres i przekazała proxy gotowe IP. Konsekwencje:

  • zapytanie DNS poszło przez twoją sieć lokalną i jest widoczne dla twojego dostawcy lub administratora;
  • dostałeś ten IP, który DNS wydał dla twojego regionu; dla stron za CDN oznacza to, że proxy stojące w innym kraju będzie się łączyć z „obcym” edge-serwerem, co spowalnia połączenie i może wyglądać anomalnie;
  • jeśli twoja maszyna nie ma IPv6, nigdy nie dostaniesz rekordu AAAA i nie skorzystasz z trasy IPv6 proxy, nawet jeśli ona jest;
  • jeśli DNS w twojej sieci zachowuje się niestandardowo, proxy dostanie błędny adres i długo będziesz szukać przyczyny.

Jeśli klient używa ATYP=0x03, rozwiązywanie wykonuje proxy. Korzysta ze swojej infrastruktury DNS, dostaje adres właściwy dla swojej lokalizacji, a twoja sieć lokalna nie widzi, do jakich domen się odwołujesz. Dla zadań z geolokalizacją to krytyczne: sens proxy w danym kraju częściowo się gubi, jeśli serwer docelowy jest wybierany po DNS twojej domowej sieci.

Jak zmusić klienta, by przekazywał domenę? Zależy od klienta. W curl i bibliotekach Pythona odpowiada za to wybór schematu socks5 kontra socks5h, i to temat osobnego rozbioru. Tu ważne jest zrozumienie przyczyny: litera h oznacza „hostname” i włącza ATYP=0x03. Bez niej biblioteka rozwiązuje nazwę lokalnie.

Krok 4: odpowiedź serwera

05 00 00 01 C0 A8 01 0A 1F 90
VER=5 REP=00 (sukces) RSV=00 ATYP=01 BND.ADDR=192.168.1.10 BND.PORT=8080

Pole REP zawiera kod wyniku. Warto znać je na pamięć przy debugowaniu:

  • 00 sukces;
  • 01 ogólny błąd serwera;
  • 02 połączenie zabronione przez reguły;
  • 03 sieć nieosiągalna;
  • 04 host nieosiągalny;
  • 05 połączenie odrzucone przez serwer docelowy;
  • 06 upłynął TTL;
  • 07 komenda nieobsługiwana;
  • 08 typ adresu nieobsługiwany.

Kod 08 pojawia się na starych lub uproszczonych implementacjach, które nie obsługują ATYP=0x03 lub IPv6. Proxeon obsługuje wszystkie trzy typy adresów.

Dlaczego SOCKS5 nie analizuje zawartości

Po odpowiedzi REP=00 protokół SOCKS5 się skończył. Wszystko, co klient pisze dalej, proxy przekłada do połączenia docelowego bez analizy. To nie ograniczenie implementacji, a cecha projektu. SOCKS5 nie ma ani pojęcia „żądanie”, ani pojęcia „nagłówek”. Nie wie, czym jest HTTP, IMAP czy TLS. Przekazano mu adres i port, on połączył dwie rury.

Wynika z tego kilka praktycznych konsekwencji:

  • SOCKS5 nie może cachować: nie rozumie, gdzie kończy się jedna odpowiedź, a zaczyna druga;
  • SOCKS5 nie może dodawać nagłówków ani podkładać zawartości; maksimum, co może, to zamknąć połączenie;
  • SOCKS5 nie może filtrować po URL, tylko po hoście i porcie;
  • SOCKS5 równie dobrze działa z dowolnym protokołem TCP, w tym tym, który wymyśliłeś wczoraj.

Pełny uścisk dłoni SOCKS5 w Pythonie

import socket, struct

def socks5_connect(proxy, user, pwd, host, port):
s = socket.create_connection(proxy)
s.sendall(b"\x05\x02\x00\x02")
ver, method = s.recv(2)
if method == 0x02:
u, p = user.encode(), pwd.encode()
s.sendall(b"\x01" + bytes([len(u)]) + u + bytes([len(p)]) + p)
if s.recv(2)[1] != 0:
raise RuntimeError("auth failed")
elif method != 0x00:
raise RuntimeError("no acceptable auth method")
h = host.encode()
s.sendall(b"\x05\x01\x00\x03" + bytes([len(h)]) + h + struct.pack("!H", port))
reply = s.recv(4)
if reply[1] != 0:
raise RuntimeError(f"connect failed, REP={reply[1]}")
atyp = reply[3]
s.recv({1: 4, 4: 16}.get(atyp, 0) if atyp != 3 else s.recv(1)[0])
s.recv(2)
return s

sock = socks5_connect(("gate.proxeon.net", 1080), "user", "pass", "shop.example", 443)
# dalej sock można opakować w ssl.wrap_socket lub przekazać dowolnemu protokołowi

Trzydzieści linii i masz działającego klienta SOCKS5, który przekazuje domenę (ATYP=0x03) i zostawia rozwiązywanie serwerowi proxy. Właśnie ta prostota czyni z SOCKS5 standard de facto dla programowanego dostępu.

Porównanie po kryteriach: gdzie każde wygrywa

Teraz, gdy mechanika obu protokołów jest rozebrana do bajtów, porównanie przestaje być sporem o gusta i staje się listą mierzalnych różnic.

Protokoły nie-HTTP

SOCKS5 działa z dowolnym protokołem TCP w standardzie: komenda CONNECT, host, port, gotowe. Proxy HTTP też może przez CONNECT, ale z zastrzeżeniami: klient musi umieć wysyłać CONNECT dla ruchu nie-HTTP (klienty pocztowe umieją, większość narzędzi CLI nie), a proxy musi pozwalać na potrzebny port. Zwycięzca: SOCKS5.

UDP

SOCKS5 ma UDP ASSOCIATE. Proxy HTTP w wersjach 1.1 i 2 nie ma nic, a CONNECT-UDP z HTTP/3 praktycznie nie jest obsługiwany przez klientów. Jeśli zadanie obejmuje zapytania DNS bezpośrednio, QUIC, protokoły głosowe, ruch gier, nie ma wyboru. Zwycięzca: SOCKS5, z zastrzeżeniem, że nie każdy serwer SOCKS5 włącza UDP, sprawdź w dokumentacji taryfy.

Narzut na ustanowienie połączenia

Liczmy w rundach (RTT) między klientem a proxy, ponad samo połączenie TCP:

  • proxy HTTP, tryb przezroczysty, bez autoryzacji: 0 dodatkowych RTT, żądanie idzie od razu;
  • HTTP CONNECT z autoryzacją w pierwszym żądaniu: 1 RTT (CONNECT, odpowiedź 200);
  • SOCKS5 bez autoryzacji: 2 RTT (powitanie, żądanie);
  • SOCKS5 z loginem i hasłem: 3 RTT (powitanie, uwierzytelnianie, żądanie).

W bajtach różnica jest odwrotna: pełny uścisk dłoni SOCKS5 z autoryzacją mieści się w około 40 bajtach, a CONNECT z nagłówkami Host, Proxy-Authorization i User-Agent łatwo zajmuje 150 i więcej. Ale w realnych zadaniach decyduje RTT, nie bajty. Przy opóźnieniu do proxy 50 ms SOCKS5 z autoryzacją dodaje 150 ms do każdego nowego połączenia wobec 50 ms u CONNECT. Jeśli klient używa połączeń ponownie (keep-alive, pule), to jednorazowa opłata. Jeśli każde żądanie otwiera nowy socket, różnica się kumuluje. Zwycięzca pod kątem RTT: HTTP. Sposób na skrócenie dystansu dla SOCKS5: autoryzacja po IP, która usuwa jedno RTT.

Cachowanie

Tylko proxy HTTP w trybie przezroczystym. Nie CONNECT, nie SOCKS5. Przy tym cachować może tylko niezaszyfrowany ruch, którego dziś jest mało, więc to kryterium z decydującego stało się niszowe. Jest istotne dla wewnętrznych systemów budujących, luster pakietów, powtarzających się zapytań do API bez TLS w zaufanym obwodzie. Zwycięzca: HTTP, ale z wąskim obszarem zastosowania.

Logowanie

Ten punkt jest często rozumiany błędnie. Co może zapisać w logu proxy w każdym trybie?

  • HTTP przezroczysty: pełny URL, metodę, nagłówki, w razie potrzeby ciało; status odpowiedzi; objętości.
  • HTTP CONNECT: host i port z linii CONNECT; czas; objętości; w razie potrzeby SNI z ClientHello.
  • SOCKS5 z ATYP=0x03: nazwę domenową i port; czas; objętości; w razie potrzeby SNI.
  • SOCKS5 z ATYP=0x01/0x04: tylko IP i port; domeny proxy nie zna; czas; objętości; SNI.

Dla zaszyfrowanego ruchu CONNECT i SOCKS5 dają pośrednikowi taką samą widoczność. Różnica pojawia się tylko tam, gdzie klient SOCKS5 przekazuje IP zamiast domeny, i wtedy proxy wie nawet mniej. Ale serwer docelowy dostaje wtedy żądanie z „niewłaściwego” regionu, patrz sekcja o ATYP. Remis z niuansami.

Diagnostyka błędów

Proxy HTTP odpowiada czytelnymi dla człowieka kodami: 407 mówi o autoryzacji, 403 o zakazie, 502 o niedostępności celu, 504 o przekroczeniu czasu. Niektóre implementacje dodają ciało z wyjaśnieniem. SOCKS5 odpowiada jednym bajtem REP, i nie każda biblioteka tłumaczy go na zrozumiały komunikat. Przy debugowaniu w nieznanym środowisku proxy HTTP diagnozuje się łatwiej. Zwycięzca: HTTP.

Multipleksowanie

Proxy HTTP/2 pozwala przeprowadzić wiele tuneli CONNECT przez jedno połączenie. SOCKS5 wymaga osobnego połączenia TCP na każdy cel. Dla klientów z setkami równoległych połączeń to zauważalnie zmniejsza obciążenie stosu sieciowego i proxy. Ale wsparcie HTTP/2 do proxy w klientach jest na razie fragmentaryczne. Potencjalny zwycięzca: HTTP, faktyczny remis.

Możliwość ingerencji w ruch

Proxy HTTP w trybie przezroczystym może zmienić wszystko. W trybie CONNECT i w SOCKS5 może tylko zerwać połączenie. Dla klienta, który chce gwarancji niezmienności ruchu, najlepszy jest SOCKS5 albo CONNECT z TLS w środku. Zwycięzca pod kątem przewidywalności: SOCKS5.

Uwierzytelnianie

Oba umieją login i hasło. HTTP dodatkowo obsługuje schematy Digest, NTLM, Negotiate, co jest ważne w środowiskach firmowych. SOCKS5 formalnie ma metodę GSSAPI, ale w komercyjnych proxy praktycznie się nie spotyka. Dla pracy z serwisem takim jak Proxeon to nie ma znaczenia: używa się Basic albo białej listy IP.

Co wybrać pod zadanie: tabela

Zbierzmy wnioski w robocze narzędzie. Tabela wychodzi z założenia, że oba tryby są dostępne na jednym IP, tak jak w Proxeon, i pytanie dotyczy tylko tego, który port podać.

ZadanieZalecany protokółDlaczego
Przeglądarka do ręcznej pracy lub testówHTTP (z CONNECT dla HTTPS)Wszystkie przeglądarki obsługują proxy HTTP z autoryzacją przez ustawienia systemowe lub rozszerzenia; SOCKS5 z loginem i hasłem w przeglądarkach Chromium przez proxy systemowe nie działa, autoryzacja możliwa tylko po IP
Klient HTTP, parser, zbieracz danych w Pythonie, Node.js, GoSOCKS5 z przekazywaniem domeny (ATYP=0x03)Rozwiązywanie po stronie proxy daje właściwe regionalne adresy CDN, biblioteki obsługują oba tryby, a SOCKS5 nie ryzykuje ingerencji w nagłówki
Parser z dużą liczbą krótkich połączeń bez keep-aliveHTTP CONNECT lub SOCKS5 z autoryzacją po IPKażde RTT uścisku dłoni mnoży się przez liczbę połączeń; CONNECT oszczędza 1-2 RTT wobec SOCKS5 z hasłem
Klient pocztowy (IMAP, SMTP, POP3)SOCKS5Protokoły pocztowe nie są HTTP; desktopowe klienty obsługują SOCKS5 bezpośrednio, a przez proxy HTTP wymagałyby CONNECT na niestandardowe porty
SSH, klienty baz danych, RDP, dowolny protokół TCPSOCKS5Standardowe wsparcie w OpenSSH przez ProxyCommand lub nakładki zgodne z ProxyJump, w większości klientów baz danych natywnie; HTTP CONNECT działa nie wszędzie
Aplikacje używające UDP: klienty DNS, QUIC, głosSOCKS5 z UDP ASSOCIATEJedyny z dwóch protokołów, który ma UDP w specyfikacji
Cachujące proxy dla wewnętrznych buildów i luster pakietów po HTTPHTTP przezroczystyTylko on rozumie semantykę odpowiedzi i może je cachować
Aplikacja firmowa obsługująca tylko systemowe proxy WindowsHTTPWinHTTP i ustawienia systemowe Windows działają z proxy HTTP; wsparcie SOCKS jest tam ograniczone i bez autoryzacji
Aplikacja mobilna na Androida lub iOS w środowisku testowymHTTPSystemowe ustawienia Wi-Fi obu platform obsługują tylko proxy HTTP; SOCKS5 wymagałby proxyfikatora na poziomie aplikacji
Własny soft z bezpośrednią pracą na socketachSOCKS5Implementacja 30 linii, format binarny bez parsowania, wsparcie dowolnego protokołu na wierzchu, wyraźna kontrola nad miejscem rozwiązywania nazw
Narzędzia wiersza poleceń: curl, wget, gitHTTP dla wget; SOCKS5 lub HTTP dla curl i gitwget w ogóle nie obsługuje SOCKS; curl i git obsługują oba tryby
Monitoring dostępności stron z różnych regionówSOCKS5 z ATYP=0x03Potrzebne jest, by rozwiązywanie DNS szło z regionu proxy, inaczej sprawdza się nie ten edge-serwer
Debugowanie, gdy coś nie działa i nie wiadomo dlaczegoHTTPKody 407, 403, 502, 504 są zrozumialsze niż bajt REP, a curl -v pokazuje cały dialog z proxy

Algorytm wyboru w czterech krokach

  1. Ustal protokół w środku. Jeśli to nie HTTP i nie HTTPS, bierz SOCKS5 i nie zastanawiaj się.
  2. Sprawdź, co umie klient. Otwórz jego dokumentację i poszukaj słów socks5, proxy, CONNECT. Jeśli SOCKS5 nie ma lub jest bez autoryzacji, wybór został dokonany za ciebie.
  3. Zdecyduj, gdzie ma się rozwiązywać domena. Jeśli ważny jest region (CDN, treści zależne od geolokalizacji, monitoring), bierz SOCKS5 z przekazywaniem domeny albo HTTP CONNECT: w obu przypadkach rozwiązuje proxy.
  4. Oceń profil połączeń. Wiele krótkich połączeń bez puli: patrz na RTT uścisku dłoni, wybieraj HTTP CONNECT lub włącz autoryzację po IP.

Kompatybilność w popularnych klientach i bibliotekach

Teoria kończy się tam, gdzie zaczynają się realne klienty. Poniżej rozbiór zachowania najczęstszych narzędzi według stanu na 2026 rok. Sprawdzaj aktualne wersje: zachowanie zmienia się z wydania na wydanie.

curl

Obsługuje wszystko. Schematy w parametrze -x lub zmiennych środowiskowych: http://, https:// (TLS do samego proxy), socks4://, socks4a://, socks5://, socks5h://. Różnica socks5 i socks5h jest opisana w osobnym artykule, tu zapamiętaj: do rozwiązywania na proxy potrzebne jest socks5h.

curl -x socks5h://user:pass@gate.proxeon.net:1080 https://shop.example/
curl -x http://user:pass@gate.proxeon.net:8080 https://shop.example/

Zmienne środowiskowe http_proxy, https_proxy, all_proxy są czytane automatycznie; all_proxy przyjmuje też schematy SOCKS.

wget

Tylko proxy HTTP. SOCKS nie jest obsługiwany w żadnej postaci. Jeśli potrzebujesz wget przez SOCKS5, konieczny będzie systemowy proxyfikator.

Python: requests

Proxy HTTP od razu z pudełka. Dla SOCKS5 potrzebny dodatkowy pakiet PySocks (instalowany jako requests[socks]).

import requests

proxies = {
"http": "socks5h://user:pass@gate.proxeon.net:1080",
"https": "socks5h://user:pass@gate.proxeon.net:1080",
}
r = requests.get("https://shop.example/api/items", proxies=proxies, timeout=15)
print(r.status_code, r.headers.get("cf-ray"))

Dla HTTPS przez proxy HTTP requests automatycznie używa CONNECT. Dla HTTP przez proxy HTTP używana jest forma absolutna.

Python: httpx

Proxy HTTP od razu z pudełka, SOCKS5 przez pakiet socksio (httpx[socks]). Schemat socks5:// w httpx przekazuje domenę serwerowi proxy. Obsługuje async, co czyni go wygodnym do zadań równoległych.

import httpx, asyncio

async def main():
async with httpx.AsyncClient(proxy="socks5://user:pass@gate.proxeon.net:1080") as c:
r = await c.get("https://shop.example/")
print(r.status_code)

asyncio.run(main())

Python: aiohttp

Proxy HTTP natywnie. SOCKS5 przez pakiet aiohttp-socks z klasą ProxyConnector, której parametr rdns steruje miejscem rozwiązywania nazw.

Node.js: fetch i undici

Wbudowany fetch w Node.js używa undici, gdzie jest ProxyAgent dla proxy HTTP. Dla SOCKS5 stosuje się osobny agent z ekosystemu, na przykład socks-proxy-agent dla modułów http/https.

import { ProxyAgent, fetch } from "undici";

const agent = new ProxyAgent({
 uri: "http://gate.proxeon.net:8080",
 token: "Basic " + Buffer.from("user:pass").toString("base64"),
});
const res = await fetch("https://shop.example/", { dispatcher: agent });
console.log(res.status);

Go

Standardowe net/http obsługuje proxy HTTP przez Transport.Proxy i zmienne środowiskowe. Od Go 1.13 schemat socks5:// w HTTP_PROXY też jest przyjmowany przez standardową bibliotekę. Do drobiazgowej kontroli używa się pakietu golang.org/x/net/proxy.

package main

import (
"fmt"
"net/http"
"net/url"
)

func main() {
u, _ := url.Parse("socks5://user:pass@gate.proxeon.net:1080")
tr := &http.Transport{Proxy: http.ProxyURL(u)}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://shop.example/")
if err != nil {
panic(err)
}
fmt.Println(resp.Status)
}

W Go schemat socks5 przekazuje domenę proxy: lokalne rozwiązywanie nie jest wykonywane.

Java

Proxy HTTP przez właściwości systemowe http.proxyHost, https.proxyHost lub obiekt Proxy z typem Type.HTTP. SOCKS przez socksProxyHost i Proxy.Type.SOCKS. Autoryzacja przez klasę Authenticator. Od JDK 8u111 schemat Basic dla HTTPS przez CONNECT jest domyślnie wyłączony właściwością jdk.http.auth.tunneling.disabledSchemes, trzeba ją wyczyścić, inaczej dostaniesz 407 bez wyjaśnienia. To jedna z najczęstszych przyczyn zgłoszeń do wsparcia.

.NET

HttpClient z SocketsHttpHandler obsługuje proxy HTTP przez WebProxy. Wsparcie SOCKS4, SOCKS4a i SOCKS5 pojawiło się w .NET 6 i włącza się tą samą konstrukcją WebProxy z adresem w postaci socks5://host:port.

Przeglądarki

Przeglądarki Chromium używają systemowych ustawień proxy lub flagi --proxy-server. Proxy HTTP z autoryzacją działa: przeglądarka pokazuje okno logowania. SOCKS5 przez ustawienia systemowe działa bez autoryzacji, loginu i hasła przekazać nie można. Dla SOCKS5 z hasłem potrzebne jest rozszerzenie z API proxy lub autoryzacja po IP. Firefox ma własne ustawienia proxy, obsługuje SOCKS5 i opcję „Proxy DNS when using SOCKS v5”, która włącza ATYP=0x03. Autoryzacja dla SOCKS5 w Firefoksie także standardowo nie jest przewidziana.

Klienty pocztowe

Thunderbird używa ustawień proxy podobnych do Firefoksa i umie SOCKS5 dla IMAP i SMTP. Wiele innych desktopowych klientów pocztowych ma własną sekcję proxy SOCKS5 w ustawieniach konta. Przez proxy HTTP poczta działa tylko, jeśli klient umie wysyłać CONNECT na porty 993 i 465, co zdarza się rzadko.

Systemowe proxyfikatory

Dla aplikacji bez własnych ustawień proxy istnieją programy przechwytujące wywołania sieciowe na poziomie systemu i przekierowujące je do SOCKS5 lub proxy HTTP. Praktycznie wszystkie preferują SOCKS5 jako transport właśnie dlatego, że nie zależy od protokołu w środku. Jeśli twoje zadanie obejmuje takie narzędzie, przygotuj port SOCKS5.

Lista kontrolna kompatybilności

  • Czy klient umie SOCKS5? Czy umie przekazywać login i hasło w SOCKS5?
  • Czy klient rozwiązuje domenę sam, czy oddaje ją proxy? Czy jest ustawienie remote DNS?
  • Czy klient poprawnie obsługuje 407 i powtarza żądanie z autoryzacją?
  • Czy klient używa CONNECT dla HTTPS, czy próbuje wysłać absolutny URI ze schematem https (tak robią niektóre archaiczne biblioteki, i to nie działa)?
  • Czy klient ponownie używa połączeń do proxy, czy otwiera nowe na każde żądanie?

Kazusy z praktyki inżynierskiej

Liczby poniżej są typowe dla opisanych scenariuszy i podane dla zrozumienia rzędu efektu, a nie jako gwarantowany wynik.

Kazus 1: monitoring witryn z różnych regionów

Zespół śledził dostępność i ceny własnych witryn regionalnych przez proxy z kilku krajów. Używano Pythona i requests ze schematem socks5://. Okresowo metryki pokazywały „niewłaściwą” cenę dla regionu, choć witryna działała poprawnie. Przyczyna: biblioteka rozwiązywała domenę lokalnie, w kraju biura, i przekazywała proxy gotowy adres IP edge-serwera CDN. Proxy z innego kraju uczciwie łączyło się z tym adresem, a CDN oddawał treść, określając region po swoim węźle, a nie po IP klienta. Zamiana schematu na socks5h przeniosła rozwiązywanie na proxy. Udział anomalnych pomiarów spadł praktycznie do zera, a mediana czasu odpowiedzi zmniejszyła się o około jedną trzecią dzięki temu, że proxy zaczęło chodzić do najbliższego sobie węzła CDN.

Kazus 2: park kolektorów danych z krótkimi połączeniami

Serwis agregacji otwartych cen wykonywał do kilkuset tysięcy zapytań na dobę przez SOCKS5 z loginem i hasłem, otwierając nowe połączenie na każde zapytanie. Profilowanie pokazało, że trzy RTT uścisku dłoni na połączenie przy opóźnieniu do proxy około 40 ms dawały 120 ms narzutu na każde zapytanie, około jednej czwartej całego czasu. Dwie zmiany: włączono pulę połączeń w kliencie HTTP i przeszliśmy na autoryzację po IP, usuwając jedno RTT. Łączny czas przejścia po liście skrócił się o około 30 procent bez zmiany liczby proxy. Protokół przy tym zostawiono SOCKS5, bo zmiana na HTTP CONNECT dałaby mniejszy zysk niż pula.

Kazus 3: skrzynki pocztowe i IMAP

Dział wsparcia wdrażał desktopowego klienta pocztowego dla kilku przedstawicielstw regionalnych, gdzie każda skrzynka miała łączyć się z serwerem pocztowym przez IP określonego regionu. Pierwsza próba przez proxy HTTP nie powiodła się: klient nie umiał CONNECT dla IMAP. Przełączenie na port SOCKS5 w Proxeon rozwiązało zadanie w kilka minut, bo klient miał natywne ustawienie SOCKS5 dla każdego konta. Żadnego dodatkowego softu.

Kazus 4: aplikacja Java i tajemniczy 407

Firmowy integrator podłączał serwis Java do zewnętrznego API przez proxy HTTP z autoryzacją Basic. Proxy uparcie zwracało 407, choć dane uwierzytelniające były poprawne, a curl z tymi samymi parametrami działał. Przyczyna: od pewnej aktualizacji JDK autoryzacja Basic dla tuneli CONNECT jest domyślnie wyłączona. Jedna flaga JVM czyszcząca jdk.http.auth.tunneling.disabledSchemes rozwiązała problem. Tu przydało się właśnie to, że proxy HTTP odpowiada czytelnym kodem: kod 407 od razu wskazał kierunek poszukiwań, podczas gdy SOCKS5 w analogicznej sytuacji zwróciłby 05 FF i bez znajomości protokołu trudniej byłoby to zrozumieć.

Częste błędne przekonania

  • „SOCKS5 jest bezpieczniejszy niż proxy HTTP”. Dla zaszyfrowanego ruchu oba protokoły dają pośrednikowi taką samą widoczność: host, port, czasy, objętości, SNI. Bezpieczeństwo zawartości zapewnia TLS, a nie protokół proxy. Różnica jest tylko dla niezaszyfrowanego HTTP, gdzie przezroczyste proxy HTTP widzi wszystko.
  • „Proxy HTTP nie działa z HTTPS”. Działa przez CONNECT. To standardowy i powszechny mechanizm, dokładnie tak wszystkie przeglądarki chodzą na strony HTTPS przez firmowe proxy.
  • „SOCKS5 jest szybszy, bo binarny”. Na ustanowienie połączenia SOCKS5 z autoryzacją zużywa więcej RTT niż HTTP CONNECT. Na przekazywaniu danych oba nie dodają nic: po uścisku dłoni to czysta rura TCP w obu przypadkach. Szybkość określa kanał proxy, a nie protokół.
  • „CONNECT jest potrzebny tylko dla portu 443”. Standard nie ogranicza portu. Ograniczenia wprowadza konfiguracja konkretnego proxy.
  • „SOCKS5 zawsze rozwiązuje domenę na proxy”. Tylko jeśli klient przekazuje ATYP=0x03. Wiele bibliotek domyślnie rozwiązuje lokalnie i przekazuje IP.
  • „Proxy HTTP zawsze dodaje X-Forwarded-For i ujawnia moje IP”. To zachowanie konkretnych firmowych ustawień, a nie cecha protokołu. Komercyjne proxy takich nagłówków nie dodają, a w trybie CONNECT dodanie ich jest fizycznie niemożliwe.
  • „Proxy widzi moje hasło do proxy otwartym tekstem, więc widzi też hasło do strony”. Hasło do proxy jest przekazywane proxy i zgodnie ze standardem nie jest przekazywane dalej. Hasła do strony wewnątrz tunelu TLS proxy nie widzi.
  • „Skoro SOCKS5 nie analizuje zawartości, nie można go ograniczyć”. Proxy może ograniczać po hoście docelowym, porcie, objętości, prędkości i liczbie połączeń. Po prostu nie po URL.
  • „Porty HTTP i SOCKS5 u jednego dostawcy to różne serwery”. Z reguły to jeden serwer i jeden wychodzący IP, różni się tylko protokół na wejściu. W Proxeon właśnie tak jest.
  • „W przeglądarce SOCKS5 z hasłem konfiguruje się tak samo jak HTTP”. Nie, systemowe ustawienia Chromium i Firefoksa nie przekazują danych uwierzytelniających w SOCKS5. Potrzebna jest autoryzacja po IP lub rozszerzenie.

FAQ

Czy serwer docelowy może rozpoznać, czy przyszedłem przez proxy HTTP, czy przez SOCKS5?

Nie. Serwer docelowy widzi tylko drugie połączenie, od proxy do siebie, i w obu przypadkach jest to zwykły TCP z adresu IP proxy. Jedyny wyjątek: przezroczyste proxy HTTP, które dodaje nagłówki Via lub X-Forwarded-For. W trybie CONNECT i w SOCKS5 to niemożliwe.

Jeśli używam proxy HTTP dla HTTPS, czy proxy może podejrzeć lub podłożyć zawartość?

Tylko jeśli wykona przechwycenie TLS z podłożeniem certyfikatu, i wtedy twój klient zobaczy błąd weryfikacji certyfikatu, chyba że ręcznie zainstalowałeś zaufany certyfikat główny tego proxy. W standardowej pracy po CONNECT proxy widzi zaszyfrowany strumień i nie może ani przeczytać, ani zmienić jego zawartości.

Dlaczego SOCKS5 z hasłem nie działa w Chrome, a proxy HTTP z hasłem działa?

Implementacja stosu sieciowego Chromium obsługuje dialog autoryzacji dla proxy HTTP przez mechanizm 407, ale nie realizuje metody 0x02 z RFC 1929 dla SOCKS5. To decyzja twórców przeglądarki, a nie ograniczenie protokołu. Rozwiązanie: autoryzacja po adresie IP w panelu klienta Proxeon albo rozszerzenie sterujące proxy przez API.

Co robić, jeśli proxy zwraca REP=05 w SOCKS5?

Kod 05 oznacza, że serwer docelowy odrzucił połączenie TCP: port zamknięty, usługa nieuruchomiona albo firewall celu blokuje IP proxy. Sprawdź, czy podałeś właściwy port, i spróbuj innego adresu proxy. Samo proxy przy tym działa poprawnie, problem jest na drugiej połowie drogi.

Jaka jest różnica między REP=02 w SOCKS5 a 403 u proxy HTTP?

Semantycznie to samo: proxy odmówiło ustanowienia połączenia według swoich reguł. Zwykle oznacza to, że docelowy port lub host jest zabroniony polityką proxy. Proxy HTTP w ciele odpowiedzi 403 czasem ma wyjaśnienie, SOCKS5 tylko bajt.

Czy można używać tego samego loginu i hasła dla portu HTTP i SOCKS5?

W Proxeon tak: konto jest wspólne, różni się tylko port i protokół. Przy zmianie protokołu nie trzeba zmieniać danych uwierzytelniających.

Jak sprawdzić, czy mój klient rozwiązuje domenę lokalnie, czy na proxy?

Najpewniejszy sposób: uruchomić przechwytywanie ruchu na swoim interfejsie i zobaczyć, czy zapytanie DNS do docelowej domeny wychodzi przed podłączeniem do proxy. Prostszy: tymczasowo wpisać w pliku hosts dla docelowej domeny z góry błędny adres. Jeśli żądanie przez proxy nadal działa, rozwiązuje proxy. Jeśli się psuje, rozwiązuje klient.

Czy warto używać HTTP/2 do proxy, jeśli biblioteka to obsługuje?

Jeśli masz wiele równoległych połączeń do różnych celów, a klient rzeczywiście multipleksuje strumienie CONNECT, zysk będzie zauważalny: mniej połączeń TCP, mniej uścisków dłoni. Ale wsparcie tej możliwości w klientach i serwerach proxy jest na razie nierównomierne. Sprawdzaj dokumentację swojego klienta i upewnij się, czy twój plan obsługuje HTTP/2 na wejściu.

Dlaczego w proxy HTTP jest absolutny URI, skoro jest nagłówek Host?

Standard HTTP/1.1 wymaga od klienta używania formy absolutnej przy zwracaniu się do proxy, żeby proxy jednoznacznie rozumiało, że żądanie trzeba przekazać, a nie przetworzyć lokalnie. Nagłówek Host zostaje, bo proxy prześle żądanie serwerowi docelowemu już w origin-form, a Host jest tam obowiązkowy. Duplikowanie to cena za kompatybilność.

Co ważniejsze dla scrapingu: HTTP czy SOCKS5?

Dla celów HTTPS nie ma różnicy w widoczności, różnica jest w zachowaniu biblioteki. Jeśli biblioteka normalnie działa z SOCKS5 i przekazuje domenę, bierz SOCKS5: nie ryzykuje ingerencji w nagłówki i daje właściwe regionalne rozwiązywanie. Jeśli biblioteka z SOCKS5 kaprysi albo masz wiele krótkich połączeń bez puli, HTTP CONNECT nie jest niczym gorszy. Główna rada: nie otwieraj nowego połączenia z proxy na każde żądanie, to droższe niż jakikolwiek wybór protokołu.

Zakończenie

Dwa porty w panelu klienta to nie marketingowa para „zwykły i zaawansowany”. To dwa różne języki rozmowy z tą samą maszyną. Proxy HTTP mówi językiem żądań i odpowiedzi, rozumie semantykę, może cachować i wyjaśnia błędy czytelnymi kodami, a na wszystko niezrozumiałe ma CONNECT, który zamienia go w tunel TCP. SOCKS5 mówi językiem „host i port”, nie analizuje zawartości, obsługuje dowolny protokół TCP i UDP, i pozwala wyraźnie sterować tym, gdzie rozwiązuje się domena.

Dla zaszyfrowanego ruchu oba protokoły dają pośrednikowi taką samą widoczność. Wybór między nimi określają nie względy bezpieczeństwa, a trzy praktyczne rzeczy: co umie twój klient, jaki protokół jest w środku i gdzie chcesz rozwiązywać nazwy.

Co zrobić teraz

  1. Ustal protokół w swoim zadaniu. Nie HTTP: od razu SOCKS5.
  2. Sprawdź w dokumentacji klienta wsparcie SOCKS5 z autoryzacją i opcję zdalnego rozwiązywania nazw.
  3. Jeśli pracujesz z zasobami zależnymi od geolokalizacji, upewnij się, że domena idzie do proxy: socks5h, remote DNS, ATYP=0x03 lub HTTP CONNECT.
  4. Włącz pulę połączeń lub keep-alive do proxy. To da więcej niż jakakolwiek zmiana protokołu.
  5. Jeśli klient nie umie przekazywać loginu w SOCKS5, skonfiguruj autoryzację po IP w panelu Proxeon.
  6. Przy debugowaniu zaczynaj od curl -v: pokaże cały dialog z proxy i od razu oddzieli problem klienta od problemu sieci.

I na koniec. Oba protokoły są starsze niż większość inżynierów, którzy ich używają, i oba wciąż działają bez zasadniczych zmian. To rzadki przypadek, gdy prostota projektu zwyciężyła. Rozumiejąc, co dokładnie dzieje się w pierwszych czterdziestu bajtach połączenia, przestajesz wybierać port na chybił trafił i zaczynasz wybierać narzędzie.