Red del host y SDN: bridges, VLAN, bonding, NAT y overlays

Por: Artiko
proxmoxredbridgevlanbondingsdnevpnvxlannatifupdown2frrwireguard

Red del host y SDN: bridges, VLAN, bonding, NAT y overlays

Hasta ahora casi todo lo que has hecho vive dentro del nodo. Creaste VMs en el capítulo 3, contenedores en el capítulo 6 y les colgaste discos del almacenamiento del capítulo 7. Todos comparten una cosa que aún no has tocado en serio: el vmbr0 que dejó el instalador, con la IP de gestión encima y la primera NIC como único puerto.

Ese vmbr0 funciona hasta que deja de funcionar. Deja de funcionar cuando necesitas separar gestión de guests, cuando el hoster te corta el puerto porque ve cinco MAC en una interfaz, cuando quieres redundancia de enlace sin romper corosync, cuando dos clientes necesitan la misma VLAN 100 sin verse, o cuando quieres una red L2 que atraviese tres nodos en subredes IP distintas.

Este capítulo cubre las dos capas que resuelven todo eso. Primero la red clásica de Linux, que es la que realmente usa Proxmox: un fichero de texto, ifupdown2, bridges, bonds y VLANs. Después el stack SDN, que no sustituye a la anterior sino que se apoya en ella para generar bridges, túneles VXLAN y configuración de FRRouting en todos los nodos a la vez.

Advertencia: tocar red en un nodo remoto es la forma más habitual de dejarte fuera de tu propio servidor. Todo lo que sigue asume que tienes IPMI, iKVM o acceso físico. Si no lo tienes, lee primero la sección de orden seguro del final.

/etc/network/interfaces, el fichero .new y pvenetcommit

Proxmox VE no inventa un stack de red propio: usa el estándar de Debian, un fichero en formato interfaces(5). Lo que sí añade es un mecanismo de staging, y esta cita literal es la clave del capítulo entero:

“Proxmox VE does not write changes directly to /etc/network/interfaces. Instead, we write into a temporary file called /etc/network/interfaces.new, this way you can do many related changes at once.”

Cuando editas la red en Nodo → System → Network, nada se aplica. Se acumula en /etc/network/interfaces.new y la GUI muestra el aviso de cambios pendientes con los botones Apply Configuration y Revert.

Hay un tercer camino: reiniciar. El servicio systemd pvenetcommit activa el .new antes de que arranque networking.service. Es útil y peligroso a partes iguales: si dejas cambios a medias en staging y meses después alguien reinicia el nodo, la red cambia sin previo aviso.

flowchart TD
    A["Editas la red en la GUI"] --> B["Se escribe en /etc/network/interfaces.new"]
    B --> C{"Como aplicas"}
    C -->|"Boton Apply Configuration"| D["Mueve el .new al fichero real y ejecuta ifreload -a"]
    C -->|"Reboot del nodo"| E["pvenetcommit activa el .new antes de networking.service"]
    C -->|"Boton Revert"| F["Borra interfaces.new y no cambia nada"]
    G["Editas el fichero a mano"] --> H["ifreload -a"]
    D --> Z["Red activa"]
    E --> Z
    H --> Z

Comprobar si tienes cambios colgando es una orden:

ls -l /etc/network/interfaces.new
diff -u /etc/network/interfaces /etc/network/interfaces.new

Las herramientas de PVE se esfuerzan en conservar las modificaciones manuales, pero la documentación recomienda la GUI porque valida antes de escribir.

ifupdown2 e ifreload: recarga sin cortar a los guests

Proxmox usa ifupdown2, que viene por defecto en instalaciones nuevas desde PVE 7.0. Si instalaste sobre Debian a mano, comprueba que está: apt install ifupdown2.

La diferencia con las herramientas clásicas importa mucho. Aviso literal:

“It’s discouraged to use the traditional Debian tools ifup and ifdown if unsure, as they have some pitfalls like interrupting all guest traffic on ifdown vmbrX but not reconnecting those guest again when doing ifup on the same bridge later.”

En la práctica: haces ifdown vmbr0 && ifup vmbr0, el bridge vuelve, pero los tap de las VMs y los veth de los contenedores no se reenganchan. Todos tus guests quedan sin red hasta que los reinicias uno a uno.

La orden correcta es ifreload -a, que reconcilia en caliente: “It is non-disruptive. It will fix running config to match what is configured in the interfaces file without bringing the interface down.” Su sinopsis es ifreload [-h] (-a|-c) [-v] [-d] [-f] [-n] [-s], con -a para todas las interfaces auto, -c para las actualmente levantadas, -s para syntax-check, -n para dry-run, -d para depuración y -X para excluir interfaces.

La secuencia de validación que evita disgustos:

ifreload -a -s && ifreload -a -n    # syntax check y dry-run: no tocan nada
ifreload -a                          # aplicar
journalctl -b -u networking -u pvenetcommit

