Hai aggiunto una rotta basata su policy che invia il traffico di un client VPN verso un host che esegue un listener SOCKS sulla porta 1080. I pacchetti arrivano, il listener non registra nulla e la connessione resta appesa. La rotta non ha nulla di sbagliato: il salto successivo sceglie dove va un pacchetto, e SOCKS è una conversazione che il client deve avviare. Confronta le tre architetture che le persone di solito intendono quando inviano traffico attraverso un proxy, e diventa chiaro quale pezzo manca alla tua configurazione.

Routing, DNAT e SOCKS cambiano cose diverse

Una rotta basata su policy riscrive una decisione di livello 3. Due righe bastano per inviare il traffico di un client a un salto successivo scelto:

ip route add default via 10.50.0.2 table 101
ip rule add from 10.77.0.2 lookup 101

Dopo di che, il kernel consegna il pacchetto a 10.50.0.2 con la destinazione originale ancora nell’intestazione IP. Se 10.50.0.2 è un router, inoltra il pacchetto. Se è un host con un demone SOCKS su 1080, il pacchetto non è indirizzato a nulla che possa accettarlo, e anche il DNAT verso la porta 1080 non aiuta, perché un pacchetto tradotto porta ancora il payload originale dell’applicazione invece di un saluto SOCKS.

SOCKS5 inizia con un byte di versione, un elenco di metodi, uno scambio di autenticazione e una richiesta che nomina la destinazione. Sono dati applicativi. Nessuna voce di routing e nessun target netfilter li genera, e questo è il confronto in una riga: il routing sceglie un percorso, SOCKS chiede a un server di aprire una seconda connessione.

Caso uno: l’applicazione sa parlare SOCKS da sola

Quando il programma ha un’impostazione proxy, è la via più breve e non richiede modifiche al kernel. Puntala al listener, fornisci credenziali se il server le chiede e decidi se i nomi vengono risolti localmente o passati al proxy. Con curl sono flag diversi, e la differenza conta quando la destinazione si risolve solo dal lato del proxy:

curl --socks5 10.50.0.2:1080 https://docs.example.com
curl --socks5-hostname 10.50.0.2:1080 https://internal.example.com

Le applicazioni che ignorano le variabili d’ambiente del proxy, o che aprono socket grezze, non possono essere aiutate in questo modo. I browser e la maggior parte degli strumenti HTTP vanno bene; un client di gioco, un demone di posta o un binario arbitrario di un fornitore di solito no. Il confine è per applicazione e per protocollo, per questo questa opzione è ottima per i test e debole come risposta per l’intera VPN.

Caso due: un adattatore che converte flussi IP in sessioni proxy

Per i programmi che non sanno parlare SOCKS, la conversione deve avvenire in qualcosa che termina il traffico IP e apre sessioni proxy per loro conto. Quel componente possiede un’interfaccia di tunnel, accetta i flussi selezionati dal routing basato su policy, esegue la stretta di mano SOCKS per ciascuno e ricostruisce le risposte. La rotta indirizza il traffico verso di esso; l’adattatore è ciò che crea la sessione.

Leggi la sua documentazione prima di affidargli un’intera sottorete. Molti adattatori trasportano bene TCP e gestiscono UDP solo tramite un’associazione UDP di SOCKS5, e nessuno di loro trasforma ICMP in traffico proxy, quindi un ping riuscito non dice nulla sul percorso del proxy. Il DNS è l’altra trappola: se l’adattatore risolve i nomi localmente, i record solo interni si risolvono in una risposta sbagliata, o in nulla.

La prevenzione dei loop è il dettaglio operativo che morde. Le connessioni dell’adattatore stesso verso il server SOCKS non devono essere instradate di nuovo verso l’adattatore, quindi il suo traffico ha bisogno di un’eccezione nella regola o di un indirizzo sorgente dedicato. Se lo fai male, la sessione proxy tenta di fare da proxy a se stessa.

Caso tre: l’host è in realtà un gateway instradato

A volte la configurazione che funziona non contiene alcun SOCKS. L’host remoto inoltra i pacchetti o applica loro NAT, e la regola basata sulla sorgente lo sceglie semplicemente come uscita. Quel progetto è legittimo, e spiega perché una configurazione copiata funziona su una rete e fallisce su un’altra: la regola è identica, il pezzo mancante è un servizio di inoltro dall’altra parte.

I tre casi si separano rapidamente. Controlla cosa sta realmente ascoltando, poi guarda i primi byte che raggiungono l’host:

ss -ltnp 'sport = :1080'
tcpdump -ni eth0 -X 'tcp port 1080'

Il primo byte di carico utile di un vero client SOCKS è 0x05, la versione nel saluto. Se la cattura mostra invece dati applicativi originali, nessun demone SOCKS risponderà, perché la negoziazione non è mai iniziata. Se nulla ascolta su 1080, l’host è un gateway, e la domanda diventa se inoltra e se esiste un percorso di ritorno.

Scegli il livello con quattro domande

Il programma ha un’impostazione proxy? Usala e fermati lì. Il traffico include UDP o ICMP che devono sopravvivere? Solo un gateway instradato o NAT trasporta ICMP, e UDP richiede un’associazione SOCKS5 supportata da entrambe le estremità. Ogni processo della macchina deve essere coperto, compresi quelli che non puoi configurare? Allora serve un adattatore che possieda l’interfaccia e termini i flussi. Puoi assumerti anche il suo routing, DNS ed eccezioni per la prevenzione dei loop? Se no, il gateway semplice costerà meno da gestire.

Una distinzione va tenuta chiara. L’opzione socks-proxy di un client VPN descrive come la connessione del tunnel esterno raggiunge il suo server, e non dice nulla sulla conversione dei flussi interni del client. Le due cose vengono confuse di continuo nello stesso ticket. Decidi quale relazione ti serve prima di toccare una rotta.

Articoli correlati