bridged networking with Virtualbox

Virtualbox is a great tool. It looks a lot like VMWare, and has a lot of it's functionality. It seems to runs faster and it's opensource AND it has ubuntu packages.

But virtualbox's networksetup sucks. Like VMWare, it allows for network-connections from the guest OS through NAT, which works nicely. But for most of my applications, I need bridged networking between the guest OS and the network adapter of the host OS.

Several guides exist on the internet that explain in detail how to do each step. But none of them explain the big red lines.

As I found out, it's pretty simple:


OK, that's it ! See ? It's not difficult at all.

But there is trickery involved to be able to keep using the physical device together with virtualbox. Once you setup the bridge, you will not be able to use the physical device anymore and network connectvity will be lost.

Instead of setting an IP address on the physical interface (be it either with DHCP or static), you now need to set this IP on the bridge.

To me this all sounds ugly. I use Ubuntu, and I don't want to mess with the networksettings this much because I expect NetworkManager to do that. The solution is to trick NetworkManager into thinking that nothing has changed. And to do that, we pull an old switcheroo on the network devices.



NetworkManager expects eth0 (in my case) to be the interface it needs to configure. But when using Virtualbox, I need to create a bridge (br0) and tell NetworkManager to use that interface instead. I have no idea how NetworkManager works, but I assume it just looks at the devicename. So before NetworkManager starts, I rename eth0 to something else (old-eth0) and createn a bridge called eth0.



This setup works greatly. When I reboot, all devices are set up nicely and I can start Virtualbox and use bridged networkinng. But there is still a problem: NetworkManager is very confused.

I'll look into that later on

This is the script I use to create tap1 and tap2
It should be made executable and linked into the subdirectories of /etc/network (if-down.d, if-post-down.d, if-pre-up.d and if-up.d)

Don't give the script an extension like "virtualbox.sh", because it apparently doesn't work that way.


#!/bin/bash

TAPS="tap1 tap2"
MYINTERFACES="eth0"

if [ "$IFACE" != "$MYINTERFACES" ];
then
exit;
fi



pre_down() {
# first, remove all setup
for INT in $TAPS; do
echo "# switching off $INT"
ifconfig $INT down
echo "# removing $INT from bridge"
brctl delif $IFACE $INT
echo "# removing $INT alltogether"
tunctl -d $INT
done
}

post_down() {
echo "# bringing down the physical interface"
ifconfig old-$IFACE down
echo "# removing the physical interface from the bridge"
brctl delif $IFACE old-$IFACE
echo "# deleting the bridge $IFACE"
brctl delbr $IFACE
echo "# renaming the physical interface old-$IFACE back to $IFACE"
ip link set old-$IFACE name $IFACE
}

pre_up() {
echo "# renaming $IFACE to old-$IFACE"
ip link set $IFACE name old-$IFACE
echo "# setting up $IFACE to be a bridge"
brctl addbr $IFACE
echo "# adding old-$IFACE to the bridge $IFACE"
brctl addif $IFACE old-$IFACE
echo "# bringing up the physical interface"
ifconfig old-$IFACE up
}

post_up() {
# setting up the tun devices
for INT in $TAPS; do
echo "# creating $INT"
tunctl -t $INT -u deepstar
done

chown root.vboxusers /dev/net/tun

for INT in $TAPS; do
echo "# adding $INT to bridge"
brctl addif $IFACE $INT
echo "# switching on $INT"
ifconfig $INT up
done
}


case $PHASE in
pre-up)
pre_up
;;
post-down)
post_down
;;
post-up)
post_up
;;
pre-down)
pre_down
;;
esac