Lo hice y lo entendí

El blog de Vicente Navarro
04 dic

Host Interface Networking en VirtualBox sobre Debian/Ubuntu

Hay que reconocer que VMWare resulta bastante más cómodo que VirtualBox a la hora de usar interfaces en el sistema guest conectados directamente al interfaz de red del sistema host (es decir, no mediante NAT ni mediante una red privada entre el guest y el host). Mientras que con una instalación estándar de VMWare Server en Linux ya puedes usar un interfaz así en el asistente de configuración, con VirtualBox, no podemos hacerlo sin usar interfaces bridge e interfaces TAP. A cambio, dispondremos de más versatilidad a la hora de configurar la red.

El manual de VirtualBox denomina a esta forma de configurar la red entre el guest y el host Host Interface Networking (HIF). En su sección “6.8 Host Interface Networking and bridging on Linux hosts“, “6.8.1.1 Debian and Ubuntu hosts“, el manual nos detalla cómo conseguir configurar el sistema host para que el sistema guest pueda acceder a sus interfaces. Básicamente, los comandos que nos propone ejecutar en el host son:

1. sudo apt-get install bridge-utils

2. Añadir al fichero /etc/network/interfaces:

auto br0
   iface br0 inet dhcp
   bridge_ports eth0

3. sudo /etc/init.d/networking restart

4. sudo VBoxAddIF vbox0 <user> br0

Bueno, pues haciendo eso, lo que conseguiremos será perder la conectividad en el host y no tendremos red ni en el sistema real ni en el virtual.

Como sí que nos explica bien el manual de Ubuntu de VirtualBox en su sección de networking, sólo falta un detalle para que todo funcione bien, y es especificar que el interfaz real del sistema host lo pongamos a manual en el fichero /etc/network/interfaces, no a automático, que es lo que normalmente se tiene por defecto:

auto eth0
iface eth0 inet manual

auto br0
iface br0 inet dhcp
   bridge_ports eth0

Haciendo esto, sí que nos funcionará bien la red en el sistema real y en el virtual.

Pero, ¿de qué va todo esto? ¿Qué es el interfaz br0? ¿Y en qué consiste el interfaz vbox0?

Los interfaces brX son interfaces de bridge. Usando Linux, si tuviéramos un PC con, digamos, 8 interfaces de red, podríamos hacer que el sistema se comportara como un switch de red típico implementando el protocolo 802.1d. Para ello, lo que haríamos sería crear un interfaz de bridge:

$ sudo brctl addbr br4

y especificar qué interfaces de red formarán el bridge:

$ sudo brctl addif br4 eth0
$ sudo brctl addif br4 eth1
$ sudo brctl addif br4 eth2

y podríamos consultar los interfaces que forman parte de cada bridge:

$ sudo brctl show
bridge name	bridge id		STP enabled	interfaces
br0		8000.0011d8c4595e	no		eth0
							eth1
							eth2

A partir de este momento, los tres interfaces están unidos internamente igual que lo estarían cada una de las bocas de un switch. El uso de Linux como un switch está documentado en The Linux Foundation:Net:Bridge, y de esa documentación, lo que más nos interesa es ver que es muy importante que los interfaces que forman parte del bridge no se han de levantar, no se les ha de asignar IP y no deben de recibir una por DHCP, justo lo que olvidó decirnos el manual oficial de VirtualBox:

Before you start make sure both network cards are set up and working properly. Don’t set the IP address, and don’t let the startup scripts run DHCP on the ethernet interfaces either. The IP address needs to be set after the bridge has been configured.

The command ifconfig should show both network cards, and they should be DOWN.

Con estas líneas en el /etc/network/interfaces

auto eth0
iface eth0 inet manual

auto br0
iface br0 inet dhcp
   bridge_ports eth0

el script /etc/network/if-pre-up.d/bridge del paquete bridge-utils podrá, en el momento de crear el interfaz br0, formar un bridge formado, de momento, sólo por eth0.

