Kategorien

Druckansicht des Beitrags Druckansicht des Beitrags

Virtualbox und Intrepid – das perfekte Setup – Netzwerk

Nach der Installation von Virtualbox erhält man zunächst folgende Fehlermeldung: „Could not load the Host USB Proxy Service (VERR_FILE_NOT_FOUND). The service might be not installed on the host computer. Fehlercode:  NS_ERROR_FAILURE (0x00004005)“. Damit USB wie gewünscht funktioniert und die Fehlermeldung verschwindet muss man unter Intrepid folgende Zeile in /etc/fstab einfügen:

none	/proc/bus/usb	usbfs	devgid=46,devmode=775	0	0

Als nächstes machen wir uns an die Netzwerkeinstellungen. Für die virtuellen Maschinen möchte ich tap Interfaces nutzen, die über eine Proxy ARP Bridge in mein Netzwerk eingebunden werden und per dhcp eine IP zugewiesen bekommen sollen. Die Proxy ARP Bridge hat den Vorteil, dass sie auch in einem drahtlosen Netzwerk funktioniert, wo eine normale Bridge mit brctl Probleme verursacht. Benötigt werden dazu die Programme parprouted und bcrelay. Gilbert Mendoza beschreibt ausführlich, wie man dieses Setup manuell einrichten kann. Zunächst müssen wir verschiedene Programme installieren:

sudo apt-get install parprouted uml-utilities bcrelay

Damit bei jedem Rechnerstart die Netzwerkinterfaces automatisch erstellt werden, habe ich ein Skript gebastelt, das die entsprechenden Netzwerkinterfaces, z.B. tap0 bereitstellt. Dieses Skript basiert auf der Vorarbeit von Jochem Kossen und der Anleitung von Dominic Edmonds. Zur Einrichtung müssen wir zunächst die Konfigurationsdatei erstellen und einrichten:

sudo mkdir /etc/virtualbox
sudo nano /etc/virtualbox/config

Diese Datei hat bei mir folgenden Inhalt:

HOST_IF="eth1"
HOST_IP="192.168.0.64"
VM_USER="markus"
USE_NAT="no"
TAPS="tap0 tap1"
USE_ARPBRIDGE="yes"
ARP_IPS="169.254.0.1/32 169.254.0.2/32"

Die Datei config muss nun natürlich angepasst werden. HOST_IF bezeichnet das Netzwerkinterfaces, mit dem die virtuellen Systeme verbunden werden sollen, die HOST_IP ist die entsprechene IP-Adresse des Hosts. Als VM_USER muss der Benutzer eingetragen werden, der die virtuellen Maschinen nutzt. USE_NAT wird auf no gesetzt, da ein Anbindung über NAT bei Proxy ARP nicht notwendig ist. Unter TAPS werden die zu erzeugenden tap-Netzwerkinterfaces durch ein Leerzeichen getrennt aufgelistet. USE_ARPBRIDGE setzen wir auf yes, denn wir wollen eine Proxy ARP Bridge erzeugen. Unter ARP_IPS listen wir die zu den tap-Interfaces zugehörigen IP-Adressen auf. Dazu muss man allerdings wissen, dass diese IP-Adressen keinerlei Bedeutung haben und eigentlich völlig beliebig sind. Man sollte jedoch darauf achten, dass die vergebenen IP-Adressen nicht mit denen im Netzwerksetup im Konflikt stehen. Ich verwende deshalb die oben angegebenen Microsoft IP-Adressen, die eigentlich von Windows vergeben werden, wenn kein DHCP-Server eine IP-Adresse zuweist.
Im nächsten Schritt erzeugen wir eine weitere Konfigurationsdatei, die die Namen derjenigen virtuellen Systeme enthält (jedes in einer Zeile), die automatisch gestartet werden sollen, wenn das System hochfährt. Ich persönlich habe hierauf verzichtet und erzeuge deshalb eine leere Datei.

sudo touch /etc/virtualbox/machines_enabled

Nun erzeugen wir das eigentlich Skript vboxcontrol, das die gesamte Arbeit erledigt mit

