>Setting up a bridge for your headless VirtualBox machine

>

Last week, I wrote an article on how to set up a bridge for QEMU, which is quite practical for when you want to set up servers quickly and easily. QEMU has its drawbacks, however, when it comes to using graphic interfaces, so I tend to prefer using VirtualBox for my day-to-day virtualization needs.
I’ve been working on a virtual machine for teaching purposes, lately, and have determined that a headless VirtualBox VM is the way to go.  Here are a few notes that I’ve taken on setting up a headless VM on a bridged network – this allows the person running the VM to start the machine without starting up a console, and to be hit the VM’s services from the host machine.
Before I go on, though, here are the URL’s I use as a reference:
Good howtoforge by Falko Timme:
http://www.howtoforge.com/vboxheadless-running-virtual-machines-with-virtualbox-2.0-on-a-headless-ubuntu-8.04-server
Setting up a bridge, according to the VirtualBox wiki:
http://www.virtualbox.org/wiki/Advanced_Networking_Linux
These cover (with a fair amount of detail, I might add) the topics of setting up VirtualBox, creating a machine, and creating a fully functional bridge with DHCP etc etc. That’s something I’m not going to cover here – namely because it would be a pale copy of someone else’s work.  I’m writing about setting yourself up with something that you can run in a classroom or as a sandbox for short-term activities.  Hope this helps.

Setting up VirtuaBox 2.1 (or later)
At the time this article is written, Ubuntu Hardy Heron is the current LTS and VirtualBox 2.1 is the latest version. I will therefore be writing under the assumption that you are using these versions — please remember to change the commands according to your distro / version of VirtualBox!
First, you have to add VirtualBox’s repository and public key to your APT sources. Add the following line to your /etc/apt/sources.list file — you can tack it on to the end:
deb http://download.virtualbox.org/virtualbox/debian hardy non-free
You’ll also have to download and set up the key. You can do this using wget and apt-key:
wget http://download.virtualbox.org/virtualbox/debian/sun_vbox.asc
sudo apt-key add sun_vbox.asc
You can then retrieve virtualbox straight from apt-get:
apt-get install virtualbox-2.1
As opposed to VirtualBox open source edition (which can be run using the command ‘virtualbox’), VirtualBox 2.1 is run using ‘VirtualBox’ (case-sensitive, of course). I simply set up my VM using the GUI.

Setting up the bridge
As with qemu, you have to set yourself up with a virtual network interface (tap0, for instance), set it up with an IP address, and set up IP forwarding on your host machine.  I used the first of the scripts below to set myself up.  I then needed to run VirtualBox once again to modify the settings:  I added a Host Interface NIC to my machine’s configuration, which pointed to tap0.  I then ran my machine, and tested my config by having my guest ping my website, then my host and vice-versa.
I shutdown my guest, and tore down my virtual network using the second script below.

#!/bin/bash

# Script to set up bridging for your virtualbox machines. When setting up your VM, add an extra network interface of type “Host Network”, called tap0.  You can use this script as the network “startup script”.

# Create a TAP interface, tap0, to be used for bridging; set the owner of that interface to the current user (hence the whoami command):
sudo tunctl -t tap0 -u `whoami`

# Create a bridge, br0, and add the tap interface to it. DO NOT ADD THE PHYSICAL INTERFACE: you will kill your network connection if you do that 🙂
sudo brctl addbr br0
sudo brctl addif br0 tap0

# Bring up the bridge and tap interfaces:
sudo ifconfig br0 10.1.1.1/24 up
sudo ifconfig tap0 10.1.1.2/24 up

# Turn on IP forwarding:
sudo xterm -e “echo 1 > /proc/sys/net/ipv4/ip_forward”

# Add a rule to forward traffic over to eth0:
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE


#!/bin/bash
# Script to tear down bridging for your virtualbox machines. You can use this script as the network “shutdown script”.

# Flush the traffic forwarding rules:
sudo iptables -t nat -F

# Disable IP forwarding
sudo xterm -e “echo 0 > /proc/sys/net/ipv4/ip_forward”

# bring down the bridge and tap interfaces
sudo ifconfig br0 down
sudo ifconfig tap0 down

# kill the bridge
sudo brctl delbr br0

# kill the tap interface
sudo tunctl -d tap0


Spreadin’ the love

Once the guest machine was configured and connected, I powered it down.  At this point, the guest is ready to transfer to a DVD or to a tarball.  I simply copied the machine’s config folder (~/.VirtualBox/Machines/<machine name>) and Virtual Disk (~/.VirtualBox/VDI/<machine name>.vdi) to a DVD. Before using them, of course, one needs to copy them to the correct locations on one’s disk. The VDI file will need to be registered using the Virtual Disk Manager of VirtualBox (or the equivalent VBoxManage command) and the machine will need to be registered using the following command:
VBoxManage registervm Machines/<machine name>/<machine name>.xml
I also copied the scripts to the DVD; I tacked on the following line at the end of the startup script:
VBoxManage startvm <machine name> -type vrdp
And this line at the beginning of the shutdown script:
VBoxManage controlvm <machine name> poweroff

