Modo semplice per creare un tunnel da una porta locale a un'altra?


76

Ho un server di sviluppo, accessibile solo da 127.0.0.1:8000, non 192.168.1.x: 8000. Come hack rapido, c'è un modo per impostare qualcosa da ascoltare su un'altra porta (diciamo, 8001) in modo che dalla rete locale potrei connettere 192.168.1.x: 8001 e tunnel il traffico tra il client e 127.0 .0.1: 8000?


4
netcat può farlo.
Andy,

Risposte:


44

L'uso di ssh è la soluzione più semplice.

ssh -g -L 8001: localhost: 8000 -f -N user@remote-server.com

Questo inoltra la porta locale 8001 sulla tua stazione di lavoro all'indirizzo localhost sulla porta 8000 di remote-server.com.
-gSignifica consentire ad altri client sulla mia rete di connettersi alla porta 8001 sulla mia stazione di lavoro. In caso contrario, solo i client locali sulla workstation possono connettersi alla porta inoltrata.
-Nsignifica che tutto ciò che sto facendo è inoltrare le porte, non avviare una shell.
-fsignifica passare in background dopo una connessione SSH riuscita e il login.
La porta 8001 rimarrà aperta per molte connessioni, fino a quando ssh muore o viene ucciso. Se ti capita di trovarti su Windows, anche l'eccellente client SSH PuTTY può farlo. Utilizzare 8001 come porta locale e localhost: 8000 e destinazione e aggiungere un port forwarding locale nelle impostazioni. Puoi aggiungerlo dopo una connessione riuscita con PuTTY.


4
Che cosa user@remote-server.comfa? Non è assolutamente necessario per il port forwarding, tuttavia i mandati ssh che hanno questo argomento, più oltre, cerca di connettersi lì. E dopo aver impostato questa fastidiosa opzione su hostname, viene emesso …port 22: Connection refused (no, non ho usato la porta 22) . A meno che non mi manchi qualcosa, il comando chiaramente non funziona.
Hi-Angel,

@ Hi-Angel user@remote-server.comè solo un esempio e non dovresti prenderlo alla lettera. Devi sostituirlo con un nome di computer a cui vuoi connetterti e il tuo nome utente su questo computer. Queste informazioni sono necessarie per stabilire una connessione ssh. Solo dopo aver stabilito la connessione SSH è possibile inoltrare le porte tramite questa connessione.
Piotr Dobrogost,

Se vuoi che la porta sia disponibile all'avvio, vedi "autossh" in un servizio systemd usando il metodo sopra - everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh
Richard Hollis,

Ricevo anche "connessione rifiutata". E ancora non capisco perché l'argomento user@remote-server.com sia necessario quando non è coinvolta alcuna connessione SSH (secondo -N). Dovrebbe semplicemente inoltrare i pacchetti.
Alexander Taylor,

2
@AlexanderTaylor -Nnon significa che non esiste una connessione SSH. Significa semplicemente do not execute a remote command(vedi la pagina man ). L' <user>@<host>argomento è necessaria, perché questo fa aprire una connessione SSH <host>(che per il caso del PO sarebbe localhost), e inoltra la porta desiderata attraverso il tunnel SSH. È una soluzione al problema di OP, ma non la più semplice. Per inoltrare a localhost senza usare ssh, puoi usare socato netcatcome in StephaneChazelas e le risposte di un utente

94

Con socatsul server:

socat tcp-listen:8001,reuseaddr,fork tcp:localhost:8000

Per impostazione predefinita, socatascolterà sulla porta TCP 8001 su qualsiasi indirizzo IPv4 o IPv6 (se supportato) sulla macchina. È possibile limitarlo a IPv4 / 6 sostituendolo tcp-listencon tcp4-listeno tcp6-listenoppure a un indirizzo locale specifico aggiungendo un ,bind=that-address.

Lo stesso vale per la presa di connessione a cui si sta eseguendo il proxy, è possibile utilizzare qualsiasi indirizzo al posto di localhoste sostituire tcpcon tcp4o tcp6se si desidera limitare la risoluzione dell'indirizzo agli indirizzi IPv4 o IPv6.

Si noti che per il server in ascolto sulla porta 8000, la connessione apparirà come proveniente dal proxy (nel caso di localhost, che sarà localhost), non dal client originale. Dovresti usare gli approcci DNAT (ma che richiedono i privilegi di superutente) affinché il server sia in grado di dire chi è il client.


1
Grazie, questo è fantastico poiché non è necessario disporre di un server SSH locale in esecuzione.
jontro,

Posso usare la stessa porta ma un indirizzo diverso?
Amos,

@amos, vedi modifica.
Stéphane Chazelas,

Sarebbe anche possibile inoltrare il traffico solo da IP specifici?
Phate,

1
@Phate, vedi Dì a socat di ascoltare le connessioni da un singolo indirizzo IP (e le opzioni rangee tcpwrapnella socatpagina man).
Stéphane Chazelas,

46

L'uso del tradizionale ncè la soluzione più semplice:

