--- title: "Redes avanzadas con iproute2 en Ubuntu 24.04: ip, tc y netns" description: "Gestiona interfaces, rutas y enrutamiento por políticas con ip, crea redes aisladas con namespaces y bridges, y limita el ancho de banda con tc en Ubuntu 24.04." category: "Temas Avanzados" language: es source: https://cubepath.com/es/docs/temas-avanzados/redes-avanzadas-con-iproute2 updated: 2026-09-25 --- # Redes avanzadas con iproute2 en Ubuntu 24.04: ip, tc y netns iproute2 es el conjunto de herramientas estándar para configurar la red en Linux: `ip` para interfaces, direcciones, rutas y namespaces, `tc` para el control de tráfico y `ss` para los sockets. Sustituye a `ifconfig`, `route` y `netstat`, que llevan años obsoletos. En este tutorial usarás iproute2 en Ubuntu 24.04 para inspeccionar la red, configurar enrutamiento por políticas, montar una red de namespaces con salida a Internet y limitar su ancho de banda, y al final verás cómo hacer persistentes los cambios con netplan. ## Requisitos previos Para seguir esta guía necesitas: - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. - Un usuario no root con privilegios `sudo`. - Acceso a la consola del servidor (por ejemplo, la consola VNC del panel de CubePath) por si un cambio en la interfaz principal corta la conexión SSH. > Advertencia: Los cambios hechos con `ip` y `tc` son inmediatos y **no persisten** tras un reinicio. Eso los hace ideales para probar, pero un error en la interfaz o la ruta por defecto puede dejarte sin SSH. Los ejercicios de esta guía usan interfaces virtuales para no tocar la interfaz pública. ## Paso 1: Instalar las utilidades de prueba `iproute2` viene instalado en Ubuntu. Instala `iperf3` para medir ancho de banda y `tcpdump` para ver el tráfico: ```bash sudo apt update sudo apt install iperf3 tcpdump ``` Si el instalador pregunta si quieres arrancar `iperf3` como servicio, responde que no; lo lanzarás a mano. Comprueba la versión de iproute2: ```bash ip -V ``` ```output ip utility, iproute2-6.1.0, libbpf 1.3.0 ``` ## Paso 2: Inspeccionar interfaces, direcciones y rutas La opción `-br` (breve) da una vista compacta del estado de las interfaces y sus direcciones: ```bash ip -br link ip -br addr ``` ```output lo UNKNOWN 00:00:00:00:00:00 eth0 UP bc:24:11:5a:3e:10 lo UNKNOWN 127.0.0.1/8 ::1/128 eth0 UP 203.0.113.10/24 2001:db8:10::10/64 fe80::be24:11ff:fe5a:3e10/64 ``` En esta guía la interfaz pública es `eth0`. En tu servidor puede llamarse de otra forma (por ejemplo `ens18`); sustitúyela donde aparezca. Consulta la tabla de rutas principal: ```bash ip route show ``` ```output default via 203.0.113.1 dev eth0 proto static 203.0.113.0/24 dev eth0 proto kernel scope link src 203.0.113.10 ``` El comando más útil para depurar enrutamiento es `ip route get`, que pregunta al kernel qué ruta, interfaz y dirección de origen usaría para llegar a un destino: ```bash ip route get 1.1.1.1 ``` ```output 1.1.1.1 via 203.0.113.1 dev eth0 src 203.0.113.10 uid 1000 cache ``` Para ver estadísticas de tráfico y errores de una interfaz: ```bash ip -s link show dev eth0 ``` Y para ver la tabla de vecinos (ARP en IPv4, NDP en IPv6): ```bash ip neigh show ``` ## Paso 3: Practicar con una interfaz dummy Una interfaz `dummy` es una interfaz virtual que no está conectada a nada. Es perfecta para practicar sin riesgo: ```bash sudo ip link add dummy0 type dummy sudo ip link set dummy0 up ``` Añade dos direcciones IPv4 y una IPv6. Una interfaz puede tener tantas direcciones como necesites: ```bash sudo ip addr add 192.168.50.1/24 dev dummy0 sudo ip addr add 192.168.51.1/24 dev dummy0 sudo ip -6 addr add fd00:50::1/64 dev dummy0 ip -br addr show dev dummy0 ``` ```output dummy0 UNKNOWN 192.168.50.1/24 192.168.51.1/24 fd00:50::1/64 fe80::a8c1:abff:fe12:3456/64 ``` Añade una ruta estática hacia una red que se alcanza a través de un router de la red de `dummy0`, cambia el MTU y comprueba el resultado: ```bash sudo ip route add 10.99.0.0/16 via 192.168.50.254 dev dummy0 sudo ip link set dummy0 mtu 1400 ip route get 10.99.1.1 ``` ```output 10.99.1.1 via 192.168.50.254 dev dummy0 src 192.168.50.1 uid 1000 cache ``` Para modificar una ruta existente sin borrarla antes usa `ip route replace`, y para eliminar una dirección `ip addr del`: ```bash sudo ip route replace 10.99.0.0/16 via 192.168.51.254 dev dummy0 sudo ip addr del 192.168.51.1/24 dev dummy0 ``` Comprueba el estado con `ip -br addr show dev dummy0` e `ip route show dev dummy0`. Borra la interfaz cuando termines; sus direcciones y rutas se van con ella: ```bash sudo ip link delete dummy0 ``` ## Paso 4: Configurar enrutamiento por políticas Normalmente el kernel elige la ruta solo por el destino. Con el **enrutamiento por políticas** puedes usar varias tablas de rutas y elegir la tabla según el origen, la interfaz de entrada o una marca del firewall. El caso típico es un servidor con dos IP de redes distintas que debe responder por la puerta de enlace correspondiente a cada una. Las reglas se evalúan por orden de prioridad (número menor primero). Mira las que hay por defecto: ```bash ip rule show ``` ```output 0: from all lookup local 32766: from all lookup main 32767: from all lookup default ``` Dale un nombre a una tabla nueva, la `100`. Los nombres se definen en archivos dentro de `/etc/iproute2/rt_tables.d/`: ```bash sudo mkdir -p /etc/iproute2/rt_tables.d echo "100 secundaria" | sudo tee /etc/iproute2/rt_tables.d/secundaria.conf ``` Para practicar, crea de nuevo una interfaz dummy con una dirección de "segunda red" y añade una ruta por defecto en la tabla `secundaria` que salga por ella: ```bash sudo ip link add dummy1 type dummy sudo ip link set dummy1 up sudo ip addr add 192.168.60.10/24 dev dummy1 sudo ip route add default via 192.168.60.1 dev dummy1 table secundaria ``` Crea la regla: todo el tráfico cuyo origen sea `192.168.60.10` consulta la tabla `secundaria`: ```bash sudo ip rule add from 192.168.60.10 lookup secundaria priority 1000 ``` Verifica la decisión del kernel para el mismo destino con y sin esa dirección de origen: ```bash ip route get 8.8.8.8 ip route get 8.8.8.8 from 192.168.60.10 ``` ```output 8.8.8.8 via 203.0.113.1 dev eth0 src 203.0.113.10 uid 1000 cache 8.8.8.8 from 192.168.60.10 via 192.168.60.1 dev dummy1 uid 1000 cache ``` La misma consulta sale por `eth0` o por `dummy1` según el origen. Puedes ver el contenido de la tabla con `ip route show table secundaria`. Limpia el ejercicio: ```bash sudo ip rule del from 192.168.60.10 lookup secundaria priority 1000 sudo ip link delete dummy1 ``` ## Paso 5: Montar una red de namespaces con bridge y NAT Los network namespaces son pilas de red independientes: tienen sus propias interfaces, rutas y firewall. Aquí crearás dos, `ns1` y `ns2`, conectados a un bridge `br-lab` en el host, que hará de router hacia Internet con NAT. Es, a pequeña escala, lo que hace Docker con `docker0`. Crea los namespaces y el bridge: ```bash sudo ip netns add ns1 sudo ip netns add ns2 sudo ip link add br-lab type bridge sudo ip addr add 10.10.0.1/24 dev br-lab sudo ip link set br-lab up ``` Conecta cada namespace al bridge con un par `veth`. Un extremo se mueve al namespace y el otro se enchufa al bridge: ```bash sudo ip link add veth-ns1 type veth peer name eth0 netns ns1 sudo ip link add veth-ns2 type veth peer name eth0 netns ns2 sudo ip link set veth-ns1 master br-lab up sudo ip link set veth-ns2 master br-lab up ``` Configura la dirección, la interfaz loopback y la ruta por defecto dentro de cada namespace: ```bash sudo ip -n ns1 addr add 10.10.0.11/24 dev eth0 sudo ip -n ns1 link set eth0 up sudo ip -n ns1 link set lo up sudo ip -n ns1 route add default via 10.10.0.1 sudo ip -n ns2 addr add 10.10.0.12/24 dev eth0 sudo ip -n ns2 link set eth0 up sudo ip -n ns2 link set lo up sudo ip -n ns2 route add default via 10.10.0.1 ``` `ip -n ns1` es la forma corta de `ip netns exec ns1 ip`. Comprueba que los namespaces se ven entre sí a través del bridge: ```bash sudo ip netns exec ns1 ping -c 2 10.10.0.12 ``` ```output 64 bytes from 10.10.0.12: icmp_seq=1 ttl=64 time=0.062 ms 64 bytes from 10.10.0.12: icmp_seq=2 ttl=64 time=0.048 ms ``` Para que salgan a Internet, el host tiene que reenviar paquetes y traducir las direcciones privadas a su IP pública. Activa el reenvío IPv4: ```bash sudo sysctl -w net.ipv4.ip_forward=1 ``` Crea una tabla de nftables con una regla de masquerade para la red del laboratorio: ```bash sudo nft add table ip lab sudo nft add chain ip lab postrouting '{ type nat hook postrouting priority srcnat; }' sudo nft add rule ip lab postrouting ip saddr 10.10.0.0/24 oifname "eth0" masquerade ``` Si UFW está activo, su política de reenvío por defecto es `DROP` y bloqueará este tráfico. Permite el reenvío desde el bridge hacia la interfaz pública: ```bash sudo ufw route allow in on br-lab out on eth0 ``` Comprueba la salida a Internet desde `ns1`: ```bash sudo ip netns exec ns1 ping -c 2 1.1.1.1 ``` ```output 64 bytes from 1.1.1.1: icmp_seq=1 ttl=57 time=1.92 ms 64 bytes from 1.1.1.1: icmp_seq=2 ttl=57 time=1.85 ms ``` Mantén este laboratorio en marcha para el paso siguiente. ## Paso 6: Controlar el tráfico con tc `tc` gestiona las colas (qdisc) de cada interfaz. Primero mide el ancho de banda sin límites. Arranca un servidor `iperf3` dentro de `ns1` en segundo plano: ```bash sudo ip netns exec ns1 iperf3 -s -D ``` Y mide desde el host, que alcanza `ns1` a través del bridge: ```bash iperf3 -c 10.10.0.11 -t 5 ``` ```output [ ID] Interval Transfer Bitrate Retr [ 5] 0.00-5.00 sec 24.1 GBytes 41.4 Gbits/sec 0 sender ``` ### Limitar el ancho de banda El qdisc `tbf` (token bucket filter) limita la velocidad de salida de una interfaz. El tráfico que va del host hacia `ns1` sale por `veth-ns1`, así que aplica ahí un límite de 20 Mbit/s: ```bash sudo tc qdisc add dev veth-ns1 root tbf rate 20mbit burst 32kbit latency 400ms ``` Repite la medición: ```bash iperf3 -c 10.10.0.11 -t 5 ``` ```output [ ID] Interval Transfer Bitrate Retr [ 5] 0.00-5.00 sec 12.2 MBytes 20.4 Mbits/sec 0 sender ``` Las estadísticas del qdisc muestran cuántos paquetes ha enviado, descartado o retrasado: ```bash tc -s qdisc show dev veth-ns1 ``` ### Simular latencia y pérdida El qdisc `netem` añade retardo, variación y pérdida de paquetes, muy útil para probar cómo se comporta una aplicación en una red mala. Sustituye el `tbf` por un retardo de 100 ms con 10 ms de variación y un 1 % de pérdida: ```bash sudo tc qdisc replace dev veth-ns1 root netem delay 100ms 10ms loss 1% ``` Compruébalo con `ping` desde el host: ```bash ping -c 5 10.10.0.11 ``` ```output 64 bytes from 10.10.0.11: icmp_seq=1 ttl=64 time=104 ms 64 bytes from 10.10.0.11: icmp_seq=2 ttl=64 time=93.7 ms ... ``` Elimina el qdisc para volver al comportamiento por defecto (`fq_codel` en Ubuntu 24.04): ```bash sudo tc qdisc del dev veth-ns1 root ``` > Nota: `tc` controla sobre todo el tráfico de **salida** de una interfaz. Para limitar lo que entra a un namespace, aplica el qdisc a su extremo `veth` en el host, como en este ejemplo; para limitar lo que sale del namespace, aplícalo a su `eth0` con `ip netns exec`. ## Paso 7: Monitorizar cambios y sockets `ip monitor` muestra en tiempo real los cambios de enlaces, direcciones y rutas. Déjalo en una sesión y, en otra, levanta o baja una interfaz del laboratorio: ```bash ip monitor link address route ``` ```output [LINK]4: veth-ns2@if2: mtu 1500 qdisc noqueue master br-lab state DOWN ``` `ss` muestra los sockets. Estas son las consultas más habituales: ```bash sudo ss -tlnp ss -s ss -tn state established '( dport = :443 )' ``` La primera lista los puertos TCP en escucha con el proceso que los abre, la segunda un resumen por protocolo y la tercera las conexiones HTTPS salientes establecidas. La mayoría de comandos de `ip` admiten `-j` para salida JSON, cómoda para scripts: ```bash ip -j -br addr | python3 -m json.tool ``` ## Paso 8: Limpiar el laboratorio Borra los namespaces (sus extremos `veth` desaparecen con ellos), el bridge, la tabla nftables y la regla de UFW, y desactiva el reenvío si no lo necesitas: ```bash sudo pkill iperf3 sudo ip netns delete ns1 sudo ip netns delete ns2 sudo ip link delete br-lab sudo nft delete table ip lab sudo ufw route delete allow in on br-lab out on eth0 sudo sysctl -w net.ipv4.ip_forward=0 ``` Si has instalado Docker u otro software que necesita reenvío, no desactives `ip_forward`. ## Paso 9: Hacer persistente la configuración con netplan En Ubuntu 24.04 la configuración de red permanente se define con netplan en `/etc/netplan/`. Todo lo que has hecho con `ip addr`, `ip route` e `ip rule` tiene equivalente en YAML. Por ejemplo, para añadir una segunda IP a `eth0` con su propia tabla de rutas y su regla, crea un archivo nuevo: ```bash sudo nano /etc/netplan/60-secundaria.yaml ``` ```yaml network: version: 2 ethernets: eth0: addresses: - 198.51.100.20/24 routes: - to: default via: 198.51.100.1 table: 100 routing-policy: - from: 198.51.100.20 table: 100 priority: 1000 ``` Las direcciones de este ejemplo son de documentación: usa las que te haya asignado tu proveedor. Netplan combina este archivo con el existente de `eth0`. Protege los permisos y prueba la configuración con `netplan try`, que la revierte automáticamente si no confirmas en 120 segundos (por ejemplo, porque has perdido el SSH): ```bash sudo chmod 600 /etc/netplan/60-secundaria.yaml sudo netplan try ``` Verifica el resultado: ```bash ip rule show ip route show table 100 ``` ```output 0: from all lookup local 1000: from 198.51.100.20 lookup 100 proto static 32766: from all lookup main 32767: from all lookup default default via 198.51.100.1 dev eth0 proto static ``` ## Solución de problemas **`RTNETLINK answers: File exists`**: la dirección, ruta o interfaz ya existe. Usa `ip route replace` en lugar de `add`, o bórrala antes. **`Error: Nexthop has invalid gateway`**: el gateway no está en ninguna red conectada directamente. Añade antes la dirección de esa red a la interfaz o indica `onlink` si sabes que el gateway es alcanzable en el enlace. **El namespace llega al bridge pero no a Internet**: revisa en este orden `sysctl net.ipv4.ip_forward` (debe ser `1`), `sudo nft list table ip lab` (regla de masquerade con la interfaz correcta), `sudo ufw status verbose` (regla de `route allow`) y `sudo ip -n ns1 route` (ruta por defecto hacia `10.10.0.1`). **La regla de `ip rule` no tiene efecto**: comprueba su prioridad con `ip rule show` y que la tabla tiene rutas con `ip route show table `. Una regla que apunta a una tabla vacía hace que el kernel pase a la siguiente regla. **`tc` no limita nada**: probablemente aplicaste el qdisc a la interfaz equivocada o al sentido contrario del tráfico. Recuerda que limita la salida; comprueba con `tc -s qdisc show dev ` que los contadores `Sent` aumentan durante la prueba. ## Conclusión Has usado `ip` para inspeccionar la red, gestionar direcciones y rutas y configurar enrutamiento por políticas, has construido una red de namespaces con bridge y NAT, y has limitado y degradado el tráfico con `tc`. También sabes trasladar estos cambios a netplan para que sobrevivan a un reinicio. Como siguientes pasos puedes: - Usar `tc` con el qdisc `htb` para repartir el ancho de banda entre clases de tráfico. - Crear túneles WireGuard o VXLAN con `ip link add` para unir servidores de distintas ubicaciones. - Profundizar en los namespaces y cgroups que usan los contenedores.