Comment ouvrir le tunnel SSH au public?


174

En revenant à cette question, je lance la commande

ssh -R 8080:localhost:80 -N root@example.com

sur un Mac. Pourtant, le port sous tunnel ne fonctionne pas publiquement. J'exécute une telle commande pour que le port local puisse être ouvert sur l'ordinateur distant. Et cela fonctionne lorsque vous ouvrez le port sur l'hôte local sur l'ordinateur distant, mais lorsque j'essaie d'accéder à l'adresse IP publique de l'ordinateur distant à partir de mon ordinateur local, le port ne semble pas être ouvert. Comment pourrais-je rendre le tunnel public sur l'IP pour que n'importe qui puisse y accéder?

EDIT: Il semble que le côté distant se lie uniquement à localhost et non à toutes les interfaces.

EDIT 2: le client est Mac OS X 10.6 et le serveur est Linux Mint, mais ils sont tous deux OpenSSH.


Que signifie IP publique? Si vous essayez de vous connecter à un ordinateur local via le routeur et via Internet, la plupart des routeurs n'autorisent pas ce type de bouclage.
harrymc

Réponses:


351

Si vous consultez la page de manuel relative à ssh, vous constaterez que la syntaxe de -Rlecture est la suivante:

-R [ adresse_bind :] port : hôte : hostport

Quand bind_addressest omis (comme dans votre exemple), le port est lié à l'interface de bouclage uniquement. Afin de le lier à toutes les interfaces, utilisez

ssh -R \*:8080:localhost:80 -N root@example.com

ou

ssh -R 0.0.0.0:8080:localhost:80 -N root@example.com

ou

ssh -R "[::]:8080:localhost:80" -N root@example.com

La première version se lie à toutes les interfaces individuellement. La deuxième version crée une liaison générale uniquement IPv4, ce qui signifie que le port est accessible sur toutes les interfaces via IPv4. La troisième version est probablement techniquement équivalente à la première, mais là encore, elle ne crée qu'une seule liaison ::, ce qui signifie que le port est accessible via IPv6 de manière native et via IPv4 via des adresses IPv6 mappées IPv4 (ne fonctionne pas sous Windows, OpenBSD). . (Vous avez besoin des guillemets, car ils [::]pourraient autrement être interprétés comme un glob.)

Notez que si vous utilisez un sshdserveur OpenSSH , l' GatewayPortsoption du serveur doit être activée (définie sur yesou clientspecified) pour que cela fonctionne (vérifier le fichier /etc/ssh/sshd_configsur le serveur). Sinon (la valeur par défaut de cette option est no), le serveur forcera toujours le port à être lié à l'interface de bouclage uniquement.


12
OH MON DIEU CELA A FONCTIONNE !!!!! Je l'ai fait exactement 1 million de fois! J'ai juste oublié que *dans bash va donner des fichiers et j'avais besoin\*
Trevor Rudolph

4
Ouais, c'est exactement pourquoi je préfère toujours 0.0.0.0- c'est uniquement IPv4, mais ça marche la plupart du temps :)
Stefan Seidel

34
GatewayPorts a résolu mon problème.
Sunry

4
GatewayPorts = yes (sur la configuration sshd distante) l'a corrigé pour moi aussi
Phil_1984_

3
"GatewayPorts oui" fait ma journée, merci @StefanSeidel
karser

37

Modifier:

-g fonctionne pour les ports transférés locaux, mais ce que vous voulez, c'est un port transféré inversé / distant, ce qui est différent.

Ce que tu veux, c'est ça .

Pour l' essentiel, sur example.com, mis GatewayPorts=clientspecifieden /etc/ssh/sshd_config.

--- réponse précédente (incorrecte) ---

Utilisez l'option -g. De la page de manuel de ssh:

-g     Allows remote hosts to connect to local forwarded ports.

ne semble pas fonctionner ... ça démarre mais je ne peux pas me connecter à distance
Trevor Rudolph

2
Essayez d’exécuter netstat -elnptdepuis un terminal séparé pour déterminer quels ports sont associés à quelle adresse. Sans cela -g, un port devrait être lié à 127.0.0.1:PORT. Avec -g, il devrait être lié à 0.0.0.0:PORT, ce qui le rend accessible à distance.
Snapshoe


