Tengo una máquina virtual que ejecuta Debian Wheezy en la que algunas búsquedas de nombres de host tardan varios segundos en completarse, aunque el solucionador responde de inmediato. Curiosamente, las búsquedas con getaddrinfo()
se ven afectadas, pero gethostbyname()
no lo es.
He cambiado a los solucionadores de Google para excluir la posibilidad de que los locales estén rotos, por lo que mi /etc/resolv.conf
aspecto es el siguiente:
search my-domain.com
nameserver 8.8.4.4
nameserver 8.8.8.8
Mi nsswitch.conf
tiene la línea:
hosts: files dns
y mi /etc/hosts
no contiene nada inusual.
Si lo intento telnet webserver 80
, se cuelga durante varios segundos antes de obtener una resolución de nombre. Una ltrace
salida [1] muestra que el bloqueo está en una getaddrinfo()
llamada:
getaddrinfo("ifconfig.me", "telnet", { AI_CANONNAME, 0, SOCK_STREAM, 0, 0, NULL, '\000', NULL }, 0x7fffb4ffc160) = 0 <5.020621>
Sin embargo, tcpdump
revela que el servidor de nombres respondió de inmediato, y solo en la segunda respuesta se telnet
desbloqueó. Las respuestas parecen idénticas:
05:52:58.609731 IP 192.168.1.75.43017 > 8.8.4.4.53: 54755+ A? ifconfig.me. (29)
05:52:58.609786 IP 192.168.1.75.43017 > 8.8.4.4.53: 26090+ AAAA? ifconfig.me. (29)
05:52:58.612188 IP 8.8.4.4.53 > 192.168.1.75.43017: 54755 4/0/0 A 219.94.235.40, A 133.242.129.236, A 49.212.149.105, A 49.212.202.172 (93)
[...five second pause...]
05:53:03.613811 IP 192.168.1.75.43017 > 8.8.4.4.53: 54755+ A? ifconfig.me. (29)
05:53:03.616424 IP 8.8.4.4.53 > 192.168.1.75.43017: 54755 4/0/0 A 219.94.235.40, A 133.242.129.236, A 49.212.149.105, A 49.212.202.172 (93)
05:53:03.616547 IP 192.168.1.75.43017 > 8.8.4.4.53: 26090+ AAAA? ifconfig.me. (29)
05:53:03.618907 IP 8.8.4.4.53 > 192.168.1.75.43017: 26090 0/1/0 (76)
Revisé los registros del firewall del host y no se bloquea nada en el puerto 53.
¿Qué está causando que se ignore la primera respuesta DNS?
[1] Agregué un par de líneas para ltrace.conf
poder ver dentro de la addrinfo
estructura.
Respuestas:
La primera respuesta DNS no se ignora.
getaddrinfo()
no regresó hasta que recibió la respuesta a la primera consulta AAAA (ID: 26090). Entonces, el verdadero problema aquí es por qué su máquina no ha recibido inmediatamente la respuesta a la consulta AAAA, mientras que ha recibido la respuesta para la consulta A (ID: 54755).Una de las diferencias entre
getaddrinfo()
ygethostbyname()
es que el primero es compatible con IPv4 e IPv6, mientras que el segundo solo es compatible con IPv4. Entonces, cuando llamegetaddrinfo()
conai_family
set a 0 (AF_UNSPEC
), no regresará hasta que obtenga una respuesta (o llegue a un tiempo de espera) para las consultas A y AAAA para el nombre de dominio proporcionado.gethostbyname()
solo consultas para un registro A.Es difícil determinar de forma remota qué puede estar causando su problema, especialmente porque ha recortado algunos
tcpdump
resultados. Algo podría estar filtrando / soltando selectivamente el tráfico DNS entre su VM y los solucionadores de DNS públicos de Google. Intenté reproducir su problema usando una máquina virtual Debian Wheezy de KVM, perotelnet ifconfig.me
casi de inmediato imprimí laTrying <IP_address_here>...
línea (lo que significa que ya ha resuelto el nombre para entonces).fuente
Esto fue causado por un conjunto de reglas demasiado restrictivo en un firewall de Juniper que se encuentra frente a la infraestructura de VMware.
Construí un dispositivo de resolución de prueba para poder ver ambos lados de la conversación, y el paquete faltante identificado por Kempniu en su excelente respuesta se dejó caer en algún lugar del camino. Como se señaló en esa respuesta,
getaddrinfo()
sin una dirección especificada, la familia esperará las respuestas relacionadas con todas las familias apoyadas antes de regresar (o, en mi caso, agotar el tiempo de espera).Mi colega que dirige la red señaló que
Entonces, el firewall vio la respuesta de IPv4, notó que respondió a la consulta de la máquina virtual y cerró la ruta de entrada para ese puerto. Por lo tanto, el siguiente paquete de respuesta IPv6 se descartó. No tengo idea de por qué ambos paquetes lograron pasar la segunda vez, pero deshabilitar esta función en el firewall solucionó el problema.
Este es un extracto relacionado del Juniper KB:
Si está pensando en votar esta respuesta, por favor también vote la respuesta de Kempniu. Sin él, todavía estaría dando vueltas tratando de encontrar algún problema de configuración en la VM.
fuente