Encaminhamento de porta reversa Vagrant?

121

Estou trabalhando em uma arquitetura de serviços da web. Eu tenho alguns softwares que eu preciso executar na máquina host nativa, não no Vagrant. Mas eu gostaria de executar alguns serviços ao cliente no convidado.

O config.vm.forwarded_portparâmetro do Vagrant abrirá uma porta no host e enviará os dados para o convidado. Mas como posso abrir uma porta no convidado e enviar os dados para o host? (Ainda é encaminhamento de porta, mas na direção inversa.)

Dan Fabulich
fonte
Como o Vagrant está usando o SSH, é teoricamente possível e a gem de implementação do Ruby SSH suporta isso, mas nunca vi nada parecido no documento do Vagrant.
cmur2
Veja também: stackoverflow.com/q/19933550/1157054
Ajedi32

Respostas:

134

Quando você executa vagrant ssh, na verdade, está usando este comando subjacente:

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

O SSH suporta portas de encaminhamento na direção desejada com a -R guestport:host:hostportopção Portanto, se você deseja se conectar à porta 12345no convidado e tê-la encaminhado localhost:80, use este comando:

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]

Como o Eero comenta corretamente, você também pode usar o comando vagrant ssh -- -R 12345:localhost:80, que tem o mesmo efeito em um comando muito mais conciso.

wlritchi
fonte
67
e você pode executá-lo de maneira mais simples usando. vagrant ssh -- -R 12345:localhost:80 Segue a sintaxe da opção ssh -R [bind_address:] port: host: hostport , em que o primeiro número é o número da porta a ser ouvida dentro da máquina convidada e os dois últimos são o endereço do serviço conforme visível na máquina host.
Eero
1
Tanto quanto eu entendo que o encaminhamento reverso só funciona no shell ssh correspondente. Acho que Dan Fabulich queria uma solução sem a necessidade de ssh na vm.
Alp
2
@ Alp Eu acredito que é uma porta disponível para todo o sistema, não apenas disponível para o processo ssh. Funciona bem para mim!
Henrik Heimbuerger
1
Para aqueles que usam PuTTy, a seção SSH / Tunnels do gui de configuração permite o encaminhamento de porta remota (daí o -R no comando) ou o encaminhamento de porta local (-L na linha de comando)
Titou
3
Ou algo representando de vagabundos potencialmente differente de configuração, se você tem configuração vagabundo múltipla:vagrant ssh-config | ssh -F /dev/stdin $BOX -R $PORT_VM:localhost:$PORT -N
ibizaman
100

No livro Vagrant: Up and Running(data de publicação: 12 de junho de 2013), escrito pelo criador do Vagrant, ele mencionou que não é possível para a máquina convidada acessar serviços executados na máquina host.

Em vez de usar Forwarded Ports, você pode configurar uma rede privada usando Host-Only Networks.

  • Prós de usar Host-Only Networksmais deForwarded Ports

    1. Máquinas convidadas podem acessar os serviços em execução na máquina host

      Esse recurso resolveria seu problema.

    2. Máquinas convidadas podem acessar os serviços em execução em outra máquina convidada

      Esse recurso é muito útil para separar serviços em várias máquinas para imitar com mais precisão um ambiente de produção.

    3. Seguro

      Máquinas externas não têm como acessar os serviços em execução nas máquinas convidadas

    4. Menos trabalho

      Não há necessidade de configurar todos os Forwarded Port


  • Como configurar Host-Only Networks

    config.vm.network :"hostonly", "192.168.0.0" # Versão Vagrant # 1

    config.vm.network :private_network, ip: "192.168.0.0" # Versão Vagrant # 2

    Ter esta linha no seu Vagrantfileinstruirá o vagrant a criar uma rede privada que tenha um endereço IP estático:192.168.0.0

    O endereço IP do host é sempre o mesmo endereço IP, mas com o octeto final como um 1. No exemplo anterior, a máquina host teria o endereço IP 192.168.0.1.

