Resolver el nombre de host tarda 5 segundos

Resolver el nombre de host tarda 5 segundos

Tengo un bind9servidor DNS maestro y 2 servidores esclavos ejecutándose en IPv4 (Debian Jessie), usando /etc/bind/named.conf:

listen-on-v6 { none; };

Cuando intento conectarme desde diferentes servidores, cada conexión tarda al menos 5 segundos (estoy usandoInformación del tiempo de Josépara depurar):

$ curl -w "@curl-format.txt" -o /dev/null -s https://example.com
            time_namelookup:  5.512
               time_connect:  5.512
            time_appconnect:  5.529
           time_pretransfer:  5.529
              time_redirect:  0.000
         time_starttransfer:  5.531
                            ----------
                 time_total:  5.531

Según curl, la búsqueda lleva la mayor parte del tiempo, sin embargo, el estándar nslookupes muy rápido:

$ time nslookup example.com > /dev/null 2>&1

real    0m0.018s
user    0m0.016s
sys     0m0.000s

Después de forzar curlel uso de IPv4, se pone mucho mejor:

$ curl -4 -w "@curl-format.txt" -o /dev/null -s https://example.com

            time_namelookup:  0.004
               time_connect:  0.005
            time_appconnect:  0.020
           time_pretransfer:  0.020
              time_redirect:  0.000
         time_starttransfer:  0.022
                            ----------
                 time_total:  0.022

He desactivado IPv6 en el host:

echo 1 > /proc/sys/net/ipv6/conf/eth0/disable_ipv6

aunque el problema persiste. Intenté ejecutar stracepara ver cuál es el motivo de los tiempos de espera:

write(2, "*", 1*)                        = 1
write(2, " ", 1 )                        = 1
write(2, "Hostname was NOT found in DNS ca"..., 36Hostname was NOT found in DNS cache
) = 36
socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP) = 4
close(4)                                = 0
mmap(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f220bcf8000
mprotect(0x7f220bcf8000, 4096, PROT_NONE) = 0
clone(child_stack=0x7f220c4f7fb0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f220c4f89d0, tls=0x7f220c4f8700, child_tidptr=0x7f220c4f89d0) = 2004
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, NULL, 8) = 0
rt_sigaction(SIGPIPE, NULL, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, 8) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, NULL, 8) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, NULL, 8) = 0
poll(0, 0, 4)                           = 0 (Timeout)
rt_sigaction(SIGPIPE, NULL, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, 8) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, NULL, 8) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, NULL, 8) = 0
poll(0, 0, 8)                           = 0 (Timeout)
rt_sigaction(SIGPIPE, NULL, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, 8) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, NULL, 8) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, NULL, 8) = 0
poll(0, 0, 16)                          = 0 (Timeout)
rt_sigaction(SIGPIPE, NULL, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, 8) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, NULL, 8) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, NULL, 8) = 0
poll(0, 0, 32)                          = 0 (Timeout)
rt_sigaction(SIGPIPE, NULL, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, 8) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, NULL, 8) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f22102e08d0}, NULL, 8) = 0
poll(0, 0, 64)                          = 0 (Timeout)

No parece ser un problema de firewall ya que nslookup(o curl -4) está usando los mismos servidores DNS. ¿Alguna idea de qué podría estar mal?

Esto es tcpdumpdel anfitrión tcpdump -vvv -s 0 -l -n port 53:

tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
20:14:52.542526 IP (tos 0x0, ttl 64, id 35839, offset 0, flags [DF], proto UDP (17), length 63)
    192.168.1.1.59163 > 192.168.1.2.53: [bad udp cksum 0xf9f3 -> 0x96c7!] 39535+ A? example.com. (35)
20:14:52.542540 IP (tos 0x0, ttl 64, id 35840, offset 0, flags [DF], proto UDP (17), length 63)
    192.168.1.1.59163 > 192.168.1.2.53: [bad udp cksum 0xf9f3 -> 0x6289!] 45997+ AAAA? example.com. (35)
20:14:52.543281 IP (tos 0x0, ttl 61, id 63674, offset 0, flags [none], proto UDP (17), length 158)
    192.168.1.2.53 > 192.168.1.1.59163: [udp sum ok] 45997* q: AAAA? example.com. 1/1/0 example.com. [1h] CNAME s01.example.com. ns: example.com. [10m] SOA ns01.example.com. ns51.domaincontrol.com. 2016062008 28800 7200 1209600 600 (130)
20:14:57.547439 IP (tos 0x0, ttl 64, id 36868, offset 0, flags [DF], proto UDP (17), length 63)
    192.168.1.1.59163 > 192.168.1.2.53: [bad udp cksum 0xf9f3 -> 0x96c7!] 39535+ A? example.com. (35)
20:14:57.548188 IP (tos 0x0, ttl 61, id 64567, offset 0, flags [none], proto UDP (17), length 184)
    192.168.1.2.53 > 192.168.1.1.59163: [udp sum ok] 39535* q: A? example.com. 2/2/2 example.com. [1h] CNAME s01.example.com., s01.example.com. [1h] A 136.243.154.168 ns: example.com. [30m] NS ns01.example.com., example.com. [30m] NS ns02.example.com. ar: ns01.example.com. [1h] A 136.243.154.168, ns02.example.com. [1h] A 192.168.1.2 (156)
20:14:57.548250 IP (tos 0x0, ttl 64, id 36869, offset 0, flags [DF], proto UDP (17), length 63)
    192.168.1.1.59163 > 192.168.1.2.53: [bad udp cksum 0xf9f3 -> 0x6289!] 45997+ AAAA? example.com. (35)