Gotcha del SDN: al final de /etc/network/interfaces tiene que existir esta línea, en todos los nodos: source /etc/network/interfaces.d/*. PVE la instala, pero se pierde en instalaciones manuales sobre Debian, y sin ella las VNets del SDN no se crean nunca sin que ningún error te lo diga.

Desde PVE 5.0 las instalaciones nuevas usan el esquema de nombres predecibles de systemd con prefijo en*; los hosts anteriores conservan eth0 y compañía incluso tras actualizar. Los bridges suelen ser vmbr[N] con 0 <= N <= 4094, aunque vale cualquier cadena alfanumérica que empiece por letra y tenga como máximo 10 caracteres. Las VLANs añaden el ID tras un punto: eno1.50, bond1.30.

Los patrones systemd para Ethernet son o<index> para on-board, s<slot> para hotplug, [P<domain>]p<bus>s<slot>[f<function>] por bus PCI y x<MAC> por dirección MAC; eno1 es la primera NIC integrada y enp3s0f1 la función 1 de la tarjeta en el bus 3, slot 0. Referencia completa en systemd.net-naming-scheme(7).

El problema aparece en los upgrades: un systemd nuevo puede renombrarte las interfaces. Se puede fijar la versión del esquema con el parámetro de kernel net.naming-scheme=v252 y un reboot, pero aun así los nombres pueden cambiar por kernel o driver nuevos. La guía de upgrade de 8 a 9 lo dice: el kernel nuevo reconoce más funciones del hardware, como virtual functions, y como el nombre deriva de la dirección PCI, algunas NIC cambian de nombre y hay que adaptar la configuración.

pve-network-interface-pinning

PVE 9 trae una herramienta que fija los nombres generando ficheros .link de systemd en /usr/local/lib/systemd/network:

pve-network-interface-pinning generate                        # todas, prefijo nic1, nic2, ...
pve-network-interface-pinning generate --prefix myprefix
pve-network-interface-pinning generate --interface enp1s0
pve-network-interface-pinning generate --interface enp1s0 --target-name if42

Reescribe automáticamente el nombre viejo en /etc/network/interfaces, /etc/pve/nodes/<nodename>/host.fw, /etc/pve/sdn/controllers.cfg y /etc/pve/sdn/fabrics.cfg.

Gotcha: como el mapeo es local al nodo, los nombres de /etc/pve/firewall/cluster.fw no se actualizan. Ese fichero lo editas tú, y si no lo haces, las reglas del datacenter que referencian interfaces dejan de coincidir. El firewall completo está en el capítulo 10.

Por cada fichero tocado se genera uno con sufijo .new, revisable con diff -y /etc/network/interfaces /etc/network/interfaces.new. Para revertir antes del reboot, borra los .new y los .link; para aplicar, reinicia el nodo.

Van en /etc/systemd/network/ con nombre <n>-<id>.link, con n menor que 99:

# /etc/systemd/network/10-enwan0.link
[Match]
MACAddress=aa:bb:cc:dd:ee:ff
Type=ether

[Link]
Name=enwan0

Uno. Type=ether es obligatorio en la práctica: sin él la regla captura bridges, bonds o VLANs que comparten MAC con la física. Dos. Los .link se copian al initramfs, así que tras crear, modificar o borrar uno hace falta update-initramfs -u -k all y reboot. Tres. Nombra empezando por en o eth para que PVE lo reconozca como dispositivo físico, pero eligiendo algo que no colisione con ningún patrón systemd; enwan0 sirve.

El bridge vmbrX como switch virtual

Un bridge Linux es un switch en software. Cada host admite hasta 4094; el instalador crea uno, vmbr0, con la primera Ethernet como puerto:

auto lo
iface lo inet loopback

iface eno1 inet manual

auto vmbr0
iface vmbr0 inet static
        address 192.168.10.2/24
        gateway 192.168.10.1
        bridge-ports eno1
        bridge-stp off
        bridge-fd 0
AtributoDescripciónDefault
bridge-portspuertos del bridge; obligatorio, none para bridge sin uplink
bridge-stpactiva Spanning Treeno
bridge-fdforward delay15, PVE pone 0
bridge-vlan-awareactiva el filtrado VLAN
bridge-vidsVLAN IDs permitidos; bajo el bridge o bajo el puerto
bridge-pvid / bridge-accessPVID y VLAN de acceso; solo bajo el puerto
bridge-mcqueriermulticast querierno
mtuMTU de la interfaz1500

Los bridge-vids puestos bajo el bridge los heredan sus puertos salvo que el puerto declare los suyos.

El comportamiento visible desde fuera es la raíz de media docena de problemas posteriores: “the network sees each virtual machine as having its own MAC, even though there is only one network cable connecting all of these VMs to the network”. Perfecto en una LAN propia, letal en un hoster con binding IP/MAC.

Desde PVE 7.3 existe un anti-spoofing L2: añadiendo bridge-disable-mac-learning 1 al bridge, PVE inserta manualmente en la FDB la MAC configurada de cada VM y contenedor y el bridge deja de aprender. Consecuencia: un guest solo puede emitir con su MAC real, así que un bridge propio o un contenedor anidado dentro de la VM se quedan sin red.

Bridge VLAN-aware frente al modelo tradicional

La documentación enumera cuatro formas de hacer VLAN para guests, y se mezclan mal:

ModoCómo funcionaCuándo
VLAN awareness en el bridge Linuxcada NIC virtual lleva su tag, el bridge filtra de forma transparente; también admite modo trunkel default razonable hoy
VLAN tradicionalcrea un dispositivo VLAN y un bridge por VLAN; una VM en VLAN 5 genera eno1.5 y vmbr0v5, que permanecen hasta el siguiente rebootcompatibilidad con setups antiguos
VLAN de Open vSwitchusa la función VLAN de OVSsi ya estás en OVS
VLAN dentro del guestel guest etiqueta y no se puede influir desde fueravarias VLANs en una sola NIC virtual

La regla oficial de dónde poner la VLAN del host: “In general, you should configure the VLAN on the interface with the least abstraction layers between itself and the physical NIC.”

Con bridge tradicional, dejar la gestión en la VLAN 5 obliga a un bridge extra, vmbr0v5, colgado de eno1.5, mientras vmbr0 queda inet manual sobre eno1. Con bridge VLAN-aware todo eso desaparece:

auto lo
iface lo inet loopback

iface eno1 inet manual

auto vmbr0.5
iface vmbr0.5 inet static
        address  10.10.10.2/24
        gateway  10.10.10.1

auto vmbr0
iface vmbr0 inet manual
        bridge-ports eno1
        bridge-stp off
        bridge-fd 0
        bridge-vlan-aware yes
        bridge-vids 2-4094

Tres detalles. Uno. El bridge padre queda sin IP; la dirección va en la subinterfaz vmbr0.5. Dos. bridge-vids 2-4094 es exactamente lo que escribe la GUI al marcar “VLAN aware”. Tres. La VLAN 1 no está en ese rango porque es el PVID untagged por defecto.

VLAN en el guest: tag, trunks y las opciones de net[n]

El etiquetado de una VM va en su clave net[n] de /etc/pve/qemu-server/<VMID>.conf:

net[n]: [model=]<enum> [,bridge=<bridge>] [,firewall=<1|0>] [,host-tunnel=<1|0>]
        [,link_down=<1|0>] [,macaddr=<XX:XX:XX:XX:XX:XX>] [,mtu=<integer>]
        [,queues=<integer>] [,rate=<number>] [,tag=<integer>]
        [,trunks=<vlanid[;vlanid...]>] [,<model>=<macaddr>]
ClaveRangoQué significa
bridge=vmbr0, …bridge al que se engancha. Si lo omites, la VM cae en la red kvm user NATeada
tag=1 – 4094VLAN tag aplicado a los paquetes de esa interfaz
trunks=vlanid[;vlanid...]VLANs que pasan sin tocar; etiqueta el guest
firewall=0/1si la interfaz la protege el firewall
mtu=1 – 65520fuerza el MTU, solo VirtIO; 1 o vacío hereda el del bridge
queues=0 – 64multiqueue; se recomienda igualarlo al número de vCPUs
rate=númerolímite de tasa en mbps, que la doc define como megabytes por segundo
model=virtio, e1000, vmxnet3, …virtio rinde mejor; e1000 es el default de la GUI
host-tunnel=0/1GSO over UDP tunnel offload en VirtIO; requiere QEMU > 10.2 y está deshabilitado por defecto desde machine version 11.0+pve1 por un problema del driver virtio-net en kernels guest

En LXC la clave lleva además la IP: net[n]: name=<string> [,bridge=<bridge>] [,firewall=<1|0>] [,gw=<GatewayIPv4>] [,hwaddr=...] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=...] [,mtu=...] [,rate=<mbps>] [,tag=<integer>] [,trunks=...] [,type=<veth>].

# VM en VLAN 100, virtio, firewall activo en la NIC
qm set 100 --net0 virtio,bridge=vmbr0,tag=100,firewall=1

# Trunk de VLANs 10, 20 y 30: la VM etiqueta por su cuenta
qm set 100 --net0 virtio,bridge=vmbr0,trunks=10;20;30

# Contenedor con IP estatica en VLAN 50
pct set 200 --net0 name=eth0,bridge=vmbr0,tag=50,ip=10.50.0.10/24,gw=10.50.0.1,firewall=1

Sobre omitir bridge=: la VM recibe la red de usuario de QEMU, con gateway 10.0.2.2, DNS 10.0.2.3, SMB 10.0.2.4 y DHCP desde 10.0.2.15. La doc es tajante: “The NAT mode is much slower than the bridged mode, and should only be used for testing. This mode is only available via CLI or the API, but not via the web UI.”

Bonding: los siete modos y los avisos para corosync

ModoNombre ifupdown2Qué haceRequiere switch
Round-robinbalance-rrtransmite en orden secuencial del primer slave al último; balanceo y tolerancia a fallossí, etherchannel estático
Active-backupactive-backupun solo slave activo, otro releva al fallar; la MAC del bond solo se ve en un puerto para no distorsionar el switch. Solo tolerancia a fallosno
XORbalance-xor(MAC origen XOR MAC destino) mod nº slaves; mismo slave por MAC destino
Broadcastbroadcasttransmite por todos los slaves
LACP802.3adIEEE 802.3ad; agrupa enlaces de igual velocidad y duplex y usa todos los del aggregator activosí, con LACP
Adaptive TX LBbalance-tlbreparte el saliente según la carga de cada slave; el entrante lo recibe un slave designadono
Adaptive LBbalance-albbalance-tlb más balanceo de entrada IPv4 reescribiendo la source hardware address de las ARP Repliesno

Recomendación oficial: “If your switch supports the LACP (IEEE 802.3ad) protocol, then we recommend using the corresponding bonding mode (802.3ad). Otherwise you should generally use the active-backup mode.”

Advertencia sobre corosync. La doc recomienda para el clúster configurar varias redes en vez de un bond, porque corosync conmuta entre ellas por sí solo, y añade que “Some bond modes are known to be problematic for Corosync”. Eso descarta balance-rr, balance-xor, balance-tlb y balance-alb para la red de corosync. Si usas LACP ahí, pon bond-lacp-rate fast en el nodo y en el switch: baja el failover de 90 segundos a unos 3, que es la diferencia entre un parpadeo y un fence. El quorum está en el capítulo 11.

Defaults de ifupdown2 que no conviene heredar por descuido: bond-mode es balance-rr, bond-miimon es 0 con rango 0-255, bond-xmit-hash-policy es layer2 (valores layer2, layer2+3, layer3+4), bond-lacp-rate es 0, es decir slow cada 30 s, y bond-min-links es 0. Que el modo por defecto sea balance-rr significa que un bond sin bond-mode explícito no es el que crees.

La combinación que acaba en producción casi siempre es bond LACP más bridge VLAN-aware con la gestión en su propia VLAN:

auto bond0
iface bond0 inet manual
      bond-slaves eno1 eno2
      bond-miimon 100
      bond-mode 802.3ad
      bond-xmit-hash-policy layer3+4
      bond-lacp-rate 1

auto vmbr0
iface vmbr0 inet manual
        bridge-ports bond0
        bridge-stp off
        bridge-fd 0
        bridge-vlan-aware yes
        bridge-vids 2-4094

auto vmbr0.10
iface vmbr0.10 inet static
        address 10.10.10.2/24
        gateway 10.10.10.1

Sin switch gestionado, el bloque del bond se sustituye por bond-mode active-backup más bond-primary eno1, y se quitan bond-xmit-hash-policy y bond-lacp-rate. Diagnóstico: cat /proc/net/bonding/bond0 para ver modo, slaves y partner LACP, e ip -d link show bond0 para los detalles del driver.

MTU y jumbo frames: qué restar en cada encapsulación

El default es 1500 en todo. Para jumbo frames hay que subir el MTU en la NIC física, el bond y el bridge, los tres: si te olvidas de uno, la trama grande muere ahí. En OVS el atributo se llama ovs_mtu. En una VM, mtu=1 en net[n] hereda el del bridge y solo funciona con VirtIO.

EscenarioBytes que se restanMTU con físico 1500
Ethernet normal01500
QinQ / 802.1ad41496
VXLAN501450
IPsec sobre VXLAN, IPv450 + 601390
IPsec sobre VXLAN, IPv650 + 801370

La documentación del SDN usa 1370 como referencia para VXLAN cifrado con strongSwan, porque 1370 + 80 + 50 = 1500.

Gotcha de hardware documentado: “Some newer Intel Gigabit NICs have a hardware limitation which means the maximum MTU they can support is 8996 (instead of 9000). If your interfaces aren’t coming up and you are trying to use 9000, this is likely the reason and can be difficult to debug.” Si pones 9000 y la interfaz no sube, prueba 8996 antes de perder la tarde.

Verificación de extremo a extremo, con el bit de no fragmentar:

ip link show vmbr0 | grep mtu
ping -M do -s 8972 10.55.0.11    # 9000 menos 20 de IP y 8 de ICMP
ping -M do -s 1422 10.0.3.101    # prueba de 1450, tipico VXLAN

Open vSwitch: cuándo compensa y el error número uno

Se instala aparte con apt install openvswitch-switch. La justificación oficial: “Open vSwitch supports most of the features you would find on a physical switch, providing some advanced features like RSTP support, VXLANs, OpenFlow, and supports multiple vlans on a single bridge. If you need these features, it makes sense to switch to Open vSwitch.”

Como el bridge Linux VLAN-aware ya te da multi-VLAN en un solo bridge, hoy OVS aporta valor sobre todo si necesitas RSTP, OpenFlow o topologías mesh directas entre nodos.

Regla absoluta, sin excepciones:

“Open vSwitch and Linux bonding and bridging or vlans MUST NOT be mixed. For instance, do not attempt to add a vlan to an OVS Bond, or add a Linux Bond to an OVSBridge or vice-versa.”

Los tipos de puerto son OVSBridge (el switch, que debe contener los ethernet crudos, los bonds y los puertos internos), OVSBond (agregación, que debe referirse a dispositivos ethernet crudos), OVSIntPort (interfaz interna del host para una VLAN concreta del bridge) y OVSPort (configuración de una interfaz individual con tags y vlan_mode).

Y ahora el error número uno, que la wiki repite dos veces con mayúsculas:

“NOTE: All interfaces must be listed under ovs_ports that are part of the bridge even if you have a port definition (e.g. OVSIntPort) that cross-references the bridge!!!”

El síntoma es exacto: la interfaz existe en /etc/network/interfaces, declara su ovs_bridge, y nunca sube; ovs-vsctl show no la lista. Ejemplo correcto, con bond LACP y dos puertos internos, uno de gestión y otro para Ceph con jumbo frames:

auto bond0
iface bond0 inet manual
  ovs_bridge vmbr0
  ovs_type OVSBond
  ovs_bonds eth0 eth1
  ovs_options bond_mode=balance-tcp lacp=active other_config:lacp-time=fast
  ovs_mtu 9000

auto vmbr0
iface vmbr0 inet manual
  ovs_type OVSBridge
  ovs_ports bond0 vlan50 vlan55
  ovs_mtu 9000

auto vlan50
iface vlan50 inet static
  ovs_type OVSIntPort
  ovs_bridge vmbr0
  ovs_options tag=50
  address 10.50.10.44
  netmask 255.255.255.0
  gateway 10.50.10.1
  ovs_mtu 1500

El segundo puerto interno, vlan55 para Ceph, es idéntico salvo por ovs_options tag=55, su dirección y ovs_mtu 9000, y también tiene que estar listado en ovs_ports.

Sin switch gestionado, el modo del bond pasa a balance-slb en lugar de balance-tcp con LACP. Dos avisos más: RSTP no se puede activar con ovs_options ni ovs_extra, hace falta un script up ovs-vsctl set Bridge ${IFACE} rstp_enable=true, y un bond no puede participar en RSTP; y sobre multicast, “Right now Open vSwitch doesn’t do anything in regards to multicast… you should instead set up your querier at your router or switch”. Para diagnosticar: ovs-vsctl show, ovs-vsctl list-ports vmbr0, ovs-appctl bond/show bond0 y ovs-appctl lacp/show bond0.

Redes routed y masquerading: el caso del hoster

Todo lo anterior asume que puedes emitir tramas con MACs arbitrarias por tu puerto. En un servidor dedicado alquilado casi nunca es cierto:

“Most hosting providers do not support the above setup. For security reasons, they disable networking as soon as they detect multiple MAC addresses on a single interface.”

flowchart TD
    A["Donde vive el nodo"] --> B{"LAN privada con gateway propio"}
    B -->|"Si"| C["Bridged: vmbr0 con la NIC como puerto"]
    B -->|"No"| D{"El hoster da rango publico para los guests"}
    D -->|"Si y permite varias MAC"| E["Bridged con MAC virtuales registradas"]
    D -->|"Si pero con binding IP y MAC"| F["Routed: bridge-ports none mas proxy_arp y rutas /32"]
    D -->|"Solo una IP publica"| G["Masquerading con SNAT para la salida"]
    G --> H["Port forwarding con DNAT para la entrada"]

Configuración routed

Escenario de la documentación: IP pública 198.51.100.5, bloque adicional para VMs 203.0.113.16/28.

auto eno0
iface eno0 inet static
        address  198.51.100.5/29
        gateway  198.51.100.1
        post-up echo 1 > /proc/sys/net/ipv4/ip_forward
        post-up echo 1 > /proc/sys/net/ipv4/conf/eno0/proxy_arp

auto vmbr0
iface vmbr0 inet static
        address  203.0.113.17/28
        bridge-ports none
        bridge-stp off
        bridge-fd 0

Uno. bridge-ports none significa que el bridge no toca la NIC física: el tráfico pasa por routing L3 y hacia el switch del hoster solo sale una MAC, la del host. Dos. proxy_arp en la física es lo que hace que el host responda ARP por las IPs del bloque enrutado. Nota oficial: 203.0.113.17 es la primera dirección utilizable del bloque, porque la dirección de red no se puede asignar a una interfaz.

Masquerading con una sola IP pública

auto vmbr0
#private sub network
iface vmbr0 inet static
        address  10.10.10.1/24
        bridge-ports none
        bridge-stp off
        bridge-fd 0

        post-up   echo 1 > /proc/sys/net/ipv4/ip_forward
        post-up   iptables -t nat -A POSTROUTING -s '10.10.10.0/24' -o eno1 -j MASQUERADE
        post-down iptables -t nat -D POSTROUTING -s '10.10.10.0/24' -o eno1 -j MASQUERADE

Para publicar un servicio interno se añade DNAT en el mismo bloque, con su post-down simétrico: post-up iptables -t nat -A PREROUTING -i eno1 -p tcp --dport 8443 -j DNAT --to 10.10.10.20:443.

El gotcha de las conntrack zones

Cuesta horas de depuración y es una sola cita:

“In some masquerade setups with firewall enabled, conntrack zones might be needed for outgoing connections. Otherwise the firewall could block outgoing connections since they will prefer the POSTROUTING of the VM bridge (and not MASQUERADE).”

El síntoma: con el firewall de Proxmox activado, las VMs NATeadas dejan de salir a internet y las reglas parecen correctas. La solución oficial va también en /etc/network/interfaces:

        post-up   iptables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1
        post-down iptables -t raw -D PREROUTING -i fwbr+ -j CT --zone 1

El fwbr+ referencia los bridges de firewall que Proxmox intercala por guest cuando activas el firewall en la NIC.

Breaking change de PVE 9 con sysctl

Advertencia: en PVE 9 /etc/sysctl.conf ya no lo honra systemd-sysctl. Los ajustes van a /etc/sysctl.d/<NN>-<nombre>.conf. Afecta directamente a ip_forward en setups routed y a rp_filter en EVPN con varios exit nodes. Si vienes de PVE 8 con el forwarding en sysctl.conf, tras el upgrade el NAT deja de funcionar sin explicación aparente.

printf 'net.ipv4.ip_forward = 1\nnet.ipv6.conf.all.forwarding = 1\n' > /etc/sysctl.d/99-forward.conf
systemctl restart systemd-sysctl
sysctl net.ipv4.ip_forward

Escenarios reales: Hetzner y OVH

Hetzner lo explica sin rodeos: “Hetzner has a strict IP/MAC binding to ensure security and prevent spoofing. In some scenarios, only a routed setup is possible. For example, additional subnets, single failover IPs and failover subnets are always MAC-bound and statically routed on the main IP address of the server, and can only be configured in a routed setup.”

Lo concreto que hay que respetar. Durante la instalación, marcar “Pin network interface names”. Las IPs adicionales se ponen con máscara /32 sobre vmbr0, con una ruta por cada una; la razón textual es que “devices such as vmbr0 inherently route traffic only for IP addresses that fall within the same subnet. By using a /32 mask, each additional IP is treated as its own unique network entity”. Con vSwitch, MTU 1400 es obligatorio. Y si vas por bridged, hay que pedir una MAC virtual por cada IP adicional en el Robot Panel: si el router no reconoce la MAC de origen, el tráfico se marca como abuso y el servidor puede acabar bloqueado.

auto vmbr0
iface vmbr0 inet static
        address 198.51.100.10/32     # IP principal
        bridge-ports none
        bridge-stp off
        bridge-fd 0
        post-up ip route add 192.0.2.20/32 dev vmbr0     # IP adicional de otra subred
        post-up ip route add 198.51.100.30/32 dev vmbr0  # IP adicional de la misma subred
        post-up ip route add 172.17.234.100/32 dev vmbr0 # IP failover

Con vSwitch y subred pública el bridge cuelga de una subinterfaz VLAN (enp0s31f6.4009 en un vmbr4009 con mtu 1400), sin necesidad de bridge VLAN-aware ni de etiquetar dentro de la VM.

Gotcha operativo, literal: “you will have to restart the network after applying the network configuration for the Proxmox host to add the static routes. If virtual machines or containers are running during the network restart, you will need to stop (not just restart) and then start them again.” Parar y arrancar, no reiniciar: solo así se recrean las conexiones punto a punto de cada guest con el host.

OVH. Dos datos que evitan la mayoría de los fallos: el gateway sigue el patrón x.y.z.254 de la subred del servidor y se consulta en el panel o por API; y como en el guest la máscara es /32 con el gateway fuera de la subred, en netplan hay que declararlo on-link.

network:
  ethernets:
    ens18:
      addresses:
          - 192.0.2.1/32
      routes:
           - to: 0.0.0.0/0
             via: 203.0.113.254
             on-link: true
  version: 2

Las alternativas de OVH al bridging con MAC virtual son vRack o el modo routed.

SDN: estado de soporte, instalación y modelo pending/apply

Todo lo anterior es por nodo. El SDN define redes a nivel de datacenter y las materializa en cada nodo: bridges, subinterfaces VLAN, túneles VXLAN y configuración de FRRouting. Su estado de soporte en agosto de 2026, que conviene saber antes de apoyarse en él:

CapaEstado
Core SDN: gestión de VNets e integración con el stack de PVEfully supported
IPAM, incluida la gestión DHCP para gueststechnology preview
Routing complejo vía FRRouting e integración de controladorestechnology preview

El core viene por defecto desde PVE 8.1; el resto es opt-in:

# DHCP e IPAM
apt install dnsmasq
systemctl disable --now dnsmasq   # la instancia por defecto NO se usa

# FRRouting: necesario para EVPN y para los fabrics
apt install frr frr-pythontools
systemctl enable frr.service

Y de nuevo: verifica que exista source /etc/network/interfaces.d/* al final de /etc/network/interfaces en todos los nodos.

Toda la configuración vive en /etc/pve/sdn/, replicada por pmxcfs a todo el clúster tal como viste en el capítulo 2: zones.cfg, vnets.cfg, subnets.cfg, controllers.cfg, fabrics.cfg, ipams.cfg, dns.cfg, prefix-lists.cfg, route-maps.cfg, firewall/<vnet>.fw, más .running-config con el estado realmente desplegado y .version con la versión aplicada. Las claves privadas de WireGuard de los fabrics van aparte, en /etc/pve/priv/wg-keys.cfg.

El modelo de aplicación es el mismo espíritu que el interfaces.new del principio:

“New changes are not immediately applied but recorded as pending first. You can then apply a set of different changes all at once in the main SDN overview panel on the web interface. This system allows to roll-out various changes as single atomic one.”

La configuración de FRR resultante se escribe en /etc/frr/frr.conf de cada nodo, y lo que pongas en /etc/frr/frr.conf.local se anexa encima.

Zonas: simple, VLAN, QinQ, VXLAN y EVPN

Una zona define aislamiento y transporte. De ella cuelgan VNets, y de cada VNet subnets.

flowchart LR
    Z["Zona SDN"] --> S["Simple: bridge aislado y routing L3 con NAT"]
    Z --> V["VLAN: 802.1q sobre un bridge existente"]
    Z --> Q["QinQ: 802.1ad con VLAN apilada"]
    Z --> X["VXLAN: L2 sobre UDP 4789"]
    Z --> E["EVPN: VXLAN mas BGP para L3 enrutable"]
    S --> VN["VNets"]
    V --> VN
    Q --> VN
    X --> VN
    E --> VN
    VN --> SB["Subnets con CIDR gateway SNAT y rango DHCP"]

Opciones comunes a todas: Nodes, IPAM (opcional, default pve), DNS, ReverseDNS y DNSZone.

Simple. “It will create an isolated VNet bridge. This bridge is not linked to a physical interface, and VM traffic is only local on each the node. It can be used in NAT or routed setups.” Es la única zona con DHCP automático.

VLAN. Una sola opción, Bridge: el bridge Linux u OVS ya configurado en cada nodo que permite la conexión entre nodos. El tag va en la VNet.

QinQ. Requiere bridge local VLAN-aware, un Service VLAN que es el tag externo, un Service VLAN Protocol que puede ser 802.1q (default) o 802.1ad, y MTU reducido a 1496 si el físico es 1500. Los switches deben soportar VLANs apiladas. Su caso canónico es aislar dos clientes que usan internamente la misma VLAN 100 y el mismo rango IP: con S-VLAN 20 y 30 no se ven entre sí.

VXLAN. Encapsula tramas L2 en UDP con puerto destino 4789 por defecto. Requiere una Peers Address List con las IPs de todos los nodos de la zona, o un SDN Fabric que la genere, y el underlay lo montas tú: “You have to configure the underlay network yourself to enable UDP connectivity between all peers.” Aviso explícito: VXLAN no cifra nada, y para unir sitios hay que establecer una conexión segura aparte, por ejemplo una VPN site-to-site.

EVPN. Red L3 enrutable que puede abarcar varios clústeres, usando BGP para distribuir rutas. La VNet tiene IP y MAC anycast: el bridge tiene la misma IP en todos los nodos, así que un guest la usa como gateway esté donde esté, y el routing entre VNets pasa por una interfaz VRF.

Opción de zona EVPNDetalle
VRF VXLAN IDVXLAN-ID dedicado a interconectar VNets; debe diferir de los VXLAN-ID de las VNets
Primary Controllercontrolador EVPN principal; se usa para autoderivar las IPs VTEP
Additional Controllerscontroladores extra que anuncian las rutas L2VPN EVPN de la zona
VNet MAC AddressMAC anycast común a todas las VNets; se autogenera si no la das
Exit Nodesnodos que hacen de gateway hacia la red real y anuncian ruta por defecto
Primary Exit Nodefuerza el tráfico por un nodo en vez de balancear. Necesario con SNAT o si el router upstream no soporta ECMP
Exit Nodes Local Routingnecesario para alcanzar un servicio de un guest desde el propio exit node
Advertise Subnetsanuncia la subred completa; necesario con VMs silenciosas o con varias IPs
Disable ARP ND Suppressionrequerido con floating IPs, donde IP y MAC se mueven entre máquinas
Route-target Importimportar route targets EVPN externos, para cross-DC
MTU50 bytes menos que el físico. Default 1450

VNets, subnets, IPAM y DHCP con dnsmasq

Una VNet acaba viéndose como un bridge con el mismo nombre en cada nodo, listo para poner en el net0 de un guest. Su ID admite como máximo 8 caracteres; tiene Alias, Zone, Tag (el VLAN ID o VXLAN ID único), VLAN Aware para configurar VLANs dentro del guest e Isolate Ports, que marca como aislados los puertos de guest de esa interfaz y exige reiniciar el guest afectado. Ese aislamiento es local a cada host: para aislar también entre nodos hay que usar el firewall de la VNet.

Las subnets restringen qué IPs son configurables, asignan gateway en zonas L3, habilitan SNAT, permiten autoasignar IPs vía IPAM y registrar en DNS. Sus opciones son ID (el CIDR, por ejemplo 10.0.0.0/8), Gateway, SNAT y DNS Zone Prefix.

El IPAM por defecto es el plugin pve, con panel en Datacenter → SDN, y es el único que hoy permite crear, editar y borrar mapeos de IP. Los otros son NetBox y phpIPAM, con URL y token; NetBox pide además un fingerprint SHA-256 que se obtiene con openssl x509 -in /etc/ssl/certs/netbox.crt -noout -fingerprint -sha256.

El DHCP tiene un solo backend, dnsmasq, y su ciclo de vida es automático: al añadir una NIC a un guest se reserva una IP en el IPAM de la zona, al arrancar el guest se crea el mapeo MAC-IP en el plugin DHCP, y al quitar la NIC o destruir el guest se borran ambas entradas. Los rangos se definen por subnet:

pvesh set /cluster/sdn/vnets/<vnet>/subnets/<subnet> \
 -dhcp-range start-address=10.0.1.100,end-address=10.0.1.200 \
 -dhcp-range start-address=10.0.2.100,end-address=10.0.2.200

Gotcha: “You also need to have a gateway configured for the subnet - otherwise automatic DHCP will not work.” Rango sin gateway es DHCP que no reparte nada.

Los ficheros generados viven en /etc/dnsmasq.d/<zone>/: 00-default.conf con la config global de esa instancia, 10-<zone>-<subnet_cidr>.conf con las opciones de la subred, 10-<zone>-<subnet_cidr>.ranges.conf con los rangos y ethers con los mapeos MAC-IP tomados del IPAM. No los edites, se regeneran: para personalizar, añade en la misma carpeta un 90-custom.conf, que se lee después por orden alfabético. Hay un servicio systemd por zona, dnsmasq@<zone>, y las concesiones se guardan en /var/lib/misc/dnsmasq.<zone>.leases.

Controladores EVPN y BGP, y las reglas del ASN

El controlador EVPN traduce tu zona a sesiones BGP en FRR.

OpciónDetalle
ASN #ASN de BGP. Privados recomendados: 64512-65534 o 4200000000-4294967294
SDN Fabricfabric con todos los nodos de la zona, usado como underlay
PeersIPs de todos los nodos de la zona, más route reflectors o nodos externos
Nodesnodos donde el controlador está activo
Peer Group Namepor defecto VTEP; con varios controladores EVPN cada uno necesita el suyo
BGP Modeauto, el histórico, que usa iBGP salvo que exista un BGP controller; o explícito
ebgp-multihopsaltos extra para peers no directamente conectados, solo en modo external

La regla del ASN es dura y su violación se rechaza: “Every router can be member of exactly one Autonomous System, so any iBGP sessions on a given node (irregardless of address family) need to have the same ASN configured. Any configuration that has two iBGP sessions with different ASNs is rejected and an error thrown.” Y en la misma línea: “Every EVPN controller configured on a node must have the same ASN configured.”

El orden en que FRR deriva el ASN local está documentado: si solo existe un controlador BGP o EVPN, se usa el suyo; por compatibilidad, si hay controladores EVPN en modo auto y además un BGP controller, gana el ASN del BGP controller; en su defecto, el del EVPN controller. La IP VTEP se autogenera con su propio orden: la del loopback si hay un controlador BGP o IS-IS con interfaz loopback; si no, una IP de la lista de peers que esté configurada localmente; si no, la source IP de la ruta hacia el primer peer, cosa que puede fallar si esa ruta se anuncia dinámicamente, por ejemplo a través de un fabric.

El BGP Controller no lo usa una zona directamente: configura FRR para gestionar peers BGP, y sirve para definir un ASN distinto por nodo con eBGP o exportar rutas EVPN a un peer externo. Cita útil: “By default, for a simple full mesh EVPN, you don’t need to define a BGP controller.” El ISIS Controller cubre exportar rutas EVPN a un dominio IS-IS.

Ejemplo completo de la documentación con tres nodos y dos VNets: controlador myevpnctl con ASN 65000 y peers 192.168.0.1,192.168.0.2,192.168.0.3; zona myevpnzone con VRF VXLAN Tag 10000, MTU 1450, MAC 32:F4:05:FE:6C:0A y exit nodes node1,node2; y dos VNets, myvnet1 con tag 11000 y subnet 10.0.1.0/24 gateway 10.0.1.1, y myvnet2 con tag 12000 y subnet 10.0.2.0/24 gateway 10.0.2.1. Dentro del guest:

auto eth0
iface eth0 inet static
        address 10.0.1.100/24
        gateway 10.0.1.1
        mtu 1450

Gotcha crítico: “You need to add reverse routes for the 10.0.1.0/24 and 10.0.2.0/24 networks to node1 and node2 on your external gateway, so that the public network can reply back.” Sin ellas, el tráfico sale y no vuelve. La excepción es tener un router BGP externo que reciba las rutas anunciadas.

Segundo gotcha: con varios exit nodes los paquetes pueden entrar por un nodo y salir por otro, y el reverse path filter los descarta. Hay que desactivarlo, recordando el cambio de PVE 9:

# /etc/sysctl.d/99-rp-filter.conf
net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.all.rp_filter=0

Fabrics de PVE 9: OpenFabric, OSPF, BGP y WireGuard

Los fabrics llegaron en PVE 9.0 y se ampliaron en 9.2. Automatizan el routing entre nodos del clúster: son el underlay natural de EVPN y VXLAN, y sirven también como full-mesh para Ceph, tema del capítulo 12.

Se configuran en Datacenter → SDN → Fabrics → Add Fabric y requieren apt install frr frr-pythontools. Permisos: SDN.Audit o SDN.Allocate para ver, SDN.Allocate para crear o modificar, y Sys.Modify sobre cada nodo concreto para añadirlo o actualizarlo, porque eso escribe en su /etc/network/interfaces.

Dos conceptos transversales. El Loopback Prefix es un CIDR que valida que todos los router-ID caigan dentro. El Router-ID es una IPv4 en notación decimal, y por cada uno se crea automáticamente una interfaz dummy, pasiva por defecto; además se generan una access-list y un route-map que reescriben la source address de los paquetes salientes hacia la IP de esa dummy local.

ProtocoloNotas
OpenFabricbasado en IS-IS, optimizado para spine-leaf. Nombre del fabric: máximo 8 caracteres. Hello Interval default 3 s, CSNP Interval default 10 s, Hello Multiplier por interfaz default 10. Único que soporta IPv6 hoy
OSPFArea como entero de 32 bits o IP, donde 0 o 0.0.0.0 es el backbone. Redistribute desde bgp, connected, kernel o static, con route-map opcional. La dummy queda passive y toda interfaz sin IP se trata como point-to-point
BGP (9.2)eBGP unnumbered: cada nodo con su ASN, peering por interfaces físicas sin IP usando link-local IPv6. BFD para detección rápida de fallos, Route Filter, route maps de entrada y salida, Redistribute. Al menos uno de IPv4/IPv6 Prefix es obligatorio. Nodos que peerean directamente deben tener ASN distintos
WireGuard (9.2)VPN entre nodos PVE y externos. No aporta routing dinámico por sí mismo, pero transporta EVPN o VXLAN cifrado bajo OSPF o BGP

Con IPv6, que solo soporta OpenFabric, hace falta forwarding IPv6 global en todos los nodos del fabric, con post-up sysctl -w net.ipv6.conf.all.forwarding=1. Aviso repetido en OSPF y OpenFabric: “When you remove an interface with an entry in /etc/network/interfaces that has manual set, then the IP will not get removed on applying the SDN configuration.”

flowchart TB
    subgraph UNDER["Underlay: fabric BGP o OpenFabric"]
      N1["node1 con router-id en dummy"] --- N2["node2 con router-id en dummy"]
      N2 --- N3["node3 con router-id en dummy"]
      N1 --- N3
    end
    UNDER --> VTEP["Sesiones BGP entre VTEPs del peer group VTEP"]
    VTEP --> VRF["VRF de la zona EVPN con su VRF VXLAN ID"]
    VRF --> V1["VNet myvnet1 con subnet 10.0.1.0/24"]
    VRF --> V2["VNet myvnet2 con subnet 10.0.2.0/24"]
    VRF --> EX["Exit nodes node1 y node2"]
    EX --> GW["Gateway externo con rutas inversas hacia las subnets"]

BGP fabric como underlay de EVPN

Por defecto las sesiones VTEP del overlay corren como iBGP con el ASN del EVPN controller, mientras que el ASN de fabric de cada nodo se aplica con local-as en el grupo de vecinos del underlay. Por tanto el ASN del controlador y los ASN de fabric por nodo tienen que ser distintos: por ejemplo 65001, 65002 y 65003 en el underlay y 65000 en el controlador. Con BGP Mode = external las sesiones VTEP pasan a eBGP con el ASN de fabric del nodo, y el del controlador se sigue usando para derivar los route-targets. Requisito adicional: “Using a BGP fabric for an EVPN underlay requires each node to have an IPv4 address, since EVPN uses it as the VTEP address.”

Fabric WireGuard

Requiere apt install wireguard-tools y distingue nodos Internal (nodos PVE) y External (peers reutilizables de fuera). Los campos que importan: el Endpoint interno es la IP o hostname que otros nodos usan para conectar y se combina con el Listen Port, cuyo default es 51820; el Endpoint externo lleva puerto explícito, con IPv6 entre corchetes como [2001:db8::1]:51820; Allowed IPs es a la vez filtro de origen entrante y destino de routing saliente; el Name de la interfaz admite de 1 a 8 caracteres empezando por alfanumérico; Persistent Keepalive ayuda con NAT y firewalls stateful; y Skip Route Generation evita insertar rutas en la tabla del kernel para ese peer.

La clave privada se autogenera en /etc/pve/priv/wg-keys.cfg al guardar la interfaz, y la configuración resultante se escribe en /etc/wireguard/proxmox/<iface>.conf:

[Interface]
PrivateKey = EpP9R0kqNA1UjGGeDL0/y9Ok66G44dqa2ALYJ0jTWwQ=
ListenPort = 51820

[Peer]
PublicKey = xIlHE6ZA25Qnpa+HYT1un3fbjO5/0A9YUbbRmTyLWW4=
AllowedIPs = 198.51.100.10/32, 203.0.113.0/24
Endpoint = 192.0.2.10:51820

Un bloque [Peer] por cada nodo del fabric, con la clave pública que PVE guardó junto a ese nodo en la configuración.

Prefix lists, route maps e IPSets automáticos del firewall

PVE 9.2 añadió prefix lists y route maps como entidades cluster-wide bajo /etc/pve/sdn/, gestionables desde Datacenter → SDN, que se traducen a stanzas de FRR. La semántica es la de FRR, Cisco y Juniper: evaluación por número de secuencia, parada en la primera coincidencia y deny implícito al final.

Una prefix list tiene Sequence Nr. único y mayor o igual que 1 (si lo dejas vacío PVE asigna max + 5), Action, Prefix y los modificadores ge y le. PVE valida que ge no exceda a le, que ninguno sea menor que la longitud del propio prefijo y que ambos estén dentro del límite de la familia, /32 en IPv4 y /128 en IPv6. Nombres reservados: only_default, only_default_v6 y loopbacks_ips.

Un route map tiene Order de 0 a 65535, Action, Match, Set, Exit Action y Call. Entre las claves de Match están route-type, vni, las cuatro variantes de prefix-list sobre dirección y next-hop, metric, local-preference, peer y tag; entre las de Set, los distintos ip-next-hop, local-preference, tag, weight, metric y src, donde metric acepta N, +N, -N, rtt, igp o aigp y tag acepta un entero o el literal untagged. Nombres reservados: MAP_VTEP_IN, MAP_VTEP_OUT, correct_src y cualquiera que empiece por pve_.

# /etc/pve/sdn/prefix-lists.cfg
prefix-list: internal-subnets
 entries action=permit,prefix=10.0.0.0/8,ge=16,le=24,seq=10
 entries action=deny,prefix=10.0.0.0/8,le=32,seq=20

# /etc/pve/sdn/route-maps.cfg
route-map-entry: bgp-out_10
 action permit
 match key=ip-address-prefix-list,value=internal-subnets
 set key=local-preference,value=50

route-map-entry: bgp-out_20
 action permit

Esa segunda entrada sin match es el patrón de FRR para “permite todo lo demás”. Sin ella, el deny implícito descartaría todas las rutas que no coincidieron.

Por cada VNet, el firewall genera automáticamente cuatro IPSets en el scope SDN: <vnet>-all con los CIDRs de todas sus subnets, <vnet>-gateway con las IPs de gateway, <vnet>-no-gateway con los CIDRs excluyendo los gateways mediante entradas negadas, y <vnet>-dhcp con todos los rangos DHCP. Con el IPAM pve se genera además guest-ipam-<VMID>, por ejemplo guest-ipam-100, con todas las IPs del guest en todas sus VNets.

Advertencia: “When removing all entries for a guest and there are firewall rules still referencing the auto-generated IPSet then the firewall will fail to update the ruleset, since it references a non-existing IPSet.” Borrar las entradas IPAM de un guest cuyas reglas siguen referenciando su IPSet deja el firewall entero sin poder recargarse.

Diagnóstico de red y orden seguro para tocar producción

# --- Red base ---
ip -br addr
ip -br link
cat /etc/network/interfaces.new          # hay cambios pendientes?
ifreload -a -s                            # syntax check
journalctl -b -u networking -u pvenetcommit

# --- Bridge, VLAN y bonding ---
bridge link show
bridge vlan show                          # VLANs por puerto en bridges VLAN-aware
bridge fdb show br vmbr0                  # tabla MAC
cat /proc/net/bonding/bond0

# --- SDN ---
cat /etc/pve/sdn/.running-config          # y .version para la config aplicada
vtysh -c "show bgp l2vpn evpn summary"
vtysh -c "show bgp l2vpn evpn route"
vtysh -c "show ip route"
ip -d link show type vxlan
systemctl status dnsmasq@<zone>
cat /var/lib/misc/dnsmasq.<zone>.leases

El procedimiento que evita quedarte fuera del nodo, en este orden exacto. Uno. Abre una sesión SSH persistente y ten IPMI o iKVM disponible antes de empezar. Dos. Copia de seguridad: cp /etc/network/interfaces /root/interfaces.$(date +%F). Tres. Edita por GUI, que deja el staging en .new, o a mano. Cuatro. ifreload -a -s y luego ifreload -a -n. Cinco. Aplica; si el cambio es arriesgado y estás en remoto, programa antes un rollback automático:

echo 'cp /root/interfaces.backup /etc/network/interfaces && ifreload -a' | at now + 5 minutes

Seis. Verifica con ip -br addr y un ping al gateway, y abre una segunda sesión SSH nueva antes de cerrar la primera. Si la segunda entra, el cambio es bueno.

Errores comunes y diagnóstico

SíntomaCausa probableDiagnóstico y solución
Los cambios hechos en la GUI no surten efectosiguen en stagingls -l /etc/network/interfaces.new; pulsar Apply Configuration o ejecutar ifreload -a
Tras ifdown vmbr0 && ifup vmbr0 las VMs pierden la redlos tap y veth no se reenganchan al bridgeusar ifreload -a; si ya ocurrió, reiniciar los guests
Tras un upgrade cambian los nombres de NIC y el nodo queda sin rednuevo esquema systemd o kernel y driver nuevosconsola IPMI, ip -br link, pve-network-interface-pinning generate o un .link manual más update-initramfs -u -k all
Las VNets del SDN no aparecen en el nodofalta source /etc/network/interfaces.d/* al final del ficheroañadir la línea y ifreload -a
Un OVSIntPort está configurado pero nunca subeno aparece en ovs_ports del bridgeañadirlo a ovs_ports; comprobar con ovs-vsctl show
Interfaces con mtu 9000 que no levantan en NIC Intel Gigabitlímite de hardware de 8996bajar a 8996 todas las MTU implicadas
VXLAN funciona pero se pierden los paquetes grandesMTU sin restar los 50 bytes1450 en la zona y en el guest; verificar con ping -M do -s 1422
QinQ con problemas de MTUfaltan 4 bytes1496
Las conexiones salientes de VMs NATeadas se bloquean con el firewall activofalta la zona de conntrackañadir iptables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1 y su post-down
El NAT deja de funcionar tras actualizar de PVE 8 a 9ip_forward estaba en /etc/sysctl.conf, que ya no se honramoverlo a /etc/sysctl.d/99-forward.conf y systemctl restart systemd-sysctl
EVPN con varios exit nodes: tráfico asimétrico descartadorp_filter estricto/etc/sysctl.d/99-rp-filter.conf con rp_filter=0 en all y default
Los guests EVPN salen pero nadie les respondefaltan rutas inversas en el gateway externoañadir rutas hacia las subnets apuntando a los exit nodes, o usar un router BGP
El SDN rechaza la configuración con error de ASNdos sesiones iBGP con ASN distintos en el mismo nodounificar el ASN de los controladores EVPN; separar el ASN del fabric del ASN del controlador
El DHCP del SDN no reparte direccionesla subnet no tiene gateway configuradodefinir el gateway; revisar systemctl status dnsmasq@<zone> y el fichero de leases
Tras el upgrade 8 a 9 la red no arranca y FRR bloqueapost-up systemctl restart frr.service provoca deadlocksustituir por post-up /usr/bin/systemctl is-active --quiet frr.service && /usr/bin/systemctl restart frr.service || true
La configuración de /etc/frr/frr.conf.local deja de aplicarseel SDN desactiva daemons en /etc/frr/daemonscrear /etc/default/frr con ospfd=yes o fabricd=yes
El firewall falla al actualizar el ruleset tras borrar entradas de IPAMhay reglas que referencian un guest-ipam-<VMID> inexistentequitar la referencia o restaurar la entrada del IPAM
El hoster corta la red en cuanto arrancan las VMsvarias MAC en una sola interfazpasar a modo routed, o registrar MACs virtuales en el panel del proveedor
Los cambios de pve-network-interface-pinning no llegan al firewall del clústercluster.fw no se actualiza automáticamenteeditar /etc/pve/firewall/cluster.fw a mano

Lo que queda funcionando

Tienes la red del nodo bajo control: sabes que la GUI escribe en /etc/network/interfaces.new y que solo Apply o pvenetcommit lo activan, que ifreload -a recarga sin desconectar a los guests mientras ifup/ifdown los deja aislados, cómo montar un bridge VLAN-aware con la gestión en su propia VLAN sobre un bond LACP, qué restar al MTU en cada encapsulación, y cómo sobrevivir en un hoster con binding IP/MAC usando routed o masquerading con sus conntrack zones.

Del lado SDN tienes el modelo completo: zonas Simple, VLAN, QinQ, VXLAN y EVPN, VNets con subnets e IPAM, DHCP con dnsmasq, controladores con sus reglas de ASN y los fabrics de PVE 9 con OpenFabric, OSPF, BGP unnumbered y WireGuard.

Lo que ha ido apareciendo sin desarrollarse es el firewall: las reglas FORWARD, los flags que hay que activar para que una regla de VM tenga efecto, los IPSets management y local_network, y los bridges fwbr que se cuelan en el camino del NAT. Eso, junto con usuarios, permisos, realms de autenticación y 2FA, es el contenido del capítulo 10.