Tunnel de port inversé

59

Je dois montrer à quelqu'un un site Web fonctionnant sur ma machine locale demain. Normalement, je le fais en transférant les ports sur mon routeur local, mais, en raison du matériel défectueux et de son remplacement insupportable, mon routeur actuel ne me permet pas d'effectuer de transfert de port.

Donc, coincé dans ce délai et ne voulant pas tout transférer sur un serveur approprié, j'ai eu une idée folle: puis-je simplement transférer mon port sur un serveur externe via SSH?

J'ai déjà fait des tunnels de port, mais je le fais habituellement de la bonne façon:

  • Je me connecte à une boîte distante et demande que le port 12345 apparaisse sur mon ordinateur local au port 12345.
  • Je commence quelque chose sur P12345 sur la machine distante
  • Je peux y accéder via localhost: 12345

Ce que je veux faire:

  • Connectez-vous à un ordinateur distant et demandez à son P12345 local d'aller chercher des objets dans mon P12345 local (via le tunnel).
  • Je commence quelque chose sur mon ordinateur local sur P12345
  • D'autres personnes peuvent accéder à distance à: 12345 et voir mon hôte local: 12345
Oli
la source

Réponses:

97

La commande permettant de transférer le port 80 de votre ordinateur local ( localhost) vers l'hôte distant sur le port 8000 est la suivante:

ssh -R 8000:localhost:80 oli@remote-machine

Cela nécessite un tweak supplémentaire sur le serveur SSH, ajoutez les lignes à /etc/ssh/sshd_config:

Match User oli
   GatewayPorts yes

Ensuite, rechargez la configuration en exécutant le serveur sudo reload ssh.

Ce paramètre GatewayPorts yesforce SSH à lier le port 8000 à l'adresse générique, de sorte qu'il devient disponible à l'adresse publique de remote-machine( remote-machine:8000).

Si vous avez besoin de ne pas tout lier à l'adresse générique, remplacez- GatewayPorts yesle GatewayPorts clientspecified. Étant donné que les sshliens à l'adresse de bouclage sont activés par défaut, vous devez spécifier un vide bind_addresspour lier l'adresse générique:

ssh -R :8000:localhost:80 oli@remote-machine

L' :avant 8000est obligatoire si GatewayPortsest défini sur clientspecifiedet que vous souhaitez autoriser l'accès public à remote-machine:8000.

Extraits manuels pertinents:

ssh (1)

-R [bind_address:] port: host: hostport
Spécifie que le port donné sur l'hôte distant (serveur) doit être transféré à l'hôte donné et au port côté local. Cela fonctionne en allouant un socket pour écouter le port du côté distant, et chaque fois qu'une connexion est établie à ce port, la connexion est transférée sur le canal sécurisé et une connexion est établie pour héberger le port hostport de la machine locale. Par défaut, le socket d'écoute sur le serveur sera uniquement lié à l'interface de bouclage. Cela peut être annulé en spécifiant une bind_address. Une bind_address vide, ou l'adresse '*', indique que le socket distant doit écouter toutes les interfaces. La spécification d'une adresse bind unique à distance ne réussira que si l'option GatewayPorts du serveur est activée (voir sshd_config (5)).

sshd_config (5)

GatewayPorts
Spécifie si les hôtes distants sont autorisés à se connecter aux ports transférés pour le client. GatewayPorts peut être utilisé pour spécifier que sshd doit autoriser les redirections de ports distants à se lier à des adresses autres que le bouclage, permettant ainsi à d'autres hôtes de se connecter. L'argument peut être «non» pour forcer les transferts de port distants à être disponible pour l'hôte local uniquement, «oui» pour forcer les redirections de port distants à se lier à l'adresse générique, ou «client spécifié» pour permettre au client de sélectionner l'adresse à laquelle la transmission est liée. La valeur par défaut est "non".

Voir également:

Lekensteyn
la source
7
GatewayPortsétait la balle magique ici. J'aime que vous ayez trouvé une version qui me permette de limiter cette technique assez puissante à certains utilisateurs.
Oli
1
Ce qui me déroutait, c’est que GatewayPorts doit être défini sur la machine qui exécute la commande ssh pour lancer le tunnel inverse (local). Dans mon esprit, il était en quelque sorte plus logique que l’autre extrémité (distante) se préoccupe de savoir où accepter les connexions, car c’est à partir de là que vous vous connectez et êtes redirigé. Cela m'a pris du temps pour contourner ça.
Ars Magika
2
@ArsMagika Je ne sais pas si je vous comprends bien. GatewayPorts doit être défini sur le serveur SSH, et non sur votre ordinateur local qui exécute la sshcommande. Il configure si d'autres clients peuvent communiquer avec les ports transférés sur le serveur.
Lekensteyn
Inconvénient de cette solution: vous perdez la possibilité de déterminer l'adresse IP du client dans le journal d'accès du serveur Web. Un moyen de résoudre cette nuisance aussi?
Twonky
@Twonky Si vous n'avez pas besoin de connaître l'adresse IP exacte du client (juste qu'il s'agissait d'une adresse distante et non "localhost") et que votre serveur local écoute sur l'adresse générique (c'est-à-dire qu'il accepte des connexions à partir de n'importe quelle adresse), alors vous pouvez essayer de transférer à -R :8000:127.0.1.1:80(ou toute autre 127.x.x.xadresse). Sinon, vous ne pourrez pas connaître l'adresse IP distante.
Lekensteyn
14

Si le serveur a GatewayPorts no, vous pouvez obtenir le même résultat en exécutant ssh -g -L 8001:localhost:8000 oli@remote-machinesur le serveur une fois que vous avez exécuté la ssh -Rcommande sur le client. Cela rendra le port de bouclage 8000 sur le serveur accessible sur toutes les interfaces du port 8001.

FaST4
la source