20:14:57.548934 IP (tos 0x0, ttl 61, id 64568, offset 0, flags [none], proto UDP (17), length 158)
    192.168.1.2.53 > 192.168.1.1.59163: [udp sum ok] 45997* q: AAAA? example.com. 1/1/0 example.com. [1h] CNAME s01.example.com. ns: example.com. [10m] SOA ns01.example.com. ns51.domaincontrol.com. 2016062008 28800 7200 1209600 600 (130)

EDITAR: En los registros de vinculación aparece con frecuencia este mensaje:

error sending response: host unreachable

Sin embargo, cada consulta finalmente se responde (solo se necesitan 5 segundos). Todas las máquinas son servidores físicos (no es culpa de NAT), es más probable que un enrutador bloquee los paquetes. Aquí hay una pregunta muy probablemente relacionada:Las búsquedas de DNS a veces tardan 5 segundos.

Respuesta1

Respuesta corta:

Una solución alternativa es obligar glibca reutilizar un socket para buscar registros AAAAy Aagregando una línea a /etc/resolv.conf:

options single-request-reopen

La verdadera causa de este problema podría ser:

Respuesta larga:

Programas como curlo wgetusan la función de glibcobteneraddrinfo(), que intenta ser compatible tanto con IPv4 como con IPv6 buscando ambos registros DNS en paralelo. No devuelve resultado hasta que se reciben ambos registros (hayvarios problemas relacionados con tal comportamiento) - esto explica lo straceanterior. Cuando se fuerza IPv4, como curl -4internamente gethostbyname(), que consulta Asolo para registros.

De tcpdumppodemos ver que:

  • -> A?Se envían dos solicitudes al principio.
  • -> AAAA?(solicitando dirección IPv6)
  • <- AAAAresponder
  • -> A?solicitando nuevamente la dirección IPv4
  • <- Aobtuve respuesta
  • -> AAAA?solicitando IPv6 nuevamente
  • <- AAAAresponder

Una Arespuesta se descarta por algún motivo; ese es este mensaje de error:

error sending response: host unreachable

Sin embargo, no me queda claro por qué es necesaria una segunda AAAAconsulta.

Para verificar que tienes el mismo problema, puedes actualizar el tiempo de espera en /etc/resolv.conf:

options timeout:3

Primero cree un archivo de texto conconfiguración de informes de tiempo personalizados:

cat >./curl-format.txt  <<-EOF
   time_namelookup: %{time_namelookup}\n
      time_connect: %{time_connect}\n
   time_appconnect: %{time_appconnect}\n
     time_redirect: %{time_redirect}\n
  time_pretransfer: %{time_pretransfer}\n
time_starttransfer: %{time_starttransfer}\n
                    ----------\n
time_total: %{time_total}\n
EOF

luego envía una solicitud:

$ curl -w "@curl-format.txt" -o /dev/null -s https://example.com

            time_namelookup:  3.511
               time_connect:  3.511
            time_appconnect:  3.528
           time_pretransfer:  3.528
              time_redirect:  0.000
         time_starttransfer:  3.531
                            ----------
                 time_total:  3.531

Hay otras dos opciones relacionadas en man resolv.conf:

solicitud única (desde glibc 2.10)se establece RES_SNGLKUP en _res.options. De forma predeterminada, glibc realiza búsquedas de IPv4 e IPv6 en paralelo desde la versión 2.9. Algunos servidores DNS de dispositivos no pueden manejar estas consultas correctamente y hacen que las solicitudes expiren. Esta opción desactiva el comportamiento y hace que glibc realice las solicitudes de IPv6 e IPv4 de forma secuencial (a costa de cierta ralentización del proceso de resolución).

reapertura de solicitud única (desde glibc 2.9) El solucionador utiliza el mismo socket para las solicitudes A y AAAA. Algunos hardware envían por error sólo una respuesta. Cuando eso suceda, el sistema cliente se sentará y esperará la segunda respuesta. Activar esta opción cambia este comportamiento de modo que si dos solicitudes del mismo puerto no se manejan correctamente, se cerrará el socket y se abrirá uno nuevo antes de enviar la segunda solicitud.

Asuntos relacionados:

Respuesta2

Como dice @Tombart, el retraso se debe a la espera del tiempo de espera de resolución de IPv6.

Otro posible curso de acción es dar prioridad a IPv4 en /etc/gai.conf

De comentarios en /etc/gai.conf

#   For sites which prefer IPv4 connections change the last line to
#
precedence ::ffff:0:0/96  100

Después de cambiar gai.conf, debe reiniciar cualquier aplicación que utilice la biblioteca de resolución de DNS para que el cambio surta efecto.

Tenga en cuenta que si está utilizando un servidor BIND sin conectividad IPv6, le recomiendo deshabilitar IPv6 namedy tomar de la raíz las direcciones IPv6. Obviamente seguirá intentando resolver las direcciones AAAA.

Entonces, para la configuración BIND,

En /etc/default/bind9, agregue -4 para direcciones IPv4:

OPTIONS="-4 -u bind"

y en /etc/bind/db.root, elimine todas las líneas con raíces DNS AAAA.

Respuesta3

Tuve un problema similar al usar BIND9. Para solucionar esto necesitaba agregar:

filter-aaaa-on-v4 yes;

opción a mi named.conf.

(Más información)

Respuesta4

En caso de que alguien esté buscando el archivo curl-format.txt. Pega esto en tu shell y creará el archivo de formato por ti. El enlace original no funcionó para mí. encontré este ejemploaquí

cat >./curl-format.txt  <<-EOF
   time_namelookup: %{time_namelookup}\n
      time_connect: %{time_connect}\n
   time_appconnect: %{time_appconnect}\n
     time_redirect: %{time_redirect}\n
  time_pretransfer: %{time_pretransfer}\n
time_starttransfer: %{time_starttransfer}\n
                    ----------\n
time_total: %{time_total}\n
EOF

información relacionada