Redirection de port inversée vagabonde?

121

Je travaille sur une architecture de services Web. J'ai un logiciel dont j'ai besoin pour exécuter sur la machine hôte native, pas dans Vagrant. Mais j'aimerais exécuter certains services client sur l'invité.

Le config.vm.forwarded_portparamètre de Vagrant ouvrira un port sur l'hôte et enverra les données à l'invité. Mais comment puis-je ouvrir un port sur l'invité et envoyer les données à l'hôte? (Il s'agit toujours de la redirection de port, mais dans le sens inverse.)

Dan Fabulich
la source
Puisque Vagrant utilise SSH, cela est théoriquement possible et le gem d'implémentation Ruby SSH le prend en charge mais n'a jamais rien vu de tel dans le document Vagrant.
cmur2

Réponses:

134

Lorsque vous exécutez vagrant ssh, il utilise en fait cette commande sous-jacente:

ssh -p 2222 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR -o IdentitiesOnly=yes -i ~/.vagrant.d/insecure_private_key [email protected]

SSH prend en charge les ports de transfert dans la direction souhaitée avec l' -R guestport:host:hostportoption. Donc, si vous vouliez vous connecter au port 12345sur l'invité et le faire transférer localhost:80, vous utiliseriez cette commande:

ssh -p 2222 -R 12345:localhost:80 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR -o IdentitiesOnly=yes -i ~/.vagrant.d/insecure_private_key [email protected]

Comme Eero le commente correctement, vous pouvez également utiliser la commande vagrant ssh -- -R 12345:localhost:80, qui a le même effet dans une commande beaucoup plus concise.

wlritchi
la source
67
et vous pouvez l'exécuter plus simplement en utilisant vagrant ssh -- -R 12345:localhost:80 Ceci suit la syntaxe de l'option ssh -R [bind_address:] port: host: hostport , où le premier numéro est le numéro de port à écouter à l'intérieur de la machine invitée, et les deux derniers sont l'adresse du service comme visible depuis la machine hôte.
Eero
1
Autant que je sache, le transfert inversé ne fonctionne que dans le shell ssh correspondant. Je pense que Dan Fabulich voulait une solution sans avoir besoin de ssh dans le vm.
Alp
2
@Alp Je crois que c'est un port disponible pour tout le système, pas seulement disponible pour le processus ssh. Fonctionne bien pour moi!
Henrik Heimbuerger
1
Pour ceux qui utilisent PuTTy, la section SSH / Tunnels de l'interface de configuration permet à la fois le transfert de port distant (d'où le -R dans la commande) ou le transfert de port local (-L dans la ligne de commande)
Titou
3
Ou quelque chose qui explique la configuration potentiellement différente de vagrant si vous avez plusieurs configurations vagabondes:vagrant ssh-config | ssh -F /dev/stdin $BOX -R $PORT_VM:localhost:$PORT -N
ibizaman
100

Dans le livre Vagrant: Up and Running(Date de publication: 12 juin 2013), écrit par le créateur de Vagrant, il a mentionné qu'il n'est pas possible pour la machine invitée d'accéder aux services exécutés sur la machine hôte.

Au lieu d'utiliser Forwarded Ports, vous pouvez configurer un réseau privé en utilisant Host-Only Networks.

  • Avantages de l'utilisation Host-Only NetworksdeForwarded Ports

    1. Les machines invitées peuvent accéder aux services exécutés sur la machine hôte

      Cette fonctionnalité résoudrait votre problème.

    2. Les ordinateurs invités peuvent accéder aux services exécutés sur d'autres ordinateurs invités

      Cette fonction est très utile pour séparer les services sur plusieurs machines afin d'imiter plus précisément un environnement de production.

    3. Sécurise

      Les machines extérieures n'ont aucun moyen d'accéder aux services exécutés sur les machines invitées

    4. Moins de travail

      Pas besoin de configurer chacun Forwarded Port


  • Comment configurer Host-Only Networks

    config.vm.network :"hostonly", "192.168.0.0" # Vagrant Version # 1

    config.vm.network :private_network, ip: "192.168.0.0" # Vagrant Version # 2

    Avoir cette ligne dans votre Vagrantfileva demander à vagrant de créer un réseau privé qui a une adresse IP statique:192.168.0.0

    L'adresse IP de l'hôte est toujours la même adresse IP mais avec le dernier octet en tant que 1. Dans l'exemple précédent, la machine hôte aurait l'adresse IP 192.168.0.1.

