Comment transférer un port d'une machine à une autre?

19

Considérez la situation suivante:

Chez moi, j'ai un routeur (qui est connecté à Internet), un serveur (S) et ma machine principale (M). S est accessible depuis Internet (il a une adresse IP statique), et il est disponible 24h / 24 et 7j / 7, tandis que M ne l'est pas.

Parfois, je veux rendre une application (qui écoute sur un port sur M, par exemple 8888) accessible depuis Internet externe.

Pour cela, je voulais configurer un port sur S (2222) pour le transmettre au port 8888 de M, afin que quiconque accédant à S: 2222 se sente comme s'il accédait à M: 8888.

J'ai essayé d'utiliser la redirection de port ssh, ma meilleure tentative était la suivante:

ssh -L 2222:M:8888 -N M

Mais cela ne me permet d'accéder au port 2222 qu'à partir du serveur lui-même, pas à partir d'autres machines.

Existe-t-il un moyen de le faire correctement? De préférence, j'aimerais que ce soit une commande simple, que je serais en mesure de démarrer et d'arrêter avec ^ C lorsque je n'aurai plus besoin de ce transfert.

Rogach
la source
Essayez localhost.run qui est un site Web auquel vous pouvez accéder sur localhost.run. Je pense qu'il existe un moyen de
diffuser

Réponses:

16

Oui, cela s'appelle GatewayPortsen SSH. Un extrait de ssh_config(5):

GatewayPorts
        Specifies whether remote hosts are allowed to connect to local
        forwarded ports.  By default, ssh(1) binds local port forwardings
        to the loopback address.  This prevents other remote hosts from
        connecting to forwarded ports.  GatewayPorts can be used to spec‐
        ify that ssh should bind local port forwardings to the wildcard
        address, thus allowing remote hosts to connect to forwarded
        ports.  The argument must be “yes” or “no”.  The default is “no”.

Et vous pouvez utiliser localhostau lieu de Mdans le transfert, car vous transférez vers la même machine que celle vers laquelle vous vous connectez - si je comprends bien votre question.

Ainsi, la commande deviendra ceci:

ssh -L 2222:localhost:8888 -N -o GatewayPorts=yes hostname-of-M

et ressemblera à ceci dans netstat -nltp:

tcp        0      0    0.0.0.0:2222   0.0.0.0:*  LISTEN  5113/ssh

Désormais, toute personne accédant à cette machine sur le port 2222 TCP parlera réellement à localhost: 8888 comme vu dans la machine M. Notez que ce n'est pas la même chose que la redirection simple vers le port 8888 de M.

gertvdijk
la source
1
Merci! Ça marche! Mais il y a une certaine étrangeté - pour une raison quelconque, la sortie contient la ligne "bind: Adresse déjà utilisée". Qu'est-ce que cela pourrait signifier?
Rogach
1
Vous avez déjà un processus en cours d'exécution sur ce port. Utilisez la même netstatcommande pour savoir quoi exactement. Probablement un autre SSH similaire toujours en cours d'exécution en arrière-plan et le tuer en utilisant le netstat PID vous dit.
gertvdijk
Ce qui est amusant, c'est que je l'ai déjà fait - aucun processus sur ces ports, à la fois sur S et M. S'il y en avait, alors la construction aurait probablement échoué.
Rogach
10

Il y a une autre manière. Vous pouvez configurer la redirection de port de S: 2222 vers W: 8888 avec iptables. Commande unique:

iptables -t nat -A PREROUTING -p tcp --dport 2222 \
         -j DNAT --to-destination 1.2.3.4:8888

où 1.2.3.4 est l'adresse IP de M. Il s'appelle NAT (Network Address Translation).

Gevial
la source
1
Comme vous ne faites que le NAT de destination ici (contrairement au NAT source), cela ne fonctionnera de manière fiable que dans des situations spécifiques et pourrait nécessiter de modifier les tables de routage. Pour le transfert vers des machines virtuelles (M) exécutées sur l'hôte (S), cela peut cependant fonctionner correctement.
gertvdijk
Cette commande doit être émise sur la passerelle. Je suppose que S et M sont sur le même LAN. Le NAT source serait fait automatiquement par le traqueur de connexion dans les noyaux Linux modernes. J'ai une telle configuration dans mon réseau de bureau et cela fonctionne parfaitement. Cependant, il est possible de rendre la commande plus spécifique (par exemple, en indiquant à iptables -i eth0 où eth0 est l'interface externe).
Gevial
Si S et M sont sur le même LAN, vous n'avez pas besoin de redirection de port, car aucun trafic entre eux ne passe par la passerelle.
gertvdijk
1
Oui, mais la connexion à M: 8888 se fait à partir d'Internet, je suppose. Quelqu'un forme Internet -> S: 2222 -> Routeur LAN M et S avec iptables -> M: 8888
Gevial