Einfache Möglichkeit, einen Tunnel von einem lokalen Port zu einem anderen zu erstellen?


76

Ich habe einen Entwicklungsserver, auf den nur von 127.0.0.1:8000 zugegriffen werden kann, nicht von 192.168.1.x: 8000. Als schnellen Hack gibt es eine Möglichkeit, etwas einzurichten, um auf einem anderen Port (z. B. 8001) zu lauschen, sodass ich über das lokale Netzwerk 192.168.1.x: 8001 verbinden und den Datenverkehr zwischen dem Client und 127.0 tunneln kann 0,1: 8000 & le;


4
netcat kann das.
Andy

Antworten:


44

Ssh ist die einfachste Lösung.

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

Dadurch wird der lokale Port 8001 auf Ihrer Workstation an die localhost-Adresse auf remote-server.com, Port 8000
-g, weitergeleitet. Dies bedeutet, dass andere Clients in meinem Netzwerk eine Verbindung zu Port 8001 auf meiner Workstation herstellen können. Andernfalls können nur lokale Clients auf Ihrer Workstation eine Verbindung zum weitergeleiteten Port herstellen.
-NDas heißt, ich leite nur Ports weiter und starte keine Shell.
-fbedeutet, nach einer erfolgreichen SSH-Verbindung und Anmeldung in den Hintergrund zu treten.
Port 8001 bleibt für viele Verbindungen offen, bis ssh stirbt oder getötet wird. Wenn Sie zufällig unter Windows arbeiten, ist dies auch mit dem hervorragenden SSH-Client PuTTY möglich. Verwenden Sie 8001 als lokalen Port und localhost: 8000 als Ziel und fügen Sie in den Einstellungen eine lokale Portweiterleitung hinzu. Sie können es nach einer erfolgreichen Verbindung mit PuTTY hinzufügen.


4
Was macht der user@remote-server.com? Es ist definitiv nicht für die Portweiterleitung erforderlich, aber wenn ssh dieses Argument hat, versucht es, sich dort zu verbinden. Und wenn diese lästige Option auf Hostname gesetzt wird, wird sie ausgegeben …port 22: Connection refused (nein, ich habe den 22-Port nicht verwendet) . Sofern ich nichts vermisse, funktioniert der Befehl einfach nicht.
Hi-Angel

@ Hi-angel user@remote-server.comist nur ein beispiel und du solltest es nicht wörtlich nehmen. Sie müssen dies durch den Namen des Computers, zu dem Sie eine Verbindung herstellen möchten, und Ihren Benutzernamen auf diesem Computer ersetzen. Diese Informationen werden benötigt, um eine SSH-Verbindung herzustellen. Erst nachdem die SSH-Verbindung hergestellt wurde, können Ports über diese Verbindung weitergeleitet werden.
Piotr Dobrogost

Wenn Sie möchten, dass der Port vom Boot aus verfügbar ist, lesen Sie "autossh" in einem systemd-Dienst mit der oben beschriebenen Methode - everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh
Richard Hollis

Ich bekomme auch "Verbindung abgelehnt". Und ich verstehe immer noch nicht, warum das Argument user@remote-server.com benötigt wird, wenn keine SSH-Verbindung besteht (laut -N). Sollte nur Pakete weiterleiten.
Alexander Taylor

2
@AlexanderTaylor -Nbedeutet nicht, dass keine SSH-Verbindung besteht. Es bedeutet einfach do not execute a remote command(siehe Manpage ). Das <user>@<host>Argument ist notwendig, da dies tut , eine SSH - Verbindung öffnen <host>(die für OP Fall wäre localhost), und leitet den gewünscht Port durch diesen SSH Tunnel. Es ist eine Lösung für das OP-Problem, aber nicht die einfachste. Um ohne Verwendung von ssh zu localhost weiterzuleiten, können Sie socatoder netcatwie in StephaneChazelas und Antworten von

94

Mit socatauf dem Server:

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

Standardmäßig socatüberwacht TCP-Port 8001 eine beliebige IPv4- oder IPv6-Adresse (sofern unterstützt) auf dem Computer. Sie können es auf IPv4 / 6 beschränken, indem Sie es tcp-listendurch tcp4-listenoder ersetzen tcp6-listen, oder auf eine bestimmte lokale Adresse, indem Sie a hinzufügen ,bind=that-address.

Das Gleiche gilt für die Anschlussbuchse Sie Proxying, können Sie eine beliebige Adresse anstelle von verwenden localhost, und ersetzen Sie tcpmit tcp4oder , tcp6wenn Sie die Adressauflösung zu IPv4 oder IPv6 - Adressen zu beschränken.

Beachten Sie, dass für den Server, der Port 8000 abhört, die Verbindung als vom Proxy stammend angezeigt wird (im Fall von localhostwird dies der Fall sein localhost), nicht vom ursprünglichen Client. Sie müssen DNAT-Ansätze verwenden (für die jedoch Superuser-Berechtigungen erforderlich sind), damit der Server erkennen kann, wer der Client ist.


1
Danke, das ist großartig, da kein lokaler SSH-Server ausgeführt werden muss.
Jontro

Kann ich den gleichen Port aber eine andere Adresse verwenden?
Amos

@amos, siehe bearbeiten.
Stéphane Chazelas

Wäre es auch möglich, Datenverkehr nur von bestimmten IPs weiterzuleiten?
Phate

