Guias

Network bonding y VLANs en Linux sin GUI: nmcli y systemd-networkd

Network bonding y VLANs en Linux sin GUI: nmcli y systemd-networkd

Si manejás un servidor Linux serio (homelab, datacenter, cloud), tarde o temprano necesitas configurar bonding (varias NICs como una sola, para redundancia y bandwidth) o VLANs (separar tráfico por red lógica). NetworkManager (con nmcli) y systemd-networkd son las dos formas modernas de hacerlo sin GUI. Esta guía te enseña ambos, cuándo usar cada uno, y los errores más comunes.

El setup que más he recomendado a clientes en los últimos 3 años: bonding de 2 NICs para redundancia, VLANs taggeadas para segmentación, todo gestionado con nmcli o systemd-networkd según preferencia. La razón por la que esta combinación funciona es que ambos management tools exponen las mismas primitivas del kernel, así que puedes migrar de uno a otro sin re-aprender. Esta guía documenta el setup de referencia, con los 3 errores que más he visto (mtu mal, native VLAN por default, bridge no creado), y el test de failover que verifica que el bond efectivamente cambia de slave en menos de 2 segundos cuando un cable se desconecta.

Si vas a configurar bonding + VLANs en un server Linux, esta guía te lleva a un setup production-ready.

TL;DR — Lo que vas a tener al final

  • Tiempo de setup: 30-60 minutos para cifrar un disco limpio, 1-2 horas para migrar un sistema ya instalado.
  • Requisitos: 2+ NICs en el server, switch gestionable con 802.1Q, root.
  • Resultado: Bonding + VLANs funcionales, failover <2s, DHCP por VLAN, troubleshooting claro.
  • Troubleshooting típico: mtu no negocia, native VLAN mal, bridge ausente. Solución: `ip link show` + `bridge vlan show` + tcpdump.

Qué es bonding y qué es VLAN (en 30 segundos)

Bonding (también llamado NIC teaming o link aggregation)

Es tomar 2+ interfaces de red físicas y hacer que actúen como una sola. Beneficios:

  • Redundancia: si un cable/NIC falla, el otro sigue (failover)
  • Bandwidth agregado: 2 NICs de 1 Gbps = 2 Gbps (en teoría; depende del modo)
  • Balanceo de carga: distribuir tráfico entre NICs

El switch tiene que estar configurado del otro lado también (LAG, LACP).

VLAN (Virtual LAN)

Es separar una red física en múltiples redes lógicas. Beneficios:

  • Segmentación: tráfico de servidores, usuarios, IoT en VLANs distintas, no se ven entre sí
  • Seguridad: compromiso de IoT no afecta servidores
  • Performance: menos broadcast domain = menos ruido

El switch tiene que estar configurado como “trunk” (pasar múltiples VLANs por un cable).

Las VLANs usan tags IEEE 802.1Q. El “native VLAN” o “PVID” es la que va sin tag (access port).

Cuándo usar nmcli vs systemd-networkd

NetworkManager (con nmcli para CLI):

  • Default en: Ubuntu Desktop, Fedora Workstation, RHEL, Pop!_OS, casi todas las desktop
  • Bueno para: dynamic environments (WiFi, VPN, mobile broadband)
  • Setup: comandos nmcli o archivos en /etc/NetworkManager/system-connections/
  • Si ya tienes NetworkManager corriendo, usa nmcli para mantener consistencia

systemd-networkd:

  • Default en: Debian minimal, Ubuntu Server (netplan lo usa por debajo), muchas distros server
  • Bueno para: servers estáticos, containers, configuración reproducible
  • Setup: archivos .netdev y .network en /etc/systemd/network/
  • Más predecible, menos “magia”

No mezcles ambos en la misma máquina — se pelean. Si vas a usar systemd-networkd, deshabilitá NetworkManager:


sudo systemctl disable --now NetworkManager
sudo systemctl enable --now systemd-networkd

disable --now apaga NetworkManager inmediatamente y lo deja fuera del próximo boot. enable --now arranca systemd-networkd ya. Antes de hacer esto, asegurate de tener una forma alternativa de acceder al server (consola IPMI, KVM cloud, conexión serie) porque si NetworkManager manejaba tu única interface de red y la deshabilitas mal, te quedás sin red hasta reiniciar. Si estás en una laptop con WiFi, esto es particularmente arriesgado.