Mingyu
la source
2
Dans la même veine (également de Vagrant: Up and Running), vous pouvez mettre en place un réseau ponté. Sur un réseau ponté, d'autres machines de votre réseau local peuvent accéder à votre machine virtuelle, et vice versa. Mais comme l'adresse IP est attribuée via DHCP, vous devrez ifconfigdans la machine virtuelle pour trouver son adresse IP.
Nucléaire du
28
Le fait que lorsque vous configurez config.vm.network: private_network, ip: "192.168.50.4" signifie que l'invité accédera à l'hôte en accédant à "192.168.50.1" est le bit clé d'information ici. Je ne trouve pas cette petite information documentée nulle part.
Nucleon
1
J'ai trouvé que l'utilisation de l'adresse de réponses de 192.168.0.0ne fonctionnait pas - le curling / le ping de la machine hôte entraînait une connexion t / o. L'utilisation de l'adresse de @ Nucleon (cohérente avec la documentation de Vagrant sur le sujet) a fonctionné comme annoncé.
markdsievers
8
@Mingyu Non - l'utilisation de votre ligne de configuration config.vm.network :private_network, ip: "192.168.0.0"et le curling / ping de l'hôte 192.168.0.1entraînait des délais de connexion. Configurer le réseau à 192.168.50.4résoudre, c'est-à-dire l'hôte disponible sur 192.168.50.1.
markdsievers
3
"192.168.0.0" n'est pas un bon exemple, xxx0 est normalement destiné à la diffusion
numéro5
73

Vous pouvez accéder aux ports de la machine hôte via la passerelle par défaut à l'intérieur du système d'exploitation invité. (Qui a généralement une adresse IP de 10.0.2.2.)

Par exemple, si vous avez un serveur Web fonctionnant sur le port 8000 sur votre machine hôte ...

echo 'Hello, guest!' > hello
python -m SimpleHTTPServer 8000

Vous pouvez y accéder depuis l'intérieur de la VM Vagrant à 10.0.2.2:8000(à condition que 10.0.2.2l'adresse IP de la passerelle par défaut de l'invité soit fournie ):

vagrant ssh
curl http://10.0.2.2:8000/hello # Outputs: Hello, guest!

Pour trouver l'adresse IP de la passerelle par défaut dans le système d'exploitation invité, exécutez netstat -rn(ou ipconfigsur un invité Windows) et recherchez la ligne avec une adresse IP de destination 0.0.0.0(ou le champ intitulé «Passerelle par défaut» sous Windows):

$ netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.0.2.2        0.0.0.0         UG        0 0          0 eth0
10.0.2.0        0.0.0.0         255.255.255.0   U         0 0          0 eth0
192.168.33.0    0.0.0.0         255.255.255.0   U         0 0          0 eth1

Vous pouvez extraire cette IP par programme avec netstat -rn | grep "^0.0.0.0 " | tr -s ' ' | cut -d " " -f2.

Sources: Comment se connecter avec l'hôte PostgreSQL à partir de la machine virtuelle vagrant ; Se connecter à la machine hôte à partir d'un OS invité VirtualBox?

Ajedi32
la source
J'aime beaucoup cette solution aussi parce qu'elle fonctionnait sans même arrêter ma session ssh vagrant actuelle. Merci!
Rubix
Bravo! c'est exactement ce que je cherchais
Khan Shahrukh
Excellent! ifconfiget ip addressje ne me procurais pas ce dont j'avais besoin, mais je l'ai netstat -rnfait.
geerlingguy
9

Ajoutez ce qui suit à votre ~/.ssh/configsur la machine hôte:

Host 127.0.0.1
RemoteForward 52698 127.0.0.1:52698

Il vous permet d'accéder à un service sur le port de la machine hôte 52698 à partir de Vagrant, tant que vous vous êtes connecté via vagrant ssh.

Vous pouvez confirmer que cela fonctionne en exécutant netstat -ltsur vagrant VM et en prenant une note sur les lignes suivantes:

tcp      0    0 localhost:52698         *:*                 LISTEN
tcp6     0    0 ip6-localhost:52698     [::]:*              LISTEN
empileur-baka
la source
2
+1 Cela m'a beaucoup aidé. J'ai ajouté le texte donné en remplaçant par le port 5037 pour permettre à ma boîte vagrant de pouvoir écouter l'émulateur Android fonctionnant sur ma boîte hôte.
rob
2

Je peux accéder aux services exécutés sur ma machine hôte via son adresse IP locale (et non son adresse de bouclage). J'ai testé en créant un serveur http sur le port 80 (puis sur le port 987) et en curling 197.45.0.10:80 et 197.45.0.10:987 (l'adresse IP réelle a été modifiée pour protéger les innocents). Cela a fonctionné les deux fois, et je n'ai pas de configuration spéciale de vagabond (pas de réseau_public, pas de port_fourni) et bien que certains ports soient transmis via PuTTY, je n'ai pas les ports 80 et 987 transmis. Essayez donc peut-être d'utiliser l'adresse IP locale ou publique de la machine hôte.

Et si vous souhaitez accéder (ssh à) une instance de vagrant invité à partir d'une autre, vous pouvez activer public_networkainsi que la redirection à partir du port 22 de la manière Vagrantfilesuivante:

config.vm.network "public_network"
config.vm.network "forwarded_port", guest: 22, host: 2200

Ensuite, tant que ce port est ouvert (c'est-à-dire faire un peu plus de redirection de port dans la configuration de votre routeur), vous pouvez accéder à cette machine de n'importe où, même du monde extérieur.

BT
la source