VirtualBox Host-only Shared Networking
A few days ago I wrote a bit about VirtualBox 4.3 NAT Networks. Then, looking for something else, I stumbled upon a related question regarding VirtualBox Host-only networks, and allowing different host-only networks to see each other. The general and short answer is "no, they can't."
The longer and better answer is "yes, they can!"
I answered the question on the link above, but thought to put some more detail in this discussion. Much of this text is the same, but some of the details have been made more specific to a generic case, and less about the specific case outlined in the forum question. This assumes a little bit of network configuration knowledge, and some familiarity with VirtualBox (and at least a couple of hosts and guests...).
You can do host-only networking and connect guests to other guests on host-only networks on multiple hosts, or multiple host-only networks on the same host. 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 participating 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
- Add static routes between hosts
First, some assumptions. For the sake of easing the discussion, let's let the host network be the SOHO NAT default of 192.168.1.0/24 and that each host will have only one host-only network. Then we'll use the helpful plan of changing the next-to-last octet for each host-only network to the last octet of the host machine. That way the machine with the host address of 192.168.1.100 will have the host-only network of 192.168.100.0/24; it'll make it easy to define and find host-only networks later. We'll reserve the 192.168.56.0/24 network for "default" host only use, and plan not to route to that one (which is only trouble for the machine assigned 192.168.1.56.
For bigger flexibility, change the NAT to the 10.0.0.0/8 network. It's likely that those same NAT routers will require a /24 network, but since you can use any 10.x.y.0/24 network (for simple subnetting always use /24, which is your friendly netmask of 255.255.255.0), that makes 64K of networks available!
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. They can't be the same because then hosts that need to access different networks won't know which to reach, of course.
For example, since we're using the example of the 192.168.1.0/24 network used by default by so many SOHO NAT routers, this means we could choose to use any of the other 192.168.x.0/24 networks for the host-only networks. Make sure each host-only network uses a different "x" value; there are 254 choices after removing the one the host is on as all values from 0 to 255 are valid in that octet.
The VirtualBox documentation (and links therein) outlines 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.
In the VirtualBox GUI it's pretty straight-forward; from the VirtualBox library find the "preferences" dialog. In the dialog, choose the Network, then the host-only network, and finally in the list the host-only network to alter (or create a new one). In the properties panel for that network are facilities for editing the IP address and DHCP settings.
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 (it's the one defined in the previously mentioned preferences), so using the 192.168.x.1 in these examples, the command becomes route add default gw 192.168.x.1 (where x is a real value, of course).
Making this permanent varies by OS enough to not try to outline how to do it here. Use the OS' GUI or edit the appropriate /etc/ files as necessary, or run the "route add" command 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.
Out of the box the host and guest should be able to access each other using the host-only networking. The thing that's missing is that the hosts may not be configured to route between interfaces (few are by default). The host can use both interfaces, but we need to change it so the host will take traffic from one network and move it to the other when necessary.
On a Linux host, it's as easy as setting the /proc/sys/net/ipv4/ip_forward file to have the value of 1 (one) 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
Or edit the file with your favorite editor and make sure it contains only the one-character of 1 (the number one, in case that's tough to read).
Routes
Then make sure that the host has a route to the host-only network. My hosts with host-only networking already had the correct routing for the real and virtual networks. For example, on my Ubuntu hosts all I did was check by running route -n in the command-line (the -n suppresses the route command's desire to resolve IP addresses into names).
Note that the virtual network adapter may not be on until a guest is running that uses it. If you don't have a running guest, that might be why your vboxnet0 (the default device name) is not visible. Also note that often the virtual interfaces aren't available in GUI tools; for example, my Mac doesn't show the virtual adapter in the System Preferences panes.
Google "myOS 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.
Multiple Host-only Adapters
Note that if you're working on getting multple host-only networks working on one host, and those networks don't need to see networks on other hosts or other resources on the host's network, this should be the last step. The host in this case should have a route to each of its host-only adapters, and if it's configured for routing, and the guests are configured to use the host as their gateay, the guests should be able to see each other no matter which host-only network they're on.
If you want those multiple host-only networks to see other networks, or have other nodes on the host's network (or other host-only networks on those other hosts), continue with the static routing bits.
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." That means in the general SOHO NAT world, if an address isn't on the 192.168.1.0/24 network, it's on the other side of the router (which for many out-of-the-box routers is 192.168.1.1).
Something like this will work on most host OSs.
route add -net host-only-network netmask host-only-netmask gw host-if
Continuing our example, you'd put route add -net 192.168.x.0 netmask 255.255.255.0 gw 192.168.1.x (where x is the host IP, which we've made match the host-only network definition in the previous bit) 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, but needed access to (or the ability to respond to requests from) host-only network guests.
Static Routes in Router
Alternatively, if access is available, the static routes to each host-only network could be added to the router instead. In some SOHO NAT routers, this is possible with the right administrative access. It requires some additional network considerations, like making sure the hosts don't change their IPs (which rarely happens for frequently used hosts).
When the routers know these static routes, then every device that uses that router as its gateway will be able to see and interact with the host-only networks (as long as the host-only hosts and guests are configured as above). Traffic will leave the node (even guests on other host-only networks) and hit the router; the router will see the traffic that's bound for a host-only network is "behind" a node on the network, so it will send the traffic to that node; that node should then see that the traffic is on its virtual network and send it to that network; if the node is on, it will handle the traffic and the opposite will occur.
End-to-end Example
Let's say you have two hosts on your network for which you want to apply this: 192.168.1.101 and 192.168.1.201. For ease of remembering, change each of their host-only networks to use their last octet as the network definition, so 192.168.1.101.0/24 on the .101 host, and 192.168.201.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 192.168.101..0/24 machines route add default gw 192.168.101.1 and on the 192.168.201.0/24 machines route add default gw 192.168.201.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 checked to make sure that route -n would show something like this (edited to match the example):
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
192.168.1.101 0.0.0.0 255.255.255.0 U 1 0 0 eth0
192.168.101.1 0.0.0.0 255.255.255.0 U 0 0 0 vboxnet0
Then on each host (or the network router) 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 192.168.201.0 netmask 255.255.255.0 gw 192.168.1.201 and on the .201 host you'd enter route add -net 192.168.101.0 netmask 255.255.255.0 gw 192.168.1.101 to establish the static routes. Checking our route -n again should give us the likes of this:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
192.168.201.0 192.168.1.201 255.255.255.0 U 0 0 0 eth0
192.168.1.101 0.0.0.0 255.255.255.0 U 1 0 0 eth0
192.168.101.1 0.0.0.0 255.255.255.0 U 0 0 0 vboxnet0
You should now be able to use the network to get from your 192.168.101.101 (first default DHCP address on a host network) to your 192.168.201.101 virtual machine on the other host, or from either host to either host-only network guest, and from any guest on either host-only network to either host.... I don't know what the 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 routes. That means any machine on the 192.168.101.0/24 or 192.168.201.0/24 network, or the 192.168.1.101 or 192.168.1.201 hosts can interact, but devices on the host-only networks couldn't interact with other hosts on the 192.168.1.0/24 network that didn't also have the static route added.
This can be also changed by further configuring the VM hosts with more robust forwarding rules, adding NAT or proxy software to the host, for example. A bigger routing solution could be made if this was a critical, like putting the static routes in the hosts' default router.