VXLAN (Virtual Extensible LAN) encapsula tramas Ethernet dentro de paquetes UDP, de modo que varios servidores en redes IP distintas comparten un mismo segmento de capa 2 como si estuvieran conectados al mismo switch. Es la tecnología que usan Kubernetes, OpenStack o Proxmox SDN para sus redes virtuales. En este tutorial crearás una red overlay 10.0.100.0/24 (VNI 100) entre dos servidores Ubuntu 24.04 usando solo el kernel e iproute2, la conectarás a un bridge Linux, añadirás un tercer host y la harás persistente con systemd-networkd.

Requisitos previos

  • Dos servidores con Ubuntu 24.04 LTS (y un tercero opcional para el paso 5), por ejemplo VPS de CubePath.
  • Un usuario no root con privilegios sudo.
  • Conectividad IP entre los servidores. Lo ideal es una red privada; este tutorial usa 192.0.2.10 y 192.0.2.20 como IP subyacentes (underlay).
  • El puerto UDP 4789 permitido entre los servidores.

Algunos términos que aparecen en la guía:

TérminoSignificado
VTEPExtremo del túnel VXLAN; aquí, la interfaz vxlan100 de cada servidor.
VNIIdentificador de 24 bits de la red virtual. Ambos extremos deben usar el mismo.
FDBTabla que asocia direcciones MAC con el VTEP remoto al que hay que enviarlas.
UnderlayLa red IP real por la que viajan los paquetes encapsulados.
OverlayLa red de capa 2 virtual que ven las máquinas.

Paso 1: Preparar los servidores

Identifica la interfaz y la IP que usarás como underlay en cada servidor:

ip -br addr
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             203.0.113.10/24
eth1             UP             192.0.2.10/24

En este ejemplo el underlay es eth1 con 192.0.2.10. Anota el nombre de tu interfaz: en tu servidor puede llamarse ens18, enp1s0 u otro.

Si usas UFW, permite UDP 4789 solo desde la IP del otro servidor. En el host A (192.0.2.10):

sudo ufw allow from 192.0.2.20 to any port 4789 proto udp

En el host B (192.0.2.20):

sudo ufw allow from 192.0.2.10 to any port 4789 proto udp

UFW también filtra el tráfico que entra por la interfaz overlay. Permite el tráfico de la red overlay en ambos hosts:

sudo ufw allow in on vxlan100 from 10.0.100.0/24

Paso 2: Crear un túnel VXLAN punto a punto

Con solo dos hosts, la forma más sencilla es indicar el VTEP remoto con remote. El puerto 4789 es el asignado por IANA; si no lo indicas, Linux usa 8472 por compatibilidad histórica, así que especifícalo siempre.

En el host A:

sudo ip link add vxlan100 type vxlan id 100 local 192.0.2.10 remote 192.0.2.20 dstport 4789 dev eth1
sudo ip link set vxlan100 mtu 1450 up
sudo ip addr add 10.0.100.1/24 dev vxlan100

En el host B:

sudo ip link add vxlan100 type vxlan id 100 local 192.0.2.20 remote 192.0.2.10 dstport 4789 dev eth1
sudo ip link set vxlan100 mtu 1450 up
sudo ip addr add 10.0.100.2/24 dev vxlan100

La MTU de 1450 se debe a que VXLAN sobre IPv4 añade 50 bytes de cabeceras (Ethernet interna, VXLAN, UDP e IP exterior) a cada paquete. Si la MTU del underlay es mayor de 1500 (jumbo frames), puedes subirla restando esos 50 bytes.

Revisa los parámetros de la interfaz con la salida detallada:

ip -d link show vxlan100
5: vxlan100: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether 3a:5c:91:0e:7b:21 brd ff:ff:ff:ff:ff:ff promiscuity 0 allmulti 0 minmtu 68 maxmtu 65535
    vxlan id 100 remote 192.0.2.20 local 192.0.2.10 dev eth1 srcport 0 0 dstport 4789 ttl auto ageing 300 ...

Paso 3: Verificar la conectividad overlay

