Configuración de Red Virtual con Libvirt: Guía Completa

Introducción

La red virtual es un componente fundamental de la virtualización KVM/QEMU, que permite a las máquinas virtuales comunicarse entre sí, con el sistema host y con redes externas. Libvirt proporciona un marco integral para configurar y administrar redes virtuales, ofreciendo flexibilidad que va desde configuraciones NAT simples hasta arquitecturas de red multinivel complejas.

Esta guía completa explora en profundidad las capacidades de red virtual de libvirt, cubriendo modos de red, configuraciones de puente, escenarios de enrutamiento avanzados y optimización de rendimiento. Ya sea que esté construyendo un laboratorio doméstico, un entorno de desarrollo o una infraestructura de producción, comprender la red de libvirt es esencial para crear entornos virtualizados seguros, eficientes y escalables.

Las redes virtuales de Libvirt aprovechan componentes de red de Linux que incluyen puentes, dispositivos TAP, iptables y dnsmasq para proporcionar servicios de red a las máquinas virtuales. La capa de abstracción que proporciona libvirt simplifica configuraciones de red complejas mientras mantiene la flexibilidad para implementar escenarios de red avanzados cuando sea necesario.

Al final de esta guía, dominará la configuración de red de libvirt, desde configuraciones NAT básicas hasta escenarios avanzados que involucran VLANs, múltiples puentes, enrutamiento personalizado y estrategias de aislamiento de red utilizadas en entornos de producción.

Comprendiendo la Red Virtual de Libvirt

Arquitectura de Red de Libvirt

┌─────────────────────────────────────────────┐
│      Máquina Virtual (Invitado)             │
│              eth0 (NIC Invitado)            │
└──────────────────┬──────────────────────────┘
                   │
         ┌─────────▼─────────┐
         │  vnet0 (Dispositivo TAP)│
         │   52:54:00:xx:xx  │
         └─────────┬──────────┘
                   │
         ┌─────────▼─────────┐
         │  virbr0 (Puente)  │
         │   192.168.122.1   │
         └─────────┬──────────┘
                   │
    ┌──────────────┴───────────────┐
    │                              │
┌───▼────┐                  ┌──────▼─────┐
│dnsmasq │                  │  iptables  │
│ (DHCP) │                  │    (NAT)   │
└────────┘                  └──────┬─────┘
                                   │
                           ┌───────▼────────┐
                           │ NIC Física     │
                           │ (Red del Host) │
                           └────────────────┘

Componentes de Red

Interfaz de Red Virtual (vnet):

  • Dispositivo TAP conectado a la VM invitada
  • Aparece como NIC regular dentro del invitado
  • Administrado automáticamente por libvirt

Puente Virtual (virbr):

  • Switch de software que conecta VMs
  • Agrupa dispositivos TAP juntos
  • Proporciona conectividad de capa 2

dnsmasq:

  • Proporciona servicios DHCP
  • Reenvío y caché de DNS
  • Administrado por libvirt

iptables:

  • Reglas NAT y de reenvío
  • Firewall y filtrado
  • Enrutamiento entre redes

Modos de Red en Libvirt

1. Modo NAT (Predeterminado)

El modo NAT (Network Address Translation) proporciona conectividad a Internet a las VMs mientras las mantiene aisladas de la red externa.

Características:

  • Las VMs obtienen direcciones IP privadas (192.168.122.0/24 por defecto)
  • Las VMs pueden acceder a redes externas
  • Las redes externas no pueden acceder directamente a las VMs
  • El host actúa como enrutador con NAT

Casos de uso:

  • Entornos de desarrollo
  • VMs de prueba
  • VMs que necesitan Internet pero no acceso externo

Creando Red NAT:

# Crear configuración de red NAT
cat > nat-network.xml << 'EOF'
<network>
  <name>nat-network</name>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='virbr1' stp='on' delay='0'/>
  <domain name='nat-network.local'/>
  <ip address='192.168.100.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.100.10' end='192.168.100.250'/>
      <host mac='52:54:00:11:22:33' name='webserver' ip='192.168.100.50'/>
    </dhcp>
  </ip>
</network>
EOF

# Definir e iniciar la red
virsh net-define nat-network.xml
virsh net-start nat-network
virsh net-autostart nat-network

