martes, 2 de diciembre de 2008

VirtualBox. Configurar la red en Linux.

Cuando se instala una máquina virtual con VirtualBox, la tarjeta de red se configura en modo NAT, que no dispone de funciones avanzadas de red y, por lo tanto, las prestaciones de la interfaz de red son muy limitadas. Con este modo, VirtualBox utiliza su propio enrutador y DHCP, permitiendo salir a internet desde la máquina virtual, pero impidiendo, entre otras acciones, comunicarnos con el equipo anfitrión o, si tenemos dos máquinas virtuales en el mismo equipo anfitrión, comunicarse entre ellas. Para conocer las limitaciones que tenemos con esta configuración, se puede consultar la ayuda de VirtualBox: Virtual networking -> Networking Address Translation -> NAT limitations.

En este artículo se va a configurar la tarjeta de red de la máquina virtual para que no tengamos estas limitaciones y, por ejemplo, podamos conectarnos con el equipo anfitrión y comunicar dos o más máquinas virtuales creadas en el mismo equipo anfitrión.

La correcta configuración consiste en crear un bridge (puente) para unir las interfaces de red del equipo anfitrión y de la máquina o máquinas virtuales. Vamos a ello (recuerdo que el equipo anfitrión tiene instalado una distribución de Linux; en mi caso, Linux Ubuntu 8.04).

Todas las operaciones las vamos a realizar desde un terminal. Al ser tareas administrativas, vamos a ejecutar la orden sudo su y escribir nuestra contraseña para no tener que escribir sudo delante de cada orden.

La configuración inicial de la tarjeta de red del equipo anfitrión podemos consultarla en el archivo /etc/network/interfaces:

root@elnuevo:/home/coralio# cat /etc/network/interfaces

auto lo

iface lo inet loopback

auto eth0

iface eth0 inet dhcp


Las líneas referentes a la interfaz eth0 pueden no estar incluidas en este archivo si estamos utilizando el modo itinerante.

Si ejecutamos la orden ifconfig, se visualizará la información sobre las tarjetas de red:

root@elnuevo:/home/coralio# ifconfig

eth0 Link encap:Ethernet direcciónHW 00:1d:72:07:df:f0

inet dirección:192.168.1.33 Difusión:192.168.1.255 Máscara:255.255.255.0

dirección inet6: fe80::21d:72ff:fe07:dff0/64 Alcance:Vínculo

ARRIBA DIFUSIÓN CORRIENDO MULTICAST MTU:1500 Métrica:1

RX packets:9 errors:0 dropped:0 overruns:0 frame:0

TX packets:40 errors:0 dropped:0 overruns:0 carrier:0

colisiones:0 txqueuelen:1000

RX bytes:1254 (1.2 KB) TX bytes:6028 (5.8 KB)

Interrupción:16


lo Link encap:Bucle local

inet dirección:127.0.0.1 Máscara:255.0.0.0

dirección inet6: ::1/128 Alcance:Anfitrión

ARRIBA LOOPBACK CORRIENDO MTU:16436 Métrica:1

RX packets:1252 errors:0 dropped:0 overruns:0 frame:0

TX packets:1252 errors:0 dropped:0 overruns:0 carrier:0

colisiones:0 txqueuelen:0

RX bytes:62600 (61.1 KB) TX bytes:62600 (61.1 KB)


Para crear y utilizar el bridge hay que descargar e instalar el paquete bridge-utils:

root@elnuevo:/home/coralio# apt-get install bridge-utils

Este software nos instala las utilidades necesarias para administrar el bridge. Si ejecutamos la orden brctl se muestran algunas de estas utilidades:

root@elnuevo:/home/coralio# brctl

La siguiente acción a realizar es crear el bridge:

root@elnuevo:/home/coralio# brctl addbr br0


A continuación, hay que crear la interfaz virtual que se utilizará desde la máquina virtual (esta acción se realiza con la orden VBoxAddIF que proporciona VirtualBox; se puede consultar la ayuda de VirtualBox para más información sobre estas órdenes):

root@elnuevo:/home/coralio# VBoxAddIF vbox0 coralio br0

VirtualBox host networking interface creation utility, version 1.6.0

