Inoltro dinamico SSH come proxy SOCKS sopra la vostra VPN
Un’applicazione che parla solo SOCKS non ha alcun endpoint proxy su una VPN ordinaria. Due salti, un solo listener loopback e una risoluzione del nome che il server SSH deve fare da sé.
Un’applicazione che parla solo SOCKS non ha con chi parlare su una VPN ordinaria, perché il tunnel trasporta pacchetti e l’applicazione vuole un endpoint proxy. OpenSSH può fornire quell’endpoint quando il proprietario dell’accesso lo consente, dato che l’inoltro dinamico trasforma una sessione SSH in un proxy locale. Poi ci sono due salti da tenere distinti: il tunnel che raggiunge l’host SSH e la connessione che quell’host apre in seguito. Separarli spiega sia perché la disposizione funziona sia ciò che non farà mai.
In cosa diventa il listener SSH e in cosa no
L’inoltro dinamico fa ascoltare localmente il client SSH e parlare SOCKS4 o SOCKS5 con tutto ciò che si connette. Ogni richiesta nomina una destinazione e il server SSH apre la connessione successiva, per questo la risoluzione della destinazione può avvenire dall’altro lato. È inoltro TCP a livello applicativo, non una VPN per l’intero dispositivo. Non trasporta alcuna associazione UDP, né ICMP, né nulla per le applicazioni che ignorano del tutto le impostazioni proxy. Anche il salto dal server SSH all’applicazione non è dentro il vostro tunnel, cosa che conta quando la destinazione accetta traffico solo da reti note.
I prerequisiti sono reali: una rotta verso l’host SSH, un account autorizzato, una chiave host del server verificata e il permesso di inoltrare. Nessuno è creato dal proxy, e l’ultimo di solito è il primo a mancare. Verificate tutti e quattro prima di eseguire qualsiasi altra diagnosi, perché dal client il guasto appare identico, quale che sia quello assente.
Avviatelo su loopback con una porta esplicita
Scegliete una porta locale inutilizzata e legatela esplicitamente a loopback invece di lasciare l’indirizzo vuoto. Le tre opzioni qui sotto esistono ciascuna per un motivo.
ssh -D 127.0.0.1:1080 -NT -o ControlPath=none -o ExitOnForwardFailure=yes \
[email protected]
-N salta il comando remoto e -T salta lo pseudo-terminale, così la sessione esiste solo per inoltrare. ExitOnForwardFailure fa uscire il client quando il listener non può essere creato, invece di girare senza l’inoltro richiesto. ControlPath=none tiene la sessione fuori da una connessione multiplexata esistente che potrebbe aggiungere i propri inoltri. Loopback tiene il listener fuori dalla LAN, ma su una macchina condivisa non è un confine di autorizzazione, perché anche altri processi locali possono raggiungerlo. Il riferimento del client OpenSSH documenta tutte queste opzioni, e l’avvertenza su loopback deriva da che cosa è un socket in ascolto.
Fate passare i nomi dentro il proxy, non attorno
Un client SOCKS5 può risolvere la destinazione da solo o chiedere al proxy di farlo, e questa scelta decide quale resolver risponde. Con socks5h, curl invia il nome host attraverso il proxy, quindi la risoluzione avviene sul server SSH. Con socks5 semplice, il portatile risolve prima e viaggia solo la connessione, il che annulla in silenzio lo scopo quando il nome è interno. La richiesta qui sotto svuota anche l’elenco senza proxy, così un valore NO_PROXY ereditato non può portarla attorno al proxy.
curl -sS --noproxy '' --proxy socks5h://127.0.0.1:1080 https://app.corp.example/health
La convalida del certificato e l’accesso proprio dell’applicazione valgono ancora, perché il proxy non sostituisce nessuno dei due. Restano due risoluzioni: il portatile deve raggiungere l’host SSH attraverso il percorso VPN e DNS consentito, e il server SSH deve risolvere da sé il nome dell’applicazione. La seconda si può provare da sola prima che qualsiasi traffico passi dal proxy.
ssh [email protected] getent hosts app.corp.example
Dimostrate una destinazione consentita, poi chiudete la sessione
Provate una destinazione che la politica consente e una che dovrebbe rifiutare, perché un inoltro funzionante dimostra solo che il listener funziona e nulla di più. L’applicazione vede l’indirizzo di origine scelto dal server SSH, e non è l’indirizzo del tunnel del vostro portatile. Dove l’estremità remota registra le connessioni per origine, quella differenza è la prima cosa da controllare quando una richiesta viene rifiutata.
Fermate la sessione tramite il processo che la possiede invece di uccidere una shell non correlata. Poi confermate che il listener è sparito, perché una porta che risponde ancora è una sessione che non avete davvero chiuso. Rimuovete solo l’impostazione proxy introdotta da questo esercizio, e lasciate in pace il resto della configurazione dell’applicazione. Un terminale incustodito che detiene una regola di inoltro non è un servizio, e un proxy permanente richiede un ciclo di vita approvato, non una finestra dimenticata.
ss -ltn | grep 1080
Guasti che questa disposizione non può correggere
Alcuni sintomi puntano dritti ai limiti qui sopra, e riconoscerli presto risparmia un pomeriggio di diagnosi del proxy. La tabella associa ciò che vedete a ciò che di solito significa. Qualunque cosa nell’ultima colonna è una questione di progettazione, non un errore di configurazione.
| What you see | What it usually means | Where to look |
|---|---|---|
| The app connects and nothing follows | It ignores proxy settings entirely | Its own network settings, not the SSH session |
| A name resolution error for the destination | The SSH server cannot resolve it | Server resolver and search domains |
| A UDP-only application fails | Dynamic forwarding carries TCP only | This arrangement cannot serve it |
| curl works, the browser does not | The browser is not using the socks5h endpoint | Browser proxy configuration |
| The listener answers after the session ended | Another process owns port 1080 | The ss output, then the owning process |
Le prime tre righe sono quelle che le persone diagnosticano male, perché ciascuna produce un tentativo di connessione invece di un errore sul proxy stesso. Un nome che si risolve sul portatile non dice nulla sul resolver del server, e il guasto si legge invece come un problema di certificato o di timeout. Le applicazioni solo UDP restano fuori dalla progettazione, non rotte dentro, e nessuna opzione ssh aggiuntiva lo cambia. La riga del browser è il promemoria abituale che le impostazioni proxy valgono per applicazione. L’ultima riga è il motivo per cui esiste il controllo di chiusura: una porta che ascolta ancora significa che ora la possiede qualcos’altro.