Es interesante notar, además, que una línea como bridge_ports eth0 será pasada a los scripts de /etc/network/if-*.d en forma de una variable de entorno llamada IF_BRIDGE_PORTS. Del “man interfaces“:

       Additionally,  all  options given in an interface definition stanza are
       exported to the environment in upper case with "IF_" prepended and with
       hyphens   converted  to  underscores  and  non-alphanumeric  characters
       discarded.

Bueno, pues con esta configuración hemos creado un bridge de un solo interfaz. Ahora, al arrancar, el interfaz br0 será el principal, obtendrá IP por DHCP y el eth0 ni siquiera tendrá IP, pero la red funcionará con normalidad:

$ ifconfig
br0       Link encap:Ethernet  HWaddr 00:11:d8:c4:59:5e  
          inet addr:192.168.2.43  Bcast:192.168.2.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1469100 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1258316 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:2117375236 (2.1 GB)  TX bytes:101712367 (101.7 MB)

eth0      Link encap:Ethernet  HWaddr 00:11:d8:b4:49:5e  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1469308 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1258590 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:2138248612 (2.1 GB)  TX bytes:106803712 (106.8 MB)
          Interrupt:23 Base address:0x4000 

La idea es ahora añadir al bridge un interfaz TAP para que el interfaz de red y el TAP compartan acceso. Un interfaz TAP es un interfaz virtual soportado por un driver disponible para muchas plataformas diferentes (Linux, Solaris, Windows, MacOSX, etc.) que no tiene un interfaz de red hardware real por debajo. Aunque los interfaces TAP tienen multitud de aplicaciones diferentes, como la creación de túneles para VPN y su uso como interfaces de apoyo al host networking en entornos de virtualización (como VirtualBox, QEMU o User Mode Linux). Las utilidades para configurar los interfaces TAP están, precisamente, en el paquete uml-utilities.

Con el paquete uml-utilities instalado, tendremos acceso al comando tunctl, que es el que nos permitirá añadir interfaces TAP y además, asignárselos a un usuario, para que éste pueda usarlo, por ejemplo, creando un túnel o al virtualizar un sistema:

$ sudo tunctl -t vic_tap0 -u vicente
Set 'vic_tap0' persistent and owned by uid 1000

A este interfaz podríamos incluso ponerle una IP y hacerle ping:

$ sudo ifconfig vic_tap0 23.45.67.89 netmask 255.255.255.0 up

$ ifconfig vic_tap0
vic_tap0  Link encap:Ethernet  HWaddr 8e:24:59:69:82:bd  
          inet addr:23.45.67.89  Bcast:23.45.67.255  Mask:255.255.255.0
          inet6 addr: fe80::8c24:59ff:fe69:82bd/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:22 overruns:0 carrier:0
          collisions:0 txqueuelen:500 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

$ ping 23.45.67.89
PING 23.45.67.89 (23.45.67.89) 56(84) bytes of data.
64 bytes from 23.45.67.89: icmp_seq=1 ttl=64 time=0.065 ms
64 bytes from 23.45.67.89: icmp_seq=2 ttl=64 time=0.056 ms

Pero si, en cambio, añadimos ese nuevo interfaz TAP al bridge br0 (sin IP, que el ejemplo anterior era sólo una demostración), ¡lo podremos usar dentro de VirtualBox para que tenga acceso completo a la red del host!

$ sudo brctl addif br0 vic_tap0

$ sudo brctl show
bridge name	bridge id		STP enabled	interfaces
br0		8000.0011d8c4595e	no		eth0
							vic_tap0

Y justamente esto es lo que hace el script VBoxAddIF. Cuando ejecutamos:

VBoxAddIF vbox0 <user> br0

el script crea con VBoxTunctl (similar al tunclt, pero al incluir una versión propia, VirtualBox no depende del paquete uml-utilities) un interfaz TAP llamado vbox0, que puede usar user, y añadirlo al bridge br0 con brctl. Además, añade una línea en /etc/vbox/interfaces:

$ cat /etc/vbox/interfaces 
# This file is for registering VirtualBox permanent host networking interfaces
# and optionally adding them to network bridges on the host.
# Each line should be of the format <interface name> <user name> [<bridge>].

vbox0 vicente br0

para que el script de arranque /etc/init.d/vboxnet cree el interfaz TAP durante el arranque de la máquina.

Si quisiéramos prescindir de las utilidades propietarias de VirtualBox, podríamos crear el interfaz a mano como hemos hecho antes. Si además quisiéramos que se configure todo durante el arranque automáticamente, pondríamos esta configuración en el /etc/network/interfaces:

auto eth0
iface eth0 inet manual

auto tap0
iface tap0 inet manual
   up ifconfig $IFACE 0.0.0.0 up
   down ifconfig $IFACE down
   tunctl_user vicente

auto br0
iface br0 inet dhcp
   bridge_ports eth0 tap0

Fijémonos en que ahora sí que ponemos ambos interfaces en el bridge:

bridge_ports eth0 tap0

Igual que habíamos visto antes con la línea bridge_ports y la variable IF_BRIDGE_PORTS, la línea tunctl_user crea una variable IF_TUNCTL_USER que usa el script /etc/network/if-pre-up.d/uml-utilities de las uml-utilities, que vemos que apenas hace un tunctl y le pone los permisos adecuados al fichero de dispositivo /dev/net/tun:

$ cat /etc/network/if-pre-up.d/uml-utilities
#!/bin/sh

test -x /usr/sbin/tunctl || exit 0
test -n "${IF_TUNCTL_USER}" || exit 0

/usr/sbin/tunctl -u "${IF_TUNCTL_USER}" -t "${IFACE}"

#
# why the hell does this need to be done?
#
chown root:uml-net /dev/net/tun
chmod 660 /dev/net/tun

Por eso, si tenemos instaladas las uml-utilities, los usuarios que vayan a usar VirtualBox deben pertenecer al grupo uml-net o no podrán acceder a los interfaces TAP.

Actualización 20/12/08: Tal y como apuntan en los comentarios, la versión 2.1 de VirtualBox lleva como nueva característica:

New Host Interface Networking implementations for Windows and Linux hosts with easier setup (replaces TUN/TAP on Linux and manual bridging on Windows)

Además, lo acabo de probar y funciona muy bien. Por tanto, lo que hemos visto aquí, ya no será necesario, pero al menos nos sirve de referencia sobre los interfaces bridge y TUN/TAP.

:wq

Entradas relacionadas

