I\'m working on a web services architecture. I\'ve got some software that I need to run on the native host machine, not in Vagrant. But I\'d like to run some client services
When you run vagrant ssh
, it's actually using this underlying command:
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 supports forwarding ports in the direction you want with the -R guestport:host:hostport
option. So, if you wanted to connect to port 12345
on the guest and have it forwarded to localhost:80
, you would use this command:
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
As Eero correctly comments, you can also use the command vagrant ssh -- -R 12345:localhost:80
, which has the same effect in a much more concise command.
You can access ports on the host machine through the default gateway inside the guest OS. (Which typically has an IP of 10.0.2.2
.)
For example, if you have a webserver running on port 8000 on your host machine...
echo 'Hello, guest!' > hello
python -m SimpleHTTPServer 8000
You can access it from inside the Vagrant VM at 10.0.2.2:8000
(provided 10.0.2.2
is the ip of the guest's default gateway):
vagrant ssh
curl http://10.0.2.2:8000/hello # Outputs: Hello, guest!
To find the IP of the default gateway inside the guest OS, run netstat -rn
(or ipconfig
on a Windows guest) and look for the row with a destination IP of 0.0.0.0
(or the field labeled "Default Gateway" on 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
You can extract this IP programmatically with netstat -rn | grep "^0.0.0.0 " | tr -s ' ' | cut -d " " -f2
.
Sources: How to connect with host PostgreSQL from vagrant virtualbox machine; Connect to the host machine from a VirtualBox guest OS?
Add following to your ~/.ssh/config
on the host machine:
Host 127.0.0.1
RemoteForward 52698 127.0.0.1:52698
It lets you access a service on host machine port 52698 from Vagrant, as long as you logged in via vagrant ssh
.
You can confirm it works by running netstat -lt
on vagrant VM and taking a note on the following lines:
tcp 0 0 localhost:52698 *:* LISTEN
tcp6 0 0 ip6-localhost:52698 [::]:* LISTEN
I can access services running on my host machine via its local IP address (not its loopback address). I tested by creating an http server on port 80 (and then on port 987) and curl
ing 197.45.0.10:80 and 197.45.0.10:987 (actual ip address changed to protect the innocent). It worked both times, and I don't have any special vagrant configuration (no public_network, no forwarded_port) and while I do have some ports forwarded via PuTTY, I don't have ports 80 and 987 forwarded. So maybe try using the host machine's local or public IP address.
And if you want to access (ssh into) one guest vagrant instance from another, you can enable public_network
as well as forwarding from port 22 in the Vagrantfile
like this:
config.vm.network "public_network"
config.vm.network "forwarded_port", guest: 22, host: 2200
Then as long as that port is open (ie do some more port forwarding in your router config) you can access that machine from anywhere, even the outside world.
In the book Vagrant: Up and Running
(Pub. date: June 12, 2013), written by the creator of Vagrant, he mentioned that it is not possible for guest machine to access services running on the host machine.
Instead of using Forwarded Ports
, you could set up a private network using Host-Only Networks
.
Pros of using Host-Only Networks
over Forwarded Ports
Guest machines may access the services running on host machine
This feature would solve your problem.
Guest machines may access the services running on other guest machine
This feature is very useful to separate services onto multiple machines to more accurately mimic a production environment.
Secure
Outside machines have no ways to access the services running on the guest machines
Less work
No need to configure every single Forwarded Port
How to configure 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
Having this line in your Vagrantfile
will instruct vagrant to create a private network that has a static IP address: 192.168.0.0
The IP address of the host is always the same IP address but with the final octet as a 1. In the preceding example, the host machine would have the IP address 192.168.0.1
.