Virtualbox: Connecting Host-Only networks on separate hosts

If i create multiple ubuntu guests on the same host (windows 7), all with a network adapter configured as "Host-Only" the result is that all guests in the host can ping each other

On windows 7 host, with ipconfig i see something like

Ethernet adapter Local Area Connection:

   Connection-specific DNS Suffix  . : wr
   Link-local IPv6 Address . . . . . : ......
   IPv4 Address. . . . . . . . . . . : 10.15.38.101
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 10.16.2.254

Ethernet adapter VirtualBox Host-Only Network:

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : .........
   IPv4 Address. . . . . . . . . . . : 192.168.56.1
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . :

and in fact all guests show their ip to be on the 192.168.56.X subnet.

Question: is it possible to easily connect guests running on different hosts with this Host-Only network which are accessible through LAN?


The short answer is no. You can't use "Host-Only Networking" and connect guests on multiple, physical hosts. You are probably better off using bridged networking if you need to connect the guests to your LAN.

If you could provide more details of what you are trying to accomplish we could perhaps make a better recommendation.


The longer and better answer is "yes."

You can do host-only networking and connect guests (and hosts) to other guests on host-only networks on multiple hosts, or multiple host-only networks on the same host, but it isn't easy. Not too hard, but not easy.

What makes it possible is that the host is also participating in the host-only network (the only virtual network scheme where the host directly participates), as long as the hosts can do the routing necessary. It does require some administrative access, so it might be hard to do for that reason, too.

Four Easy Steps

Here are the four bits you need to do, from the inside out: configure your host-only networks, add gateways to your guests, make your host a router, and add static routes between hosts.

Host-only Network Configuration

Make sure your host-only networks are unique (at least any that are participating in the scheme). That is, each host-only network needs to be different, and not all the same default 192.168.56.0/24 network.

Your example puts your host in the 10.15.38.0/24 network, which is already a private range (not that that matters), so you could choose to use other 10.x.y.0/24 networks (you've got about 64K choices!) for your host-only networks. (Note that since your example gateway isn't on your network, it suggests your network is really 10.0.0.0/8, so be wary of other potential conflicts.) Of course, you can continue to use the 192.168.y.0/24 networks, too, but make sure each host-only network uses a different "y" value.

The VirtualBox documentation at https://www.virtualbox.org/manual/ch08.html#idp59149232 outlines how to configure the host-only interface and related DHCP server to change the addresses. The GUI offers mechanisms, too, if the command-line isn't your friend, but the docs help make it understandable (or it should), and don't really address the GUI.

Guest Gateways

Configure your guests to have routes off the host-only network through the host's host-only network IP. Unlike the NAT virtual networks, the host-only DHCP server doesn't provide guests with routing information, just addresses.

This can be done a variety of ways, like replacing the DHCP server, but essentially all you have to do is tell each guest OS how to get off of the host-only network. For most OS' it's the same command (which requires administrative powers):

route add default gw <<host-only-if>>

By default, the host-only interface will be given the .1 node of the network, so 10.x.y.1 in these examples, so the command becomes route add default gw 10.x.y.1 (where x and y are real values, of course).

Making this permanent varies by guest OS, but use the GUI or edit the /etc/ files as necessary, or run the route add line every time you fire up the VM.

Host Routing Between NICs

Configure your VM hosts to route between the interfaces. This is where it gets tricky and many people give up. As far as your host OS' are concerned, using the host-only network means they are multi-NIC machines, and they can be configured to move traffic from the virtual network to the real network.

Since you're using Windows, http://windows.microsoft.com/en-us/windows/configuring-multiple-network-gateways outlines this concept and gives some details on the route command. It seems turning on the RIP Listener and adding/verifying the routing "is all it takes."

On a Linux host, it's as easy as setting the /proc/sys/net/ipv4/ip_forward file to have the value of 1 in it, and ensuring the routing table includes the virtual and real networks. This works on my Ubuntu host:

echo "1" | sudo tee /proc/sys/net/ipv4/ip_forward

