Wednesday, May 9, 2012

Create a NAT for VirtualBox Host Only Network

VirtualBox does a fairly good job with the built in NAT feature on the virtual network device. But there are some drawbacks:
  1.  You can't easily monitor the network on the built in NAT.  So if your VM is misbehaving, you couldn't use tcpdump to troubleshoot.
  2. The built in NAT reaches directly to the Internet in a transparent manner.  If you wanted to control access to the Internet you would have to switch to a bridge device or go with host-only.
  3. Most importantly for me, it does not support GRE packets very well.  This means that if you want to access a Microsoft PPTP VPN from your VM, it won't work with the VirtualBox built in NAT. (Well it didn't for me anyway)
EDIT: An updated script for the firewall component is described in a new post found here:

So with some simple tweaks to your host, you can NAT the VirtualBox host only network and enjoy some extra features.

In VirtualBox create a default host-only network.  This is done in File -> Preferences -> Network.  Click the green icon with a PLUS sign in it.  A new network is created called vboxnet0.  Then click the little screwdriver icon to edit the vboxnet0 settings.  Select the DHCP Server tab and make sure "Enable Server" is unticked.  It will be ticked by default.

Make sure that the DHCP server is not enabled.  This is important because you will configure DHCP with dnsmasq on the next step.

Then install dnsmasq.  You need this for DNS.  I like that with dnsmasq, and dhcp client id's specified on the VM's, I can do things like "ssh vm_hostname" from the host pc.

sudo apt-get install dnsmasq

Accept the defaults.

dnsmasq uses a config.d approach for configuration so create a file called: /etc/dnsmasq.d/virtualbox as follows:

# cat /etc/dnsmasq.d/virtualbox

Restart dnsmasq:

sudo /etc/init.d/dnsmasq restart

Now configure IPTABLES.  I took a lazy approach and added these commands to /etc/rc.local
I have not bothered to learn how to do this with ubunut's default UFW becasue I don't much like UFW and so don't use it.

sudo ufw disable (if you're interested ...)

Add the following lines to /etc/rc.local (before the last line which is "exit 0")
iptables -F
iptables -t nat -F
# Loopack
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Allow all from virtualbox
iptables -A INPUT -s -j ACCEPT

# Accept SSH  If you have openssh installed that is.
iptables -A INPUT -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT

# Accept DNS
#iptables -A INPUT -p tcp --dport 53 -j ACCEPT
#iptables -A INPUT -p udp --dport 53 -j ACCEPT

# Accept DHCP
#iptables -A INPUT -p tcp --dport 67 -j ACCEPT
#iptables -A INPUT -p udp --dport 67 -j ACCEPT

# Masquerade virtualbox network
iptables -t nat -A POSTROUTING -s -j MASQUERADE

#turn on ip forwarding.  Can be done in /etc/syctl.conf - As I said - lazy.
sysctl -w net.ipv4.ip_forward=1

Then reboot your computer.

sudo reboot

Now change the nic on your VirtualBox vm to a Host Only network and start the VM.  If you did everything right, your VM will start, obtain a lease from dnsmasq and have access to the internet.

The firewall rules above allow everything from VirtualBox to go out on the internet.  If you wanted to lock things down a bit, you could add more rules to do so and remove the line that accepts everything from the subnet.

Oh and your Microsoft PPTP VPN will work now.  Even if you use wireless...

Have fun!

1 comment:

Unknown said...

The DNS and DHCP lines in the iptables portion are commented out because they are not required. I forgot to remove them when I wrote the post.