# Verificar red
virsh net-list
virsh net-info nat-network

Ver reglas de iptables generadas:

# Verificar reglas NAT
iptables -t nat -L -n -v | grep virbr1

# Verificar reglas de reenvío
iptables -L FORWARD -n -v | grep virbr1

# Ver todas las reglas para red virtual
iptables-save | grep virbr1

2. Modo Enrutado

El modo enrutado conecta las VMs a la red física a través de enrutamiento en lugar de puentes, manteniendo subredes separadas.

Características:

  • Las VMs usan direcciones IP enrutables
  • Sin traducción NAT
  • Requiere rutas estáticas en la red física
  • Conectividad de capa 3

Creando Red Enrutada:

cat > routed-network.xml << 'EOF'
<network>
  <name>routed-network</name>
  <forward mode='route' dev='eth0'/>
  <bridge name='virbr-route' stp='on' delay='0'/>
  <ip address='10.10.10.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='10.10.10.10' end='10.10.10.250'/>
    </dhcp>
  </ip>
</network>
EOF

virsh net-define routed-network.xml
virsh net-start routed-network
virsh net-autostart routed-network

# Agregar ruta en enrutador externo (ejemplo)
# Enrutar 10.10.10.0/24 vía <IP-del-host>

Configurar enrutamiento del host:

# Habilitar reenvío de IP
echo 1 > /proc/sys/net/ipv4/ip_forward

# Hacer permanente
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

# Agregar reglas de firewall
iptables -A FORWARD -i virbr-route -j ACCEPT
iptables -A FORWARD -o virbr-route -j ACCEPT

3. Modo Puente

El modo puente conecta las VMs directamente a la red física, haciendo que aparezcan como hosts físicos en la misma red.

Características:

  • Las VMs obtienen direcciones IP del DHCP de la red física
  • Conectividad directa de capa 2
  • VMs visibles en la red física
  • Mejor rendimiento

Prerequisitos:

# Instalar utilidades de puente
apt install bridge-utils  # Debian/Ubuntu
dnf install bridge-utils  # RHEL/CentOS

# Verificar puentes existentes
brctl show
ip link show type bridge

Creando Puente del Host (Netplan - Ubuntu/Debian):

# Respaldar configuración existente
cp /etc/netplan/01-netcfg.yaml /etc/netplan/01-netcfg.yaml.bak

# Crear configuración de puente
cat > /etc/netplan/01-netcfg.yaml << 'EOF'
network:
  version: 2
  ethernets:
    ens18:
      dhcp4: no
      dhcp6: no
  bridges:
    br0:
      interfaces: [ens18]
      dhcp4: yes
      parameters:
        stp: true
        forward-delay: 4
EOF

# Aplicar configuración
netplan apply

# Verificar puente
ip addr show br0
brctl show br0

Creando Puente del Host (NetworkManager - RHEL/CentOS):

# Crear puente
nmcli connection add type bridge ifname br0 con-name br0

# Agregar interfaz física al puente
nmcli connection add type bridge-slave ifname ens18 master br0

# Configurar IP del puente (DHCP o estática)
nmcli connection modify br0 ipv4.method auto

# Activar puente
nmcli connection up br0

# Verificar
nmcli connection show
bridge link show

Creando Red Puente de Libvirt:

cat > bridge-network.xml << 'EOF'
<network>
  <name>bridge-network</name>
  <forward mode='bridge'/>
  <bridge name='br0'/>
</network>
EOF

virsh net-define bridge-network.xml
virsh net-start bridge-network
virsh net-autostart bridge-network

Adjuntar VM al Puente:

# Adjuntar a VM existente
virsh attach-interface ubuntu-vm bridge br0 --model virtio --config --live

# O crear VM con puente
virt-install \
  --name ubuntu-bridge \
  --memory 2048 \
  --vcpus 2 \
  --disk path=/var/lib/libvirt/images/ubuntu-bridge.qcow2,size=20 \
  --network bridge=br0,model=virtio \
  --os-variant ubuntu22.04 \
  --cdrom /path/to/ubuntu.iso

4. Modo Aislado

El modo aislado crea una red donde las VMs pueden comunicarse entre sí pero no tienen conectividad al host o redes externas.