sudo nano /etc/init.d/vboxcontrol

Die Datei füllen wir mit folgendem Inhalt (alternativ kann man das Script herunterladen):

#! /bin/sh
### BEGIN INIT INFO
# Provides: virtualbox_vms
# Required-Start:    $local_fs $syslog $remote_fs
# Required-Stop:     $local_fs $syslog $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Control VirtualBox Virtual Machine instances
### END INIT INFO
#
# Modified by Markus Effinger, http://www.effinger.org
# based on
# Version 2008051100 by Jochem Kossen <jochem.kossen@gmail.com>
# http://farfewertoes.com
#
# Released in the public domain
#
# This file came with a README file containing the instructions on how
# to use this script.
#
 
. /lib/lsb/init-functions
 
# Are we running from init?
run_by_init() {
    ([ "$previous" ] && [ "$runlevel" ]) || [ "$runlevel" = S ]
}
 
################################################################################
# INITIAL CONFIGURATION
VBOXDIR="/etc/virtualbox"
VM_USER="root"
USE_NAT="yes"
USE_ARPBRIDGE="no"
 
export PATH="${PATH:+$PATH:}/bin:/usr/bin:/usr/sbin:/sbin"
 
if [ -f $VBOXDIR/config ]; then
    . $VBOXDIR/config
else
    echo "ERROR: $VBOXDIR/config does not exist. Exiting."
    exit 1
fi
 
SU="su $VM_USER -c"
VBOXMANAGE="VBoxManage -nologo"
PARPROUTEDBIN=`which parprouted`
BCRELAYBIN=`which bcrelay`
 
################################################################################
# FUNCTIONS
 
# Determine if USE_NAT is set to "yes"
use_nat() {
    if [ "$USE_NAT" = "yes" ]; then
        return `true`
    else
        return `false`
    fi
}
 
# Determine if USE_ARPBRIDGE is set to "yes"
use_arpbridging() {
    if [ "$USE_ARPBRIDGE" = "yes" ]; then
        return `true`
    else
        return `false`
    fi
}
 
# Bring up the bridge interface
enable_bridge() {
    # If NAT is enabled, don't do anything
    use_nat && return
 
    # If ARP Bridge is enabled, don't do anything
    use_arpbridging && return
 
    # Load the tun module
    if [ ! -e /dev/net/tun ]; then
        modprobe tun
    fi
 
    brctl addbr br0 || /bin/true
 
    # Disable $HOST_IF; host will use br0 instead
    ifdown $HOST_IF
    ifconfig $HOST_IF 0.0.0.0 promisc
    brctl addif br0 $HOST_IF
 
    # Bring up br0
    ifup br0
 
    # Answer ARP requests for $HOST_IP (which now come on br0) with the MAC
    # address of $HOST_IF
    arp -Ds $HOST_IP $HOST_IF pub
}
 
# Bring down the bridge interface
disable_bridge() {
    # If NAT is enabled, don't do anything
    use_nat && return
 
    ifdown br0
    brctl delbr br0
    ifup $HOST_IF
}
 
# Activate tap interfaces
enable_taps() {
    # If NAT is enabled, don't do anything
    use_nat && return
 
    # If ARP Bridge is enabled, don't do anything
    use_arpbridging && return
 
    for TAP in $TAPS; do
        # Check if $TAP is configured already
        ifconfig $TAP > /dev/null 2>&1
        if [ $? != 0 ]; then
            tunctl -t $TAP -u $VM_USER
            brctl addif br0 $TAP
 
            # Disable tap interfaces for host; guest will activate them for themselves
            ifconfig $TAP 0.0.0.0 promisc
 
            # Enable proxy_arp so that ARP requests can be answered correctly
            # by the host
            sysctl net.ipv4.conf.$TAP.proxy_arp=1
 
            # Add a route for the tap device
            route add -host $HOST_IP dev $TAP
        else
            log_failure_msg "Interface $TAP already configured"
        fi
    done
}
 
