Policy-routing versus SOCKS: welke laag doet nu echt het proxywerk
Een route naar een SOCKS-poort is geen SOCKS-sessie. Vergelijk proxy-instellingen op applicatieniveau, een IP-naar-proxy-adapter en een gerouteerde gateway op de laag die converteert.
Je hebt een policy-route toegevoegd die het verkeer van een VPN-client naar een host stuurt waarop een SOCKS-listener op poort 1080 draait. De pakketten komen aan, de listener logt niets en de verbinding blijft hangen. Er is niets mis met de route: een volgende hop kiest waar een pakket heen gaat, en SOCKS is een gesprek dat een client moet beginnen. Vergelijk de drie architecturen die mensen meestal bedoelen als ze verkeer via een proxy sturen, en het wordt duidelijk welk stuk je opstelling mist.
Routing, DNAT en SOCKS veranderen verschillende dingen
Een policy-route herschrijft een beslissing op laag 3. Twee regels zijn genoeg om het verkeer van één client naar een gekozen volgende hop te sturen:
ip route add default via 10.50.0.2 table 101
ip rule add from 10.77.0.2 lookup 101Daarna geeft de kernel het pakket aan 10.50.0.2, terwijl de oorspronkelijke bestemming nog in de IP-header staat. Als 10.50.0.2 een router is, stuurt die het pakket door. Als het een host met een SOCKS-daemon op 1080 is, is het pakket niet geadresseerd aan iets dat het kan aannemen, en DNAT naar poort 1080 helpt ook niet, omdat een vertaald pakket nog steeds de oorspronkelijke applicatielading draagt in plaats van een SOCKS-groet.
SOCKS5 begint met een versiebyte, een lijst met methoden, een authenticatie-uitwisseling en een verzoek dat de bestemming noemt. Dat zijn applicatiegegevens. Geen routingregel en geen netfilter-doel genereert ze, en dat is de vergelijking in één regel: routing kiest een pad, SOCKS vraagt een server om een tweede verbinding te maken.
Geval één: de applicatie kan zelf SOCKS spreken
Als het programma een proxy-instelling heeft, is dat de kortste weg en die vereist geen kernelwijziging. Wijs het naar de listener, geef inloggegevens op als de server daarom vraagt, en beslis of namen lokaal worden opgelost of aan de proxy worden doorgegeven. Bij curl zijn dat verschillende vlaggen, en het verschil is belangrijk wanneer de bestemming alleen vanaf de proxyzijde wordt opgelost:
curl --socks5 10.50.0.2:1080 https://docs.example.com
curl --socks5-hostname 10.50.0.2:1080 https://internal.example.comApplicaties die proxy-omgevingsvariabelen negeren, of die ruwe sockets openen, kunnen zo niet worden geholpen. Browsers en de meeste HTTP-gereedschappen zijn in orde; een gameclient, een maildaemon of een willekeurige leveranciersbinary meestal niet. De grens loopt per applicatie en per protocol, daarom is deze optie uitstekend voor testen en zwak als antwoord voor de hele VPN.
Geval twee: een adapter die IP-stromen omzet in proxysessies
Voor programma's die geen SOCKS kunnen spreken, moet de conversie gebeuren in iets dat IP-verkeer beëindigt en namens hen proxysessies opent. Dat onderdeel bezit een tunnelinterface, accepteert de stromen die policy-routing heeft geselecteerd, voert voor elk de SOCKS-handshake uit en bouwt de antwoorden opnieuw op. De route stuurt verkeer erheen; de adapter is wat de sessie maakt.
Lees de documentatie voordat je er een heel subnet aan toevertrouwt. Veel adapters dragen TCP goed en behandelen UDP alleen via een SOCKS5 UDP-associatie, en geen enkele zet ICMP om in proxyverkeer, dus een geslaagde ping zegt niets over het proxypad. DNS is de andere valkuil: als de adapter namen lokaal oplost, worden alleen-interne records opgelost naar het verkeerde antwoord, of naar niets.
Luspreventie is het operationele detail dat bijt. De eigen verbindingen van de adapter naar de SOCKS-server mogen niet terug in de adapter worden gerouteerd, dus het verkeer heeft een uitzondering in de regel of een eigen bronadres nodig. Doe je dat fout, dan probeert de proxysessie zichzelf te proxyen.
Geval drie: de host is eigenlijk een gerouteerde gateway
Soms bevat de werkende opstelling helemaal geen SOCKS. De externe host stuurt pakketten door of doet NAT, en de op bron gebaseerde regel kiest hem simpelweg als uitgang. Dat ontwerp is legitiem, en het verklaart waarom een gekopieerde configuratie op het ene netwerk werkt en op het andere faalt: de regel is identiek, het ontbrekende stuk is een doorstuurdienst aan de andere kant.
De drie gevallen scheiden zich snel. Controleer wat er werkelijk luistert, en kijk dan naar de eerste bytes die de host bereiken:
ss -ltnp 'sport = :1080'
tcpdump -ni eth0 -X 'tcp port 1080'De eerste payloadbyte van een echte SOCKS-client is 0x05, de versie in de groet. Als de opname in plaats daarvan oorspronkelijke applicatiegegevens toont, zal geen enkele SOCKS-daemon antwoorden, omdat de onderhandeling nooit begon. Als er niets op 1080 luistert, is de host een gateway, en wordt de vraag of hij doorstuurt en of er een retourpad bestaat.
Kies de laag met vier vragen
Heeft het programma een proxy-instelling? Gebruik die en stop daar. Bevat het verkeer UDP of ICMP dat moet overleven? Alleen een gerouteerde of NAT-gateway draagt ICMP, en UDP heeft een SOCKS5-associatie nodig die beide kanten ondersteunen. Moet elk proces op de machine worden gedekt, ook de processen die je niet kunt configureren? Dan heb je een adapter nodig die de interface bezit en stromen beëindigt. Kun je ook het routeren, DNS en de uitzonderingen voor luspreventie overnemen? Zo niet, dan kost de gewone gateway minder om te beheren.
Eén onderscheid is de moeite waard om recht te houden. De eigen socks-proxy-optie van een VPN-client beschrijft hoe de buitenste tunnelverbinding zijn server bereikt, en zegt niets over het omzetten van de binnenste clientstromen. De twee worden voortdurend verward in hetzelfde ticket. Beslis welke relatie je nodig hebt voordat je een route aanraakt.