Even better, my Ubuntu host already had the correct routing for the real and virtual networks, so all I had to do was change that value in that file.

Google "my OS as router" or something like that until you find something that makes you comfortable. You can use whatever mechanism makes you happy to enable routing and set up the routes.

Static Routing

Configure your hosts to route to other hosts' virtual networks. This is where it gets messy and even people who can get through step 3 will sometimes give up. It's messy because on each virtual machine host you need to do this configuration, and if you have many hosts and host-only networks, it can be tricky to track and busy to complete.

Your general default network configuration is going to be "everything not on my subnet is on the other side of my default gateway." In your example, if it isn't on the 10.15.38.0/24 network, it's on the other side of 10.16.2.254 (which again suggests your network is really 10.0.0.0/8, and your network mask is wrong, but that's OK). What you need to do is tell your hosts to set up a static route to the other hosts' virtual networks. Alternatively, you can configure your hosts' default router (yours is 10.16.2.254) to know these routes...the traffic will leave the host, hit the router, go back to the other host...

Something like this will work on most host OSs.

route add -net <<guest-ip-range>> netmask <<correct-mask>> gw <<host-lan-IP>>

So in the case of your example, you'd put route add -net 10.x.y.0 netmask 255.255.255.0 gw 10.15.38.101 on each other host that needed to access your host's virtual network.

This could also be done to other systems on the host's network that needed to access a device on a host-only network, even if it wasn't hosting a virtual network of its own.

End-to-end Example

Let's say you have two hosts on your network for which you want to apply this: 10.15.38.101 and 10.15.38.201. For ease of remembering, change each of their host-only networks to use their last octet as the network definition, so 10.101.0.0/24 on the .101 host, and 10.201.0.0/24 on the .201 host.

On each guest in the host-only network, add a route through the host-only host interface. So on the 10.101.0.0/24 machines route add default gw 10.101.0.1 and on the 10.201.0.0/24 machines route add default gw 10.201.0.1 will do the trick.

On each host, turn on routing and ensure the routing table includes both networks. On my Ubuntu host, I did echo "1" | sudo tee /proc/sys/net/ipv4/ip_forward and then route -n would show something like this (edited to match your example):

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.16.2.254     0.0.0.0         UG    0      0        0 eth0
10.15.38.0      0.0.0.0         255.255.255.0   U     1      0        0 eth0
10.101.0.0      0.0.0.0         255.255.255.0   U     0      0        0 vboxnet0

Then on each host you need to add the static route to the other host's host-only network. So on the .101 host you'd enter route add -net 10.201.0.0 netmask 255.255.255.0 gw 10.15.38.201 and on the .201 host you'd enter route add -net 10.101.0.0 netmask 255.255.255.0 gw 10.15.38.101 to establish the static routes.

You should now be able to use the network to get from your 10.101.0.101 (first default DHCP address on a host network) to your 10.201.0.101 virtual machine on the other host. I don't know what your guest OS offers, but SSH or web browser, or usually ping, should work.

With all of that, your hosts and virtual machines should be able to see each other even when on different host-only networks.

Caveats

What remains is to configure other services, like DNS to make resolving all of the hosts easier. This could be as easy as adding lines to the /etc/resolv.conf or whatever GUI mechanism in the guest OS, or editing /etc/hosts files with other host addresses.

It may not be clear, but the static routing trick needs to be on any system that a host-only network guest needs to access. In the step-by-step example only the two hosts are configured with the static address. That means any machine on the 10.101.0.0/24 or 10.201.0.0/24 network, or the 10.15.38.101 or 10.15.38.201 hosts can interact, but devices on the host-only networks couldn't interact with other hosts on the 10.15.38.0/24 networks (or other 10.0.0.0/8 networks) that didn't also have the static route added.

This can be changed by further configuring the VM hosts with more robust forwarding rules, adding NAT or proxy software. That software doesn't need to be on any more than one of the VM hosts, or a different system, as long as that device was configured with static routes to all of the host-only networks that it needed to serve. A bigger routing solution could be made if this was a critical need.