Desde el host A, haz ping a la IP overlay del host B:

ping -c 3 10.0.100.2
64 bytes from 10.0.100.2: icmp_seq=1 ttl=64 time=0.703 ms
64 bytes from 10.0.100.2: icmp_seq=2 ttl=64 time=0.611 ms

Para confirmar que el tráfico va encapsulado, captura en la interfaz underlay del host B mientras repites el ping:

sudo tcpdump -ni eth1 udp port 4789
10:14:02.118 IP 192.0.2.10.47213 > 192.0.2.20.4789: VXLAN, flags [I] (0x08), vni 100
IP 10.0.100.1 > 10.0.100.2: ICMP echo request, id 3, seq 1, length 64

Comprueba también que el tamaño máximo pasa sin fragmentar. 1422 bytes de datos más 28 de cabeceras ICMP e IP suman exactamente 1450:

ping -c 3 -M do -s 1422 10.0.100.2

Si este ping falla con message too long y el anterior funciona, la MTU del underlay es menor de 1500 y debes reducir la de vxlan100 en la misma proporción.

Paso 4: Conectar la VXLAN a un bridge Linux

Una IP en vxlan100 sirve para comunicar los propios hosts. Para que máquinas virtuales o contenedores compartan el segmento, conecta la VXLAN a un bridge y pon la IP del host en el bridge. En el host A, primero quita la IP de la interfaz VXLAN:

sudo ip addr del 10.0.100.1/24 dev vxlan100

Crea el bridge, añade la VXLAN como puerto y asigna la IP al bridge:

sudo ip link add br100 type bridge
sudo ip link set br100 mtu 1450 up
sudo ip link set vxlan100 master br100
sudo ip addr add 10.0.100.1/24 dev br100

Repite en el host B con 10.0.100.2/24. Cualquier interfaz que conectes a br100 (la tap de una VM de KVM o el extremo de un par veth de un contenedor) queda en el mismo segmento de capa 2 que las del otro host. Esas interfaces también deben usar MTU 1450.

Comprueba los puertos del bridge y las MAC aprendidas a través de la VXLAN:

bridge link show
bridge fdb show dev vxlan100
6: vxlan100: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 master br100 state forwarding priority 32 cost 100
00:00:00:00:00:00 dst 192.0.2.20 self permanent
6e:1f:24:9a:0c:33 dst 192.0.2.20 self

La primera entrada FDB, con MAC todo ceros, es el destino por defecto que creó la opción remote: el tráfico broadcast, multicast y el de MAC desconocidas se envía ahí. Las demás son MAC aprendidas del tráfico recibido.

Si tu firewall está activo, la regla del paso 1 para vxlan100 deja de aplicarse al tráfico con IP del host, que ahora entra por br100. Añade la equivalente:

sudo ufw allow in on br100 from 10.0.100.0/24

Paso 5: Añadir un tercer host con entradas FDB

La opción remote solo admite un destino. Con tres o más hosts, crea la VXLAN sin remote y añade una entrada FDB con MAC todo ceros por cada VTEP remoto. Linux replicará el tráfico broadcast (por ejemplo, las peticiones ARP) a todos ellos y aprenderá después qué MAC está detrás de cada uno.

En el host C (192.0.2.30), crea la VXLAN y el bridge:

sudo ip link add vxlan100 type vxlan id 100 local 192.0.2.30 dstport 4789 dev eth1
sudo ip link add br100 type bridge
sudo ip link set vxlan100 mtu 1450 master br100 up
sudo ip link set br100 mtu 1450 up
sudo ip addr add 10.0.100.3/24 dev br100

Añade los VTEP de los hosts A y B:

sudo bridge fdb append 00:00:00:00:00:00 dev vxlan100 dst 192.0.2.10
sudo bridge fdb append 00:00:00:00:00:00 dev vxlan100 dst 192.0.2.20

En los hosts A y B, añade el host C como destino adicional (la entrada del otro host ya existe gracias a remote):

sudo bridge fdb append 00:00:00:00:00:00 dev vxlan100 dst 192.0.2.30