2
GatewayPorts=clientspecifiedouGatewayPorts clientspecified
Trevor Rudolph

et puis-je ajouter cela au client ou à distance?
Trevor Rudolph

14

Voici ma réponse pour l'achèvement:

J'ai fini par utiliser ssh -R ...pour la création de tunnels, et en socatplus pour rediriger le trafic réseau vers 127.0.0.1:

tunnel lié à 127.0.0.1: ssh -R mitm:9999:<my.ip>:8084 me@mitm

socat: mitm$ socat TCP-LISTEN:9090,fork TCP:127.0.0.1:9999

Une autre option est de faire un tunnel local uniquement en plus de cela, mais je trouve cela beaucoup plus lent

mitm$ ssh -L<mitm.ip.address>:9090:localhost:9999 localhost


J'aime le fait que je n'ai pas à gérer la configuration de sshd et que je puisse tout faire sans sudo. De plus, j'apprends que socat existe. Merci!
BrutusCat

+ tu vas bien monsieur. J'ai essayé de dire à ssh de se lier à 0.0.0.0 sans succès .. puis j'ai vu la syntaxe *, j'ai essayé, pas de dés. J'imagine qu'il peut s'agir d'une fonctionnalité de sécurité sur sshd config ou de quelque chose qui ne le permet pas. Enfin vu ce post et a socattravaillé génial. Super utile, mettre ceci dans ma poche arrière;]
Jaime

10

Vous pouvez également utiliser un double transfert si vous ne voulez pas ou ne pouvez pas modifier / etc / ssh / sshd_config.

Commencez par transférer vers le port temporaire (par exemple 10080) sur le périphérique de bouclage sur la machine distante, puis utilisez le transfert local pour rediriger le port 10080 vers 80 sur toutes les interfaces:

ssh -A -R 10080:localhost_or_machine_from:80 user@remote.tld "ssh -g -N -L 80:localhost:10080 localhost"

1
Cela fonctionne réellement pour contourner les règles de transmission!
Michael Schubert

J'adore cette solution. Excellente solution de contournement lorsque vous ne souhaitez pas modifier la configuration de la machine
Grezzo

8

Utilisez l'option "ports de passerelle".

ssh -g -R REMOTE_PORT:HOST:PORT ...

Pour utiliser cela, vous devrez probablement ajouter " GatewayPorts yes" à celui de votre serveur /etc/ssh/sshd_config.


En fait, cela a fonctionné. Ce que je fais est que j'utilise une instance EC2 en tant que redirecteur vers mon serveur REST. De cette façon, je n'ai pas besoin de coller mon serveur dans la zone démilitarisée et je n'ai pas besoin d'une adresse IP publique. Assez drôle, avec la première instance EC2 que j'ai créée, ssh -R remote_port: localhost: port xxx @ ec2xxx fonctionnait parfaitement, mais je devais créer une autre instance ultérieurement pour une raison quelconque et à partir de ce moment, je recevais toujours: connection refusé. Tcpdump utilisé pour regarder ce que je devenais et il n'y avait pas beaucoup d'informations. -g plus GatewayPorts oui a fait le tour.
ET le

1

Les hôtes de saut sont un ajout assez récent à OpenSSH. Cela nécessite un accès SSH à l’intermédiaire, mais devrait fonctionner sans configuration supplémentaire.

ssh -J root@example.com remoteuser@localhost -p 8080

Cette commande indique à SSH de se connecter d’abord à root@example.com, puis à partir de cette machine, d’établir une connexion au port 8080 sur localhost(c’est- à -dire, le port qui est tunnelé de l’hôte de saut à l’hôte distant) sous le remoteusernom d’utilisateur.


0

Si vous souhaitez mettre la configuration en vous ~/.ssh/configau lieu d'utiliser des paramètres de ligne de commande, vous pouvez essayer quelque chose comme:

Host REMOTE_HOST_NAME RemoteForward \*:8080 127.0.0.1:80

N'oubliez pas que le pare-feu de votre hôte distant autorise les connexions à 8080 et veille à ce que l' GatewayPortsoption de votre /etc/ssh/sshdconfiguration ne soit pas définie surno

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.