====== Cómo funciona una red con namespaces ====== Versión: V_26_11 ¿Qué es un //network namespace// y cómo viaja un paquete desde un host hasta otro?. El objetivo no es memorizar órdenes, sino entender qué representa cada elemento de la red simulada. ===== 1. La idea principal ===== En una sola máquina virtual se crean tres redes Linux independientes: hostA ── LAN 10.10.1.0/24 ── router ── LAN 10.10.2.0/24 ── hostB No son tres máquinas virtuales. Son tres entornos de red diferentes dentro del mismo kernel Linux. Para la red se comportan como si fueran dos ordenadores y un router físico. ^ Namespace ^ Papel que representa ^ | hostA | Un ordenador conectado a la primera LAN. | | router | Un router con una tarjeta en cada LAN. | | hostB | Un ordenador conectado a la segunda LAN. | ===== 2. Qué es un network namespace ===== Un network namespace es un espacio aislado de red dentro del mismo sistema Linux. Cada namespace tiene su propia visión de la red. Cada uno dispone de sus propias: Interfaces de red. Direcciones IP. Tabla de rutas. Caché de vecinos ARP. Reglas de filtrado de red o firewall. Puertos, sockets y conexiones de red. Por eso hostA no puede ver la interfaz r1a del router ni la dirección IP de hostB como interfaces propias. Solo ve sus propias interfaces, rutas y direcciones. Los namespaces sí comparten el kernel, el procesador, la memoria, los usuarios y el sistema de archivos de la VM anfitriona. Un namespace de red no crea una máquina virtual completa: únicamente separa la pila de red. ===== 3. Crear los tres espacios de red ===== sudo ip netns add hostA sudo ip netns add router sudo ip netns add hostB sudo ip netns list La orden ip netns add crea un namespace con ese nombre. Al crearlo no aparece una tarjeta Ethernet conectada: inicialmente dispone de una interfaz local llamada lo o //loopback//, normalmente apagada. El modificador -n permite ejecutar órdenes de ip dentro de uno de ellos: sudo ip -n hostA address show Para ejecutar cualquier otro programa dentro del namespace se utiliza ip netns exec: sudo ip netns exec hostA ping -c 3 10.10.1.1 En ese caso, el programa ping se ejecuta usando las interfaces, rutas y direcciones que existan en hostA. ===== 4. Qué es un enlace veth ===== Un par veth es un cable Ethernet virtual formado por dos extremos. Todo paquete enviado por un extremo aparece en el otro. Extremo A <──────── cable virtual ────────> Extremo B Se crea así: sudo ip link add ha-veth type veth peer name r1a-veth La orden crea dos interfaces enlazadas: ha-veth r1a-veth Al principio ambas nacen en la VM anfitriona. Después se mueve cada una al namespace que corresponda: sudo ip link set ha-veth netns hostA sudo ip link set r1a-veth netns router Así se crea el primer segmento Ethernet: hostA: ha-veth <────────────────────> r1a-veth : router Se crea un segundo par para el otro segmento: hostB: hb-veth <────────────────────> r1b-veth : router Se necesitan dos pares veth porque un router une dos redes diferentes. Un único par conectaría únicamente dos extremos y no permitiría que el router tuviera una interfaz en cada LAN. ===== 5. Renombrar y activar interfaces ===== Los extremos se renombran para que la topología sea más clara: ^ Namespace ^ Nombre final ^ | hostA | eth0 | | router | r1a y r1b | | hostB | eth0 | sudo ip -n hostA link set ha-veth name eth0 sudo ip -n router link set r1a-veth name r1a Una interfaz nueva está apagada. Hay que activar tanto lo como los extremos virtuales: sudo ip -n hostA link set lo up sudo ip -n hostA link set eth0 up sudo ip -n router link set r1a up Para que exista conectividad, los dos extremos de cada enlace deben estar en estado UP. ===== 6. Direcciones IP y redes creadas ===== ^ Namespace ^ Interfaz ^ Dirección IPv4 ^ Significado ^ | hostA | eth0 | 10.10.1.10/24 | Equipo de la LAN A. | | router | r1a | 10.10.1.1/24 | Gateway de la LAN A. | | router | r1b | 10.10.2.1/24 | Gateway de la LAN B. | | hostB | eth0 | 10.10.2.10/24 | Equipo de la LAN B. | La máscara /24 equivale a 255.255.255.0. Por tanto, se forman dos redes distintas: LAN A: 10.10.1.0/24. LAN B: 10.10.2.0/24. El router pertenece a las dos porque dispone de una interfaz y una dirección en cada una. ===== 7. Por qué son necesarios los gateways ===== hostA conoce automáticamente su red conectada: 10.10.1.0/24. Puede comunicarse directamente con el router en 10.10.1.1, pero no conoce cómo llegar a 10.10.2.0/24. Se le indica que todo destino desconocido debe enviarse al router: sudo ip -n hostA route add default via 10.10.1.1 La expresión default via 10.10.1.1 significa: «para cualquier red que no conozca, entrega el paquete a 10.10.1.1». hostB necesita la misma idea, pero utilizando su lado del router: sudo ip -n hostB route add default via 10.10.2.1 El gateway siempre debe estar en la misma red local que el host. Por ejemplo, hostA no puede utilizar directamente 10.10.2.1: primero tendría que alcanzar esa dirección, que pertenece a otra red. ===== 8. Por qué el router necesita ip_forward ===== Tener dos interfaces con IP no convierte automáticamente a Linux en router. Por seguridad, Linux no reenvía paquetes entre interfaces si no se le autoriza expresamente. sudo ip netns exec router sysctl -w net.ipv4.ip_forward=1 Esta orden activa el reenvío IPv4 dentro del namespace router. Activarlo en la VM anfitriona no resolvería la práctica: el paquete llega al namespace router y es allí donde debe tomarse la decisión de reenviarlo por r1b. ===== 9. Viaje completo de un ping ===== Cuando se ejecuta lo siguiente: sudo ip netns exec hostA ping -c 3 10.10.2.10 ocurre este proceso: hostA compara el destino con su propia dirección y máscara. Detecta que 10.10.2.10 no pertenece a 10.10.1.0/24. Consulta su ruta por defecto y decide entregar el paquete a 10.10.1.1. Antes de enviarlo, resuelve por ARP la dirección MAC de 10.10.1.1, que es la interfaz r1a del router. El paquete cruza el primer cable virtual desde hostA:eth0 hasta router:r1a. El router comprueba que conoce directamente la red 10.10.2.0/24 por r1b. Como ip_forward=1, reenvía el paquete por r1b. Si no conoce la MAC de hostB, realiza ARP en la LAN B. El segundo cable virtual entrega el paquete a hostB:eth0. hostB reconoce que 10.10.2.10 es su propia dirección y responde. La respuesta sigue el recorrido inverso a través del router. ===== 10. Qué demuestra el fallo controlado ===== sudo ip netns exec router sysctl -w net.ipv4.ip_forward=0 sudo ip netns exec hostA ping -c 3 10.10.2.10 sudo ip netns exec hostA ping -c 3 10.10.1.1 Con ip_forward=0 ocurre lo siguiente: El ping de hostA a 10.10.1.1 responde: el router puede responder a los paquetes destinados a su propia interfaz. El ping de hostA a 10.10.2.10 falla: el router recibe el paquete, pero no puede reenviarlo hacia hostB. Esto separa dos conceptos importantes: que una interfaz IP funcione y que un router reenvíe tráfico entre redes. Al restaurar el valor 1, el ping remoto debe volver a responder: sudo ip netns exec router sysctl -w net.ipv4.ip_forward=1 ===== 11. Cómo comprobar lo que está ocurriendo ===== sudo ip -n hostA route get 10.10.2.10 Esta orden debe indicar que hostA usa 10.10.1.1 como siguiente salto por eth0. También se puede observar el tráfico dentro del router: sudo ip netns exec router tcpdump -ni r1a icmp Mientras está abierta la captura, ejecute el ping desde hostA. Se verán peticiones ICMP de 10.10.1.10 a 10.10.2.10 entrando por r1a. Si se repite la captura sobre r1b, se comprobará que los mismos paquetes salen hacia hostB. ===== 12. Limpieza y persistencia ===== sudo ip netns del hostA sudo ip netns del router sudo ip netns del hostB Al borrar un namespace se eliminan sus interfaces virtuales, direcciones y rutas. La práctica se realiza con configuración temporal: también desaparecería después de reiniciar la VM.