(C) 2005-2007 Sun Microsystems, Inc.

All rights reserved.


Creating the permanent host networking interface "vbox0" for user coralio.


La orden VBoxAddIF crea la interfaz virtual vbox0 que utilizará la máquina virtual, asigna permisos al usuario coralio para utilizar la interfaz (esto significa que esta interfaz no podrá utilizarla otro usuario) y la enlaza con el bridge br0 creado previamente.

Si queremos utilizar otra máquina virtual en el mismo equipo anfitrión, hay que crear otra interfaz virtual para esta nueva máquina, ya que cada máquina virtual debe disponer de su propia interfaz virtual. En la siguiente orden se crea la interfaz virtual vbox1 para que sea utilizada por el usuario coralio y se añade al bridge br0 creado anteriormente:

root@elnuevo:/home/coralio# VBoxAddIF vbox1 coralio br0

VirtualBox host networking interface creation utility, version 1.6.0

(C) 2005-2007 Sun Microsystems, Inc.

All rights reserved.


Creating the permanent host networking interface "vbox1" for user coralio.


Podemos ver la configuración del bridge con las dos interfaces virtuales que se le han añadido ejecutando la siguiente orden:

root@elnuevo:/home/coralio# brctl show

bridge name bridge id STP enabled interfaces

br0 8000.00ff09719902 no vbox0

vbox1


La siguiente acción es modificar el archivo /etc/network/interfaces para que la configuración del bridge y de las tarjetas de red real y virtuales tenga efecto cuando se encienda el sistema o se reinicie el servicio networking. El contenido de este archivo sería el siguiente:

root@elnuevo:/home/coralio# gedit /etc/network/interfaces

auto lo

iface lo inet loopback


auto eth0

iface eth0 inet dhcp


auto br0

iface br0 inet dhcp

bridge_ports eth0 vbox0 vbox1


El bloque relativo al bridge br0 obtiene la dirección IP para br0 del servicio DHCP e indica que toda la información que entre o salga por las interfaces eth0, vbox0 y vbox1 se dirigirá al bridge.

Para que todo funcione hay que levantar el bridge y reiniciar el servicio networking:

root@elnuevo:/home/coralio# ifconfig br0 up


root@elnuevo:/home/coralio# /etc/init.d/networking restart


Con esta configuración todo debería funcionar correctamente, pero no es así. El problema es que, tanto la tarjeta de red real como las virtuales, funcionan de forma intermitente: unas veces sí y otras veces no. Si ejecutamos la orden ifconfig veremos la configuración que hemos realizado:

root@elnuevo:/home/coralio# ifconfig

br0 Link encap:Ethernet direcciónHW 00:ff:09:71:99:02

inet dirección:192.168.1.33 Difusión:192.168.1.255 Máscara:255.255.255.0

dirección inet6: fe80::2ff:9ff:fe71:9902/64 Alcance:Vínculo

ARRIBA DIFUSIÓN CORRIENDO MULTICAST MTU:1500 Métrica:1

RX packets:0 errors:0 dropped:0 overruns:0 frame:0

TX packets:25 errors:0 dropped:0 overruns:0 carrier:0

colisiones:0 txqueuelen:0

RX bytes:0 (0.0 B) TX bytes:5534 (5.4 KB)


eth0 Link encap:Ethernet direcciónHW 00:1d:72:07:df:f0

inet dirección:192.168.1.33 Difusión:192.168.1.255 Máscara:255.255.255.0

dirección inet6: fe80::21d:72ff:fe07:dff0/64 Alcance:Vínculo

ARRIBA DIFUSIÓN CORRIENDO MULTICAST MTU:1500 Métrica:1

RX packets:15 errors:0 dropped:0 overruns:0 frame:0

TX packets:43 errors:0 dropped:0 overruns:0 carrier:0

colisiones:0 txqueuelen:1000

RX bytes:1826 (1.7 KB) TX bytes:6379 (6.2 KB)

Interrupción:16

lo Link encap:Bucle local

inet dirección:127.0.0.1 Máscara:255.0.0.0

dirección inet6: ::1/128 Alcance:Anfitrión

