Policy-Routing gegen SOCKS: Welche Ebene den Datenverkehr tatsächlich proxyt
Eine Route zu einem SOCKS-Port ist keine SOCKS-Sitzung. Vergleichen Sie Proxy-Einstellungen auf Anwendungsebene, einen IP-zu-Proxy-Adapter und ein geroutetes Gateway nach der Ebene, die umsetzt.
Sie haben eine Policy-Route hinzugefügt, die den Datenverkehr eines VPN-Clients an einen Host schickt, auf dem ein SOCKS-Listener auf Port 1080 läuft. Die Pakete kommen an, der Listener protokolliert nichts, und die Verbindung hängt. An der Route ist nichts falsch: Ein nächster Hop wählt, wohin ein Paket geht, und SOCKS ist ein Gespräch, das ein Client beginnen muss. Vergleichen Sie die drei Architekturen, die Leute üblicherweise meinen, wenn sie Datenverkehr durch einen Proxy schicken, und es wird klar, welches Teil Ihrer Einrichtung fehlt.
Routing, DNAT und SOCKS ändern verschiedene Dinge
Eine Policy-Route schreibt eine Entscheidung auf Ebene 3 um. Zwei Zeilen genügen, um den Datenverkehr eines Clients zu einem gewählten nächsten Hop zu schicken:
ip route add default via 10.50.0.2 table 101
ip rule add from 10.77.0.2 lookup 101Danach übergibt der Kernel das Paket an 10.50.0.2, wobei das ursprüngliche Ziel weiterhin im IP-Header steht. Ist 10.50.0.2 ein Router, leitet er das Paket weiter. Ist es ein Host mit einem SOCKS-Daemon auf 1080, ist das Paket an nichts adressiert, das es annehmen könnte, und auch DNAT auf Port 1080 hilft nicht, weil ein übersetztes Paket weiterhin die ursprüngliche Anwendungsnutzlast statt einer SOCKS-Begrüßung trägt.
SOCKS5 beginnt mit einem Versionsbyte, einer Methodenliste, einem Authentifizierungsaustausch und einer Anfrage, die das Ziel benennt. Das sind Anwendungsdaten. Weder ein Routing-Eintrag noch ein netfilter-Ziel erzeugt sie, und das ist der Vergleich in einer Zeile: Routing wählt einen Pfad, SOCKS bittet einen Server um eine zweite Verbindung.
Fall eins: Die Anwendung kann selbst SOCKS sprechen
Wenn das Programm eine Proxy-Einstellung hat, ist das der kürzeste Weg, und er braucht keine Kernel-Änderung. Richten Sie es auf den Listener, geben Sie Anmeldedaten an, wenn der Server danach fragt, und entscheiden Sie, ob Namen lokal aufgelöst oder an den Proxy übergeben werden. Bei curl sind das unterschiedliche Flags, und der Unterschied zählt, wenn das Ziel nur von der Proxy-Seite aufgelöst wird:
curl --socks5 10.50.0.2:1080 https://docs.example.com
curl --socks5-hostname 10.50.0.2:1080 https://internal.example.comAnwendungen, die Proxy-Umgebungsvariablen ignorieren oder rohe Sockets öffnen, lassen sich so nicht helfen. Browser und die meisten HTTP-Werkzeuge sind in Ordnung; ein Spielclient, ein Mail-Daemon oder eine beliebige Hersteller-Binärdatei meist nicht. Die Grenze verläuft pro Anwendung und pro Protokoll, weshalb diese Option zum Testen hervorragend und als Antwort für das gesamte VPN schwach ist.
Fall zwei: ein Adapter, der IP-Ströme in Proxy-Sitzungen umsetzt
Für Programme, die kein SOCKS sprechen können, muss die Umsetzung in etwas geschehen, das IP-Datenverkehr beendet und in ihrem Namen Proxy-Sitzungen öffnet. Diese Komponente besitzt eine Tunnelschnittstelle, nimmt die vom Policy-Routing gewählten Ströme an, führt für jeden das SOCKS-Handshake aus und baut die Antworten neu auf. Die Route richtet den Datenverkehr auf sie; der Adapter ist das, was die Sitzung erzeugt.
Lesen Sie seine Dokumentation, bevor Sie ihm ein ganzes Subnetz anvertrauen. Viele Adapter übertragen TCP gut und behandeln UDP nur über eine SOCKS5-UDP-Assoziation, und keiner von ihnen macht ICMP zu Proxy-Datenverkehr, sodass ein erfolgreicher Ping nichts über den Proxy-Pfad aussagt. DNS ist die andere Falle: Löst der Adapter Namen lokal auf, werden reine interne Einträge zur falschen Antwort oder zu gar nichts aufgelöst.
Schleifenvermeidung ist das Betriebsdetail, das beißt. Die eigenen Verbindungen des Adapters zum SOCKS-Server dürfen nicht zurück in den Adapter geroutet werden, sein Datenverkehr braucht also eine Ausnahme in der Regel oder eine eigene Quelladresse. Machen Sie das falsch, versucht die Proxy-Sitzung, sich selbst zu proxyn.
Fall drei: Der Host ist tatsächlich ein geroutetes Gateway
Manchmal enthält die funktionierende Einrichtung überhaupt kein SOCKS. Der entfernte Host leitet Pakete weiter oder führt NAT dafür aus, und die quellenbasierte Regel wählt ihn einfach als Ausgang. Dieses Design ist legitim, und es erklärt, warum eine kopierte Konfiguration in einem Netz funktioniert und in einem anderen scheitert: Die Regel ist identisch, das fehlende Teil ist ein Weiterleitungsdienst auf der anderen Seite.
Die drei Fälle trennen sich schnell. Prüfen Sie, was tatsächlich lauscht, und sehen Sie sich dann die ersten Bytes an, die den Host erreichen:
ss -ltnp 'sport = :1080'
tcpdump -ni eth0 -X 'tcp port 1080'Das erste Nutzlastbyte eines echten SOCKS-Clients ist 0x05, die Version in der Begrüßung. Zeigt die Aufzeichnung stattdessen ursprüngliche Anwendungsdaten, antwortet kein SOCKS-Daemon, weil die Aushandlung nie begann. Lauscht auf 1080 nichts, ist der Host ein Gateway, und die Frage wird, ob er weiterleitet und ob ein Rückweg existiert.
Wählen Sie die Ebene mit vier Fragen
Hat das Programm eine Proxy-Einstellung? Nutzen Sie sie und hören Sie dort auf. Enthält der Datenverkehr UDP oder ICMP, das überleben muss? Nur ein geroutetes Gateway oder NAT-Gateway trägt ICMP, und UDP braucht eine SOCKS5-Assoziation, die beide Seiten unterstützen. Muss jeder Prozess auf dem Rechner abgedeckt sein, auch solche, die Sie nicht konfigurieren können? Dann brauchen Sie einen Adapter, der die Schnittstelle besitzt und Ströme beendet. Können Sie auch dessen Routing, DNS und Ausnahmen zur Schleifenvermeidung übernehmen? Wenn nicht, kostet das schlichte Gateway im Betrieb weniger.
Eine Unterscheidung sollte man sauber halten. Die eigene socks-proxy-Option eines VPN-Clients beschreibt, wie die äußere Tunnelverbindung ihren Server erreicht, und sagt nichts über die Umsetzung der inneren Client-Ströme aus. Beide werden im selben Ticket ständig verwechselt. Entscheiden Sie, welche Beziehung Sie brauchen, bevor Sie eine Route anfassen.