1
@Phate, siehe SOCAT anweisen, Verbindungen von einer einzelnen IP-Adresse abzuhören (und die Optionen rangeund tcpwrapin der socatManpage).
Stéphane Chazelas

46

Das Traditionelle ncist die einfachste Lösung:

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

Diese Version von ncist im netcat-traditionalPaket auf Ubuntu enthalten. (Du musst update-alternativesoder nennst es nc.traditional.)

Beachten Sie, dass dies im Gegensatz zu ssh nicht verschlüsselt ist. Denken Sie daran, wenn Sie es außerhalb eines Hosts verwenden.


2
Kennt jemand das Äquivalent dazu netcat-openbsd?
Sridhar Sarnobat

2
Analog zur netcatVersion , die in enthalten ist busybox: nc -v -lk -p 8001 -e /usr/bin/nc 127.0.0.1 8000. ( Beschreibung der Parameter )
Ivan Kolmychek

2
Funktioniert, aber der ncBefehl wird nach der ersten Remote-Verbindung beendet. Fügen -kSie dies hinzu, wenn Sie es am Laufen halten möchten.
Sopalajo de Arrierez

Ich erhalte diesen Fehler: nc: cannot use -p and -lunter CentOS 6.4. Gibt es eine Abhilfe?
Nick Predey

Ich bevorzuge diese Lösung gegenüber der ssh-Lösung, da sie die Verwendung als Root erleichtert, wenn ein privilegierter Port lokal weitergeleitet werden muss.
Christian

24

OpenBSD Netcat ist standardmäßig unter Linux und auch unter OS X verfügbar.

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

Eine Alternative, die unter OS X bash funktioniert, ist die Verwendung einer bidirektionalen Pipe . Es kann unter anderen Unixen funktionieren:

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

Anfangs habe ich nicht bemerkt, dass Sie openbsd netcat verwenden. Dies ist besser, als ein anderes Netcat von einem Ubuntu-Paket installieren zu müssen.
RobertR

OpenBSD-Beispiel ist unter Ubuntu 15.04 fehlgeschlagen. Mit den Shell-Weiterleitungen kann Netcat den Port nicht zum Abhören öffnen, wie dies von ss -tanoder gesehen wird netstat -tan.
Justin C

⁺¹. FTR: Der alternative Weg funktioniert auf Ubuntu
Hi-Angel

Ich verstehe deine Lösung nicht. Kannst du es erklären?
Trismegistos

@trismegistos In diesen Beispielen leiten der Netcat-Listener und der Client die Eingabe in einige gemeinsam genutzte Dateien um (mkfifo pipes..first in first out) und verwenden diese gemeinsam genutzten Dateien als Quelle / Ziel der Eingabe / Ausgabe, wodurch effektiv ein Tunnel erstellt wird. Normalerweise werden Client / Listener verwendet, aber einige Techniken verwenden Client + Client / Listener + Listener. Wiki.securityweekly.com/… und slideshare.net/amiable_indian/secrets-of-top-pentesters müssen gelesen werden.
Info5ek

4

Zitiert ein David Spillett ‚s Antwort auf ServerFault

rinetd sollte die Arbeit erledigen, und eine Windows-Binärdatei dafür finden Sie unter http://www.boutell.com/rinetd/ (für alle, die unter Linux dasselbe suchen, ist rinetd in den Standard-Repositorys so gut wie jeder Distribution enthalten) kann also mit "apt-get install rinetd" oder "yum install rinetd" oder ähnlich installiert werden)

Es ist eine einfache Binärdatei, die eine Konfigurationsdatei im Format annimmt

bindaddress bindport connectaddress connectport

Zum Beispiel:

192.168.1.1 8001 127.0.0.1 8000

oder

0.0.0.0 8001 127.0.0.1 8000

Wenn Sie den eingehenden Port an alle Schnittstellen binden möchten.


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

service iptables save
service iptables restart

Beim Versuch, eine Verbindung herzustellen dport, wie in nc -v localhost 2345, erhalte ich Connection refused. Ich bin nicht sehr gut in Iptables, aber ich denke, der Dport muss eine Listening-App haben.
Hi-Angel

Was ist, wenn sich der Ursprungsport auf einer anderen Schnittstelle als der Zielport befindet?
Trismegistos

0

Basierend auf der Antwort von Mark A. musste ich eine kleine Änderung vornehmen, damit es für meinen Mac funktioniert (zumindest unter macOS Mojave Version 10.14.4).

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

Diese printf-Aussage scheint entscheidend zu sein. Andernfalls wird der Befehl netcat zum Herstellen einer Verbindung zu Port 8000 niemals versuchen, und der Befehl netcat zum Abhören von Port 8001 wird niemals tatsächlich Port 8001 abhören. Ohne printf würde ich jedes Mal versuchen, eine Verbindung zu Port 8001 herzustellen Verbindung abgelehnt.

Ich gehe davon aus, dass netcat stdin irgendwie blockieren muss (vielleicht versucht es, es aus irgendeinem Grund zu lesen), bevor es tatsächlich Socket-Operationen ausführt. Ohne die printf-Anweisung, die in das FIFO-Format a schreibt, wird der Befehl netcat niemals Port 8001 überwachen.

Hinweis: Ich hätte eine Antwort auf Marks Beitrag hinterlassen, habe aber noch keinen Ruf.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.