Inoltro inverso della porta vagante?


121

Sto lavorando a un'architettura di servizi web. Ho del software che devo eseguire sulla macchina host nativa, non in Vagrant. Ma vorrei eseguire alcuni servizi client sull'ospite.

Il config.vm.forwarded_portparametro di Vagrant aprirà una porta sull'host e invierà i dati all'ospite. Ma come posso aprire una porta sull'ospite e inviare i dati all'host? (È ancora il port forwarding, ma nella direzione opposta.)


Poiché Vagrant utilizza SSH, è teoricamente possibile e l' implementazione di Ruby SSH gem lo supporta ma non ha mai visto nulla di simile nel documento di Vagrant.
cmur2

Risposte:


134

Quando esegui vagrant ssh, in realtà utilizza questo comando sottostante:

ssh -p 2222 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR -o IdentitiesOnly=yes -i ~/.vagrant.d/insecure_private_key vagrant@127.0.0.1

SSH supporta l'inoltro delle porte nella direzione desiderata con l' -R guestport:host:hostportopzione. Quindi, se volessi connetterti alla porta 12345sul guest e farlo inoltrare a localhost:80, dovresti usare questo 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 vagrant@127.0.0.1

Come commenta correttamente Eero, puoi anche usare il comando vagrant ssh -- -R 12345:localhost:80, che ha lo stesso effetto in un comando molto più conciso.


67
e puoi eseguirlo più semplicemente usando vagrant ssh -- -R 12345:localhost:80 Questo segue la sintassi dell'opzione ssh -R [bind_address:] port: host: hostport , dove il primo numero è il numero di porta su cui ascoltare all'interno della macchina ospite e gli ultimi due sono l'indirizzo del servizio come visibile dalla macchina host.
Eero

1
Per quanto ho capito, l'inoltro inverso funziona solo nella shell ssh corrispondente. Penso che Dan Fabulich volesse una soluzione senza la necessità di ssh nel vm.
Alp

2
@Alp Credo che sia una porta disponibile per l'intero sistema, non solo disponibile per il processo ssh. Funziona bene per me!
Henrik Heimbuerger

1
Per coloro che utilizzano PuTTy, la sezione SSH / Tunnel della gui di configurazione consente sia il port forwarding remoto (da cui la -R nel comando) sia il port forwarding locale (-L nella riga di comando)
Titou

3
O qualcosa che tenga conto della configurazione potenzialmente diversa di vagrant se si dispone di più configurazioni vagrant ssh-config | ssh -F /dev/stdin $BOX -R $PORT_VM:localhost:$PORT -N
vagrant

100

Nel libro Vagrant: Up and Running(Data di pubblicazione: 12 giugno 2013), scritto dal creatore di Vagrant, ha menzionato che non è possibile per la macchina ospite accedere ai servizi in esecuzione sulla macchina host.

Invece di usare Forwarded Ports, potresti configurare una rete privata usando Host-Only Networks.

  • Vantaggi dell'utilizzo di Host-Only NetworksoverForwarded Ports

    1. Le macchine guest possono accedere ai servizi in esecuzione sulla macchina host

      Questa funzione risolverebbe il tuo problema.

    2. Le macchine guest possono accedere ai servizi in esecuzione su altre macchine guest

      Questa funzione è molto utile per separare i servizi su più macchine per imitare più accuratamente un ambiente di produzione.

    3. Sicuro

      Le macchine esterne non hanno modo di accedere ai servizi in esecuzione sulle macchine guest

    4. Meno lavoro

      Non c'è bisogno di configurare ogni singolo Forwarded Port


  • Come configurare Host-Only Networks

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

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

    Avere questa riga nella tua Vagrantfilevolontà istruirà vagrant a creare una rete privata che abbia un indirizzo IP statico:192.168.0.0

    L'indirizzo IP dell'host è sempre lo stesso indirizzo IP ma con l'ottetto finale come 1. Nell'esempio precedente, la macchina host avrebbe l'indirizzo IP 192.168.0.1.


2
Allo stesso modo (anche da Vagrant: Up and Running), potresti creare una rete a ponte. In una rete con bridge, altre macchine nella rete locale possono accedere alla macchina virtuale e viceversa. Ma poiché l'indirizzo IP viene assegnato tramite DHCP, dovresti ifconfignella macchina virtuale per trovare il suo indirizzo IP.
nucleartide il

