Un moyen simple de créer un tunnel d'un port local à un autre?


76

J'ai un serveur de développement, qui n'est accessible qu'à partir de 127.0.0.1:8000, pas 192.168.1.x: 8000. En guise de solution rapide, existe-t-il un moyen de configurer quelque chose à écouter sur un autre port (par exemple 8001) de sorte que je puisse me connecter au réseau local 192.168.1.x: 8001 et qu'il achemine le trafic entre le client et 127.0 .0,1: 8000?


4
Netcat peut le faire.
Andy

Réponses:


44

Utiliser ssh est la solution la plus simple.

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

Cela transmet le port local 8001 de votre poste de travail à l'adresse localhost du port 8000 de remote-server.com. Cela
-gsignifie que les autres clients de mon réseau peuvent se connecter au port 8001 de mon poste de travail. Sinon, seuls les clients locaux de votre poste de travail peuvent se connecter au port transféré.
-Nsignifie que tout ce que je fais est de transférer des ports, ne lancez pas de shell.
-fsignifie passer en arrière-plan après une connexion et une connexion SSH réussies.
Le port 8001 restera ouvert pour de nombreuses connexions, jusqu'à ce que ssh décède ou soit tué. Si vous êtes sur Windows, l'excellent client SSH, PuTTY, peut également le faire. Utilisez 8001 comme port local et localhost: 8000 et la destination et ajoutez un transfert de port local dans les paramètres. Vous pouvez l'ajouter après une connexion réussie avec PuTTY.


4
Qu'est-ce que le user@remote-server.comfait? C'est absolument inutile pour la redirection de port, bien que ssh demande à avoir cet argument, en plus, il essaie de s'y connecter. Et lors de la configuration de cette option fastidieuse à hostname, il affiche …port 22: Connection refused (non, je n'ai pas utilisé le port 22) . À moins que quelque chose me manque, la commande ne fonctionne manifestement pas.
Bonjour Angel

@ Hi-Angel user@remote-server.comest juste un exemple et vous ne devriez pas le prendre à la lettre. Vous devez remplacer ceci par un nom d'ordinateur auquel vous souhaitez vous connecter et votre nom d'utilisateur sur cet ordinateur. Ces informations sont nécessaires pour établir une connexion SSH. Une fois que la connexion ssh est établie, les ports peuvent être transférés via cette connexion.
Piotr Dobrogost

Si vous voulez que le port soit disponible dès le démarrage, voyez "autossh" dans un service systemd en appliquant la méthode ci-dessus - everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh
Richard Hollis

Je reçois aussi une "connexion refusée". Et je ne comprends toujours pas pourquoi l'argument utilisateur@remote-server.com est nécessaire alors qu'aucune connexion SSH n'est impliquée (selon -N). Devrait juste transmettre des paquets.
Alexander Taylor

2
@AlexanderTaylor -Nne signifie pas qu'il n'y a pas de connexion SSH. Cela signifie simplement do not execute a remote command(voir la page de manuel ). L' <user>@<host>argument est nécessaire, parce que cela fait ouvrir une connexion SSH <host>(qui , pour le cas de OP serait localhost), et transmet le port souhaité à travers ce tunnel SSH. C'est une solution au problème de l'OP, mais pas la plus simple. Pour transmettre à localhost sans utiliser ssh, vous pouvez utiliser socatou netcatcomme StephaneChazelas et les réponses de non-utilisateur.

94

Avec socatsur le serveur:

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

Par défaut, socatécoute sur le port TCP 8001 de n’importe quelle adresse IPv4 ou IPv6 (si prise en charge) sur la machine. Vous pouvez le limiter à IPv4 / 6 en remplaçant tcp-listenpar tcp4-listenou tcp6-listen, ou à une adresse locale spécifique en ajoutant un ,bind=that-address.

Pareil pour le socket de connexion auquel vous utilisez le proxy, vous pouvez utiliser n'importe quelle adresse à la place de localhost, et remplacer tcppar tcp4ou tcp6si vous souhaitez limiter la résolution d'adresse aux adresses IPv4 ou IPv6.

Notez que pour le serveur qui écoute sur le port 8000, la connexion apparaîtra comme provenant du proxy (dans le cas de localhost, ce sera localhost), pas du client d'origine. Vous devez utiliser des approches DNAT (mais nécessitant des privilèges de superutilisateur) pour que le serveur puisse déterminer le client.


1
Merci, c’est génial car il n’est pas nécessaire de faire tourner un serveur ssh local.
Jontro

Puis-je utiliser le même port mais une adresse différente?
Amos

@amos, voir edit.
Stéphane Chazelas

Serait-il également possible de transférer le trafic uniquement à partir d'adresses IP spécifiques?
Phate

