Uno de los protocolos más utilizados y a la vez más desconocidos que se utilizan en las redes LAN es ARP. Este protocolo trabaja silenciosamente. No necesita ningún tipo de configuración ni de mantenimiento y habitualmente no ocasiona ningún problema, salvo excepciones muy excepcionales…
Este artículo no está dedicado a explicar cómo funciona ARP sino a explicar un problema derivado del uso de ARP. Veremos el escenario típico donde se puede producir y la forma de solucionarlo.
Protocolo ARP
Por hacer un resumen rápido. ARP son las siglas de Address Resolution Protocol, es decir, protocolo de resolución de direcciones. Se utiliza en redes LAN para obtener la dirección MAC (dirección física) de un nodo a partir de su dirección IP, ya que todos los servicios de red en redes TCP/IP están preparados para trabajar con direcciones IP como mecanismo de identificación del origen y el destino de una comunicación.
En muchos servicios se utilizan nombres para referirse a los nodos que forman parte de la comunicación, sin embargo, siempre hay algún procedimiento (protocolo) para obtener la dirección IP del nodo a partir de su nombre, por ejemplo:
- Para obtener la dirección IP a partir de su nombre en nodos visible en Internet o en los nodos de redes corporativas se utiliza el protocolo DNS (Domain Name Service).
- Para obtener la dirección IP a partir del nombre del equipo en redes locales se utiliza el protocolo CIFS (Common Internet File System) de Microsoft, cuya implementación libre para equipos Linux se conoce como Samba.
Sin embargo, en redes LAN, tanto cableadas (Ethernet) como inalámbricas (Wi-Fi) hay un tercer nivel de identificación de los nodos, que es el direccionamiento físico, por tanto, es necesario conocer la dirección física o dirección MAC del nodo de destino, y es aquí donde entra en funcionamiento ARP. Este protocolo utiliza un par de tramas, conocidas como ARP Request (Petición ARP) y ARP Reply (Respuesta ARP), para obtener la dirección MAC de un nodo de la red. Cada nodo mantiene una tabla conocida como tabla ARP donde almacena las correspondencias entre las direcciones IP y las direcciones MAC de otros nodos de la red con los que ya ha tenido algún tipo de comunicación. Se puede ver el contenido de dicha tabla con el comando arp:
C:\> arp -a (en sistemas Windows)
$ arp -n (en sistemas Linux)
Como se observa, gracias a las tramas ARP Request, ARP Reply y a la tabla ARP, los diferentes nodos de una red pueden conocer las direcciones MAC de otros nodos de forma transparente al usuario.
El escenario del problema
Lo cierto es que el entorno en el que se produjo el problema es algo poco frecuente y de hecho era una situación temporal. Lo explico.
Un ordenador con dos tarjetas de red y con el software adecuado puede hacer perfectamente las funciones de router dentro de una red. En este caso se utilizó un ordenador con Ubuntu y el software necesario para su función de router (este software es Zentyal, en otro artículo hablaré de él).
El “fallo” fue conectar las dos tarjetas de red al mismo medio físico, es decir, al mismo switch. La idea era crear dos subredes lógicas y que el router pudiera encaminar tráfico entre dichas subredes. En la configuración final se utilizarían VLAN diferentes (en cuyo caso el problema de ARP Flux no se manifiesta) pero para realizar pruebas se decidió no configurar ninguna VLAN. Y este fue el problema.
Cuando dos tarjetas de red de un mismo equipo están conectadas al mismo medio (para los más “puritanos”, al mismo dominio de difusión) la configuración del núcleo de Linux hace una difusión de las peticiones de direcciones MAC (ARP Request) y esto hace que la tabla ARP almacene información errónea. En este enlace se explica el problema.
En la siguiente figura se muestra la configuración del equipo con las dos tarjetas de red:
Como se observa, la tarjeta eth0 tiene asignada la dirección 192.168.0.14 (red 192.168.0.0) y la tarjeta eth1 tiene asignada la dirección 172.16.0.1 (red 172.16.0.0). A continuación se muestra el resultado de la ejecución del comando arp en el equipo Ubuntu Server después de ejecutar un comando ping desde otro equipo de la red con la dirección 172.16.12.221:
El equipo 172.16.12.221 manda una petición ARP para el obtener la dirección MAC del destino (dirección 172.16.0.1) utilizando una trama ARP Request. Esta trama se envía a la dirección MAC de broadcast, por lo tanto, llega a las dos tarjetas de red y se almacena en la tabla ARP la información duplicada.
El problema es que la respuesta (ARP Reply) se envía desde la tarjeta eth0 (la primera de la tabla) que no se corresponde con una dirección IP válida del equipo por lo que nunca le llegará la respuesta.
La consecuencia de esto es que el equipo 172.16.12.221 no se podrá comunicar con el equipo con las dos tarjetas de red. Lo curioso de la situación es que el problema no se manifiesta siempre. Depende de cómo aparezca la información en la tabla ARP. Si en la tabla ARP aparece primero la dirección correcta, entonces funcionará correctamente.
Recordemos que la tabla ARP se vacía cada cierto tiempo (típicamente cada 300 segundos) por lo que, aunque funcione en un momento dado la conexión, en el siguiente refresco de la tabla ARP puede invertirse el orden de las direcciones y por tanto dejar de funcionar.
La solución
Como he indicado al principio, el problema ocurre sólo cuando las dos tarjetas de red del equipo con Linux están conectadas a la misma red física.
En la configuración final, cada tarjeta de red se conecta a una VLAN diferente, por tanto, las tramas de difusión ARP Request llegarán sólo a la tarjeta correcta. En definitiva, una posible solución es utilizar VLAN.
La segunda solución sirve para poder mantener la configuración original sin utilizar VLAN. Fue encontrada en el siguiente enlace y consiste en modificar un parámetro del kernel llamado arp_filter, que por defecto está a valor 0. La modificación dinámica de cualquier parámetro del kernel se hace con el comando sysctl. Cualquier cambio hecho de esta forma se mantendrá hasta el siguiente reinicio del equipo. Se puede ver una lista de los parámetros configurables con:
sysctl –A
Para modificar algún parámetro se utiliza la opción –w. En nuestro caso habrá que ejecutar (con permisos de administrador) el siguiente comando:
sysctl -w net.ipv4.conf.all.arp_filter=1
El comando anterior debería funcionar cuando las IPs de las tarjetas de red son de redes lógicas diferentes (que es nuestro caso). Si no, además habría que añadir:
sysctl -w net.ipv4.conf.all.arp_ignore=1
sysctl -w net.ipv4.conf.all.arp_announce=2
Para hacer permanente el cambio del parámetro hay que modificar el fichero de configuración /etc/sysctl.conf, en el cual habrá que añadir la siguiente línea:
net.ipv4.conf.all.arp_filter = 1
Con este cambio se evita que se haga difusión de las tramas entre las dos tarjetas de red y por tanto, soluciona el problema.
Un último apunte, ARP fue publicado como protocolo estándar de TCP/IP en 1982 (RFC 826). Con IPv6, ARP desaparece y sus funciones se llevan a cabo con otro protocolo más avanzado: NDP (Neighbor Discovery Protocol).
ARP Flux,
GRACIAS UN DATO PARA CURIOSOS