# Activate tap interfaces for ARP Bridging
enable_taps_arp() {
    # If ARP Bridge is disabled, don't do anything
    ! use_arpbridging && return
 
    # Enable routing that pakets can be transfered from $TAP to $HOST_IF
    # by the host
    sysctl net.ipv4.ip_forward=1
 
    # i contains the index of the current TAP device in the array of all TAP devices
    i=0
    for TAP in $TAPS; do
        # make sure that ARP_IP contains the corresponding IP of the interface TAP
        # j contains the index of the ip address in the array of all ip addresses
        j=0
        for ARP_IP in $ARP_IPS; do
           if [ $i = $j ]; then
              break
           fi
           j=$(( $j + 1 ))
        done
        i=$(( $i + 1 ))
 
        # Check if $TAP is configured already
        ifconfig $TAP > /dev/null 2>&1
        if [ $? != 0 ]; then
            tunctl -t $TAP -u $VM_USER
 
            # Disable tap interfaces for host; guest will activate them for themselves
            #ifconfig $TAP 0.0.0.0 promisc
            ip link set $TAP up
            ip addr add $ARP_IP dev $TAP
 
            # Enable proxy_arp so that ARP requests can be answered correctly
            # by the host
            sysctl net.ipv4.conf.$TAP.proxy_arp=1
 
            # Start parprouted for Proxy ARP Bridging
            start-stop-daemon --background --start --quiet --pidfile /var/run/parprouted.$TAP.pid \
               --exec $PARPROUTEDBIN -- $HOST_IF $TAP
 
            # Start relaying broadcasts - required for dhcp to work,
            # do not use the -d switch for bcrelay - start-stop-daemon would not work then
            start-stop-daemon --background --start --quiet --make-pidfile --pidfile /var/run/bcrelay.$TAP.pid \
               --exec $BCRELAYBIN -- -n -i $TAP -o $HOST_IF
 
        else
            log_failure_msg "Interface $TAP already configured"
        fi
    done
}
 
# Disable/deconfigure tap interfaces for ARP Bridging
disable_taps_arp() {
    # If ARP Bridge is disabled, don't do anything
    ! use_arpbridging && return
 
    #Delete all created tap interfaces and kill corresponding processes
    for TAP in $TAPS; do
        start-stop-daemon --stop --quiet --pidfile /var/run/parprouted.$TAP.pid \
           --exec $PARPROUTEDBIN
        start-stop-daemon --stop --quiet --pidfile /var/run/bcrelay.$TAP.pid \
           --exec $BCRELAYBIN
        tunctl -d $TAP
    done
}
 
# Disable/deconfigure tap interfaces
disable_taps() {
    # If NAT is enabled, don't do anything
    use_nat && return
 
    # If ARP Bridge is enabled, don't do anything
    use_arpbridging && return
 
    for TAP in $TAPS; do
        route del -host $HOST_IP dev $TAP
        brctl delif br0 $TAP
        tunctl -d $TAP
    done
}
 
# Check for running machines every few seconds; return when all machines are
# down
wait_for_closing_machines() {
    RUNNING_MACHINES=`$SU "$VBOXMANAGE list runningvms" | wc -l`
    if [ $RUNNING_MACHINES != 0 ]; then
        sleep 5
        wait_for_closing_machines
    fi
}
 