1
@Phate, voir Dites à socat d'écouter les connexions à partir d'une seule adresse IP (et des options rangeet tcpwrapdans la socatpage de manuel).
Stéphane Chazelas

46

Utiliser le traditionnel ncest la solution la plus simple:

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

Cette version de ncest dans le netcat-traditionalpaquet sur Ubuntu. (Vous devez update-alternativesou appelez-le nc.traditional.)

Notez que contrairement à ssh, ce n’est pas chiffré. Gardez cela à l'esprit si vous l'utilisez en dehors d'un hôte.


2
Quelqu'un sait l'équivalent netcat-openbsd?
Sridhar Sarnobat

2
Analogique pour la netcatversion qui est inclus dans busybox: nc -v -lk -p 8001 -e /usr/bin/nc 127.0.0.1 8000. ( Description des paramètres )
Ivan Kolmychek

2
Fonctionne, mais la nccommande se termine après la première connexion à distance. Ajoutez -ksi vous avez besoin de le garder en marche.
Sopalajo de Arrierez

Je reçois cette erreur: nc: cannot use -p and -lsur CentOS 6.4. Y at-il un travail autour?
Nick Predey

Je préfère cette solution à celle de ssh car elle est plus facile à utiliser en tant que root, lorsqu’il est nécessaire de transférer localement un port privilégié.
Christian

24

OpenBSD netcat est disponible par défaut sous Linux et également sous 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

Une alternative qui fonctionne sur OS X bash consiste à utiliser un canal bidirectionnel . Cela peut fonctionner sur d'autres Unix:

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

Je n'avais pas remarqué au début que vous utilisiez openbsd netcat. C'est mieux que d'avoir à installer un autre netcat à partir d'un paquet Ubuntu.
RobertR

L'exemple OpenBSD a échoué sous Ubuntu 15.04. Avec les redirections du shell, netcat ne parvient pas à ouvrir le port pour écouter tel que vu par ss -tanou netstat -tan.
Justin C

⁺¹. FTR: l'alternative fonctionne sur Ubuntu
Hi-Angel

Je ne comprends pas votre solution. Pouvez-vous l'expliquer?
Trismegistos

@trismegistos Dans ces exemples, le programme d'écoute netcat et le client redirigent l'entrée dans certains fichiers partagés (mkfifo pipes..first in first out) et utilisent ces fichiers partagés comme source / destination des entrées / sorties, créant ainsi un tunnel. On utilise généralement client / auditeur, mais certaines techniques utilisent client + client / auditeur + auditeur- wiki.securityweekly.com/… et slideshare.net/amiable_indian/secrets-of-top-pentesters .
Info5ek

4

Citant un David Spillett de » réponse sur ServerFault

rinetd devrait faire le travail, et un binaire Windows pour cela peut être obtenu à partir de http://www.boutell.com/rinetd/ (pour ceux qui recherchent la même chose sous Linux, rinetd se trouve dans les référentiels standard de presque toutes les distributions. donc peut être installé avec "apt-get install rinetd" ou "yum install rinetd" ou similaire)

C’est un simple binaire qui prend un fichier de configuration au format

bindaddress bindport connectaddress connectport

Par exemple:

192.168.1.1 8001 127.0.0.1 8000

ou

0.0.0.0 8001 127.0.0.1 8000

si vous souhaitez lier le port entrant à toutes les interfaces.


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

service iptables save
service iptables restart

En essayant de se connecter à dport, comme dans nc -v localhost 2345, je reçois Connection refused. Je ne suis pas très bon en iptables, mais je suppose que le rapport doit avoir une application d'écoute.
Bonjour Angel

Que faire si le port d'origine est sur une interface différente de celle du port de destination?
Trismegistos

0

Sur la base de la réponse de Mark A. , je devais faire un petit ajustement pour que cela fonctionne sur mon Mac (du moins sur 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

Cette déclaration de printf semble être cruciale. Sinon, la commande netcat pour se connecter au port 8000 ne tentera jamais réellement de se connecter, et la commande netcat pour écouter sur le port 8001 ne l'écoutera jamais sur le port 8001. Sans printf, j'essaierais chaque fois de me connecter au port 8001 Connexion rejetée.

Mon hypothèse est que netcat doit d’une manière ou d’une autre bloquer sur stdin (peut-être essaie-t-il de le lire pour une raison quelconque) avant d’effectuer réellement une opération de Socket. En tant que tel, sans l'instruction printf écrite dans fifo a, la commande netcat ne commencera jamais à écouter sur le port 8001.

Note: J'aurais laissé une réponse sur le post de Mark, mais je n'ai pas encore de réputation.


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.