Abre el puerto UDP 4789 a la nueva IP en todos los hosts y verifica desde el host C:

ping -c 3 10.0.100.1
ping -c 3 10.0.100.2

Paso 6: Hacer la configuración persistente

Todo lo creado con ip link desaparece al reiniciar. Ubuntu 24.04 Server gestiona la red con systemd-networkd (a través de Netplan), así que puedes declarar la VXLAN y el bridge con archivos de networkd en /etc/systemd/network/. Netplan genera sus archivos en /run/systemd/network/, de modo que los tuyos conviven con ellos sin conflictos.

Antes de continuar, borra la configuración temporal en el host para que networkd la cree desde cero:

sudo ip link del vxlan100
sudo ip link del br100

Define el bridge en el host A:

sudo nano /etc/systemd/network/20-br100.netdev
[NetDev]
Name=br100
Kind=bridge
MTUBytes=1450

Define la VXLAN. Independent=yes permite crearla sin vincularla al archivo .network de la interfaz underlay, que en Ubuntu genera Netplan:

sudo nano /etc/systemd/network/20-vxlan100.netdev
[NetDev]
Name=vxlan100
Kind=vxlan
MTUBytes=1450

[VXLAN]
VNI=100
Local=192.0.2.10
Remote=192.0.2.20
DestinationPort=4789
Independent=yes

Conecta la VXLAN al bridge:

sudo nano /etc/systemd/network/20-vxlan100.network
[Match]
Name=vxlan100

[Network]
Bridge=br100

Y asigna la IP al bridge:

sudo nano /etc/systemd/network/20-br100.network
[Match]
Name=br100

[Network]
Address=10.0.100.1/24
ConfigureWithoutCarrier=yes

Si tienes más de dos hosts, elimina Remote= del .netdev y añade en 20-vxlan100.network una sección por cada VTEP remoto:

[BridgeFDB]
MACAddress=00:00:00:00:00:00
Destination=192.0.2.20

Recarga la configuración de networkd:

sudo networkctl reload

Comprueba el estado de las dos interfaces:

networkctl status vxlan100 br100
● 6: vxlan100
                     Link File: /usr/lib/systemd/network/99-default.link
                  Network File: /etc/systemd/network/20-vxlan100.network
                         State: enslaved (configured)
...
● 7: br100
                  Network File: /etc/systemd/network/20-br100.network
                         State: routable (configured)
                       Address: 10.0.100.1

Repite en el host B cambiando Local, Remote y la dirección, reinicia uno de los servidores y confirma que el ping por la overlay sigue funcionando después del arranque.

Solución de problemas

El ping overlay no responde. Comprueba en este orden: que ambos lados usan el mismo VNI y el mismo dstport (ip -d link show vxlan100), que el tráfico sale (sudo tcpdump -ni eth1 udp port 4789 en el origen) y que llega al destino (la misma captura en el otro host). Si sale pero no llega, el puerto UDP está bloqueado en el camino o en el firewall del destino.

El ping funciona pero SSH o HTTP se cuelgan. Es casi siempre MTU: los paquetes pequeños pasan y los grandes se descartan. Asegúrate de que vxlan100, br100 y todas las interfaces de VM o contenedor conectadas al bridge usan 1450 (o la MTU del underlay menos 50).

Las MAC no se aprenden en una VXLAN multihost. Revisa con bridge fdb show dev vxlan100 que existe una entrada 00:00:00:00:00:00 dst por cada VTEP remoto en todos los hosts. Si falta en uno, el ARP de ese host no llega a los demás.

Conclusión

Has creado una red overlay VXLAN entre servidores Ubuntu 24.04 con las herramientas del kernel: un túnel punto a punto, un bridge para conectar VM o contenedores, replicación a varios hosts con la FDB y una configuración persistente con systemd-networkd. A partir de aquí puedes cifrar el underlay llevando la VXLAN sobre una mesh WireGuard, crear varios VNI para aislar entornos (uno por bridge) o sustituir la FDB estática por EVPN con FRRouting cuando el número de hosts crezca.