Setup 1: Bonding con nmcli

Crear el bond

El nmcli trabaja con conexiones (perfiles guardados en /etc/NetworkManager/system-connections/) y devices (las interfaces físicas reales). Para bonding, primero creamos una conexión tipo bond que es la lógica del aggregator, después le “sumamos” dos slaves (NICs físicas). El kernel expone la nueva interfaz bond0 cuando activás la conexión. Importante: la sintaxis multi-línea con al final es bash continuation — pegá el bloque entero, no línea por línea.


# Ver NICs disponibles
nmcli device status
# Crear interfaz bond0 (LACP, modo 4)
sudo nmcli connection add type bond 
  con-name bond0 
  ifname bond0 
  mode 802.3ad 
  lacp_rate fast 
  miimon 100
# Agregar slaves (NICs físicas)
sudo nmcli connection add type ethernet 
  con-name bond0-slave-eth0 
  ifname eth0 
  master bond0
sudo nmcli connection add type ethernet 
  con-name bond0-slave-eth1 
  ifname eth1 
  master bond0
# Configurar IP
sudo nmcli connection modify bond0 
  ipv4.addresses 192.168.5.10/24 
  ipv4.gateway 192.168.5.1 
  ipv4.dns "1.1.1.1,8.8.8.8" 
  ipv4.method manual
# Activar
sudo nmcli connection up bond0

Verificar que los nombres de NICs coinciden con tu hardware: ip link show te lista eth0, enp0s3, ens5, eno1, etc., según el naming scheme de tu distro (predictable names del systemd, o tradicional en distros viejas). Si el comando para agregar slave dice “device eth0 not found”, no es que falte el hardware — es que tu NIC se llama distinto. En Ubuntu 20.04+ con nombres predecibles, las onboard suelen llamarse enpXsY y las de slot PCIe ensY.

Verificar


# Ver estado del bond
cat /proc/net/bonding/bond0
# Output esperado:
# Ethernet Channel Bonding Driver: v6.x
# Bonding Mode: IEEE 802.3ad Dynamic link aggregation
# Transmit Hash Policy: layer3+4 (1)
# MII Status: up
# ...
# Slave Interface: eth0
# MII Status: up
# Speed: 1000 Mbps
# ...
# Slave Interface: eth1
# MII Status: up
# Speed: 1000 Mbps

/proc/net/bonding/bond0 es el debug path oficial del kernel module de bonding. Lo que tienes que mirar: MII Status: up en ambas slaves (si alguna dice down, ese cable no está conectado o el link no negocia), Aggregator ID (debe coincidir entre slaves — si difieren, el switch no está agregándolas como un solo bundle), y Partner MAC Address (si dice 00:00:00:00:00:00, el LACP no negocia con el otro lado, lo que casi siempre significa que el switch no tiene LACP configurado en el puerto).

Modos de bonding (los principales)

Modo Nombre Cuándo usarlo balance-rr (0) Round-robin Load balancing básico, sincoordinación con switch active-backup (1) Failover Alta disponibilidad, 1 NIC activo balance-xor (2) XOR por MAC Balance básico broadcast (3) Broadcast Redundancia máxima (mismo packet por todas las NICs) 802.3ad (4) LACP El más común. Requiere switch LACP. Standard IEEE. balance-tlb (5) Adaptive TX load Balance TX, sincoordinación balance-alb (6) Adaptive load Balance TX+RX

Recomendación: usa 802.3ad (LACP) si tu switch lo soporta. Es standard, negociado, y el más predecible.

Setup 2: VLANs con nmcli

VLAN sobre bond (caso típico de servidor)

Las VLANs en Linux se exponen como sub-interfaces del device padre, con el sufijo .VID. Cuando creas bond0.10, el kernel entiende que tiene que agregar/extraer el tag 802.1Q con ID 10 en cada frame que entra/sale por bond0. La ventaja de hacerlo sobre el bond (en vez de sobre una NIC individual): si una NIC cae, el bond sigue funcionando y las VLANs no se enteran — la conmutación por error es transparente para las VLANs.