Características:

  • Aislamiento de red completo
  • Las VMs solo pueden comunicarse entre sí
  • Sin acceso a Internet o al host
  • Útil para pruebas de seguridad

Creando Red Aislada:

cat > isolated-network.xml << 'EOF'
<network>
  <name>isolated</name>
  <bridge name='virbr-iso' stp='on' delay='0'/>
  <domain name='isolated.local'/>
  <ip address='10.0.0.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='10.0.0.10' end='10.0.0.250'/>
    </dhcp>
  </ip>
</network>
EOF

virsh net-define isolated-network.xml
virsh net-start isolated
virsh net-autostart isolated

# Verificar que no hay reenvío configurado
virsh net-dumpxml isolated | grep forward
# No debería mostrar elemento forward

5. Modo Abierto/Reenvío

El modo abierto reenvía todo el tráfico sin restricciones de NAT o enrutamiento.

cat > open-network.xml << 'EOF'
<network>
  <name>open-network</name>
  <forward mode='open'/>
  <bridge name='virbr-open' stp='on' delay='0'/>
  <ip address='172.16.0.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='172.16.0.10' end='172.16.0.250'/>
    </dhcp>
  </ip>
</network>
EOF

virsh net-define open-network.xml
virsh net-start open-network

Configuración Avanzada de Red

Asignación de IP Estática vía DHCP

# Obtener dirección MAC de la VM
virsh dumpxml ubuntu-vm | grep "mac address"
# Salida: <mac address='52:54:00:xx:xx:xx'/>

# Actualizar red con entrada DHCP estática
virsh net-update default add ip-dhcp-host \
  "<host mac='52:54:00:xx:xx:xx' name='ubuntu-vm' ip='192.168.122.100'/>" \
  --live --config

# Verificar
virsh net-dhcp-leases default

# Agregar múltiples asignaciones estáticas
cat > dhcp-hosts.xml << 'EOF'
<host mac='52:54:00:11:11:11' name='web1' ip='192.168.122.11'/>
<host mac='52:54:00:22:22:22' name='web2' ip='192.168.122.12'/>
<host mac='52:54:00:33:33:33' name='db1' ip='192.168.122.20'/>
EOF

# Agregar cada host
while IFS= read -r line; do
    virsh net-update default add ip-dhcp-host "$line" --live --config
done < dhcp-hosts.xml

Reenvío de Puertos en Redes NAT

# Reenviar puerto del host a VM
virsh net-update default add-last ip-forward \
  "<forward proto='tcp' address='0.0.0.0' port='8080' dev='virbr0'> \
   <interface dev='eth0'/> \
   <backend dev='eth0'/> \
   </forward>" \
  --live --config

# Usar iptables directamente para más control
# Reenviar puerto 80 del host al puerto 80 de la VM
iptables -t nat -A PREROUTING -p tcp --dport 8080 \
  -j DNAT --to-destination 192.168.122.100:80

# Permitir reenvío
iptables -A FORWARD -d 192.168.122.100 -p tcp --dport 80 -j ACCEPT

# Hacer permanente (Ubuntu/Debian)
apt install iptables-persistent
iptables-save > /etc/iptables/rules.v4

Múltiples Rangos de IP en Una Sola Red

cat > multi-ip-network.xml << 'EOF'
<network>
  <name>multi-ip</name>
  <forward mode='nat'/>
  <bridge name='virbr-multi' stp='on' delay='0'/>
  <ip address='192.168.100.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.100.10' end='192.168.100.100'/>
    </dhcp>
  </ip>
  <ip address='10.10.10.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='10.10.10.10' end='10.10.10.100'/>
    </dhcp>
  </ip>
</network>
EOF

virsh net-define multi-ip-network.xml
virsh net-start multi-ip

Configuración IPv6

cat > ipv6-network.xml << 'EOF'
<network>
  <name>ipv6-network</name>
  <forward mode='nat'/>
  <bridge name='virbr-v6' stp='on' delay='0'/>
  <ip address='192.168.150.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.150.10' end='192.168.150.250'/>
    </dhcp>
  </ip>
  <ip family='ipv6' address='fd00:cafe:cafe::1' prefix='64'>
    <dhcp>
      <range start='fd00:cafe:cafe::10' end='fd00:cafe:cafe::ff'/>
    </dhcp>
  </ip>
</network>
EOF

