Traffico UDP attraverso il tunnel SSH


66

Il titolo lo riassume praticamente. Vorrei inviare il traffico UDP attraverso un tunnel SSH. In particolare, devo essere in grado di inviare pacchetti UDP attraverso il tunnel e avere il server in grado di rispedirmi dall'altra parte. So come farlo per le connessioni TCP. È possibile con UDP?

Risposte:


36

Questa piccola guida spiega come inviare il traffico UDP tramite SSH utilizzando strumenti standard (ssh, nc, mkfifo) con la maggior parte dei sistemi operativi simili a UNIX.

Esecuzione del tunneling UDP tramite una connessione SSH

Step by step Apri una porta forward TCP con la tua connessione SSH

Sul tuo computer locale (locale), connettiti al computer distante (server) tramite SSH, con l'opzione -L aggiuntiva in modo che SSH con port-forward TCP:

local# ssh -L 6667:localhost:6667 server.foo.com

Ciò consentirà di inoltrare le connessioni TCP sul numero di porta 6667 della macchina locale al numero di porta 6667 su server.foo.com attraverso il canale protetto. Imposta il forwarding da TCP a UDP sul server

Sul server, apriamo un listener sulla porta TCP 6667 che inoltrerà i dati alla porta UDP 53 di un IP specificato. Se vuoi fare l'inoltro DNS come me, puoi prendere l'IP del primo nameserver che troverai in /etc/resolv.conf. Ma prima, dobbiamo creare un fifo. Il fifo è necessario per avere comunicazioni bidirezionali tra i due canali. Una semplice shell shell comunicava solo l'input standard "output standard al processo giusto".

server# mkfifo /tmp/fifo
server# nc -l -p 6667 < /tmp/fifo | nc -u 192.168.1.1 53 > /tmp/fifo

Ciò consentirà di inoltrare il traffico TCP sulla porta 6667 del server al traffico UDP sulla porta 53 di 192.168.1.1 e di restituire le risposte. Imposta l'inoltro da UDP a TCP sul tuo computer

Ora, dobbiamo fare il contrario di ciò che è stato fatto in alto sulla macchina locale. È necessario un accesso privilegiato per associare la porta UDP 53.

local# mkfifo /tmp/fifo
local# sudo nc -l -u -p 53 < /tmp/fifo | nc localhost 6667 > /tmp/fifo

Ciò consentirà il traffico UDP sulla porta 53 della macchina locale da inoltrare al traffico TCP sulla porta 6667 della macchina locale. Goditi il ​​tuo server DNS locale :)

Come probabilmente hai indovinato ora, quando una query DNS verrà eseguita sul computer locale, ad esempio sulla porta UDP locale 53, verrà inoltrata alla porta TCP 6667 locale, quindi alla porta TCP 6667 del server, quindi al server DNS del server , Porta UDP 53 del 192.168.1.1. Per usufruire dei servizi DNS sul tuo computer locale, inserisci la seguente riga come primo nameserver nel tuo /etc/resolv.conf:

nameserver 127.0.0.1

28
Questa soluzione non è sicura. I flussi TCP non sono garantiti per preservare i confini dei messaggi, quindi un singolo datagramma UDP può essere suddiviso in parti, rompendo qualsiasi protocollo.
Juho Östman,