Mingyu
fonte
2
Na mesma linha (também de Vagrant: Up and Running), você pode configurar uma rede em ponte. Em uma rede em ponte, outras máquinas na rede local podem acessar sua máquina virtual e vice-versa. Mas como o endereço IP é atribuído via DHCP, você precisaria ifconfigna máquina virtual para encontrar seu endereço IP.
Nucleartide
28
O fato de que quando você configura config.vm.network: private_network, ip: "192.168.50.4" significa que o convidado acessará o host acessando "192.168.50.1", é o principal item de informação aqui. Não consigo encontrar esse pequeno petisco documentado em qualquer lugar.
Nucleon
1
Descobri que o uso do endereço de respostas 192.168.0.0não funcionou - ondular / executar ping na máquina host estava resultando em conexões t / o's. O endereço do @ Nucleon (consistente com os documentos do Vagrant sobre o tópico) funcionou como anunciado.
markdsievers
8
@Mingyu Não - o uso da sua linha de configuração config.vm.network :private_network, ip: "192.168.0.0"e o curling / ping do host 192.168.0.1estavam causando o tempo limite da conexão. Configurando a rede a ser 192.168.50.4resolvida, isto é, host disponível em 192.168.50.1.
markdsievers
3
"192.168.0.0" não é um bom exemplo, xxx0 normalmente é para transmissão de dados
número5 13/12/13
73

Você pode acessar portas na máquina host através do gateway padrão dentro do sistema operacional convidado. (Que normalmente tem um IP de 10.0.2.2.)

Por exemplo, se você tiver um servidor da web em execução na porta 8000 em sua máquina host ...

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

Você pode acessá-lo de dentro da VM Vagrant em 10.0.2.2:8000(desde que 10.0.2.2seja o ip do gateway padrão do convidado):

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

Para encontrar o IP do gateway padrão dentro do sistema operacional convidado, execute netstat -rn(ou ipconfigem um convidado do Windows) e procure a linha com um IP de destino 0.0.0.0(ou o campo "Gateway Padrão" no 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

Você pode extrair esse IP programaticamente com netstat -rn | grep "^0.0.0.0 " | tr -s ' ' | cut -d " " -f2.

Fontes: Como conectar-se ao host PostgreSQL a partir de uma máquina virtual de vagrant ; Conectar-se à máquina host de um sistema operacional convidado do VirtualBox?

Ajedi32
fonte
Eu também gosto muito desta solução, porque ela funcionou sem nem mesmo interromper minha sessão atual do vagrant ssh. Obrigado!
Rubix
Bravo! este é exatamente o que eu estava procurando
Khan Shahrukh
Excelente! ifconfige ip addressnão estavam conseguindo o que eu precisava, mas netstat -rnconsegui.
geerlingguy
9

Adicione o seguinte ao seu ~/.ssh/configna máquina host:

Host 127.0.0.1
RemoteForward 52698 127.0.0.1:52698

Permite acessar um serviço na porta 52698 da máquina host a partir do Vagrant, desde que você faça o login via vagrant ssh.

Você pode confirmar se funciona executando netstat -ltna VM vagrant e anotando as seguintes linhas:

tcp      0    0 localhost:52698         *:*                 LISTEN
tcp6     0    0 ip6-localhost:52698     [::]:*              LISTEN
stacker-baka
fonte
2
+1 Esta foi uma grande ajuda para mim. Eu adicionei o texto fornecido substituindo pela porta 5037 para permitir que minha caixa vagrant seja capaz de ouvir o emulador do Android em execução na minha caixa host.
Rob
2

Posso acessar os serviços em execução na minha máquina host por meio do endereço IP local (não do endereço de loopback). Testei criando um servidor http na porta 80 (e depois na porta 987) e curling 197.45.0.10:80 e 197.45.0.10:987 (o endereço IP real foi alterado para proteger os inocentes). Funcionou duas vezes e não tenho nenhuma configuração de vagrant especial (nenhuma rede pública, nenhuma porta encaminhada) e, embora eu tenha algumas portas encaminhadas via PuTTY, não tenho as portas 80 e 987 encaminhadas. Então, talvez tente usar o endereço IP local ou público da máquina host.

E se você quiser acessar (ssh into) uma instância vagrant guest de outra, poderá ativar public_networke encaminhar a partir da porta 22 da Vagrantfileseguinte maneira:

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

Então, desde que essa porta esteja aberta (por exemplo, faça mais um encaminhamento de porta na configuração do roteador), você poderá acessar essa máquina de qualquer lugar, até do mundo exterior.

BT
fonte