################################################################################
# RUN
case "$1" in
    start)
        if [ -f /etc/virtualbox/machines_enabled ]; then
            if [ ! use_nat ] && [ ! use_arpbridging ]; then
                enable_bridge
                enable_taps
 
                chown root.vboxusers /dev/net/tun
                chmod 0660 /dev/net/tun
            fi
 
            if [ use_arpbridging ]; then
                enable_taps_arp
                chown root.vboxusers /dev/net/tun
                chmod 0660 /dev/net/tun
            fi
 
            cat /etc/virtualbox/machines_enabled | while read VM; do
                log_action_msg "Starting VM: $VM ..."
                $SU "$VBOXMANAGE startvm \"$VM\" -type vrdp"
            done
        fi
        ;;
    stop)
        # NOTE: this stops all running VM's. Not just the ones listed in the
        # config
        $SU "$VBOXMANAGE list runningvms" | while read VM; do
            log_action_msg "Shutting down VM: $VM ..."
            $SU "$VBOXMANAGE controlvm \"$VM\" acpipowerbutton"
        done
 
        wait_for_closing_machines
 
        if [ ! use_nat ] && [ ! use_arpbridging ]; then
            disable_taps
            disable_bridge
        fi
 
        if [ use_arpbridging ]; then
            disable_taps_arp
        fi
        ;;
    bridge-up)
        enable_bridge
        ;;
    bridge-down)
        disable_bridge
        ;;
    taps-up)
        enable_taps
        ;;
    taps-down)
        disable_taps
        ;;
    taps-arp-up)
        enable_taps_arp
        ;;
    taps-arp-down)
        disable_taps_arp
        ;;
    start-vm)
        log_action_msg "Starting VM: $2 ..."
        $SU "$VBOXMANAGE startvm \"$2\" -type vrdp"
        ;;
    stop-vm)
        log_action_msg "Stopping VM: $2 ..."
        $SU "$VBOXMANAGE controlvm \"$2\" acpipowerbutton"
        ;;
    poweroff-vm)
        log_action_msg "Powering off VM: $2 ..."
        $SU "$VBOXMANAGE controlvm \"$2\" poweroff"
        ;;
    status)
        log_action_msg "The following virtual machines are currently running:"
        $SU "$VBOXMANAGE list runningvms" | while read VM; do
            echo -n "$VM ("
            echo -n `$SU "VBoxManage showvminfo $VM|grep Name:|sed -e 's/^Name:\s*//g'"`
            echo ')'
        done
        ;;
    *)
        log_failure_msg "Usage: $0 {start|stop|status|start-vm <VM name>|stop-vm <VM name>|poweroff-vm <VM name>|bridge-up|bridge-down|taps-up|taps-down}"
        exit 3
esac
 
exit 0

Nach dem Speichern der Datei setzen wir noch entsprechende Dateiberechtigungen und sorgen dafür, dass dieses Skript in den Startvorgang des Systems aufgenommen wird:

sudo chown root.root /etc/init.d/vboxcontrol
sudo chmod 755 /etc/init.d/vboxcontrol
sudo update-rc.d vboxcontrol defaults 99 10

Damit wir in Virtualbox gleich loslegen können, starten wir das Skript durch direkten Aufruf mit

sudo /etc/init.d/vboxcontrol start

Bei der virtuellen Maschine passen wir unter dem Punkt Netzwerk folgende Punkte an:
Angeschlossen an: Hostinterface
Name des Interfaces: tap0 (also eines der Interfaces, welches oben unter TAPS angegeben wurde)

Sehr praktisch an dem vboxcontrol Skript ist, dass beim Herunterfahren des Systems oder dem Aufruf des Skripts mit dem Parameter stop alle laufenden virtuellen Maschinen ordnungsgemäß heruntergefahren werden. Das Wort alle habe ich deswegen kursiv hervorgehoben, da nicht nur die
/etc/virtualbox/machines_enabled gelisteten Maschinen heruntergefahren werden.