# Crear VLAN interface sobre bond0 (VLAN ID 10)
sudo nmcli connection add type vlan 
  con-name bond0.10 
  ifname bond0.10 
  dev bond0 
  id 10
# Configurar IP para VLAN 10
sudo nmcli connection modify bond0.10 
  ipv4.addresses 10.0.10.5/24 
  ipv4.method manual
# Crear VLAN 20 (servidores)
sudo nmcli connection add type vlan 
  con-name bond0.20 
  ifname bond0.20 
  dev bond0 
  id 20
sudo nmcli connection modify bond0.20 
  ipv4.addresses 10.0.20.5/24 
  ipv4.method manual
# Crear VLAN 30 (IoT)
sudo nmcli connection add type vlan 
  con-name bond0.30 
  ifname bond0.30 
  dev bond0 
  id 30
sudo nmcli connection modify bond0.30 
  ipv4.addresses 10.0.30.5/24 
  ipv4.method manual
# Activar todas
sudo nmcli connection up bond0.10
sudo nmcli connection up bond0.20
sudo nmcli connection up bond0.30

Trampa común: si las VLANs no levantan, casi siempre es porque el bond0 padre no está activo. verifica con nmcli connection show --active que bond0 esté en la lista. Si solo ves los slaves pero no el bond, algo en la config anterior falló (probable: lacp_rate fast mal tipeado, o el switch no negociando — revisa /proc/net/bonding/bond0).

Verificar VLAN


# Ver interfaces con VLAN
ip -d link show
# Output esperado:
# 5: bond0.10@bond0:  ...
#     vlan id 10 

El flag -d muestra detalles extendidos por device. Lo crítico: vlan id 10 confirma que el ID que pusiste en nmcli matchea lo que el kernel cargó. Si ves bond0.10@bond0 con , significa que la sub-interface existe pero el link físico debajo está caído (cable suelto, switch apagado, bond sin slaves activas).

Configurar el switch

Esto es la mitad del trabajo. El switch tiene que estar en modo trunk y aceptar las VLANs 10, 20, 30. Ejemplo en un switch TP-Link gestionable:


Port 1 (conectado al servidor):
- Mode: Trunk
- Allowed VLANs: 1,10,20,30,40
- Native VLAN: 1 (PVID)
- Tagged VLANs: 10,20,30,40

Si el switch no acepta la VLAN, el Linux levanta la interface pero no llega tráfico. Troubleshooting directo: tcpdump -i bond0 -e -n (mostrado más abajo en la sección de troubleshooting) te muestra si están llegando frames con tag. Si llegan frames sin tag cuando esperas tagged, el problema es del switch — revisa que la VLAN esté en “Tagged VLANs” del puerto, no solo en “Allowed VLANs”. El tag explícito es lo que hace que el switch inyecte el header 802.1Q en cada frame.

Setup 3: Bonding con systemd-networkd

Archivos de configuración

/etc/systemd/network/10-bond0.netdev:


[NetDev]
Name=bond0
Kind=bond
[Bond]
Mode=802.3ad
LACPTransmitRate=fast
MIIMonitorSec=100ms

/etc/systemd/network/20-bond0-slaves.network (una sección por slave):


[Match]
Name=eth0
[Network]
Bond=bond0

Y otro igual para eth1 (cambiando [Match] Name=eth1).

/etc/systemd/network/30-bond0.network:


[Match]
Name=bond0
[Network]
Address=192.168.5.10/24
Gateway=192.168.5.1
DNS=1.1.1.1
DNS=8.8.8.8

Activar


sudo systemctl restart systemd-networkd
ip addr show bond0
cat /proc/net/bonding/bond0

restart (no reload) es la opción correcta acá. systemd-networkd no tiene hot-reload de archivos — lee toda la config al arrancar y la aplica. restart lee /etc/systemd/network/, genera las interfaces, y configura todo. Si tienes un error de sintaxis en algún .netdev o .network, lo vas a ver con journalctl -u systemd-networkd -n 50. El ip addr show bond0 confirma que la IP está aplicada; /proc/net/bonding/bond0 confirma que el bonding kernel module tomó el control. Si esto último devuelve “No such file or directory”, el módulo bonding no está cargado (sudo modprobe bonding).