virsh net-define ipv6-network.xml
virsh net-start ipv6-network

# Habilitar reenvío IPv6 en el host
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.conf
sysctl -p

Configuración VLAN

# Crear red con etiquetado VLAN
cat > vlan-network.xml << 'EOF'
<network>
  <name>vlan100</name>
  <forward mode='bridge'/>
  <bridge name='br0'/>
  <vlan trunk='yes'>
    <tag id='100'/>
  </vlan>
</network>
EOF

virsh net-define vlan-network.xml
virsh net-start vlan100

# Configurar VM con VLAN
virsh edit ubuntu-vm

# Agregar VLAN a la interfaz:
<interface type='network'>
  <source network='vlan100'/>
  <vlan>
    <tag id='100'/>
  </vlan>
</interface>

Configuración SR-IOV

SR-IOV (Single Root I/O Virtualization) proporciona rendimiento de red casi nativo al permitir que las VMs accedan directamente a interfaces de red físicas.

# Verificar si la NIC soporta SR-IOV
lspci | grep Ethernet
lspci -v -s <device-id> | grep SR-IOV

# Habilitar SR-IOV en la NIC
echo 4 > /sys/class/net/ens1f0/device/sriov_numvfs

# Hacer persistente (agregar a /etc/rc.local o regla udev)
cat > /etc/udev/rules.d/sriov.rules << 'EOF'
ACTION=="add", SUBSYSTEM=="net", ENV{ID_NET_NAME}=="ens1f0", \
RUN+="/bin/bash -c 'echo 4 > /sys/class/net/ens1f0/device/sriov_numvfs'"
EOF

# Listar funciones virtuales
lspci | grep Virtual

# Crear pool de red para VFs
cat > sriov-network.xml << 'EOF'
<network>
  <name>sriov-network</name>
  <forward mode='hostdev' managed='yes'>
    <pf dev='ens1f0'/>
  </forward>
</network>
EOF

virsh net-define sriov-network.xml
virsh net-start sriov-network

# Adjuntar interfaz SR-IOV a VM
virsh edit ubuntu-vm

<interface type='network'>
  <source network='sriov-network'/>
</interface>

Optimización de Rendimiento de Red

Multi-queue virtio-net

# Habilitar multi-queue en la definición de la VM
virsh edit ubuntu-vm

<interface type='network'>
  <source network='default'/>
  <model type='virtio'/>
  <driver name='vhost' queues='4'/>
</interface>

# Reiniciar VM
virsh shutdown ubuntu-vm
virsh start ubuntu-vm

# Dentro de la VM invitada, habilitar multi-queue
ethtool -L eth0 combined 4

# Verificar
ethtool -l eth0

Optimización vhost-net

# Asegurar que el módulo vhost-net esté cargado
lsmod | grep vhost
modprobe vhost_net

# Hacer permanente
echo "vhost_net" >> /etc/modules

# Usar vhost en la configuración de red
virsh edit ubuntu-vm

<interface type='network'>
  <source network='default'/>
  <model type='virtio'/>
  <driver name='vhost' txmode='iothread' ioeventfd='on' event_idx='on'/>
</interface>

Descarga de Red

# Configurar descarga en XML de VM
<interface type='network'>
  <source network='default'/>
  <model type='virtio'/>
  <driver name='vhost'>
    <host csum='on' gso='on' tso4='on' tso6='on' ecn='on' ufo='on'/>
    <guest csum='on' tso4='on' tso6='on' ecn='on' ufo='on'/>
  </driver>
</interface>

# Dentro del invitado, verificar descarga
ethtool -k eth0 | grep offload

Limitación de Ancho de Banda

# Limitar ancho de banda para interfaz de VM
virsh domiftune ubuntu-vm vnet0 \
  --inbound 100000,150000,200000 \
  --outbound 80000,120000,160000

# Parámetros: promedio,pico,ráfaga (en KiB/s)

# Verificar
virsh domiftune ubuntu-vm vnet0

# Hacer permanente
virsh edit ubuntu-vm

<interface type='network'>
  <source network='default'/>
  <bandwidth>
    <inbound average='100000' peak='150000' burst='200000'/>
    <outbound average='80000' peak='120000' burst='160000'/>
  </bandwidth>
</interface>

Configuración DNS