12 comments to Virtualbox und Intrepid – das perfekte Setup – Netzwerk

  • hey ich schulde dir was, ich hab ewig nach einer Möglichkeit gesucht meine VM’s ins gleiche Netz wie meinen Desktop zu kriegen, bisher endete das immer mit dem wiederherstellen der Netzwerkkonfiguration ^^

    Aber noch ne Frage: da ja nur 2 tap interfaces hochgebracht werden kann ich auch nur 2 VM’s gleichzeitig in meinem Netz haben oder?

  • @mw88: Du kannst die Liste der TAP-Interfaces beliebig erweitern – es sind also mehr als 2 virtuelle Interfaces möglich. Einfach die Variablen TAPS und ARP_IPS entsprechend ergänzen. Meine Konfiguration mit zwei Interfaces ist nur ein Beispiel.

  • pidi

    Wie siehts performance-technisch aus?
    Ich habe 2 Gigabit-Netzwerkkarten und möchte die Geschw. auch nutzen.
    Ist die ARP-Bridge schnell genug dafür?

  • @pidi: Also die Alternative zu Proxy ARP (oder ARP Bridge) ist es, eine Netzwerkbrücke mit brctl zu erstellen. Wenn man so beispielsweise eine br0 Bridge zwischen den Interfaces eth0 und tap0 erstellt, dann wird der gesamte Traffic, der an eth0 ankommt auch an tap0 weitergegeben und umgekehrt. Bei Proxy ARP wird dagegen geroutet, d.h. nur der Traffic, der auch für tap0 bestimmt ist, wird auch dorthin weitergegeben. Theoretisch sollte Proxy ARP also schneller sein. Aber Probieren geht bekanntlich über Studieren..
    Zur Erläuterung noch ein Beispiel: Du hast einen Server und an dessen Netzwerkkarte eth0 sind über einen Hub/Switch weitere Rechner angeschlossen, die über den Server ins Internet gehen. An tap0 hast du Virtualbox angeschlossen. Wenn du jetzt mit brctl eine Brücke zwischen eth0 und tap0 erstellst, kommt auf tap0 auch der Traffic von den anderen Netzwerkrechnern an und du könntest sogar deren Internetnutzungsverhalten protokollieren. Bei Proxy ARP dagegen kommt an tap0 tatsächlich nur der Traffic an, der für Virtualbox bzw. dessen IP bestimmt ist.

  • pidi

    Um die Arbeit auf mehr als eine reale Netzwerkkarte zu verteilen, bräuchte man mehr als eine Route.
    Gibt es eine Möglichkeit dieses Skript so zu modifizieren, dass man eth0 mit tap0 und eth1 mit tap1 verbinden kann?

    Vielen Dank für dieses Skript; dieses erspart mir eine Menge Zeit und Mühe…

  • pidi

    Ich bekomme in der VM eine IP vom DHCP,
    kann aber keine pings machen und komme auch nicht ins inet.
    Hat jemand eine Idee?

    • Wenn du eine IP bekommst, heißt das, dass bcrelay funktioniert. Du solltest aber auf jeden Fall forwarding aktivieren. Falls das nicht hilft, würde ich mal auf eine Firewall auf deinem Rechner tippen. Versuch mal von deiner VM das Hostsystem anzupingen und umgekehrt.

    • Habe selber gerade das gleiche Problem gehabt, dass das Pingen von Gast zu Host und umgekehrt funktionierte, aber kein Routing. In der syslog war außerdem Folgendes zu lesen:

      parprouted[10718]: error: ioctl SIOCGIFADDR for eth1: Cannot assign requested address

      Bei mir war letztlich die Eintragung des falschen Netzwerkinterfaces Schuld. Nach dem Ändern des Hostinterfaces in /etc/virtualbox/config unter dem Parameter HOST_IF auf eth0, hat es bei mir dann einwandfrei geklappt.

  • ich hab da genau das gleiche Problem, bei mir ist das forwarding aktiviert, ich kann auch im Heimnetz pingen aber nicht raus, dabei löst die VM anscheinend den Hostnamen korrekt auf…

    Screenshot: http://www.mw88.org/bilder/main.php?g2_itemId=460

    • Hast du eine Firewall laufen, z.B. ufw? Im Fall von ufw auf deinem Hostsystem würde ich mal ein sudo ufw disable ausführen und nochmal testen. Falls es nicht funktioniert, kannst du immer noch mit einem sudo ufw enable die Firewall reaktivieren. Die Standardeinstellungen von ufw legen iptables-Regeln an, die Forwarding blocken.

  • werd ich heute Abend mal testen, gute Idee ^^

  • […] man wie ich VirtualBox über Proxy ARP auf das Netzwerk zugreifen lässt, sollte man in der Datei /etc/default/ufw in folgender Zeile das […]

Leave a Reply to Markus Effinger Cancel reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>