Las búsquedas de DNS a veces tardan 5 segundos

11

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.confaspecto es el siguiente:

search my-domain.com
nameserver 8.8.4.4
nameserver 8.8.8.8

Mi nsswitch.conftiene la línea:

hosts: files dns

y mi /etc/hostsno contiene nada inusual.

Si lo intento telnet webserver 80, se cuelga durante varios segundos antes de obtener una resolución de nombre. Una ltracesalida [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, tcpdumprevela que el servidor de nombres respondió de inmediato, y solo en la segunda respuesta se telnetdesbloqueó. 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.confpoder ver dentro de la addrinfoestructura.

Flup
fuente
¿Cómo es la configuración de la NIC de la VM? Puenteado? NAT?
slm
Es natural. No estoy seguro exactamente dónde se aplica el NAT (ya sea por ESX o más arriba); Puedo averiguar si crees que podría importar.
Flup
Sospecho que es la VM NAT + lo que está influyendo en esto.
slm
Bien podría ser, vea mis comentarios sobre la respuesta de Kempniu a continuación.
Flup
Fue una red, pero no específicamente NAT lo que causó esto; vea mi respuesta a continuación.
Flup

Respuestas:

13

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()y gethostbyname()es que el primero es compatible con IPv4 e IPv6, mientras que el segundo solo es compatible con IPv4. Entonces, cuando llame getaddrinfo()con ai_familyset 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 tcpdumpresultados. 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, pero telnet ifconfig.mecasi de inmediato imprimí la Trying <IP_address_here>...línea (lo que significa que ya ha resuelto el nombre para entonces).

Kempniu
fuente
Gracias por tu respuesta detallada. No he cortado nada del tcpdump, solo inserté una línea para aclarar dónde estaba la pausa. Sin embargo, definitivamente me has dado algo para seguir; No me di cuenta de la diferencia significativa entre las dos llamadas a la biblioteca.
Flup
Si no hay más paquetes relacionados con DNS en su máquina, es probable que algo esté filtrando su tráfico (no necesariamente a propósito). De todos modos, si encuentra una solución, ¿podría compartirla aquí?
Kempniu
1
De hecho lo haré. Después de configurar un dispositivo de resolución de prueba, puedo ver de manera concluyente que un paquete de respuesta, el de mi pregunta, se descarta cada vez. Sospecho que algo dentro o cerca de la infraestructura de VMware lo está haciendo, así que me puse en contacto con mi homólogo que se ocupa de ese lado de las cosas. Cuando llegue al fondo, volveré y agregaré detalles. ¡Gracias de nuevo!
Flup
Solución agregada en mi propia respuesta. Muchas gracias una vez más por su ayuda.
Flup
9

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

El comportamiento predeterminado en el firewall de Juniper es cerrar una sesión relacionada con DNS tan pronto como se reciba una respuesta de DNS que coincida con esa sesión.

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:

Aquí hay un escenario donde se descartan los paquetes de respuesta DNS:

  1. Se crea una sesión para el tráfico DNS cuando el primer paquete de consulta DNS llega al cortafuegos y hay una política de permisos configurada. El tiempo de espera predeterminado es de 60 segundos.
  2. Inmediatamente antes de que se cierre la sesión, se transmite una nueva consulta DNS, y dado que coincide con una sesión existente (dado que el puerto de origen y destino / par de IP es siempre el mismo), el firewall lo reenvía. Tenga en cuenta que el tiempo de espera de la sesión no se actualiza de acuerdo con cualquier paquete recién llegado.
  3. La sesión de DNS creada caduca cuando la primera respuesta de consulta (respuesta) de DNS llega al dispositivo, independientemente de cuánto tiempo quede.
  4. Cuando se pasa una respuesta DNS a través del firewall, la sesión caduca.
  5. El firewall corta todas las respuestas DNS posteriores, ya que no existe una sesión.

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.

Flup
fuente
1
Hemos experimentado los mismos síntomas en Debian 8.2. La nuestra se debió a una causa diferente, y la "solución" fue diferente (del lado del cliente). Escribí en un blog sobre nuestro problema específico y el problema más general: philippecloutier.com/… Quiero agradecer a Flup y Kempniu, ya que sus preguntas y respuestas me pusieron en el camino correcto.
Philippe Cloutier