28
Il fatto che quando si imposta config.vm.network: private_network, ip: "192.168.50.4" significa che l'ospite accederà all'host andando su "192.168.50.1" è la chiave di informazione qui. Non riesco a trovare quel piccolo bocconcino documentato da nessuna parte.
Nucleon

1
Ho scoperto che l'utilizzo dell'indirizzo di risposta di 192.168.0.0non funzionava: il curling / ping della macchina host causava una connessione t / o. L'utilizzo dell'indirizzo di @ Nucleon (coerente con i documenti di Vagrant sull'argomento) ha funzionato come pubblicizzato.
markdsievers

8
@Mingyu No, l'utilizzo della linea di configurazione config.vm.network :private_network, ip: "192.168.0.0"e il curling / ping sull'host 192.168.0.1comportavano timeout di connessione. Configurare la rete per essere 192.168.50.4risolta cioè host disponibile su 192.168.50.1.
markdsievers

3
"192.168.0.0" non è un buon esempio, xxx0 normalmente è per la trasmissione
5

73

È possibile accedere alle porte sulla macchina host tramite il gateway predefinito all'interno del SO guest. (Che in genere ha un IP di 10.0.2.2.)

Ad esempio, se hai un server web in esecuzione sulla porta 8000 sul tuo computer host ...

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

Puoi accedervi dall'interno della VM di Vagrant 10.0.2.2:8000(fornito 10.0.2.2è l'ip del gateway predefinito del guest):

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

Per trovare l'IP del gateway predefinito all'interno del SO guest, esegui netstat -rn(o ipconfigsu un guest Windows) e cerca la riga con un IP di destinazione di 0.0.0.0(o il campo etichettato "Default Gateway" su 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

Puoi estrarre questo IP a livello di codice con netstat -rn | grep "^0.0.0.0 " | tr -s ' ' | cut -d " " -f2.

Fonti: come connettersi con l'host PostgreSQL da vagrant virtualbox machine ; Connettersi alla macchina host da un SO guest VirtualBox?


Mi piace molto anche questa soluzione perché ha funzionato senza nemmeno interrompere la mia attuale sessione ssh vagabonda. Grazie!
Rubix

Bravo! questo è esattamente quello che stavo cercando
Khan Shahrukh

Eccellente! ifconfige ip addressnon mi stavano ottenendo ciò di cui avevo bisogno, ma l' netstat -rnho fatto.
geerlingguy

9

Aggiungi quanto segue al tuo ~/.ssh/configsul computer host:

Host 127.0.0.1
RemoteForward 52698 127.0.0.1:52698

Ti consente di accedere a un servizio sulla porta della macchina host 52698 da Vagrant, purché tu abbia effettuato l'accesso tramite vagrant ssh.

Puoi confermare che funziona eseguendo netstat -ltsu vagrant VM e prendendo nota sulle seguenti righe:

tcp      0    0 localhost:52698         *:*                 LISTEN
tcp6     0    0 ip6-localhost:52698     [::]:*              LISTEN

2
+1 Questo è stato di grande aiuto per me. Ho aggiunto il testo fornito sostituendolo con la porta 5037 per consentire alla mia scatola vagabonda di essere in grado di ascoltare l'emulatore Android in esecuzione sulla mia scatola host.
rapina il

2

Posso accedere ai servizi in esecuzione sul mio computer host tramite il suo indirizzo IP locale (non il suo indirizzo di loopback). Ho provato creando un server http sulla porta 80 (e poi sulla porta 987) e curlinserendo 197.45.0.10:80 e 197.45.0.10:987 (l'indirizzo ip effettivo è cambiato per proteggere gli innocenti). Ha funzionato entrambe le volte e non ho alcuna configurazione speciale per vagabondi (no public_network, no forwarded_port) e mentre ho alcune porte inoltrate tramite PuTTY, non ho le porte 80 e 987 inoltrate. Quindi forse prova a utilizzare l'indirizzo IP locale o pubblico della macchina host.

E se vuoi accedere (ssh in) un'istanza vagrant guest da un'altra, puoi abilitare public_networke inoltrare dalla porta 22 in Vagrantfilequesto modo:

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

Quindi finché quella porta è aperta (cioè fai un po 'più di port forwarding nella configurazione del tuo router) puoi accedere a quella macchina da qualsiasi luogo, anche dal mondo esterno.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.