Ayuda OnLine de GULiC
El problema de tener más de una tarjeta conectada a una misma subred
Lo cierto es que esta es una historia vieja, pero en vista de que siempre tropiezo con la misma piedra, la voy a dejar escrita aquí a ver si la próxima vez tardo menos tiempo en resolver este asunto.
La trama
Hace poco decidimos hacer una pequeña actualización del hardware que soporta los servicios del GULiC. Aprovechamos entonces para colocar a nuestro nuevo servidor dos tarjetas de red, con IPs distintas, conectadas a la red de nuestro ISP. Dentro del servidor configuramos varios vservers. La idea era tener un vserver configurado con los servicios en producción mientras manteníamos otro vserver, réplica del primero, donde hacer las pruebas de nuevos servicios y funcionalidades. El primer vserver debería salir por una de las tarjetas de red, mientras que el segundo debería salir por la otra.
Desafortunadamente hemos tenido algunos problemas con este asunto, muchas sospechas de donde podría estar el problema y poco tiempo para resolverlo.
Desde pues de algunas pruebas descubrimos que el protocolo ARP no estaba funcionando correctamente. A continuación muestro una consulta con el arping realizada desde otra máquina de la misma subred a una de las IPs de nuestro servidor:
$ arping 193.145.155.10 ARPING 193.145.155.10 60 bytes from 00:1a:4d:4c:ff:25 (193.145.155.10): index=0 time=140.905 usec 60 bytes from 00:05:1c:06:35:e9 (193.145.155.10): index=1 time=72.002 usec 60 bytes from 00:1a:4d:4c:ff:25 (193.145.155.10): index=2 time=82.970 usec 60 bytes from 00:05:1c:06:35:e9 (193.145.155.10): index=3 time=82.016 usec
Eso indudablemente indicaba un problema. Los paquetes que llegaban a la puerta de enlace de nuestro ISP debía ser entregados a la tarjeta de red de nuestra máquina que conincidía con la IP de destino de dichos paquetes. Pero cuando la puerta de enlace preguntaba por la MAC de la tarjeta de red que tenia configurada la una de nuestras IPs, en unas ocasiones obtenía como respuesta la MAC de una de las tarjetas y en otras la MAC de la otra tarjeta. Es decir, que el paquete no siempre podía ser entregado a la tarjeta de red correcta. Eso se le conoce como el problema del flujo ARP.
El golpe
La solución pasa por activar el filtro ARP, al menos para las interfaces involucradas.
sysctl net/ipv4/conf/all/arp_filter=1
o
sysctl net/ipv4/conf/eth0/arp_filter=1 sysctl net/ipv4/conf/eth1/arp_filter=1
Si no se activa dicha opción, cuando la puerta de enlace pregunta (mediante ARP) ¿a qué máquina pertenece esta IP? la consulta llega por ambas tarjetas, puesto que están conectadas a la misma subred. El sistema sabe que dicha IP pertenece a la máquina y responde por ambas tarjetas de red con sus respectivas MAC.
Si se activa el filtro ARP, el sistema utiliza la información de enrutado para sólo responder las peticiones ARP si coinciden con la IP de la tarjeta de red. Esta no es la única solución (http://wiki.openvz.org/MultipleNetworkInterfacesAndARP_Flux) pero a nosotros nos ha funcionado perfectamente.
Para que en nuestro caso arp_filter funcione correctamente, es necesario configurar una tabla para cada tarjeta de red con rutas específicas:
ip route add 193.145.155.0/24 dev eth0 scope link src 193.145.155.10 table 100 ip route add default via 193.145.155.1 dev eth0 table 100 ip route add 193.145.155.0/24 dev eth1 scope link src 193.145.155.12 table 101 ip route default via 193.145.155.1 dev eth1 table 101
Y añadir las reglas necesarias para que para los paquetes que salen por cada una de las tarjetas se utilice la tabla de rutas adecuada:
ip rule add from 193.145.155.10 lookup 100 ip rule add from 193.145.155.12 lookup 101
Y fin
Como ya he comentado, dentro de nuestro servidor tenemos algunos vservers. Cada uno es como una máquina física con IP privada a la que debemos redirigir el tráfico que llega a las interfaces de nuestro servidor (que tienen las IPs públicas). Eso se puede hacer fácilmente utilizando iptables y DNAT (algo que no voy a explicar en este artículo). En este caso es necesario aplicar algo de policy routing, puesto que sería conveniente que el trafico enviado desde los vservers saliera por la misma interfaz del servidor que se utilizó para crear la conexión. Esto simplemente se resume en añadir las siguientes reglas a la tabla de rutas:
ip rule add from all fwmark 0x1 lookup 100 ip rule add from all fwmark 0x2 lookup 101
y a las iptables
iptables -t mangle -A OUTPUT -m conntrack --ctorigdst 193.145.155.10 -j MARK --set-mark=1 iptables -t mangle -A OUTPUT -m conntrack --ctorigdst 193.145.155.12 -j MARK --set-mark=2
Por lo general las reglas anteriores van en la tabla PREROUTING pero nosotros estamos usando vservers. Eso significa que a efectos prácticos los paquetes son generados localmente pues no vienen de un equipo externo. Así que la tabla correcta para colorar dichas reglas es OUTPUT.
Y aquí termina nuestro pequeño artículo de hoy.
Saludos.
- blog de aplatanado
- Inicie sesión para enviar comentarios
- 673 lecturas