Setup 4: VLANs con systemd-networkd

/etc/systemd/network/10-bond0.netdev (ya existe del paso anterior).

/etc/systemd/network/40-vlan10.netdev:


[NetDev]
Name=bond0.10
Kind=vlan
[VLAN]
Id=10

/etc/systemd/network/50-vlan10.network:


[Match]
Name=bond0.10
[Network]
Address=10.0.10.5/24

Repetir para cada VLAN (vlan20, vlan30, etc.).

Activar


sudo systemctl restart systemd-networkd
ip -d link show

Mismo patrón que con el bond: restart para releer config, después verificación. ip -d link show lista las VLANs nuevas con su vlan id correspondiente. Si una VLAN no aparece, el .netdev correspondiente tiene algún error de sintaxis — journalctl -u systemd-networkd -e te muestra los últimos mensajes con line numbers y razón exacta del fallo (típico: nombre duplicado, ID de VLAN fuera de rango 1-4094, sección [VLAN] mal escrita).

Tabla de referencia rápida nmcli vs systemd-networkd

Acción nmcli systemd-networkd Ver estado nmcli device status networkctl list Crear bond nmcli connection add type bond ... Crear .netdev con Kind=bond Agregar slave nmcli connection add ... master bond0 .network con Bond=bond0 Crear VLAN nmcli connection add type vlan ... .netdev con Kind=vlan Configurar IP nmcli connection modify ... ipv4.addresses ... .network con Address=... Activar nmcli connection up NAME systemctl restart systemd-networkd Debugging nmcli connection show networkctl status

Troubleshooting

El bond está UP pero no llega tráfico

Causa común: el switch no está en modo LACP o no tiene la config correcta.


# Ver qué dice el bond
cat /proc/net/bonding/bond0
# Si ves "Aggregator ID: 1" o "Partner MAC Address: 00:00:00:00:00:00",
# el LACP no negocia con el switch

La línea Partner MAC Address: 00:00:00:00:00:00 es la firma clásica de LACP sin negociar — el partner debería mostrar la MAC del switch (algo como a4:5e:60:xx:xx:xx). Si está todo en ceros, el otro lado no está enviando LACPDUs (los paquetes de protocolo LACP). Eso puede ser: 1) el puerto del switch no está en modo LACP, 2) el puerto está en modo “static trunk” en vez de LACP active, 3) hay un VLAN mismatch en el path, 4) alguien puso un dumb switch entre tu server y el switch real.

Solución:

1. verifica la config del switch (LACP habilitado en el puerto)

2. prueba con mode active-backup que no requiere switch especial

3. usa tcpdump -i eth0 -n -e y mira si llegan tagged frames

El active-backup es el modo “barato”: un NIC activo, la otra como backup. No requiere LACP en el switch (funciona con cualquier puerto Ethernet). Te da failover pero no bandwidth agregado. Es lo que usas cuando no tienes un switch gestionable.

VLAN levantada pero no hay conectividad

Causa común: el switch no tiene la VLAN en el trunk.


# Ver el tag en paquetes
tcpdump -i bond0 -e -n
# Output debe mostrar "vlan 10" en frames de esa VLAN
# Si ves frames sin tag cuando esperas tagged, problema es de switch

tcpdump -e muestra el header Ethernet con info 802.1Q. Lo que esperas: frames con la marca vlan 10 (o el ID que pusiste). Si los frames que te llegan de la VLAN 10 no muestran el tag, el switch no los está etiquetando — puede ser que el puerto esté configurado como “access” (no trunk) o que la VLAN esté mal mapeada en el trunk. Si ves el tag pero la conectividad no anda, el problema es de IP/routing, no de VLAN.

Solución: revisa config de trunk en switch.

nmcli y systemd-networkd pelean

Si ves interfaces duplicadas o estado raro:


# Deshabilitar NetworkManager si usas systemd-networkd
sudo systemctl disable --now NetworkManager
sudo systemctl mask NetworkManager
# O al revés: deshabilitar systemd-networkd
sudo systemctl disable --now systemd-networkd