Entradas DNS Personalizadas

# Agregar entradas DNS personalizadas a la red
virsh net-update default add dns-host \
  "<host ip='192.168.122.100'><hostname>web.local</hostname></host>" \
  --live --config

# Agregar múltiples nombres de host a la misma IP
virsh net-update default add dns-host \
  "<host ip='192.168.122.100'><hostname>web.local</hostname><hostname>www.local</hostname></host>" \
  --live --config

# Agregar reenviador DNS
virsh net-update default add dns-forwarder \
  "<forwarder addr='8.8.8.8'/>" \
  --live --config

virsh net-update default add dns-forwarder \
  "<forwarder addr='8.8.4.4'/>" \
  --live --config

Configuración DNS en XML de Red

cat > dns-network.xml << 'EOF'
<network>
  <name>dns-network</name>
  <forward mode='nat'/>
  <bridge name='virbr-dns'/>
  <domain name='example.local' localOnly='yes'/>
  <dns>
    <forwarder addr='8.8.8.8'/>
    <forwarder addr='1.1.1.1'/>
    <host ip='192.168.200.10'>
      <hostname>web1.example.local</hostname>
      <hostname>www.example.local</hostname>
    </host>
    <host ip='192.168.200.20'>
      <hostname>db1.example.local</hostname>
    </host>
    <txt name='example.local' value='v=spf1 a mx ~all'/>
    <srv service='ldap' protocol='tcp' domain='example.local'
         target='ldap.example.local' port='389' priority='10' weight='10'/>
  </dns>
  <ip address='192.168.200.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.200.10' end='192.168.200.250'/>
    </dhcp>
  </ip>
</network>
EOF

virsh net-define dns-network.xml
virsh net-start dns-network

Firewall y Seguridad

Reglas de Firewall Personalizadas

# Agregar reglas personalizadas a la red
cat > secure-network.xml << 'EOF'
<network>
  <name>secure-network</name>
  <forward mode='nat'/>
  <bridge name='virbr-sec'/>
  <ip address='192.168.180.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.180.10' end='192.168.180.250'/>
    </dhcp>
  </ip>
</network>
EOF

virsh net-define secure-network.xml
virsh net-start secure-network

# Agregar reglas de iptables personalizadas
iptables -I FORWARD -i virbr-sec -o virbr-sec -p tcp --dport 22 -j ACCEPT
iptables -I FORWARD -i virbr-sec -o virbr-sec -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -i virbr-sec -o virbr-sec -p tcp --dport 443 -j ACCEPT
iptables -I FORWARD -i virbr-sec -o virbr-sec -j DROP

# Guardar reglas
iptables-save > /etc/iptables/rules.v4

Filtrado de Red (nwfilter)

# Listar filtros disponibles
virsh nwfilter-list

# Ver definición de filtro
virsh nwfilter-dumpxml clean-traffic

# Crear filtro personalizado
cat > custom-filter.xml << 'EOF'
<filter name='custom-filter' chain='root'>
  <uuid>12345678-1234-1234-1234-123456789abc</uuid>
  <!-- Permitir ARP -->
  <rule action='accept' direction='inout' priority='100'>
    <mac protocolid='arp'/>
  </rule>
  <!-- Permitir IPv4 -->
  <rule action='accept' direction='out' priority='100'>
    <ip/>
  </rule>
  <!-- Permitir HTTP/HTTPS entrante -->
  <rule action='accept' direction='in' priority='100'>
    <tcp dstportstart='80' dstportend='80'/>
  </rule>
  <rule action='accept' direction='in' priority='100'>
    <tcp dstportstart='443' dstportend='443'/>
  </rule>
  <!-- Descartar todo lo demás -->
  <rule action='drop' direction='inout' priority='1000'>
    <all/>
  </rule>
</filter>
EOF

virsh nwfilter-define custom-filter.xml

# Aplicar filtro a interfaz de VM
virsh edit ubuntu-vm

<interface type='network'>
  <source network='default'/>
  <filterref filter='custom-filter'/>
</interface>

Limitación de Tasa y QoS