ARRIBA LOOPBACK CORRIENDO MTU:16436 Métrica:1

RX packets:1270 errors:0 dropped:0 overruns:0 frame:0

TX packets:1270 errors:0 dropped:0 overruns:0 carrier:0

colisiones:0 txqueuelen:0

RX bytes:63500 (62.0 KB) TX bytes:63500 (62.0 KB)


vbox0 Link encap:Ethernet direcciónHW 00:ff:09:71:99:02

dirección inet6: fe80::2ff:9ff:fe71:9902/64 Alcance:Vínculo

ARRIBA DIFUSIÓN CORRIENDO MULTICAST MTU:1500 Métrica:1

RX packets:0 errors:0 dropped:0 overruns:0 frame:0

TX packets:0 errors:0 dropped:25 overruns:0 carrier:0

colisiones:0 txqueuelen:500

RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)


vbox1 Link encap:Ethernet direcciónHW 00:ff:ca:ec:c2:8c

dirección inet6: fe80::2ff:caff:feec:c28c/64 Alcance:Vínculo

ARRIBA DIFUSIÓN CORRIENDO MULTICAST MTU:1500 Métrica:1

RX packets:0 errors:0 dropped:0 overruns:0 frame:0

TX packets:0 errors:0 dropped:25 overruns:0 carrier:0

colisiones:0 txqueuelen:500

RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)


Después de probar varias configuraciones, he llegado a la conclusión de que el problema surge porque la tarjeta de red real (eth0) y el bridge (br0) comparten la misma dirección IP (podemos verlas en la salida anterior de la orden ifconfig).

La solución que he encontrado consiste en levantar la interfaz eth0 sin asignarle ninguna dirección IP y que sólo el bridge br0 obtenga la dirección IP. El nuevo contenido del archivo /etc/network/interfaces sería el siguiente:

root@elnuevo:/home/coralio# gedit /etc/network/interfaces

auto lo

iface lo inet loopback


auto eth0

iface eth0 inet manual


auto br0

iface br0 inet dhcp

bridge_ports eth0 vbox0 vbox1


El único cambio que he realizado en este archivo es cambiar la línea iface eth0 inet dhcp por la línea iface eth0 inet manual, consiguiendo así que la interfaz eth0 se levante pero no se le asigne ninguna dirección IP. Esta configuración la he estado probando con dos máquinas virtuales (con arranque dual en Windows y Linux las dos) más el equipo anfitrión y ha funcionado de forma estable durante bastantes días.

Para que esta configuración tenga efecto, hay que reiniciar el servicio networking:

root@elnuevo:/home/coralio# /etc/init.d/networking restart


Si ejecutamos la orden ifconfig veremos que todas las interfaces están levantadas pero la interfaz eth0 no tiene dirección IP:

root@elnuevo:/home/coralio# ifconfig

br0 Link encap:Ethernet direcciónHW 00:1d:72:07:df:f0

inet dirección:192.168.1.33 Difusión:192.168.1.255 Máscara:255.255.255.0

dirección inet6: fe80::21d:72ff:fe07:dff0/64 Alcance:Vínculo

ARRIBA DIFUSIÓN CORRIENDO MULTICAST MTU:1500 Métrica:1

RX packets:8 errors:0 dropped:0 overruns:0 frame:0

TX packets:27 errors:0 dropped:0 overruns:0 carrier:0

colisiones:0 txqueuelen:0

RX bytes:1042 (1.0 KB) TX bytes:4565 (4.4 KB)


eth0 Link encap:Ethernet direcciónHW 00:1d:72:07:df:f0

dirección inet6: fe80::21d:72ff:fe07:dff0/64 Alcance:Vínculo

ARRIBA DIFUSIÓN CORRIENDO MULTICAST MTU:1500 Métrica:1

RX packets:8 errors:0 dropped:0 overruns:0 frame:0

TX packets:27 errors:0 dropped:0 overruns:0 carrier:0

colisiones:0 txqueuelen:1000

RX bytes:1186 (1.1 KB) TX bytes:4697 (4.5 KB)

Interrupción:16


lo Link encap:Bucle local

inet dirección:127.0.0.1 Máscara:255.0.0.0

dirección inet6: ::1/128 Alcance:Anfitrión

ARRIBA LOOPBACK CORRIENDO MTU:16436 Métrica:1

RX packets:1288 errors:0 dropped:0 overruns:0 frame:0

TX packets:1288 errors:0 dropped:0 overruns:0 carrier:0

colisiones:0 txqueuelen:0

RX bytes:64400 (62.8 KB) TX bytes:64400 (62.8 KB)


vbox0 Link encap:Ethernet direcciónHW 00:ff:09:71:99:02

dirección inet6: fe80::2ff:9ff:fe71:9902/64 Alcance:Vínculo

ARRIBA DIFUSIÓN CORRIENDO MULTICAST MTU:1500 Métrica:1

RX packets:0 errors:0 dropped:0 overruns:0 frame:0

TX packets:0 errors:0 dropped:55 overruns:0 carrier:0

colisiones:0 txqueuelen:500

RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)


vbox1 Link encap:Ethernet direcciónHW 00:ff:ca:ec:c2:8c

dirección inet6: fe80::2ff:caff:feec:c28c/64 Alcance:Vínculo

ARRIBA DIFUSIÓN CORRIENDO MULTICAST MTU:1500 Métrica:1

RX packets:0 errors:0 dropped:0 overruns:0 frame:0

TX packets:0 errors:0 dropped:33 overruns:0 carrier:0

colisiones:0 txqueuelen:500

RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)


Si vemos la configuración del bridge, obtendremos la siguiente salida:

root@elnuevo:/home/coralio# brctl show

bridge name bridge id STP enabled interfaces

br0 8000.001d7207dff0 no eth0

vbox0

vbox1


Esta salida indica que las interfaces eth0, vbox0 y vbox1 están utilizando el puente br0.

Seguidamente, hay que asignar permisos a los usuarios sobre el directorio /dev/net/tun que utiliza el sistema para gestionar las interfaces virtuales.

root@elnuevo:/home/coralio# chmod 0666 /dev/net/tun


Para finalizar, hay que indicar en la configuración de la red de la máquina virtual (desde VirtualBox) que se va a utilizar la configuración de la interfaz anfitrión y la interfaz virtual que se ha creado. Esta acción se muestra en la ventana de la Figura 1.

Figura 1

En esta ventana se ha seleccionado la opción Interface Anfirtión en el apartado Conectar a y se ha incluido vbox0 en el apartado Nombre de la Interface. Para la segunda máquina virtual habría que incluir vbox1 en el apartado Nombre de la Interface y mantener el resto de parámetros de la Figura 1.

Si sólo se va a utlizar una máquina virtual en el equipo anfitrión, habría que omitir toda la configuración realizada para la interfaz virtual vbox1.

Conviene recordar que el usuario que va a ejecutar las máquinas virtuales debe ser miembro del grupo vboxusers.

Un último apunte. Si vamos a utilizar las máquinas virtuales con otros usuarios, hay que crear las interfaces virtuales para estos usuarios. Hay que tener en cuenta que el permiso de utilización de la interfaz virtual se asigna cuando es creada, utilizando la orden VBoxAddIF vbox0 coralio br0. Por ejemplo, si el usuario pepe utilizara una máquina virtual, no podría usar las interfaces virtuales creadas para otro usuario y tendría que utilizar la suya propia. Para ello, habría que ejecutar la orden VBoxAddIF vbox2 pepe br0. Además, en la configuración de red de su máquina virtual (Figura 1), habría que incluir vbox2 en el apartado Nombre de la Interface. No olvidar modificar el archivo /etc/network/interfaces y añadir la interfaz vbox2 en el bloque de la interfaz bridge br0, quedando como sigue: bridge_ports eth0 vbox0 vbox1 vbox2.

Como no podía se de otra forma, Sun Microsystems, a partir de la versión 2.1.2 de VirtualBox, ha simplificado esta configuración de la red. En este artículo he publicado el nuevo método.

1 comentario:

Arturo dijo...

Buena currada, enhorabuena!!!. Yo lo hago de otra forma, pero esta me parece igualmente interesante, lo probaré. Gracias por todo, Arturo.