El mask es la clave: crea un symlink a /dev/null en el path del unit, así ni systemctl start lo puede arrancar. Es la forma “nuclear” de deshabilitar un servicio. Útil cuando NetworkManager se vuelve a activar solo después de un update de paquete o un reboot. Si los dos siguen peleando, masked NM y reiniciá — después de un reboot limpio solo uno va a tomar el control de las interfaces.

Cambios no se aplican


# nmcli: reload explícito
sudo nmcli connection reload
# systemd-networkd: restart
sudo systemctl restart systemd-networkd
# Si sigue sin aplicar: ver logs
journalctl -u NetworkManager -n 50
journalctl -u systemd-networkd -n 50

nmcli connection reload no reinicia el demonio, solo relee los archivos de configuración. Para activar la nueva config en una conexión específica, tienes que hacer nmcli connection up (eso la baja y la sube con la config nueva). En systemd-networkd no hay “reload” granular — restart lee todo de nuevo. Si los cambios no se aplican, el log es tu amigo: journalctl -u NetworkManager -f en un terminal, mientras hacés cambios en otro, te muestra qué está intentando hacer el daemon y dónde falla.

Errores comunes de principiante

1. VLAN ID 1 por error

La VLAN 1 es la “native” o “default” en muchos switches. Si la usas “porque sí”, terminás mezclando tráfico. usa VLANs con IDs específicos (10, 20, 30, etc.) y dejá la 1 para management del switch.

2. IP de management en VLAN equivocada

Si ponés la IP de management del servidor (la que usas para SSH) en la VLAN 30 (IoT), te queda bloqueado. Regla: management IP en VLAN 1 o VLAN dedicada de management.

3. No configurar el switch

El 90% de los problemas de bonding/VLAN son del lado del switch, no de Linux. Siempre verifica que el switch esté en modo LACP/trunk y que las VLANs correctas estén permitidas.

4. Olvidar el gateway

Una VLAN sin gateway (default route) no sale a otras redes. configura el gateway de cada VLAN en su .network o en nmcli.

5. Bond con NICs de velocidades diferentes

Mezclar una NIC de 1 Gbps con una de 10 Gbps en el mismo bond funciona pero perdés el balanceo real (las frames se distribuyen, pero la NIC de 1 Gbps limita). usa NICs iguales para mejor resultado.

6. MTU mal configurado en VLAN

Si tu switch soporta jumbo frames (MTU 9000), puedes configurar:


# nmcli
sudo nmcli connection modify bond0.10 
  ethernet.mtu 9000
# systemd-networkd en .network
[Link]
MTUBytes=9000

Detalle del flag en nmcli: ethernet.mtu está en bytes, no en bits. El default es 1500 (Ethernet estándar). Jumbo frames comunes son 9000 (10GbE típico) o 4000 (algunos storage). Si bajás de 1500 (por ejemplo 1400 para VPN overlay), el ajuste se hace en el device que encapsula, no en la VLAN.

Pero todas las devices en el path (NIC, switch, peer) deben soportar la MTU. Si una sola no soporta, fragments y pérdida de paquetes. Cómo verificar: después de cambiar MTU, prueba con ping -M do -s 8972 (setea el flag “don’t fragment” y manda un payload de 8972 bytes, que con headers es ~9000). Si el ping funciona, el path soporta jumbo. Si falla con “message too long”, algún device en el medio está fragmentando o rechazando — volvé a MTU 1500 hasta identificar quién rompe.

Configuración completa de ejemplo: servidor Proxmox con bond + VLANs

/etc/network/interfaces (Debian clásico, si no usas nm ni systemd-networkd):


auto lo
iface lo inet loopback
# Bond de las 2 NICs
auto bond0
iface bond0 inet manual
    bond-slaves eth0 eth1
    bond-mode 802.3ad
    bond-lacp-rate fast
    bond-miimon 100
    mtu 9000
# VLAN 10: Management
auto bond0.10
iface bond0.10 inet static
    address 192.168.5.10/24
    gateway 192.168.5.1
    dns-nameservers 1.1.1.1 8.8.8.8
# VLAN 20: VMs
auto bond0.20
iface bond0.20 inet manual
# VLAN 30: Storage
auto bond0.30
iface bond0.30 inet static
    address 10.0.30.5/24
# Bridge para VMs en VLAN 20
auto vmbr0
iface vmbr0 inet manual
    bridge-ports bond0.20
    bridge-stp off
    bridge-fd 0
    bridge-vlan-aware yes
    bridge-vids 20 21 22 23