2
Potrebbe anche essere utile usare la porta 1153 invece di 6667 (dall'esempio di SSH man), che viene utilizzata da IRC.
phil pirozhkov,

1
@ JuhoÖstman Grazie per aver segnalato questo errore. Essere consapevoli del problema ... hai eseguito accros una soluzione? i messaggi abbastanza piccoli sarebbero un modo per farlo funzionare?
umanità e

4
La soluzione sarebbe anteporre una lunghezza a ciascun pacchetto prima che vengano inviati attraverso il flusso TCP e ricostruire i pacchetti originali da quello. Sarebbe facile scrivere uno script C per farlo, ma non sono sicuro che esista una soluzione prontamente disponibile. In pratica, il TCP di solito sembra preservare i confini dei messaggi in questo caso, ma si possono verificare strani errori in qualsiasi momento.
Juho Östman,

Ho affrontato un altro problema con questo: pipe e fifo sono bufferizzati, quindi i confini del frame vengono persi. Così molti frame UDP possono essere concatenati in un frame TCP.
Julio Guerra,

26

Questo esempio (penso che la risposta di John punti la stessa cosa in un posto diverso), descrive come accedere ai servizi UDP / DNS di un'altra macchina tramite una connessione TCP / SSH.

Inoltreremo il traffico UDP / 53 locale a TCP, quindi il traffico TCP con il meccanismo di port forwarding di SSH all'altra macchina, quindi TCP a UDP / 53 all'altra estremità.
In genere, puoi farlo con openvpn.
Ma qui lo faremo con strumenti più semplici, solo openssh e netcat.

Alla fine di quella pagina, c'è un altro commento con riferimento a " socat",
lo stesso accesso UDP / DNS è fatto con,

Lato server: socat tcp4-listen:5353,reuseaddr,fork UDP:nameserver:53
lato client:socat udp4-listen:53,reuseaddr,fork tcp:localhost:5353

Fare riferimento agli esempi socat per ulteriori informazioni.


3
Questo mi sembra molto più utile della risposta accettata. Avevo bisogno di un reindirizzamento unidirezionale del flusso video (TS / UDP) ... ssh orig_strm_src socat udp4-listen:4003,reuseaddr,fork STDOUT| socat STDIN udp-sendto:localhost:4003
nhed

FWIW, ho scritto una guida più dettagliata sulla mia home page che descrive come impostare socat su SSH per l'inoltro UDP. Utilizza SNMP come esempio.
Peter V. Mørch,

20

SSH (almeno OpenSSH) ha il supporto per semplici VPN. Utilizzando l' opzione -wo Tunnelnel sshclient, è possibile creare un tundispositivo su entrambe le estremità, che può essere utilizzato per inoltrare qualsiasi tipo di traffico IP. (Vedi anche Tunnelnella pagina di manuale di ssh_config(5).) Nota che questo richiede OpenSSH (e probabilmente i privilegi di root) ad entrambe le estremità.


Ciò richiede i privilegi di root sulla macchina remota anche per il tunneling UDP delle porte non privilegiate e PermitRootLogin impostato su non 'no'. Peccato.
phil pirozhkov,

@grawity Grazie per aver sottolineato questa opzione, che anche quando indicato da philpirozhkov il login root richiesto. Mi chiedo se ci può essere un modo per indurlo a non aver bisogno della radice?
umanità e

4
@humanityANDpeace: puoi precreare i dispositivi tun / tap e renderli di proprietà di un utente specifico, usando ip tuntap add.
Grawity

Ciao @grawity. Mi piace la tua soluzione ma non riesco a farla funzionare. Ho pretrattato il tundispositivo come segue: sudo ip tuntap add mode tunma quando mai utilizzo l' -wopzione in questo modo: ssh $Server -w $portOttengo Tunnel device open failed. Could not request tunnel forwarding.Cosa sto facendo di sbagliato?
Lucas Aimaretto,

16

Oppure potresti semplicemente usare ssf (che è stato progettato per gestire questo caso d'uso), con un semplice comando:


Dalla parte del cliente:

#>./ssfc -U 53:192.168.1.1:53 server.foo.com

Questo comando reindirizza la porta locale 53 (dns) alla porta 192.168.1.1 53, attraverso un tunnel sicuro tra localhost e server.foo.com.


Avrai bisogno di un server ssf (invece di - o accanto a - il tuo server ssh):

#>./ssfs

A proposito, sia lato client che lato server di ssf funzionano su Windows / Linux / Mac. Questa è un'applicazione userland, quindi non hai bisogno di tun / tap o VPN.

Per reindirizzare la porta 53, avrai bisogno dei privilegi di amministratore, indipendentemente dallo strumento che stai utilizzando.

Per ulteriori informazioni, dettagli, casi d'uso o download: https://securesocketfunneling.github.io/ssf/


Per favore sii cauto rispondendo con "ecco il mio prodotto", è spam limite. Suggerisco di leggere e seguire le linee guida del centro assistenza .
heavyyd,

7
Al massimo, è una spina spudorata. Comunque la soluzione potrebbe soddisfare la tua richiesta. A proposito, SSF è OpenSource e non profit.
sviluppatori ssf,

11
@heavyd: se avesse pubblicato un sacco di script confusi, sarebbe accettabile, ma poiché ha creato uno strumento open source maturo, non lo è? Risponde perfettamente alla domanda originale.
Synthead

Devo ammettere a malincuore che questo è esattamente lo strumento che stavo cercando, anche se era una spina spudorata.
therealrootuser,

9

Non riuscivo nca lavorare per SNMP, perché i client SNMP continuano a scegliere una nuova porta UDP di origine e molti possono essere attivi contemporaneamente.

Invece, ho scritto un post che descrive come farlo socatin questo post del blog , usando SNMP come esempio. In sostanza, usando due terminali, a partire da una panoramica:

panoramica

Terminal uno:

client$ ssh -L 10000:localhost:10000 server
server$ socat -T10 TCP4-LISTEN:10000,fork UDP4:switch:161

Questo crea l'inoltro SSH della porta TCP 10000 ed esegue socat sul server. Notare come l'indirizzo IP dello switch è menzionato nella riga di comando di socat come "switch".

Terminal due:

client$ sudo socat UDP4-LISTEN:161,fork TCP4:localhost:10000

Ciò imposta socat sul client. Questo dovrebbe farlo.


questo ha funzionato per me :)
Paul Fenney

4

Una VPN è una soluzione migliore se si ha accesso a una porta UDP.

Se hai accesso solo alla porta TCP SSH, un tunnel SSH è buono come una VPN, almeno per il ping e il backtracking dei pacchetti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.