When creating VMs on my laptop I like to configure the minimum number network interfaces. I also tend to end up with environments where I want multiple VMs to be able to see each other, see the internet and see my physical host. It seems many people using VirtualBox use the approach of having a “Host-only Adapter” interface and a “NAT” interface. The only reason I have for not liking this is that it is possible for a “Host-only Adapter” to be able to access the wider world via the physical host and therefore I see the NAT interface as surplus to requirements.
In the past when running Snow Leopard I’d worked out that enabling “Internet Sharing” on the Mac allowed my VMs with “Host-only Adapter” to be routed out to through whatever network my Mac was connected to (assuming the network, resolv.conf, etc were appropriately configured on the VM). I’ve suggested this approach to others in the past without questioning what OS X version they were running. I had the odd report of it not working and people resorting to adding a NAT interface, but didn’t have opportunity to investigate.
Anyway, I got a new computer recently and it came with OS X Mavericks. On creating my first VM in VirtualBox I opted for my preferred approach of using “Host-only Adapter”. I then spent a while working out how to get my Mac to NAT the VMs. Here is the solution I came up with.
1. Enable IP forwarding:
$ sudo sysctl -w net.inet.ip.forwarding=1
If you want this to be persistent across reboots then you can add it to /etc/sysctl.conf.
2. Edit the pfctl configuration file (/etc/pf.conf) adding the following line below “nat-anchor”:
nat on en0 from vboxnet0:network -> (en0)
The above assumes that your Mac is connected to the internet over Airport/WiFi (en0) and that you want to allow the first VirtualBox “Host-only Network” (vboxnet0) to be NAT’d.
It is also possible to use natd & ipfw, as covered here, but they are deprecated in Mavericks, so you should probably adopt pfctl now.
3. Once pf.conf has been modified the file needs to be loaded:
$ sudo pfctl -f /etc/pf.conf
4. … And you need to ensure that PF is enabled:
$ sudo pfctl -e
The VMs will now be able to access the internet via their “Host-only Adapter” through the physical host.
This gives me a situation where my Mac can see all my VMs, my VMs can see each other and importantly my VMs can get out to the internet – All with a single interface on each VM. KISS.
[Update] Persistent Through Reboot
As mentioned above the sysctl change can be made persistent through reboots by writing it to /etc/sysctl.conf, which you will probably need to create unless you’ve already been tinkering.
The changes to /etc/pf.conf will remain in place through restarts, but there are two changes required to ensure that PF is brought up automatically after startup. The first change is covered in section 2 of this Mavericks Server knowledge base article from Apple. The part that is relevant is:
$ sudo defaults write /System/Library/LaunchDaemons/com.apple.pfctl ProgramArguments '(pfctl, -f, /etc/pf.conf, -e)'
The chmod & ptutil commands that follow the above in the article were not required in my case as the permissions on the file were already as appropriate and the plist file was already in XML format. That said their is no harm in running them.
The other change you will need to make is to modify the syntax used in /etc/pf.conf. At the point PF is started the “vboxnet0” interface will not exist and therefore PF will not be able to determine the required network information for them, which results in PF not being enabled. In order to avoid this problem it is necessary to switch to the following syntax (assuming your haven’t changed vboxnet0 from the default configuration):
nat on en0 from 192.168.56.0/24 -> (en0)
If you have changed from the default configuration or use multiple “Host-only Networks” in your VirtualBox environment then I’d imagine you can work out how to match the above to your environment.