HTTP-Proxy und SOCKS5 auf Protokollebene: CONNECT, ATYP, was der Vermittler sieht und wie man wählt
Inhalt des Artikels
- Einleitung: warum ein proxy in zwei modi angeboten wird und das kein marketing ist
- Grundlagen: wo der proxy im netzwerk-stack sitzt
- Http-proxy: anfrage mit absoluter uri, was der proxy sieht und ändern kann
- Die connect-methode: wie ein http-proxy zum tcp-tunnel wird
- Socks5: handshake, authentifizierung und atyp
- Vergleich nach kriterien: wo jedes protokoll gewinnt
- Was man für welche aufgabe wählt: die tabelle
- Kompatibilität in gängigen clients und bibliotheken
- Fälle aus der ingenieurspraxis
- Häufige missverständnisse
- Faq
- Fazit
Wenn Sie schon einmal das Kundenportal eines Proxy-Anbieters geöffnet haben, kennen Sie dieses Bild: dieselbe Adresse, derselbe Login, und daneben zwei Ports. Einer ist mit HTTP beschriftet, der andere mit SOCKS5. Viele wählen nach Gefühl oder aus Gewohnheit. Dabei stehen hinter diesen beiden Zeilen zwei völlig unterschiedliche Protokolle, die auf Byte-Ebene anders aufgebaut sind, Ihren Datenverkehr anders sehen und sich in echten Clients anders verhalten. Dieser Leitfaden zerlegt den Unterschied bis zum letzten Byte und endet mit praktischen Auswahltabellen.
Einleitung: Warum ein Proxy in zwei Modi angeboten wird und das kein Marketing ist
Beginnen wir mit einer ehrlichen Antwort auf die Frage aus der Überschrift. Wenn Proxeon Ihnen eine Adresse mit zwei Ports gibt, steckt dahinter dieselbe Maschine, dieselbe ausgehende IP-Adresse und dasselbe Konto. Der Unterschied liegt nicht darin, wohin der Datenverkehr geht. Der Unterschied liegt darin, in welcher Sprache Ihr Client auf dem ersten Wegstück mit dem Proxy-Server spricht: von Ihrer Anwendung bis zum Vermittler.
Ein HTTP-Proxy spricht HTTP. Er nimmt HTTP-Anfragen entgegen, liest sie, versteht, was Sie abrufen möchten, und holt die Ressource selbst. Er kann cachen, Header hinzufügen und mit Statuscodes antworten. Für alles, was kein HTTP ist, hat er einen universellen Trick: die CONNECT-Methode, die ihn in ein stumpfes Rohr verwandelt.
SOCKS5 weiß überhaupt nicht, was HTTP ist. Es ist ein Protokoll auf Sitzungsebene: Der Client sagt „verbinde mich mit diesem Host und Port“, der Proxy öffnet eine TCP-Verbindung und schiebt von da an einfach Bytes in beide Richtungen. Ihm ist egal, was drinsteckt: TLS, IMAP, SSH, ein Datenbankprotokoll oder Ihr eigenes binäres Format.
Warum kann man nicht einfach einen Modus behalten? Weil ihre Kompatibilität unterschiedlich ist. Die Hälfte der Unternehmens- und Desktop-Software kann nur HTTP-Proxy über Systemeinstellungen. Ein großer Teil der Netzwerkbibliotheken und praktisch der gesamte Nicht-Web-Traffic fühlt sich in SOCKS5 wohler. Beide Modi auf derselben IP anzubieten bedeutet, dass Sie das Werkzeug nach dem Client wählen, statt den Client nach dem Werkzeug zurechtzubiegen.
Was Sie in diesem Artikel erfahren:
- wie eine Anfrage an einen HTTP-Proxy auf Textebene aussieht und wie sie sich von einer normalen Anfrage an eine Website unterscheidet;
- was der Proxy im transparenten HTTP-Modus genau sieht und ändern kann;
- wie die CONNECT-Methode funktioniert und was dem Vermittler nach dem Aufbau des Tunnels sichtbar bleibt;
- der Byte-Handshake von SOCKS5, Authentifizierungsschemata und drei ATYP-Adresstypen;
- warum die Wahl zwischen Domain und IP in einer SOCKS5-Anfrage Geografie und DNS-Privatsphäre beeinflusst;
- Vergleich bei Nicht-HTTP-Protokollen, UDP, Overhead, Caching und Logging;
- eine Tabelle „Aufgabe, Protokoll, warum“ und eine Analyse der Kompatibilität in gängigen Clients und Bibliotheken.
Die Mechanik des Befehls UDP ASSOCIATE und den Unterschied zwischen den Schemata socks5 und socks5h in curl und Python behandeln wir hier nicht im Detail: Diesen Themen sind eigene Beiträge im Proxeon-Blog gewidmet, auf die wir an den passenden Stellen verlinken.
Grundlagen: Wo der Proxy im Netzwerk-Stack sitzt
Damit die Diskussion über Protokolle Sinn ergibt, einigen wir uns auf ein paar Begriffe. Es sind nicht viele.
Drei Beteiligte und zwei Verbindungen
In jedem Proxy-Szenario gibt es drei Seiten: den Client (Ihr Browser, Skript, Mailprogramm), den Proxy-Server (den Vermittler) und den Zielserver (Origin). Zwischen ihnen bestehen zwei unabhängige TCP-Verbindungen. Die erste: Client zum Proxy. Die zweite: Proxy zum Zielserver. Der Zielserver sieht nur die zweite Verbindung und damit nur die IP-Adresse des Proxys.
Alles, was wir in diesem Artikel besprechen, betrifft ausschließlich die erste Verbindung. Genau dort liegt der Unterschied zwischen HTTP und SOCKS5. Die zweite Verbindung ist in beiden Fällen gleich aufgebaut: normales TCP vom Proxy zum Zielhost.
Schichtenmodelle und warum das wichtig ist
Eine nützliche Analogie: Stellen Sie sich einen Kurierdienst vor. Ein HTTP-Proxy im transparenten Modus ähnelt einem Kurier, der Ihr Paket öffnet, Adresse und Inhalt liest, bei Bedarf umpackt und sogar selbst antworten kann, wenn er eine Kopie auf Lager hat. SOCKS5 ähnelt einem Kurier, dem Sie die Adresse nennen und das Paket versiegelt übergeben. Er weiß nicht und will nicht wissen, was drin ist.
In den Begriffen des Netzwerkmodells ausgedrückt: Ein HTTP-Proxy arbeitet auf der Anwendungsebene: Er versteht die Semantik der Anfrage. SOCKS5 arbeitet auf der Sitzungsebene: Es operiert mit den Begriffen „Host“, „Port“, „Verbindung“ und steigt nicht höher.
Wo die Namensauflösung stattfindet
Ein eigenes Konzept, das sich wie ein roter Faden durch das ganze Material zieht: die DNS-Auflösung. Wenn Sie example.com aufrufen, muss jemand den Namen in eine IP-Adresse umwandeln. Das kann Ihr Client lokal tun oder der Proxy auf seiner Seite. Davon hängt ab, wessen DNS-Infrastruktur Sie nutzen, welche regionale Antwort Sie vom CDN bekommen und ob Informationen über besuchte Domains in Ihr lokales Netzwerk abfließen. Merken Sie sich diesen Punkt, er taucht sowohl im HTTP- als auch im SOCKS5-Abschnitt wieder auf.
Authentifizierung
Sowohl HTTP-Proxy als auch SOCKS5 können Benutzername und Passwort prüfen, tun dies aber unterschiedlich. HTTP nutzt den Header Proxy-Authorization und den Statuscode 407. SOCKS5 nutzt ein eigenes Subprotokoll mit der Methodennummer 0x02. Es gibt auch eine protokollunabhängige Alternative: die Autorisierung per IP-Adresse des Clients, bei der der Proxy jeden durchlässt, der von einer vorab freigegebenen Adresse kommt. Bei Proxeon sind beide Varianten verfügbar, und die Wahl beeinflusst, wie einfach sich Clients anbinden lassen, die keine Zugangsdaten übermitteln können.
HTTP-Proxy: Anfrage mit absoluter URI, was der Proxy sieht und ändern kann
Eine normale HTTP-Anfrage an eine Website sieht so aus:
GET /catalog/items?page=2 HTTP/1.1
Host: shop.exampleBeachten Sie: In der Anfragezeile steht nur der Pfad. Der Host wird in einem separaten Header übermittelt. Dieses Format heißt origin-form. Wenn der Client weiß, dass er nicht mit der Website, sondern mit dem Proxy spricht, wechselt er zum Format absolute-form: In die Anfragezeile kommt die vollständige 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/htmlWarum den Host doppelt angeben? Historisch entstand die absolute Form früher als der Host-Header und war die einzige Möglichkeit, dem Proxy zu sagen, wohin er gehen soll. Der moderne HTTP/1.1-Standard verlangt von einem Proxy, die absolute Form zu akzeptieren, und von Clients, die einen Proxy ansprechen, genau diese zu verwenden. Der Host-Header bleibt dabei aus Kompatibilitätsgründen erhalten und für den Zielserver, an den der Proxy die Anfrage dann in origin-form weiterleitet.
Was ein HTTP-Proxy sieht
Im transparenten Modus (ohne Verschlüsselung zwischen Client und Zielwebsite) sieht der Proxy absolut alles, was in Anfrage und Antwort steht:
- Methode, vollständige URL einschließlich Query-Parameter;
- alle Anfrage-Header: User-Agent, Cookie, Authorization, Referer;
- den Anfrage-Body vollständig: Formulare, JSON, hochgeladene Dateien;
- Status der Antwort, Antwort-Header und Antwort-Body.
Das ist kein Nebeneffekt. Das ist ein fundamentaler Zug der Architektur: Um eine Anfrage weiterzuleiten, muss der Proxy sie parsen. Und wenn er sie geparst hat, kann er damit alles machen.
Was ein HTTP-Proxy ändern kann
Der Standard teilt Header in Ende-zu-Ende (end-to-end) und Hop-by-Hop (hop-by-hop) ein. Hop-by-Hop-Header gehören zu einer bestimmten Verbindung und müssen vom Proxy vor der Weiterleitung entfernt werden. Dazu gehören Connection, Keep-Alive, Proxy-Authorization, Proxy-Authenticate, TE, Trailer, Transfer-Encoding, Upgrade. Deshalb fliegen Ihr Proxy-Login und -Passwort nicht zur Zielwebsite: Der Header Proxy-Authorization wird standardgemäß am Proxy entfernt.
Neben der obligatorischen Bereinigung kann der Proxy:
- den Header Via mit seinem Namen und der Protokollversion hinzufügen; der Standard verlangt das, in der Praxis lassen anonyme Proxys ihn weg;
- X-Forwarded-For mit der echten Client-IP hinzufügen; so machen es Unternehmensproxys, und so sollte ein Proxy, den Sie für die Arbeit mit externen Ressourcen kaufen, niemals handeln;
- eine Antwort aus seinem Cache liefern, ohne den Zielserver anzufragen, wenn die Antwort als cachefähig markiert ist;
- die Kodierung des Bodys ändern, Kompression hinzufügen oder entfernen, Links in HTML umschreiben;
- die Anfrage mit einer eigenen Antwort ablehnen, zum Beispiel 403 oder 407.
Die Antwort 407 Proxy Authentication Required verdient besondere Erwähnung. Wenn der Proxy eine Autorisierung verlangt und der Client keine mitschickt, antwortet der Proxy mit dem Namen 407 und dem Header Proxy-Authenticate, in dem er die unterstützten Schemata auflistet. Gute Clients wiederholen danach die Anfrage mit Proxy-Authorization. Schlechte Clients zeigen dem Nutzer einen unverständlichen Fehler. Daher das typische Problem bei der Einrichtung: Die Anwendung „sieht den Proxy nicht“, obwohl sie in Wahrheit einfach nicht mit 407 umgehen kann.
In der Praxis durchgespielt
Der einfachste Weg, all das mit eigenen Augen zu sehen: curl mit dem Schalter -v.
curl -v -x http://user:pass@gate.proxeon.net:8080 http://httpbin.org/getIn der Ausgabe sehen Sie eine Zeile wie GET http://httpbin.org/get HTTP/1.1 und den Header Proxy-Authorization. Das ist die absolute Form.
Dieselbe Anfrage per Hand über einen Socket in Python, damit keine Magie übrig bleibt:
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"))Hier gibt es keine einzige Proxy-Bibliothek. Nur einen Socket und einen korrekt zusammengesetzten String. Ein HTTP-Proxy im transparenten Modus ist so einfach, dass man ihn an einem Abend schreiben kann, und genau darin liegt zugleich seine Stärke und seine Schwäche.
Wo der Name im HTTP-Modus aufgelöst wird
In der absoluten Form übergibt der Client dem Proxy den Hostnamen unverändert. Die Auflösung übernimmt der Proxy. Der Client muss die IP-Adresse des Zielservers nicht kennen, und es wird keine lokale DNS-Anfrage ausgeführt. Das ist praktisch, führt uns aber zur wichtigsten Einschränkung: Das beschriebene Schema funktioniert nur für unverschlüsseltes HTTP. Für HTTPS ist die absolute Form nutzlos, weil die TLS-Verbindung zwischen Client und Zielserver aufgebaut werden muss und der Proxy sich nicht dazwischenstellen kann, ohne das Zertifikat zu brechen. Genau dafür wurde CONNECT erfunden.
Die CONNECT-Methode: Wie ein HTTP-Proxy zum TCP-Tunnel wird
CONNECT ist eine HTTP-Methode, die den Proxy bittet, die Anfrage nicht weiterzuleiten, sondern eine TCP-Verbindung mit dem angegebenen Host und Port aufzubauen und danach ein transparentes Rohr zu werden. Die Anfrage sieht so aus:
CONNECT shop.example:443 HTTP/1.1
Host: shop.example:443
Proxy-Authorization: Basic dXNlcjpwYXNz
Proxy-Connection: Keep-AliveAchten Sie auf das Format des Ziels: nur Host und Port, ohne Schema und Pfad. Das ist die authority-form der Anfrage, das dritte Format nach origin-form und absolute-form.
Wenn der Proxy zustimmt, antwortet er:
HTTP/1.1 200 Connection establishedDer Text nach dem Code kann beliebig sein, Clients orientieren sich nur am 2xx. Ab diesem Moment ist HTTP beendet. Alles, was der Client in den Socket schreibt, leitet der Proxy Byte für Byte an den Zielserver weiter und umgekehrt. Der Client beginnt den TLS-Handshake direkt in diesem Socket, als wäre er direkt mit dem Server verbunden.
Was der Vermittler nach CONNECT sieht
Hier beginnt der interessante Teil. Der Proxy, der eben noch allwissend war, erblindet plötzlich. Nach erfolgreichem CONNECT weiß der Proxy:
- Hostname und Port aus der CONNECT-Zeile; das ist die einzige semantische Information, die er erhalten hat;
- die Zeit des Aufbaus und der Schließung der Verbindung;
- das Volumen der in beide Richtungen übertragenen Bytes;
- den Inhalt des TLS ClientHello, wenn im Tunnel TLS läuft: Dort wird SNI (der Servername) im Klartext übertragen, dazu die Liste der unterstützten Cipher und Erweiterungen; die moderne Erweiterung Encrypted Client Hello verbirgt auch das SNI, aber ihre Unterstützung ist noch nicht flächendeckend;
- nichts von der HTTP-Ebene: weder URL noch Header, Cookies oder Body.
Anders gesagt: Nach CONNECT sieht ein HTTP-Proxy genau so viel wie SOCKS5. Host, Port, Timing, Volumen. Der Sichtbarkeitsunterschied zwischen den beiden Protokollen existiert nur für unverschlüsselten HTTP-Traffic, und davon ist 2026 in realen Aufgaben sehr wenig übrig.
CONNECT muss nicht zu HTTPS führen
Ein verbreiteter Denkfehler: CONNECT sei nur für HTTPS nötig. Tatsächlich schränkt der Standard den Inhalt des Tunnels nicht ein. Über CONNECT lässt sich eine Verbindung zu einem IMAP-Server auf Port 993, zu SSH auf Port 22 oder zu jedem beliebigen TCP-Dienst aufbauen. Die Frage ist nur, ob die Konfiguration des Proxys das erlaubt. Viele öffentliche und Unternehmens-HTTP-Proxys erlauben CONNECT nur auf die Ports 443 und manchmal 80, um Missbrauch zu verhindern. Proxeon erlaubt CONNECT auf beliebige Ports, aber wenn Ihre Software SOCKS5 beherrscht, bleibt SOCKS5 für Nicht-HTTP-Protokolle die natürlichere Wahl, siehe unten.
Beispiel: TLS über CONNECT von Hand
Das Tool openssl kann selbstständig durch einen HTTP-Proxy gehen:
openssl s_client -proxy gate.proxeon.net:8080 -connect shop.example:443 -servername shop.exampleUnd so sieht es in Python mit der Standardbibliothek aus, ohne externe Abhängigkeiten:
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"))Die Methode set_tunnel macht genau das oben Beschriebene: CONNECT senden, auf 200 warten, dann den Socket in TLS einpacken. Beachten Sie, dass der TLS-Kontext das Zertifikat von shop.example prüft, nicht das des Proxys. Der Proxy kann in diesem Schema das Zertifikat nicht austauschen, ohne beim Client einen Fehler auszulösen.
CONNECT in HTTP/2 und HTTP/3
In HTTP/2 ist die CONNECT-Methode erhalten geblieben, funktioniert aber innerhalb einer einzigen gemultiplexten Verbindung: Jeder Tunnel ist ein eigener Stream. Das erlaubt, dutzende Tunnel über eine TCP-Verbindung mit dem Proxy zu halten und Handshakes zu sparen. Das erweiterte CONNECT (mit dem Pseudo-Header :protocol) wird für WebSocket über HTTP/2 genutzt. In HTTP/3 auf QUIC-Basis gibt es die Spezifikation CONNECT-UDP, die formal erlaubt, UDP durch einen HTTP-Proxy zu tunneln. In Client-Bibliotheken ist das aber noch Exotik, und in der Praxis werden Sie für UDP durch einen Proxy zu SOCKS5 greifen.
Was CONNECT nicht kann
- Cachen: Der Inhalt des Tunnels ist undurchsichtig.
- Header ändern: Sie sind einfach nicht sichtbar.
- Mehrere Zielhosts über einen Tunnel in HTTP/1.1 multiplexen: Ein CONNECT entspricht einer TCP-Verbindung.
- UDP in HTTP/1.1 und HTTP/2 übertragen.
SOCKS5: Handshake, Authentifizierung und ATYP
SOCKS5 ist in RFC 1928 beschrieben, sein Authentifizierungsschema mit Benutzername und Passwort in RFC 1929. Beide Spezifikationen passen auf wenige Seiten, und das ist einer der Vorteile des Protokolls: Es ist nicht schwer, von Grund auf zu implementieren, also gibt es viele Implementierungen, die selten in der Auslegung auseinandergehen.
SOCKS5 ist ein binäres Protokoll. Kein Text, nur Bytes fester Struktur. Betrachten wir den vollständigen Austausch für den Befehl CONNECT.
Schritt 1: Begrüßung und Wahl der Authentifizierungsmethode
Der Client sendet die Version und die Liste der Authentifizierungsmethoden, die er unterstützt:
05 02 00 02
VER=5 NMETHODS=2 METHODS: 00 (ohne Authentifizierung), 02 (Login/Passwort)Der Server wählt eine Methode und antwortet mit zwei Bytes:
05 02
VER=5 METHOD=02 (Server verlangt Login/Passwort)Wenn der Server mit 05 FF antwortet, bedeutet das „keine der vorgeschlagenen Methoden passt“, und der Client muss die Verbindung schließen. Genau so sieht auf Byte-Ebene die Situation aus, in der Sie das Passwort vergessen haben und der Proxeon-Proxy auf Login-Autorisierung eingestellt ist.
Schritt 2: Authentifizierung nach RFC 1929
Wenn Methode 02 gewählt wurde, sendet der Client:
01 04 75 73 65 72 04 70 61 73 73
VER=1 ULEN=4 UNAME="user" PLEN=4 PASSWD="pass"Beachten Sie: Die Version des Subprotokolls ist hier 01, nicht 05. Das ist eine häufige Fehlerquelle in selbstgeschriebenen Clients. Der Server antwortet:
01 00
VER=1 STATUS=00 (Erfolg; jeder andere Wert bedeutet Ablehnung)Login und Passwort werden im Klartext übertragen. Wenn zwischen Ihnen und dem Proxy ein nicht vertrauenswürdiges Netz liegt, sollte man das bedenken. In der Praxis läuft die Verbindung zum Proxy meist über einen eigenen Kanal des Anbieters, und die Frage wird auf Transportebene oder durch Umstellung auf IP-Autorisierung gelöst.
Schritt 3: Verbindungsanfrage
Jetzt die wichtigste Nachricht:
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 (Domain)
LEN=12 ADDR="shop.example" PORT=0x01BB (443)Das Feld CMD kennt drei Werte: 01 CONNECT (ausgehende TCP-Verbindung), 02 BIND (Warten auf eine eingehende Verbindung, praktisch ungenutzt), 03 UDP ASSOCIATE (Erstellen eines UDP-Relais). Die Mechanik von UDP ASSOCIATE und ihre Fallstricke haben wir in einem eigenen Artikel über UDP in SOCKS5 behandelt; hier halten wir nur fest: Es ist das einzige der beiden Protokolle, das UDP standardmäßig anbietet.
ATYP: Domain gegen IP
Das Feld ATYP bestimmt, in welcher Form der Client die Zieladresse übergeben hat:
- 0x01 IPv4: die nächsten 4 Bytes sind die Adresse;
- 0x03 Domainname: ein Längenbyte, dann der Name ohne abschließende Null;
- 0x04 IPv6: die nächsten 16 Bytes sind die Adresse.
Klingt nach einem technischen Detail. Tatsächlich ist es eine der wichtigsten Entscheidungen, die ein Client trifft, und zwar aus folgenden Gründen.
Wenn der Client ATYP=0x01 oder 0x04 verwendet, hat er den DNS-Resolver selbst ausgeführt, bevor er die Anfrage gesendet hat. Ihre Maschine hat ihren DNS-Server angefragt, eine Adresse erhalten und dem Proxy die fertige IP übergeben. Die Folgen:
- Die DNS-Anfrage ging durch Ihr lokales Netzwerk und ist für Ihren Provider oder Administrator sichtbar;
- Sie haben die IP erhalten, die das DNS für Ihre Region ausgegeben hat; bei Websites hinter einem CDN bedeutet das, dass ein Proxy in einem anderen Land einen „fremden“ Edge-Server anspricht, was die Verbindung verlangsamt und ungewöhnlich aussehen kann;
- Wenn Ihre Maschine kein IPv6 hat, bekommen Sie nie einen AAAA-Eintrag und nutzen nie die IPv6-Route des Proxys, selbst wenn es sie gibt;
- Wenn sich das DNS in Ihrem Netz ungewöhnlich verhält, bekommt der Proxy eine falsche Adresse, und Sie suchen lange nach der Ursache.
Wenn der Client ATYP=0x03 verwendet, übernimmt der Proxy die Auflösung. Er nutzt seine DNS-Infrastruktur, bekommt eine Adresse, die für seinen Standort relevant ist, und Ihr lokales Netz sieht nicht, welche Domains Sie aufrufen. Für Aufgaben mit Geobindung ist das entscheidend: Der Sinn eines Proxys in einem bestimmten Land geht teilweise verloren, wenn der Zielserver anhand des DNS Ihres Heimnetzwerks gewählt wird.
Wie bringt man den Client dazu, die Domain zu übergeben? Das hängt vom Client ab. In curl und Python-Bibliotheken entscheidet die Wahl des Schemas socks5 gegen socks5h darüber, und das ist Thema einer eigenen Analyse. Hier ist wichtig, den Grund zu verstehen: Der Buchstabe h steht für „hostname“ und aktiviert ATYP=0x03. Ohne ihn löst die Bibliothek den Namen lokal auf.
Schritt 4: Antwort des Servers
05 00 00 01 C0 A8 01 0A 1F 90
VER=5 REP=00 (Erfolg) RSV=00 ATYP=01 BND.ADDR=192.168.1.10 BND.PORT=8080Das Feld REP enthält den Ergebniscode. Beim Debuggen ist es nützlich, sie auswendig zu kennen:
- 00 Erfolg;
- 01 allgemeiner Serverfehler;
- 02 Verbindung durch Regeln verboten;
- 03 Netzwerk nicht erreichbar;
- 04 Host nicht erreichbar;
- 05 Verbindung vom Zielserver abgelehnt;
- 06 TTL abgelaufen;
- 07 Befehl nicht unterstützt;
- 08 Adresstyp nicht unterstützt.
Code 08 trifft man bei alten oder vereinfachten Implementierungen an, die ATYP=0x03 oder IPv6 nicht unterstützen. Proxeon unterstützt alle drei Adresstypen.
Warum SOCKS5 den Inhalt nicht analysiert
Nach der Antwort REP=00 ist das SOCKS5-Protokoll beendet. Alles, was der Client danach schreibt, leitet der Proxy ohne Analyse in die Zielverbindung. Das ist keine Einschränkung der Implementierung, sondern eine Designeigenschaft. SOCKS5 kennt weder den Begriff „Anfrage“ noch „Header“. Es weiß nicht, was HTTP, IMAP oder TLS ist. Man hat ihm Adresse und Port übergeben, es hat zwei Rohre verbunden.
Daraus ergeben sich mehrere praktische Konsequenzen:
- SOCKS5 kann nicht cachen: Es versteht nicht, wo eine Antwort endet und die nächste beginnt;
- SOCKS5 kann keine Header hinzufügen oder Inhalte austauschen; das Maximum ist, die Verbindung zu schließen;
- SOCKS5 kann nicht nach URL filtern, nur nach Host und Port;
- SOCKS5 funktioniert gleichermaßen gut mit jedem TCP-Protokoll, auch mit dem, das Sie gestern erfunden haben.
Vollständiger SOCKS5-Handshake in Python
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)
# дальше sock можно обернуть в ssl.wrap_socket или передать любому протоколуDreißig Zeilen, und Sie haben einen funktionierenden SOCKS5-Client, der die Domain übergibt (ATYP=0x03) und die Auflösung dem Proxy-Server überlässt. Genau diese Einfachheit macht SOCKS5 zum De-facto-Standard für programmatischen Zugriff.
Vergleich nach Kriterien: Wo jedes Protokoll gewinnt
Jetzt, da die Mechanik beider Protokolle bis auf die Byte-Ebene zerlegt ist, ist der Vergleich kein Geschmacksstreit mehr, sondern eine Liste messbarer Unterschiede.
Nicht-HTTP-Protokolle
SOCKS5 funktioniert standardmäßig mit jedem TCP-Protokoll: CONNECT-Befehl, Host, Port, fertig. Ein HTTP-Proxy kann das ebenfalls über CONNECT, aber mit Einschränkungen: Der Client muss CONNECT für Nicht-HTTP-Traffic senden können (Mailclients können das, die meisten CLI-Tools nicht), und der Proxy muss den nötigen Port erlauben. Sieger: SOCKS5.
UDP
SOCKS5 hat UDP ASSOCIATE. Ein HTTP-Proxy hat in den Versionen 1.1 und 2 nichts, und CONNECT-UDP aus HTTP/3 wird von Clients praktisch nicht unterstützt. Wenn die Aufgabe DNS-Anfragen direkt, QUIC, Sprachprotokolle oder Spieltraffic umfasst, gibt es keine Wahl. Sieger: SOCKS5, mit der Einschränkung, dass nicht jeder SOCKS5-Server UDP aktiviert hat; prüfen Sie die Dokumentation Ihres Tarifs.
Overhead beim Verbindungsaufbau
Rechnen wir in Round-Trips (RTT) zwischen Client und Proxy, zusätzlich zum TCP-Handshake selbst:
- HTTP-Proxy, transparenter Modus, ohne Autorisierung: 0 zusätzliche RTT, die Anfrage geht sofort raus;
- HTTP CONNECT mit Autorisierung in der ersten Anfrage: 1 RTT (CONNECT, Antwort 200);
- SOCKS5 ohne Autorisierung: 2 RTT (Begrüßung, Anfrage);
- SOCKS5 mit Login und Passwort: 3 RTT (Begrüßung, Authentifizierung, Anfrage).
In Bytes ist der Unterschied umgekehrt: Der vollständige SOCKS5-Handshake mit Autorisierung passt in etwa 40 Bytes, während CONNECT mit den Headern Host, Proxy-Authorization und User-Agent leicht 150 und mehr belegt. In realen Aufgaben entscheidet aber die RTT, nicht die Bytes. Bei 50 ms Verzögerung zum Proxy fügt SOCKS5 mit Autorisierung jedem neuen Verbindungsaufbau 150 ms hinzu, gegenüber 50 ms bei CONNECT. Wenn der Client Verbindungen wiederverwendet (Keep-Alive, Pools), ist das eine einmalige Zahlung. Wenn jede Anfrage einen neuen Socket öffnet, summiert sich die Differenz. Sieger nach RTT: HTTP. Der Weg, den Abstand bei SOCKS5 zu verkleinern: Autorisierung per IP, die einen RTT einspart.
Caching
Nur der HTTP-Proxy im transparenten Modus. Nicht CONNECT, nicht SOCKS5. Dabei kann er nur unverschlüsselten Traffic cachen, von dem es heute wenig gibt, weshalb dieses Kriterium von entscheidend zu Nische geworden ist. Relevant ist es für interne Buildsysteme, Paket-Mirrors und wiederkehrende API-Aufrufe ohne TLS innerhalb einer vertrauenswürdigen Umgebung. Sieger: HTTP, aber mit engem Anwendungsbereich.
Logging
Dieser Punkt wird oft falsch verstanden. Was kann ein Proxy in jedem Modus ins Log schreiben?
- HTTP transparent: vollständige URL, Methode, Header, auf Wunsch Body; Antwortstatus; Volumen.
- HTTP CONNECT: Host und Port aus der CONNECT-Zeile; Zeit; Volumen; auf Wunsch SNI aus dem ClientHello.
- SOCKS5 mit ATYP=0x03: Domainname und Port; Zeit; Volumen; auf Wunsch SNI.
- SOCKS5 mit ATYP=0x01/0x04: nur IP und Port; die Domain kennt der Proxy nicht; Zeit; Volumen; SNI.
Für verschlüsselten Traffic bieten CONNECT und SOCKS5 dem Vermittler die gleiche Sichtbarkeit. Der Unterschied tritt nur dort auf, wo ein SOCKS5-Client eine IP statt einer Domain übergibt, und dann weiß der Proxy sogar weniger. Der Zielserver erhält die Anfrage in diesem Fall aber aus der „falschen“ Region, siehe Abschnitt zu ATYP. Unentschieden mit Nuancen.
Fehlerdiagnose
Ein HTTP-Proxy antwortet mit menschenlesbaren Codes: 407 sagt etwas über die Autorisierung, 403 über ein Verbot, 502 über die Nichterreichbarkeit des Ziels, 504 über einen Timeout. Manche Implementierungen fügen einen erläuternden Body hinzu. SOCKS5 antwortet mit einem einzigen REP-Byte, und nicht jede Bibliothek übersetzt es in eine verständliche Meldung. Beim Debuggen in unbekannter Umgebung ist ein HTTP-Proxy einfacher zu diagnostizieren. Sieger: HTTP.
Multiplexing
Ein HTTP/2-Proxy erlaubt, viele CONNECT-Tunnel über eine Verbindung zu führen. SOCKS5 benötigt pro Ziel eine eigene TCP-Verbindung. Für Clients mit hunderten parallelen Verbindungen reduziert das spürbar die Last auf Netzwerk-Stack und Proxy. Allerdings ist die Unterstützung von HTTP/2 zum Proxy in Clients noch bruchstückhaft. Potenzieller Sieger: HTTP, faktisch Gleichstand.
Möglichkeit der Einflussnahme auf den Traffic
Ein HTTP-Proxy kann im transparenten Modus alles ändern. Im CONNECT-Modus und bei SOCKS5 kann er nur die Verbindung trennen. Für einen Client, der Garantien zur Unveränderlichkeit des Traffics will, ist SOCKS5 oder CONNECT mit TLS im Inneren am besten. Sieger in Sachen Vorhersagbarkeit: SOCKS5.
Authentifizierung
Beide beherrschen Login und Passwort. HTTP unterstützt zusätzlich die Schemata Digest, NTLM und Negotiate, was für Unternehmensumgebungen wichtig ist. SOCKS5 hat formal die GSSAPI-Methode, die in kommerziellen Proxys aber praktisch nicht vorkommt. Für den Umgang mit einem Dienst wie Proxeon spielt das keine Rolle: Dort wird Basic oder eine IP-Whitelist verwendet.
Was man für welche Aufgabe wählt: die Tabelle
Fassen wir die Erkenntnisse in einem Arbeitsmittel zusammen. Die Tabelle geht davon aus, dass beide Modi auf einer IP verfügbar sind, wie bei Proxeon, und die Frage nur lautet, welchen Port man angibt.
| Aufgabe | Empfohlenes Protokoll | Warum |
|---|---|---|
| Browser für manuelle Arbeit oder Tests | HTTP (mit CONNECT für HTTPS) | Alle Browser unterstützen HTTP-Proxy mit Autorisierung über Systemeinstellungen oder Erweiterungen; SOCKS5 mit Login und Passwort funktioniert in Chromium-Browsern über den Systemproxy nicht, Autorisierung nur per IP möglich |
| HTTP-Client, Parser, Datensammler in Python, Node.js, Go | SOCKS5 mit Domainübergabe (ATYP=0x03) | Die Auflösung auf der Proxy-Seite liefert die richtigen regionalen CDN-Adressen, Bibliotheken unterstützen beide Modi, und SOCKS5 greift nicht in Header ein |
| Parser mit vielen kurzen Verbindungen ohne Keep-Alive | HTTP CONNECT oder SOCKS5 mit IP-Autorisierung | Jeder RTT des Handshakes multipliziert sich mit der Zahl der Verbindungen; CONNECT spart 1-2 RTT gegenüber SOCKS5 mit Passwort |
| Mailclient (IMAP, SMTP, POP3) | SOCKS5 | Mailprotokolle sind kein HTTP; Desktop-Clients unterstützen SOCKS5 direkt, über einen HTTP-Proxy würden sie CONNECT auf Nicht-Standard-Ports erfordern |
| SSH, Datenbankclients, RDP, jedes TCP-Protokoll | SOCKS5 | Standardunterstützung in OpenSSH über ProxyCommand oder ProxyJump-kompatible Wrapper, in den meisten DB-Clients nativ; HTTP CONNECT funktioniert nicht überall |
| Anwendungen mit UDP: DNS-Clients, QUIC, Sprache | SOCKS5 mit UDP ASSOCIATE | Das einzige der beiden Protokolle, das UDP in der Spezifikation hat |
| Caching-Proxy für interne Builds und Paket-Mirrors über HTTP | HTTP transparent | Nur er versteht die Semantik der Antworten und kann sie cachen |
| Unternehmensanwendung, die nur den Windows-Systemproxy kennt | HTTP | WinHTTP und die Windows-Systemeinstellungen arbeiten mit HTTP-Proxy; SOCKS-Unterstützung ist dort eingeschränkt und ohne Autorisierung |
| Mobile App unter Android oder iOS in einer Testumgebung | HTTP | Die WLAN-Systemeinstellungen beider Plattformen unterstützen nur HTTP-Proxy; SOCKS5 erfordert einen Proxyfizierer auf Anwendungsebene |
| Eigene Software mit direkter Socket-Arbeit | SOCKS5 | Implementierung in 30 Zeilen, binäres Format ohne Parsing, Unterstützung jedes Protokolls darüber, explizite Kontrolle über den Ort der Auflösung |
| Kommandozeilentools: curl, wget, git | HTTP für wget; SOCKS5 oder HTTP für curl und git | wget unterstützt SOCKS überhaupt nicht; curl und git beherrschen beide Modi |
| Monitoring der Erreichbarkeit von Websites aus verschiedenen Regionen | SOCKS5 mit ATYP=0x03 | Die DNS-Auflösung muss aus der Region des Proxys erfolgen, sonst wird der falsche Edge-Server geprüft |
| Debugging, wenn etwas nicht funktioniert und unklar ist, warum | HTTP | Die Codes 407, 403, 502, 504 sind verständlicher als ein REP-Byte, und curl -v zeigt den gesamten Dialog mit dem Proxy |
Auswahlalgorithmus in vier Schritten
- Bestimmen Sie das Protokoll im Inneren. Wenn es nicht HTTP oder HTTPS ist, nehmen Sie SOCKS5 und zögern Sie nicht.
- Prüfen Sie, was der Client kann. Suchen Sie in seiner Dokumentation nach den Schlüsselwörtern socks5, proxy, CONNECT. Wenn SOCKS5 fehlt oder ohne Autorisierung ist, hat sich die Wahl von selbst erledigt.
- Entscheiden Sie, wo die Domain aufgelöst werden soll. Wenn die Region wichtig ist (CDN, geobasierte Inhalte, Monitoring), nehmen Sie SOCKS5 mit Domainübergabe oder HTTP CONNECT: In beiden Fällen löst der Proxy auf.
- Schätzen Sie das Verbindungsprofil ein. Viele kurze Verbindungen ohne Pool: Achten Sie auf die RTT des Handshakes, wählen Sie HTTP CONNECT oder aktivieren Sie die IP-Autorisierung.
Kompatibilität in gängigen Clients und Bibliotheken
Die Theorie endet dort, wo echte Clients anfangen. Unten eine Analyse des Verhaltens der verbreitetsten Werkzeuge mit Stand 2026. Prüfen Sie die aktuellen Versionen: Das Verhalten ändert sich von Release zu Release.
curl
Unterstützt alles. Schemata im Parameter -x oder in Umgebungsvariablen: http://, https:// (TLS bis zum Proxy selbst), socks4://, socks4a://, socks5://, socks5h://. Der Unterschied zwischen socks5 und socks5h ist in einem eigenen Artikel beschrieben; merken Sie sich hier: Für die Auflösung am Proxy braucht man 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/Die Umgebungsvariablen http_proxy, https_proxy, all_proxy werden automatisch gelesen; all_proxy akzeptiert auch SOCKS-Schemata.
wget
Nur HTTP-Proxy. SOCKS wird in keiner Form unterstützt. Wenn Sie wget über SOCKS5 brauchen, ist ein systemweiter Proxyfizierer nötig.
Python: requests
HTTP-Proxy out of the box. Für SOCKS5 ist das zusätzliche Paket PySocks nötig (installierbar als 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"))Für HTTPS über HTTP-Proxy verwendet requests automatisch CONNECT. Für HTTP über HTTP-Proxy wird die absolute Form verwendet.
Python: httpx
HTTP-Proxy out of the box, SOCKS5 über das Paket socksio (httpx[socks]). Das Schema socks5:// übergibt in httpx die Domain an den Proxy-Server. Unterstützt async, was es für parallele Aufgaben bequem macht.
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
HTTP-Proxy nativ. SOCKS5 über das Paket aiohttp-socks mit der Klasse ProxyConnector, deren Parameter rdns den Ort der Auflösung steuert.
Node.js: fetch und undici
Das eingebaute fetch in Node.js nutzt undici, wo es einen ProxyAgent für HTTP-Proxy gibt. Für SOCKS5 verwendet man einen separaten Agent aus dem Ökosystem, zum Beispiel socks-proxy-agent für die Module 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
Das Standardpaket net/http unterstützt HTTP-Proxy über Transport.Proxy und Umgebungsvariablen. Seit Go 1.13 wird das Schema socks5:// in HTTP_PROXY ebenfalls von der Standardbibliothek akzeptiert. Für feine Kontrolle nutzt man das Paket 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)
}In Go übergibt das Schema socks5 die Domain an den Proxy: Es findet keine lokale Auflösung statt.
Java
HTTP-Proxy über Systemeigenschaften http.proxyHost, https.proxyHost oder das Objekt Proxy mit Typ Type.HTTP. SOCKS über socksProxyHost und Proxy.Type.SOCKS. Autorisierung über die Klasse Authenticator. Seit JDK 8u111 ist das Basic-Schema für HTTPS über CONNECT standardmäßig über die Eigenschaft jdk.http.auth.tunneling.disabledSchemes deaktiviert; man muss sie leeren, sonst bekommt man ein 407 ohne Erklärung. Das ist eine der häufigsten Ursachen für Supportanfragen.
.NET
HttpClient mit SocketsHttpHandler unterstützt HTTP-Proxy über WebProxy. Die Unterstützung für SOCKS4, SOCKS4a und SOCKS5 erschien in .NET 6 und wird mit derselben WebProxy-Konstruktion mit einer Adresse der Form socks5://host:port aktiviert.
Browser
Chromium-Browser nutzen die Systemproxyeinstellungen oder den Schalter --proxy-server. HTTP-Proxy mit Autorisierung funktioniert: Der Browser zeigt einen Login-Dialog. SOCKS5 funktioniert über die Systemeinstellungen ohne Autorisierung, Login und Passwort lassen sich nicht übergeben. Für SOCKS5 mit Passwort braucht man eine Erweiterung mit Proxy-API oder die IP-Autorisierung. Firefox hat eigene Proxyeinstellungen, unterstützt SOCKS5 und die Option „Proxy DNS when using SOCKS v5“, die ATYP=0x03 aktiviert. Autorisierung ist für SOCKS5 in Firefox ebenfalls standardmäßig nicht vorgesehen.
Mailclients
Thunderbird nutzt Proxyeinstellungen ähnlich wie Firefox und beherrscht SOCKS5 für IMAP und SMTP. Viele andere Desktop-Mailclients haben einen eigenen Abschnitt für SOCKS5-Proxy in den Kontoeinstellungen. Über einen HTTP-Proxy funktioniert Mail nur, wenn der Client CONNECT auf die Ports 993 und 465 senden kann, was selten vorkommt.
Systemweite Proxyfizierer
Für Anwendungen ohne eigene Proxyeinstellungen gibt es Programme, die Netzwerkaufrufe auf Systemebene abfangen und in einen SOCKS5- oder HTTP-Proxy umleiten. Praktisch alle bevorzugen SOCKS5 als Transport, gerade weil er nicht vom inneren Protokoll abhängt. Wenn Ihre Aufgabe ein solches Werkzeug umfasst, halten Sie den SOCKS5-Port bereit.
Kompatibilitäts-Checkliste
- Beherrscht der Client SOCKS5? Kann er Login und Passwort in SOCKS5 übermitteln?
- Löst der Client die Domain selbst auf oder übergibt er sie dem Proxy? Gibt es eine Einstellung für Remote-DNS?
- Behandelt der Client 407 korrekt und wiederholt die Anfrage mit Autorisierung?
- Verwendet der Client CONNECT für HTTPS oder versucht er, eine absolute URI mit https-Schema zu senden (so machen es einige uralte Bibliotheken, und das funktioniert nicht)?
- Verwendet der Client Verbindungen zum Proxy wieder oder öffnet er für jede Anfrage eine neue?
Fälle aus der Ingenieurspraxis
Die Zahlen unten sind typisch für die beschriebenen Szenarien und dienen dem Verständnis der Größenordnung des Effekts, nicht als garantierte Ergebnisse.
Fall 1: Monitoring von Schaufenstern aus verschiedenen Regionen
Ein Team überwachte die Verfügbarkeit und Preise der eigenen regionalen Schaufenster über Proxys aus mehreren Ländern. Man nutzte Python und requests mit dem Schema socks5://. Zeitweise zeigten die Metriken den „falschen“ Preis für eine Region, obwohl das Schaufenster korrekt funktionierte. Ursache: Die Bibliothek löste die Domain lokal auf, im Land des Büros, und übergab dem Proxy die fertige IP des CDN-Edge-Servers. Der Proxy aus einem anderen Land verband sich ehrlich mit dieser Adresse, und das CDN lieferte Inhalte, dessen Region es anhand seines eigenen Knotens bestimmte, nicht anhand der Client-IP. Der Wechsel des Schemas auf socks5h verlagerte die Auflösung zum Proxy. Der Anteil anormaler Messungen fiel praktisch auf null, und die mediane Antwortzeit sank um rund ein Drittel, weil der Proxy nun den ihm nächstgelegenen CDN-Knoten ansprach.
Fall 2: Park von Datensammlern mit kurzen Verbindungen
Ein Aggregationsdienst für offene Preise führte bis zu mehreren Hunderttausend Anfragen pro Tag über SOCKS5 mit Login und Passwort aus und öffnete für jede Anfrage eine neue Verbindung. Das Profiling zeigte, dass drei RTT des Handshakes pro Verbindung bei etwa 40 ms Verzögerung zum Proxy 120 ms Overhead pro Anfrage ergaben, etwa ein Viertel der Gesamtzeit. Zwei Änderungen: Man aktivierte einen Verbindungspool im HTTP-Client und wechselte auf IP-Autorisierung, wodurch ein RTT entfiel. Die Gesamtzeit für den Durchlauf durch die Liste sank um etwa 30 Prozent, ohne die Anzahl der Proxys zu ändern. Das Protokoll blieb SOCKS5, weil ein Wechsel auf HTTP CONNECT weniger gebracht hätte als der Pool.
Fall 3: Postfächer und IMAP
Eine Supportabteilung rollte einen Desktop-Mailclient für mehrere regionale Vertretungen aus, in denen jedes Postfach sich über die IP einer bestimmten Region mit dem Mailserver verbinden sollte. Der erste Versuch über HTTP-Proxy scheiterte: Der Client beherrschte CONNECT für IMAP nicht. Die Umstellung auf den SOCKS5-Port von Proxeon löste die Aufgabe in Minuten, weil der Client eine native SOCKS5-Einstellung pro Konto hatte. Keine zusätzliche Software.
Fall 4: Java-Anwendung und ein rätselhaftes 407
Ein Unternehmensintegrator verband einen Java-Dienst über einen HTTP-Proxy mit Basic-Autorisierung mit einer externen API. Der Proxy lieferte stabil 407, obwohl die Zugangsdaten korrekt waren und curl mit denselben Parametern funktionierte. Ursache: Seit einem bestimmten JDK-Update ist die Basic-Authentifizierung für CONNECT-Tunnel standardmäßig deaktiviert. Ein JVM-Flag zum Leeren von jdk.http.auth.tunneling.disabledSchemes löste das Problem. Hier war gerade nützlich, dass der HTTP-Proxy mit einem lesbaren Code antwortet: Der Code 407 wies sofort die Richtung. SOCKS5 hätte in einer analogen Situation 05 FF zurückgegeben, und ohne Kenntnis des Protokolls wäre das schwerer zu verstehen gewesen.
Häufige Missverständnisse
- „SOCKS5 ist sicherer als HTTP-Proxy.“ Für verschlüsselten Traffic bieten beide Protokolle dem Vermittler die gleiche Sichtbarkeit: Host, Port, Timing, Volumen, SNI. Die Sicherheit des Inhalts gewährleistet TLS, nicht das Proxy-Protokoll. Der Unterschied besteht nur bei unverschlüsseltem HTTP, wo ein transparenter HTTP-Proxy alles sieht.
- „HTTP-Proxy funktioniert nicht mit HTTPS.“ Er funktioniert über CONNECT. Das ist ein standardmäßiger und allgegenwärtiger Mechanismus, genau so gehen alle Browser über Unternehmensproxys auf HTTPS-Websites.
- „SOCKS5 ist schneller, weil es binär ist.“ Beim Verbindungsaufbau verbraucht SOCKS5 mit Autorisierung mehr RTT als HTTP CONNECT. Bei der Datenübertragung fügen beide nichts hinzu: Nach dem Handshake ist es in beiden Fällen ein reines TCP-Rohr. Die Geschwindigkeit bestimmt der Kanal des Proxys, nicht das Protokoll.
- „CONNECT ist nur für Port 443 nötig.“ Der Standard schränkt den Port nicht ein. Einschränkungen macht die Konfiguration eines konkreten Proxys.
- „SOCKS5 löst die Domain immer am Proxy auf.“ Nur wenn der Client ATYP=0x03 übergibt. Viele Bibliotheken lösen standardmäßig lokal auf und übergeben die IP.
- „HTTP-Proxy fügt immer X-Forwarded-For hinzu und verrät meine IP.“ Das ist das Verhalten konkreter Unternehmenseinstellungen, keine Eigenschaft des Protokolls. Kommerzielle Proxys fügen solche Header nicht hinzu, und im CONNECT-Modus ist das physisch unmöglich.
- „Der Proxy sieht mein Proxy-Passwort im Klartext, also auch das von der Website.“ Das Proxy-Passwort wird an den Proxy übertragen und standardgemäß nicht weitergereicht. Das Passwort der Website sieht der Proxy innerhalb eines TLS-Tunnels nicht.
- „Da SOCKS5 den Inhalt nicht analysiert, kann man es nicht einschränken.“ Der Proxy kann nach Zielhost, Port, Volumen, Geschwindigkeit und Anzahl der Verbindungen einschränken. Nur nicht nach URL.
- „HTTP- und SOCKS5-Ports bei einem Anbieter sind verschiedene Server.“ In der Regel ist es ein Server und eine ausgehende IP, unterschiedlich ist nur das Protokoll am Eingang. Bei Proxeon ist es genau so.
- „Im Browser richtet man SOCKS5 mit Passwort genauso ein wie HTTP.“ Nein, die Systemeinstellungen von Chromium und Firefox übergeben keine Zugangsdaten in SOCKS5. Nötig ist eine IP-Autorisierung oder eine Erweiterung.
FAQ
Kann die Zielwebsite erkennen, ob ich über HTTP-Proxy oder über SOCKS5 komme?
Nein. Der Zielserver sieht nur die zweite Verbindung, vom Proxy zu sich selbst, und die ist in beiden Fällen ein normales TCP von der IP-Adresse des Proxys. Die einzige Ausnahme: ein transparenter HTTP-Proxy, der Via- oder X-Forwarded-For-Header hinzufügt. Im CONNECT-Modus und bei SOCKS5 ist das unmöglich.
Wenn ich für HTTPS einen HTTP-Proxy verwende, kann der Proxy den Inhalt einsehen oder austauschen?
Nur wenn er einen TLS-Abfang mit Zertifikatsaustausch durchführt, und dann sieht Ihr Client einen Zertifikatsfehler, es sei denn, Sie haben das vertrauenswürdige Root-Zertifikat dieses Proxys manuell installiert. Im regulären Betrieb sieht der Proxy nach CONNECT einen verschlüsselten Strom und kann dessen Inhalt weder lesen noch ändern.
Warum funktioniert SOCKS5 mit Passwort in Chrome nicht, während HTTP-Proxy mit Passwort funktioniert?
Die Implementierung des Netzwerk-Stacks von Chromium unterstützt einen Autorisierungsdialog für HTTP-Proxy über den 407-Mechanismus, implementiert aber nicht die Methode 0x02 aus RFC 1929 für SOCKS5. Das ist eine Entscheidung der Browserentwickler, keine Einschränkung des Protokolls. Lösung: IP-Autorisierung im Proxeon-Kundenkonto oder eine Erweiterung, die den Proxy über die API steuert.
Was tun, wenn der Proxy in SOCKS5 REP=05 zurückgibt?
Code 05 bedeutet, dass der Zielserver die TCP-Verbindung abgelehnt hat: Der Port ist geschlossen, der Dienst läuft nicht, oder die Firewall des Ziels blockiert die IP des Proxys. Prüfen Sie, ob Sie den richtigen Port übergeben haben, und versuchen Sie eine andere Proxy-Adresse. Der Proxy selbst arbeitet korrekt, das Problem liegt auf der zweiten Wegstrecke.
Was ist der Unterschied zwischen REP=02 in SOCKS5 und 403 bei einem HTTP-Proxy?
Semantisch ist es dasselbe: Der Proxy hat sich nach seinen Regeln geweigert, eine Verbindung aufzubauen. Meist bedeutet das, dass der Zielport oder Host durch die Richtlinie des Proxys verboten ist. Beim HTTP-Proxy gibt es im Body der 403-Antwort manchmal eine Erläuterung, bei SOCKS5 nur ein Byte.
Kann man denselben Login und dasselbe Passwort für den HTTP- und den SOCKS5-Port verwenden?
Bei Proxeon ja: Das Konto ist gemeinsam, unterschiedlich sind nur Port und Protokoll. Beim Wechsel des Protokolls müssen die Zugangsdaten nicht geändert werden.
Wie erkenne ich, ob mein Client die Domain lokal oder am Proxy auflöst?
Am zuverlässigsten: Starten Sie eine Traffic-Aufzeichnung auf Ihrer Schnittstelle und sehen Sie, ob vor dem Verbindungsaufbau zum Proxy eine DNS-Anfrage an die Zieldomain rausgeht. Einfacher: Tragen Sie vorübergehend in der hosts-Datei für die Zieldomain eine bewusst falsche Adresse ein. Wenn die Anfrage über den Proxy weiter funktioniert, löst der Proxy auf. Wenn sie zusammenbricht, löst der Client auf.
Sollte man HTTP/2 zum Proxy verwenden, wenn die Bibliothek das unterstützt?
Wenn Sie viele parallele Verbindungen zu verschiedenen Zielen haben und der Client CONNECT-Streams tatsächlich multiplext, ist der Gewinn spürbar: weniger TCP-Verbindungen, weniger Handshakes. Aber die Unterstützung dieser Möglichkeit in Clients und Proxy-Servern ist noch ungleichmäßig. Prüfen Sie die Dokumentation Ihres Clients und fragen Sie, ob Ihr Tarif HTTP/2 am Eingang unterstützt.
Warum steht im HTTP-Proxy eine absolute URI, wenn es den Host-Header gibt?
Der HTTP/1.1-Standard verlangt vom Client die Verwendung der absoluten Form beim Ansprechen eines Proxys, damit der Proxy eindeutig versteht, dass die Anfrage weitergeleitet und nicht lokal verarbeitet werden soll. Der Host-Header bleibt erhalten, weil der Proxy die Anfrage in origin-form an den Zielserver weiterleitet, und dort ist Host zwingend. Die Doppelung ist der Preis der Kompatibilität.
Was ist für Parsing wichtiger: HTTP oder SOCKS5?
Für HTTPS-Ziele gibt es keinen Sichtbarkeitsunterschied, der Unterschied liegt im Verhalten der Bibliothek. Wenn die Bibliothek gut mit SOCKS5 arbeitet und die Domain übergibt, nehmen Sie SOCKS5: Es greift nicht in Header ein und liefert die richtige regionale Auflösung. Wenn die Bibliothek mit SOCKS5 zickt oder Sie viele kurze Verbindungen ohne Pool haben, ist HTTP CONNECT nicht schlechter. Der wichtigste Rat: Öffnen Sie nicht für jede Anfrage eine neue Verbindung zum Proxy, das ist teurer als jede Protokollwahl.
Fazit
Zwei Ports im Kundenkonto sind kein Marketing-Paar aus „normal“ und „fortgeschritten“. Es sind zwei verschiedene Sprachen für dieselbe Maschine. Der HTTP-Proxy spricht in Anfragen und Antworten, versteht die Semantik, kann cachen und erklärt Fehler mit lesbaren Codes, und für alles Unverständliche hat er CONNECT, das ihn in einen TCP-Tunnel verwandelt. SOCKS5 spricht in „Host und Port“, analysiert den Inhalt nicht, unterstützt jedes TCP-Protokoll und UDP und erlaubt eine explizite Steuerung, wo die Domain aufgelöst wird.
Für verschlüsselten Traffic bieten beide Protokolle dem Vermittler die gleiche Sichtbarkeit. Die Wahl zwischen ihnen bestimmt sich nicht über Sicherheit, sondern über drei praktische Dinge: was Ihr Client kann, welches Protokoll innen läuft und wo Sie Namen auflösen möchten.
Was jetzt zu tun ist
- Bestimmen Sie das Protokoll in Ihrer Aufgabe. Kein HTTP: sofort SOCKS5.
- Prüfen Sie in der Dokumentation des Clients die Unterstützung für SOCKS5 mit Autorisierung und die Option der Remote-Auflösung.
- Wenn Sie mit geobasierten Ressourcen arbeiten, stellen Sie sicher, dass die Domain zum Proxy geht: socks5h, Remote-DNS, ATYP=0x03 oder HTTP CONNECT.
- Aktivieren Sie einen Verbindungspool oder Keep-Alive zum Proxy. Das bringt mehr als jeder Protokollwechsel.
- Wenn der Client keinen Login in SOCKS5 übergeben kann, richten Sie die IP-Autorisierung im Proxeon-Kundenkonto ein.
- Beginnen Sie beim Debugging mit curl -v: Es zeigt den gesamten Dialog mit dem Proxy und trennt sofort das Client-Problem vom Netzwerkproblem.
Und zum Schluss: Beide Protokolle sind älter als die meisten Ingenieure, die sie benutzen, und beide funktionieren bis heute ohne grundlegende Änderungen. Das ist ein seltener Fall, in dem die Einfachheit des Designs gesiegt hat. Wenn Sie verstehen, was in den ersten vierzig Bytes einer Verbindung genau passiert, wählen Sie den Port nicht mehr nach Gefühl, sondern wählen ein Werkzeug.