Esta config es típica de Proxmox con bond LACP + VLANs + bridge para VMs.

Performance: lo que ganas con bonding

LACP activo (modo 802.3ad)

Con 2 NICs de 1 Gbps en LACP a un switch que soporta:

Escenario Throughput 1 cliente, 1 conexión ~1 Gbps (limitado por NIC individual) 1 cliente, 4 conexiones ~2 Gbps (distribuye entre NICs) 4 clientes, 1 conexión c/u ~2 Gbps
1 NIC falla 1 Gbps (failover automático)

Importante: una sola conexión TCP no usa más de 1 Gbps aunque haya 2 NICs. Para sumar bandwidth necesitas múltiples conexiones simultáneas (ej: muchos clientes, o apps que abren varios streams).

Cuándo vale la pena

  • Sí: NAS con muchos clientes accediendo, servidor de VMs con tráfico diverso, datacenter con mucho east-west traffic
  • No: laptop personal, servidor con 1-2 clientes, workload limitado por otra cosa (disco, CPU)

El caso “todo VLAN” en 2026

En servidores modernos, la tendencia es usar VLANs para todo, no solo para separar tráfico. Esto se llama “all-VLAN approach”:


bond0 (trunk con todas las VLANs)
├── bond0.10 (management)
├── bond0.20 (VMs / containers)
├── bond0.30 (storage / NAS)
├── bond0.40 (backups)
└── bond0.50 (DMZ / servicios expuestos)

Beneficios:

  • Segmentación clara
  • Firewall rules granulares entre VLANs
  • Snapshots de configs de red son fáciles (solo cambiás archivos .network)
  • Si comprometés un servicio de la DMZ, no llega al storage

Es overkill para un homelab chico pero excelente para producción seria.

Preguntas frecuentes

¿Por qué Network bonding y VLANs en Linux sin GUI: nmcli y systemd-networkd es relevante para sysadmins Linux?

Forma parte del flujo diario de administración. Los conceptos explicados se aplican directamente a servidores en producción y resuelven problemas reales que enfrentan sysadmins hispanohablantes.

¿Qué necesito para empezar con Network bonding y VLANs en?

Distribución Linux actualizada (Debian, Ubuntu, RHEL, Fedora o Arch), acceso root, y conexión a internet. Para producción: entorno de staging separado antes de aplicar cambios.

¿Cuáles son los errores más comunes con Network bonding y VLANs en?

Los tres más frecuentes: (1) saltar la lectura de logs, (2) aplicar cambios directos en producción sin probar, (3) olvidar permisos y ownership. La documentación y un plan de rollback siempre.

¿Cuándo usar Network bonding y VLANs en y cuándo una alternativa?

Esta solución es ideal para el caso descrito. Alternativas como Docker, Ansible o configuración manual pueden ser mejores según contexto: portabilidad, escala y reproducibilidad son los factores clave.

¿Cómo migro desde una configuración previa a Network bonding y VLANs en?

Documentar el estado actual, probar la nueva configuración en staging, validar funcionalmente, y aplicar en producción con rollback plan listo. Los posts de SoyLinux incluyen troubleshooting para los problemas más comunes.

Lee también

Alfonso Moreno | Sysadmin Senior

Soy Alfonso, sysadmin senior con RHCE y más de 10 años administrando sistemas Linux para empresas y proyectos personales. Me especializo en infraestructura, redes, virtualización, monitoring, automation y self-hosting. Sobre SoyLinux.com SoyLinux.com es un blog técnico en español sobre Linux, software libre y self-hosting. Lo mantengo en mi tiempo libre. Áreas de expertise - Linux server administration: RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu - Network services: Postfix, BIND, Samba, NFS, Squid - Virtualización y containers: KVM, Proxmox, Docker, Podman - Monitoring: Prometheus, Grafana, Zabbix - Automation: Ansible, Bash scripting - Self-hosting: Vaultwarden, Nextcloud, Jellyfin, Immich, Homelab Contacto - Email: [email protected]

3 thoughts on “Network bonding y VLANs en Linux sin GUI: nmcli y systemd-networkd”

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *