Cómo Agregar Múltiples Direcciones IP a Una Interfaz de Red en Linux
Una interfaz de red de Linux sirviendo diferentes roles al vincular múltiples direcciones IP.
Por Qué Necesitaba Múltiples IPs en Una Tarjeta de Red
Me encontré con un problema: mi servidor doméstico ejecuta NFS y un servidor de fotos DLNA en 192.168.90.106. Quería agregar CoreDNS pero aislarlo de los otros servicios. Reglas de firewall diferentes, logs más limpios, troubleshooting más fácil.
Mi primer pensamiento fue agregar otra tarjeta de red. Luego me di cuenta de que era excesivo. El alias IP te permite asignar múltiples direcciones IP a una sola interfaz de red. La misma tarjeta física, diferentes IPs, aislamiento total.
Qué Sucede Cuando Agregas Una Segunda Dirección IP
El alias IP asigna múltiples direcciones a una sola interfaz. El kernel trata cada dirección como un endpoint separado. Las aplicaciones se vinculan a IPs específicas. Tu firewall aplica reglas diferentes por dirección.
Exploré cómo funciona esto en un servidor Ubuntu con la interfaz enp2s0. La IP primaria es 192.168.90.106. Agregué 192.168.90.152 como secundaria.
Cómo Agregar un Alias IP en Linux
sudo ip addr add 192.168.90.152/24 dev enp2s0Verifiqué que funcionó:
ip addr show enp2s0Esto es lo que vi:
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:16:96:ed:75:a2 brd ff:ff:ff:ff:ff:ff
inet 192.168.90.106/24 brd 192.168.90.255 scope global enp2s0
valid_lft forever preferred_lft forever
inet 192.168.90.152/24 brd 192.168.90.255 scope global secondary enp2s0
valid_lft forever preferred_lft forever
La dirección 152 aparece como “secondary”. Eso importa para las conexiones salientes: el kernel usa la dirección primaria como la IP de origen por defecto.
Qué Hace el Kernel de Linux Detrás de las Escenas
Quería entender qué pasó realmente en el kernel cuando agregué esa IP. El kernel actualiza múltiples tablas de enrutamiento.
Revisa la tabla de enrutamiento local:
ip route show table local | grep 192.168.90Esto me mostró:
local 192.168.90.106 dev enp2s0 proto kernel scope host src 192.168.90.106
local 192.168.90.152 dev enp2s0 proto kernel scope host src 192.168.90.106
broadcast 192.168.90.255 dev enp2s0 proto kernel scope link src 192.168.90.106
Ambas IPs obtuvieron rutas “local”. Esto le dice al kernel que estas direcciones pertenecen a esta máquina. Los paquetes para estas IPs se entregan a las aplicaciones locales en lugar de ser reenviados.
Nota que ambas usan 192.168.90.106 como la fuente. Esa es la dirección primaria para las respuestas.
Dentro de la Base de Información de Reenvío (FIB) del Kernel
La FIB es la estructura de búsqueda de enrutamiento del kernel. Cada paquete que llega se verifica contra la FIB para determinar hacia dónde debe ir. Usa una estructura de árbol comprimida llamada trie que hace las búsquedas extremadamente rápidas incluso con miles de rutas.
cat /proc/net/fib_trie | grep -A 5 "192.168.90"Resultado:
+--
|-- 192.168.90.0
/24 link UNICAST
|-- 192.168.90.106
/32 host LOCAL
|-- 192.168.90.152
/32 host LOCAL
|-- 192.168.90.255
/32 link BROADCAST
Qué significa cada entrada:
192.168.90.0/24: ruta de red. Maneja todo el tráfico en la subred. Tipo “link UNICAST” = red directamente conectada.192.168.90.106/32y192.168.90.152/32: rutas de host. El/32significa coincidencia exacta. El tipo “LOCAL” le dice al kernel “esta IP es mía, entrega los paquetes a los procesos locales”.192.168.90.255/32: dirección de broadcast. Tipo “link BROADCAST”.
Cuando un paquete llega para 192.168.90.152, el kernel recorre desde la red /24 hasta la ruta de host /32 en nanosegundos.
Probando la Dirección IP Secundaria
ping -c 3 192.168.90.152Funcionó inmediatamente. El kernel enrutó estos paquetes internamente sin tocar la red.
Revisé cómo el kernel enruta el tráfico hacia el alias:
ip route get 192.168.90.152Resultado:
local 192.168.90.152 dev lo src 192.168.90.106 uid 0
Esto me sorprendió al principio: la ruta muestra el dispositivo lo (loopback) aunque enp2s0 posee la dirección. Es una optimización: cuando el kernel entrega paquetes a sus propias direcciones, usa la interfaz loopback para evitar procesamiento innecesario del stack de red.
Cómo Vincular Servicios a Direcciones IP Específicas
Mi configuración:
- Servidor NFS en
192.168.90.106 - Servidor de fotos DLNA en
192.168.90.106 - CoreDNS en
192.168.90.152
Probé esto con el servidor HTTP de Python:
python3 -m http.server 8080 --bind 192.168.90.152Desde otra máquina en mi red:
curl http://192.168.90.152:8080Tiempo de conexión agotado. El servicio estaba corriendo pero no respondía.
Revisé las reglas del firewall:
iptables -L INPUT -n -v | head -n 2Chain INPUT (policy DROP 2532 packets, 153K bytes)
La política de INPUT es DROP. Todo se bloquea por defecto. Revisé qué puertos están permitidos:
iptables -L ufw-user-input -n -vReglas para SSH, NFS, DLNA y Samba, pero nada para el puerto 8080. Agregué una regla específicamente para la IP alias:
ufw allow from 192.168.90.0/24 to 192.168.90.152 port 8080 proto tcp comment 'Test server'Verifiqué:
iptables -L ufw-user-input -n -v | grep 80800 0 ACCEPT 6 -- * * 192.168.90.0/24 192.168.90.152 tcp dpt:8080
Probé de nuevo:
curl http://192.168.90.152:8080Funcionó. Luego probé la IP primaria:
curl http://192.168.90.106:8080Conexión rechazada. Perfecto. El servicio solo escucha en 152. Ese es el aislamiento que quería.
Para ver qué servicios escuchan en qué IPs:
ss -tlnp | grep 192.168.90Entendiendo la Selección de IP de Origen para Conexiones Salientes
Cuando mi servidor inicia una conexión, ¿qué IP usa?
ip route get 8.8.8.8El resultado muestra src 192.168.90.106. El kernel elige la dirección primaria por defecto.
Pero puedes forzar una IP de origen específica:
curl --interface 192.168.90.152 http://example.comCómo el Protocolo ARP Maneja Múltiples IPs
Ambas IPs comparten una sola dirección MAC física.
arp -a | grep 192.168.90192.168.90.106 at 00:16:96:ed:75:a2
192.168.90.152 at 00:16:96:ed:75:a2
Misma dirección MAC para ambas IPs. El switch de red no le importan las direcciones IP — reenvía frames Ethernet basados en MAC. El kernel en el extremo receptor mira la IP de destino para decidir qué hacer con el paquete.
Parámetros del Kernel que Afectan Múltiples IPs
Comportamiento de anuncio ARP:
cat /proc/sys/net/ipv4/conf/enp2s0/arp_announceValor 0: el kernel puede anunciar cualquier IP local en solicitudes ARP. 2 restringe los anuncios a IPs en la misma subred que el destino.
Filtrado de ruta inversa:
cat /proc/sys/net/ipv4/conf/enp2s0/rp_filterValor 2 (modo flexible): el kernel acepta paquetes si la IP de origen tiene alguna ruta válida de vuelta. 1 es modo estricto, 0 desactiva la verificación.
Troubleshooting Cuando los Servicios No Responden en IPs Alias
1. Verifica que el servicio esté escuchando:
ss -tlnp | grep 192.168.90.1522. Confirma que la ruta existe:
ip route get 192.168.90.152Debe devolver local 192.168.90.152 dev lo.
3. Prueba desde el servidor mismo:
curl http://192.168.90.152:8080Si esto funciona pero las conexiones remotas fallan, es un problema de firewall.
Haciendo los Alias IP Permanentes
El comando ip no sobrevive a los reinicios. Ubuntu usa netplan:
sudo nano /etc/netplan/00-installer-config.yamlnetwork:
version: 2
ethernets:
enp2s0:
addresses:
- 192.168.90.106/24
- 192.168.90.152/24
routes:
- to: default
via: 192.168.90.1
nameservers:
addresses: [8.8.8.8]sudo netplan applyCómo Eliminar un Alias IP
sudo ip addr del 192.168.90.152/24 dev enp2s0ip addr show enp2s0El kernel elimina automáticamente la ruta local y la entrada FIB.
Beneficios en el Mundo Real
- Reglas de firewall separadas por servicio. Las consultas DNS solo llegan a
192.168.90.152. NFS y DLNA permanecen en106. - Logs más limpios. La IP de destino muestra inmediatamente qué servicio fue accedido.
- Migración fácil de servicios. Si muevo CoreDNS a otro servidor, elimino el alias aquí y lo agrego allí. Los clientes ya apuntan a
192.168.90.152. - Un cable de red, múltiples servicios aislados. Separación a nivel de red sin agregar hardware.
Este enfoque funciona muy bien para servidores homelab, entornos de desarrollo, o cualquier situación donde necesites aislamiento de servicios sin networking complejo.
Fuente: artículo original de Rajesh Kumar en LearningDevOps. Adaptado por Sammi De Blas.