>Adding a new virtual hard drive to a Ubuntu guest in VirtualBox

>The following is a simple procedure allowing you to create a new virtual hard drive for your ubuntu guest OS and assign it to a mount point.

As you might already know, VDI’s are a pain in the ass to resize — not impossible, but certainly a pain.  With an ubuntu guest OS, the simplest thing to do is to create a new VDI and mount it!

  1. Create the disk and attribute it to your Virtual Machine
    1. Fire up Virtual Box and open the Virtual Media Manager (File > Virtual Media Manager)
    2. Follow the instructions to create a new VDI file
    3. Open the settings of the virtual machine to which you’ll add your new drive.  Under the Hard Disks tab, add the drive that you’ve just created.
  2. Fire up your virtual machine
  3. Format and mount your new hard drive
    1. Once logged into the operating system, make sure that you have gparted installed (sudo apt-get install gparted if you don’t)
      1. The system should detect that you have a new drive (probably /dev/sdb).  Select that drive and format it as an msdos drive (click on New… and, when prompted, select msdos)
      2. Create a new partition of type ext3 (New…, then select primary partition and when prompted select ext3)
      3. Open up gparted (‘sudo gparted’ from a command line)
      4. Hit Apply — gparted will take care of formatting your drive
    2. You should now be able to use your hard drive simply by mounting it (run ‘mkdir /media/my_new_drive;mount /dev/sdb /media/my_new_drive’ as root).  However, for a more permanent setup, you’ll need to modify your /etc/fstab file
      1. Open /etc/fstab with your favorite editor (be sure to run the editor as root)
      2. Create a new line (I usually copy the line for my root partition and modify as necessary).  Make sure to specify your new hard drive as the device (probably /dev/sdb1) and some empty directory as the mount point (such as /opt).

>QEMU: Accessing the Internet and making the guest pingable from your host.

>
QEMU is a nice, fast virtualization tool that allows you to create guest machines. It works much like VMWare or VirtualBox; I won’t go into the merits and drawbacks of using one over the other (I use all three, selecting the most appropriate for the situation). I’ve found that qemu is best used for sandboxing, proofs of concept, and tutorials where you need a quick, disposable machine to be set up in very little time.

The following article is nothing new. It’s simply a rehash of the qemu documentation, merged with the following ubuntu post: http://ubuntuforums.org/showthread.php?t=179472

In the past, I’ve found that reading several articles on the same topic can be useful because it gives the reader several perspectives. This is my own “recipe”, hope it will be of use to someone out there…


The procedure in a nutshell:
1) Create a TAP network interface for communicating between your guest and host
2) Set your host up for NAT so that the guest can access the internet
3) Manually configure an IP address and name server on your guest OS.

FROM THE HOST SYSTEM

– Creating the TAP interface –
You need to double-check that TAP is available on your host. To do this, simply type “ls /dev/net/tun” to check whether the device exists. By default, the Ubuntu kernel supports TAP. If your kernel doesn’t, google “Ubuntu tap interface”.

With qemu, this is not particularly complicated. Simply append the “-net nic” and “-net tap” flags to your qemu command. For instance:

qemu <name of your image> -net nic -net tap

Double check that a tap interface has indeed been created by running ifconfig
– Setting up NAT – 

You’ll need to enable IP forwarding on your host and set up iptables to forward traffic from your tap interface to your regular interface. I assume that the interface that you use to connect to the internet from your host is eth0 in the following lines. I also assume that your host connects to a router, and not directly to the internet.

To enable IP forwarding: echo 1 > /proc/sys/net/ipv4/ip_forward

To set up iptables: iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

FROM THE GUEST SYSTEM

– Configuring the IP address and name server –
Check out the IP address attributed to your host’s TAP interface and use it as a reference in your /etc/network/interfaces file. Assuming that your guest machine’s network card is eth0, your host IP is 172.20.0.1 and subnet mask is 255.255.0.0:

auto eth0

iface eth0 inet static

  address 172.20.0.2

  netmask 255.255.0.0

  gateway 172.20.0.1

You’ll need to check your host’s /etc/resolv.conf file; use the same nameserver setting as your host, that’s the easiest thing to do. In other words, if your host’s /etc/resolv.conf file indicates the nameserver is 192.168.1.2 then set up your ghost’s /etc/resolv.conf file to use 192.168.1.2 as well.