# Crear red con QoS habilitado
cat > qos-network.xml << 'EOF'
<network>
  <name>qos-network</name>
  <forward mode='nat'/>
  <bridge name='virbr-qos'/>
  <bandwidth>
    <inbound average='50000' peak='100000' burst='50000'/>
    <outbound average='50000' peak='100000' burst='50000'/>
  </bandwidth>
  <ip address='192.168.190.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.190.10' end='192.168.190.250'/>
    </dhcp>
  </ip>
</network>
EOF

virsh net-define qos-network.xml
virsh net-start qos-network

Red Multi-Host

Conectando VMs entre Hosts

Usando VXLAN:

# Host 1
ip link add vxlan100 type vxlan id 100 \
  local 10.0.0.1 \
  remote 10.0.0.2 \
  dev eth0 \
  dstport 4789

ip link set vxlan100 up
brctl addbr br-vxlan
brctl addif br-vxlan vxlan100
ip link set br-vxlan up

# Crear red libvirt
cat > vxlan-network.xml << 'EOF'
<network>
  <name>vxlan-network</name>
  <forward mode='bridge'/>
  <bridge name='br-vxlan'/>
</network>
EOF

virsh net-define vxlan-network.xml
virsh net-start vxlan-network

# Host 2 (invertir IPs local/remote)
ip link add vxlan100 type vxlan id 100 \
  local 10.0.0.2 \
  remote 10.0.0.1 \
  dev eth0 \
  dstport 4789
# ... repetir configuración de puente

Usando Túneles GRE:

# Host 1
ip tunnel add gre1 mode gre remote 10.0.0.2 local 10.0.0.1 ttl 255
ip link set gre1 up
ip addr add 172.16.0.1/30 dev gre1

brctl addbr br-gre
brctl addif br-gre gre1
ip link set br-gre up

# Host 2
ip tunnel add gre1 mode gre remote 10.0.0.1 local 10.0.0.2 ttl 255
ip link set gre1 up
ip addr add 172.16.0.2/30 dev gre1
# ... repetir configuración de puente

Resolución de Problemas de Red

Comandos de Diagnóstico

# Listar todas las redes
virsh net-list --all

# Verificar estado de red
virsh net-info default

# Ver XML de red
virsh net-dumpxml default

# Mostrar arrendamientos DHCP
virsh net-dhcp-leases default

# Verificar estado del puente
brctl show
bridge link show

# Ver base de datos de reenvío del puente
bridge fdb show br virbr0

# Verificar configuración de dnsmasq
ps aux | grep dnsmasq
cat /var/lib/libvirt/dnsmasq/default.conf

# Ver arrendamientos de dnsmasq
cat /var/lib/libvirt/dnsmasq/default.leases

# Verificar reglas de iptables
iptables -t nat -L -n -v
iptables -L FORWARD -n -v

# Monitorear tráfico de red
tcpdump -i virbr0 -n

Problemas Comunes y Soluciones

Problema: La red no inicia

# Verificar errores
virsh net-start default
# Ver error detallado

# Verificar si el puente existe
ip link show virbr0

# Verificar que dnsmasq no esté ejecutándose en otro lugar
ps aux | grep dnsmasq

# Verificar conflictos de puerto
ss -tulpn | grep :53

# Reiniciar libvirtd
systemctl restart libvirtd
virsh net-start default

Problema: Las VMs no pueden obtener direcciones IP

# Verificar rango DHCP
virsh net-dumpxml default | grep range

# Verificar que dnsmasq esté ejecutándose
ps aux | grep dnsmasq

# Verificar que el firewall permita DHCP
iptables -L INPUT -n | grep 67

# Reiniciar red
virsh net-destroy default
virsh net-start default

# Dentro de la VM, solicitar DHCP
dhclient -v eth0  # o
dhcpcd eth0

Problema: Las VMs no pueden acceder a Internet (NAT)

# Verificar reenvío de IP
cat /proc/sys/net/ipv4/ip_forward
# Debería ser 1

# Habilitar si es necesario
echo 1 > /proc/sys/net/ipv4/ip_forward

# Verificar reglas NAT
iptables -t nat -L POSTROUTING -n -v

# Verificar reglas de reenvío
iptables -L FORWARD -n -v

# Verificar ruta predeterminada en la VM
ip route show

Problema: La red puente no funciona

# Verificar que la interfaz física esté en el puente
brctl show br0

# Verificar que la interfaz física no tenga IP
ip addr show ens18
# No debería mostrar dirección inet