17 Comentarios a “Host Interface Networking en VirtualBox sobre Debian/Ubuntu”

  • Senpai dice:

    Hola Vicente:
    Gracias, muy instructivo, aunque yo como novato en Linux no me entero mucho, ahora comprendo mejor lo que he hecho siguiendo este manual:
    http://danieljay20.wordpress.com/2007/12/26/configuracion-de-red-con-ips-estaticas-en-virtualbox/
    Yo utilizo windows virtualizado desde mi Ubuntu para poder seguir con mis traducciones de programas y me gusta tener las IPs fijas, pero el problema es que tengo en Ubuntu el Cortafuegos activado con Gufw, pero eso me impide conectarme a internet con mi maquina virutal, no se los puertos que utiliza VirtualBox para ello, y no he encontrado nada en internet para saber como configurar ese cortafuegos, ni siquiera en su web me han contestado…
    ¿Puedes darme una idea de como puedo hacerlo?

    Gracias de antemano

  • Kaster dice:

    Genial!!

    estos días estaba penando precisamente: ya podría Supercoco sacar un post sobre VirtualBox Hosted Networking…y mira que sorpresa..

    Muchas gracias por las explicaciones, me tenía harto el dichoso NAT…

  • @Senpai ¡Gracias! Desafortunadamente, no conozco el Gufw, por lo que no puedo ofrecerte ayuda. Sin embargo, sí que estoy casi seguro de que no es un tema de puertos. VirtualBox no usa unos puertos concretos, sino que deja que el sistema operativo virtualizado use el interfaz TAP del host si éste está configurado como describe la entrada.

    @Kaster Vaya, pues me alegro mucho de haber podido ser de ayuda de forma tan acertada:-)

  • Alfonso dice:

    Muy interesante el artículo. Quería preguntar algo. He leido por ahí algo que no acabo de entender. Se trata de las desventajas de crear el bridge en el arranque como lo has hecho en el artículo. Según parece tiene desventajas como p.e. que no se podrían utilizar utilidades “wakeup on lan” y otras pero que no enumeran. Por ello recomiendan crear scripts para lanzar antes de poner en marcha la máquina virtual y al finalizar volver el sistema a su estado inicial con otro script. Alguien me puede aclarar algo de esto.

    Saludos.

  • @Alfonso Yo lo que sí que he notado es que el arranque tarda un poco más, ya que se para unos segundos en la configuración de los interfaces. Si no me equivoco, es por lo que en algunos sitios recomiendan hacer un “brctl setfd br0 0“, como en Net: Bridge: DHCP through a bridge.

    Si quieres levantar el bridge sólo cuando vayas a usar VirtualBox, si usas Ubuntu, tienes que deshabilitar antes el “Network Manager”, ese applet del área de notificaciones que te autoconfigura todos los interfaces. Si no lo haces, el applet intentará cargarle una IP por DHCP al interfaz real. A continuación, puedes usar el siguiente script que a mí me funciona bien (tendrás que adaptarlo a tus necesidades por el nombre de usuario y el nombre de los interfaces):

    #!/bin/sh
    tunctl -u vicente -t tap0
    brctl addbr br0
    brctl addif br0 eth0 tap0
    ifconfig eth0 0.0.0.0 up
    ifconfig tap0 0.0.0.0 up
    ifconfig br0 up
    dhclient br0

    ¡Espero que te sirva!

  • Berto dice:

    Ayer me salvaste el día..jejje. Llevaba un par de días casualmente metido con esto del virtualbox, que ya había probado antes, pero ahora me hacia falta tener varias maquinas virtuales en red: con internet, que se vieran entre ellas, y mejor si podía acceder a ellas tb desde mi maquina host (la que virtualiza); había visto algo en un par de sitios y sabia que no era del todo sencillo, sobretodo si no das con la lectura adecuada, y como tu muy bien dices la lectura de la documetación oficial tampoco aclara mucho las cosas, y para mi gusto esta incompleta. Pues bien; Tener maquinas con internet (una tarjeta de red del tipo NAT) y que se vieran entre ellas (otra tarjeta del tipo “red interna”,) era sencillo, pero para ver servicios en las maquinas virtualizadas necesitaba configurar el bridge virtual y los interfaces de red virtuales; al final todo lo que leía estaba un poco confuso, al final probando llegue a los mismos pasos que tu (mas o menos), pero sin estar seguro de que lo hacia bien, y como no me funcionaba, pues como que chungo. Al final, ayer a ultima hora, me da por buscar en google pero en español, y va y me sale tu página; y me pregunto como es que se me había pasado este articulo tan interesante; y claro, mirando la fecha me doy cuenta de que casi que habíamos coincidido los mismos días en liarnos con esto del virtualbox. Con diferencia esta es la mejor página (como casi siempre) donde se explica claramente, en que consiste todo este rollo…

    Al final lo que estaba haciendo yo estaba bien…pero sin estar seguro y como no me funcionaba (tenia el iptables levantado) , hasta que no leí tu articulo no empece a mirar otras posibles causas.

    Muchas gracias y sigue así.

    Pd: Estaría bien poner un ejemplo con ips fijas en eth0 y tap0 para entender mejor el articulo de entrada; yo no podía usar dhcp porque la uso en wlan0, y eth0 no la estaba usando…y no tenia muy claro si eth0 y tap0 tenia que tener una ip en dos redes diferentes o no era necesario.. Al final no dices que ip estas poniendo en tap0 (eth0 ya dentro de la maquina virtual). Me explico?

    un saludo

  • @Berto ¡Vaya! ¡Me alegro mucho de haber acertado con tus necesidades! ;-)

    Sobre lo de las IPs fijas, aunque las usemos en vez de DHCP, en el sistema host, los interfaces que forman parte del bridge no deberían de tener ninguna. Sólo el interfaz br0 debe de tenerla, sea obteniéndola por DHCP, sea porque le pongamos una con ifconfig:

    ifconfig br0 192.169.0.10 netmask 255.255.255.0 up

    Siguiendo con los nombres de interfaces que he usado de ejemplo en la entrada, ni eth0, ni tap0, ni vbox0, ni vic_tap0 deberían de tener ninguna dirección IP. Es el sistema operativo guest el que obtendrá una IP para el interfaz virtual, pero esa IP no la veremos nunca en el host.

    Espero haber conseguido aclararlo :-)

  • Berto dice:

    Creo que mas o menos estamos hablando de lo mismo:

    [root@bertocasa amelgar]# brctl show
    bridge name bridge id STP enabled interfaces
    br0 8000.001e8c85737c no eth0
    tap1

    [root@bertocasa amelgar]# ifconfig
    br0 Link encap:Ethernet HWaddr 00:1E:8C:85:73:7C
    inet addr:192.168.1.11 Bcast:192.168.1.255 Mask:255.255.255.0
    inet6 addr: fe80::21e:8cff:fe85:737c/64 Scope:Link
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:3582 errors:0 dropped:0 overruns:0 frame:0
    TX packets:3738 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:0
    RX bytes:293574 (286.6 KiB) TX bytes:326122 (318.4 KiB)

    eth0 Link encap:Ethernet HWaddr 00:1E:8C:85:73:7C
    UP BROADCAST PROMISC MULTICAST MTU:1500 Metric:1
    RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

    lo Link encap:Local Loopback
    inet addr:127.0.0.1 Mask:255.0.0.0
    inet6 addr: ::1/128 Scope:Host
    UP LOOPBACK RUNNING MTU:16436 Metric:1
    RX packets:401477 errors:0 dropped:0 overruns:0 frame:0
    TX packets:401477 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:0
    RX bytes:36265610 (34.5 MiB) TX bytes:36265610 (34.5 MiB)

    tap1 Link encap:Ethernet HWaddr 42:28:8E:A5:4C:32
    inet6 addr: fe80::4028:8eff:fea5:4c32/64 Scope:Link
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:3588 errors:0 dropped:0 overruns:0 frame:0
    TX packets:3738 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:500
    RX bytes:343974 (335.9 KiB) TX bytes:326122 (318.4 KiB)

    wlan0 Link encap:Ethernet HWaddr 00:19:5B:67:A0:EB
    inet addr:192.168.0.11 Bcast:192.168.0.255 Mask:255.255.255.0
    inet6 addr: fe80::219:5bff:fe67:a0eb/64 Scope:Link
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:59050 errors:0 dropped:0 overruns:0 frame:0
    TX packets:49682 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:63200414 (60.2 MiB) TX bytes:10145081 (9.6 MiB)

    Después en “interface name:” en virtualbox pongo tap1, que es el que he creado, arranco la maquina virtual…y en la eth0 de la maquina virtual (que se supone es tap1,no?)l es donde vuelvo a poner una ip fija; en este caso la 192.168.1.12;

    maquina host [192.168.1.11]–eth0–(br0)–tap1—-> maquina virtual eth0 (192.168.1.12)

    pero en realidad podían tb ser redes diferentes no? si es un bridge…esto tengo que probarlo…

    La wifi es la tarjeta que uso normalmente para salir a internet y se configura por dhcp, no he probado a añadir esta al bridge en vez de la eth0, porque en la documentación de virtualbox pone que pocas tarjetas wifi tienen soporte para bridge. Pero tb tengo que probarlo….

    saludos y espero haber aclarado algo ;)

  • @Berto Sí, con lo que comentas, veo que estamos alineados :-)

    Lo de la WiFi también lo había leído en el manual, que no sirve para HIF, pero no creo que sea difícil, jugando con las rutas y con el “IP forwarding”, conseguir que la máquina virtual también pueda salir a Internet a través de la WiFi.

    Sobre si las redes de eth0 y de la máquina virtual podrían ser diferentes, podrían ser en tanto que también podemos poner IPs de redes diferentes en una misma subred física, pero podríamos tener problemas con el router. Tal vez necesitemos configurarle rutas específicas para la nueva red.

  • Berto dice:

    Internet ya tengo en estas maquinas virtuales…creo que es al tener activado el ip_forwarding

    [root@bertocasa amelgar]# cat /proc/sys/net/ipv4/ip_forward
    1

    al tener la wlan0 y eth0 en mi maquina host…aunque en redes diferentes, al tener puesta una puerta de enlace por defecto, imagino que los paquetes buscan camino…

    Estoy de acuerdo en lo de las redes diferentes en el bridge, probablemente haya que añadir rutas de redes a la tabla de ruteo de una y otra maquina y tal vez funcione..a ver si lo pruebo.

    saludos y gracias…

  • Matias dice:

    Antes que nada gracias por los aportes que haces a la comunidad, realmente ayudan.
    Con respecto a este tema, creo que la nueva versión que salió hoy sino me equivoco lo soluciona fácil, todavía no se me actualizo desde los repositorios para probar, pero según leo en la lista de features:
    http://www.virtualbox.org/wiki/Changelog
    dice:
    “New Host Interface Networking implementations for Windows and Linux hosts with easier setup (replaces TUN/TAP on Linux and manual bridging on Windows) ”

    Yo no entiendo mucho todavía el tema, pero me parece que es esto. uds que dicen??

  • @Matias Pues si no interpreto mal dicha información, tienes toda la razón. Con la versión 2.1 no deberían de ser necesarios estos interfaces TUN/TAP para HIF. Tendremos que probarlo… ¡Muchísimas gracias por la información! ¡Es muy, muy útil!

  • Raúl dice:

    Hola:

    Quería hacer notar que con la versión 2.1.0 de VirtualBox es la mar de sencillo configurar la red en modo Host interface. Tan solo entrar en configuración y seleccionar la interfaz a la que asociarse.

    Gracias por tu blog. Saludos.

  • @Raúl Pues sí, tal y como le decía a Matias, apenas han pasado unos días para que lo escrito en la entrada ya no sea necesario con la nueva versión ;-)

    Al menos, queda como referencia de cómo usar interfaces bridge y TAP.

  • guillermo dice:

    La información esta muy bien con virtualbox 2.1 todavia es necesario hacer el puente. Sino la configuración de la maquina virtual afecta al funcionamiento de la maquina real

  • Emiliano dice:

    Hola, no se si voy por el camino correcto, tal vez alguien pueda orientarme un poco,, resulta que necesito crear una interfase virtual con diferente MAC Address que la interfase real.. necesito que MAC de eth0 != MAC de eth0:1 , y esto no es posible , al menos de la forma tradicional, ya que cambiándole la MAC a una interfase cambia la otra automáticamente. Además necesito que ambas interface ( eth0, eth0:1) estén como default gateway ya que quiero hacer load balancing entre ambas, y además ambas deben pertenecer a la misma red, es decir, ambas van a tomar IP del mismo Server DHCP , por eso necesito que cada interfase tenga diferente MAC, en síntesis: es como tener 2 placas de red en la misma PC y cada una conectada al mismo HUB/SWITCH, hago esta pregunta aquí, ya que me han dicho que para hacer eso necesito usar Bridge e interfase TAP, voy por el camino correcto? Si no es así les ruego me disculpen.

Trackbacks y pingbacks:

Tema LHYLE09, creado por Vicente Navarro