nc -l -p 8001 -c "nc 127.0.0.1 8000"

Questa versione di ncè nel netcat-traditionalpacchetto su Ubuntu. (Devi update-alternativeso chiamarlo nc.traditional.)

Nota che a differenza di ssh questo non è crittografato. Tienilo a mente se lo usi al di fuori di un host.


2
qualcuno conosce l'equivalente su netcat-openbsd?
Sridhar Sarnobat,

2
Analogico per netcatla versione che è incluso in busybox: nc -v -lk -p 8001 -e /usr/bin/nc 127.0.0.1 8000. ( Descrizione dei parametri )
Ivan Kolmychek,

2
Funziona, ma il nccomando termina dopo la prima connessione remota. Aggiungi -kse devi tenerlo in esecuzione.
Sopalajo de Arrierez,

Ricevo questo errore: nc: cannot use -p and -lsu CentOS 6.4. C'è un lavoro in giro?
Nick Predey,

Preferisco questa soluzione rispetto a quella ssh perché rende più semplice l'uso come root, quando è necessario inoltrare localmente una porta privilegiata.
Christian,

24

Netcat OpenBSD è disponibile per impostazione predefinita su Linux e anche su OS X.

OSX:

mkfifo a
mkfifo b
nc 127.0.0.1 8000 < b > a &
nc -l 8001 < a > b &

Linux:

mkfifo backpipe
nc -l 12345 0<backpipe | nc www.google.com 80 1>backpipe

Un'alternativa che funziona su OS X bash è usare una pipe bidirezionale . Potrebbe funzionare su altri Unix:

nc 127.0.0.1 8000 <&1 | nc -l 8001 >&0

All'inizio non ho notato che stavi usando openbsd netcat. Questo è meglio che dover installare un altro netcat da un pacchetto Ubuntu.
Robert R,

Esempio di OpenBSD fallito su Ubuntu 15.04. Con i reindirizzamenti della shell, netcat non riesce ad aprire la porta per l'ascolto come visto da ss -tano netstat -tan.
Justin C,

⁺¹. FTR: il modo alternativo funziona su Ubuntu
Hi-Angel,

Non capisco la tua soluzione. Puoi spiegarlo?
Trismegistos,

@trismegistos In questi esempi il listener e il client netcat reindirizzano l'input in alcuni file condivisi (mkfifo pipe ... prima in primo luogo) e usano quei file condivisi come fonte / destinazione di input / output, creando effettivamente un tunnel. Di solito vengono utilizzati client / listener, ma alcune tecniche utilizzano client + client / listener + listener- wiki.securityweekly.com/… e devono essere letti slideshare.net/amiable_indian/secrets-of-top-pentesters .
Info5ek,

4

Citando la risposta di David Spillett su ServerFault

rinetd dovrebbe fare il lavoro, e un binario di Windows per esso può essere ottenuto da http://www.boutell.com/rinetd/ (per chiunque cerchi la stessa cosa sotto Linux, rinetd è nei repository standard di quasi ogni distribuzione quindi può essere installato con "apt-get install rinetd" o "yum install rinetd" o simile)

È un semplice binario che accetta un file di configurazione nel formato

bindaddress bindport connectaddress connectport

Per esempio:

192.168.1.1 8001 127.0.0.1 8000

o

0.0.0.0 8001 127.0.0.1 8000

se si desidera associare la porta in entrata a tutte le interfacce.


3
iptables -t nat -A PREROUTING -p tcp --dport <origin-port> -j REDIRECT --to-port <destination-port>

service iptables save
service iptables restart

Quando provo a connettermi dport, come in nc -v localhost 2345, sto ricevendo Connection refused. Non sono molto bravo in iptables, ma suppongo che il dport debba avere un'app di ascolto.
Ciao Angelo

Cosa succede se la porta di origine si trova su un'interfaccia diversa rispetto alla porta di destinazione?
Trismegistos,

0

Sulla base della risposta di Mark A. , ho dovuto fare una piccola modifica per farlo funzionare sul mio Mac (almeno su macOS Mojave versione 10.14.4)

mkfifo a
mkfifo b
nc 127.0.0.1 8000 < b > a &
nc -l 8001 < a > b &
printf "" > a

Questa affermazione printf sembra essere cruciale. Altrimenti il ​​comando netcat per connettersi alla porta 8000 non proverà mai effettivamente a connettersi, e il comando netcat per ascoltare sulla porta 8001 non ascolterà mai effettivamente sulla porta 8001. Senza lo printf, ogni volta che proverei a connettermi alla porta 8001 connessione rifiutata.

La mia ipotesi è che netcat debba in qualche modo bloccare su stdin (forse sta provando a leggerlo per qualche motivo) prima di eseguire effettivamente qualsiasi operazione Socket. Pertanto, senza l'istruzione printf che scrive in fifo a, il comando netcat non inizierà mai l'ascolto sulla porta 8001.

Nota: avrei lasciato una risposta sul post di Mark, ma non ho ancora la reputazione.


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.