# Verificar que el puente tenga IP
ip addr show br0
# Debería tener dirección IP

# Probar conectividad
ping -c 4 <IP-gateway>

# Verificar reenvío del puente
cat /sys/class/net/br0/bridge/stp_state

Monitoreo y Estadísticas de Red

Monitoreo en Tiempo Real

# Monitorear estadísticas de interfaz
watch -n 1 'virsh domifstat ubuntu-vm vnet0'

# Monitorear todas las VMs
#!/bin/bash
while true; do
    clear
    echo "Estadísticas de Red - $(date)"
    echo "================================"
    for vm in $(virsh list --name); do
        echo "VM: $vm"
        virsh domiflist "$vm"
        for iface in $(virsh domiflist "$vm" | awk 'NR>2 {print $1}'); do
            virsh domifstat "$vm" "$iface"
        done
        echo ""
    done
    sleep 5
done

# Usar iftop para monitoreo de ancho de banda
iftop -i virbr0

# Usar nethogs para monitoreo por proceso
nethogs virbr0

Recopilando Métricas de Red

#!/bin/bash
# Script de recopilación de métricas de red

LOG_FILE="/var/log/vm-network-stats.log"

collect_stats() {
    timestamp=$(date '+%Y-%m-%d %H:%M:%S')

    for vm in $(virsh list --name); do
        for iface in $(virsh domiflist "$vm" | awk 'NR>2 {print $1}'); do
            stats=$(virsh domifstat "$vm" "$iface" | grep -E 'rx_bytes|tx_bytes')
            echo "$timestamp | $vm | $iface | $stats" >> "$LOG_FILE"
        done
    done
}

# Ejecutar cada 60 segundos
while true; do
    collect_stats
    sleep 60
done

Mejores Prácticas

Principios de Diseño de Red

  1. Separar redes por función:
# Red de gestión
virsh net-define mgmt-network.xml

# Red de aplicación
virsh net-define app-network.xml

# Red de base de datos (aislada)
virsh net-define db-network.xml

# Red DMZ
virsh net-define dmz-network.xml
  1. Usar DHCP estático para servidores:
# Asignar IPs consistentes a VMs de servidor
virsh net-update default add ip-dhcp-host \
  "<host mac='52:54:00:aa:bb:cc' name='web-server' ip='192.168.122.10'/>"
  1. Implementar aislamiento de red:
# Usar redes aisladas para pruebas
# Usar redes separadas para producción
# Implementar reglas de firewall entre redes
  1. Documentar topología de red:
# Crear documentación de red
virsh net-list --all > /docs/networks.txt
for net in $(virsh net-list --name); do
    virsh net-dumpxml "$net" > "/docs/network-${net}.xml"
done

Endurecimiento de Seguridad

# Deshabilitar redes no utilizadas
virsh net-destroy unused-network
virsh net-autostart unused-network --disable

# Implementar reglas de firewall estrictas
# Usar nwfilter para filtrado a nivel de VM
# Habilitar STP en puentes
# Usar VLANs para segmentación
# Implementar filtrado MAC
# Habilitar seguridad de puerto

Conclusión

Las capacidades de red virtual de Libvirt proporcionan una base robusta y flexible para construir topologías de red complejas en entornos virtualizados. Desde configuraciones NAT simples hasta escenarios avanzados multi-host con VXLANs y SR-IOV, libvirt abstrae la complejidad de la red de Linux mientras mantiene el control total cuando sea necesario.

Puntos clave:

  • Elija el modo de red apropiado (NAT, puente, enrutado, aislado) según los requisitos
  • Aproveche DHCP estático para asignaciones de IP predecibles
  • Use filtros de red e iptables para seguridad
  • Optimice el rendimiento con virtio, multi-queue y vhost-net
  • Implemente procedimientos adecuados de monitoreo y resolución de problemas
  • Diseñe redes con segmentación y aislamiento en mente

Domine la red de libvirt para construir infraestructura virtualizada segura, eficiente y escalable que cumpla con los requisitos de producción mientras mantiene flexibilidad para entornos de desarrollo y prueba. La capa de red es crítica para el rendimiento y seguridad de las VMs: invierta tiempo en una configuración y monitoreo adecuados para garantizar resultados óptimos.