A resolução do nome do host leva 5 segundos

7

Eu tenho um servidor master bind9 DNS e 2 servidores escravos em execução no IPv4 (Debian Jessie), usando /etc/bind/named.conf :

listen-on-v6 { none; };

Quando tento conectar-me a partir de diferentes servidores, cada conexão leva pelo menos 5 segundos (estou usando informações de tempo de Joseph para depuração):

$ 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

De acordo com curl , a pesquisa demora a maior parte do tempo, no entanto, o padrão nslookup é muito rápido:

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

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

Depois de forçar curl a usar o IPv4, fica muito melhor:

$ 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

Eu desabilitei o IPv6 no host:

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

embora o problema persista. Eu tentei executar strace para ver qual é o motivo dos tempos limite:

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)

Não parece haver problemas de firewall, pois nslookup (ou curl -4 ) está usando os mesmos servidores DNS. Alguma ideia do que poderia estar errado?

Aqui está tcpdump do host 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: Nos logs de ligação, aparece frequentemente esta mensagem:

error sending response: host unreachable

No entanto, cada consulta é eventualmente respondida (demora apenas 5s). Todas as máquinas são servidores físicos (não é culpa do NAT), é mais provável que os pacotes estejam sendo bloqueados por um roteador. Aqui está uma questão bastante provável: as pesquisas de DNS às vezes levam 5 segundos .

    
por Tombart 20.06.2016 / 22:21

3 respostas

7

Resposta curta:

Uma solução alternativa é forçar glibc a reutilizar um soquete para pesquisar os registros AAAA e A , adicionando uma linha a /etc/resolv.conf :

options single-request-reopen

A causa real desse problema pode ser:

Resposta longa:

Programas como curl ou wget usam a função da glibc getaddrinfo () , que tenta ser compatível com o IPv4 e o IPv6 procurando os dois registros DNS em paralelo. Ele não retorna o resultado até que ambos os registros sejam recebidos (há vários problemas relacionados a esse comportamento ) - isso explica o strace acima. Quando o IPv4 é forçado, como curl -4 internamente gethostbyname() , que consulta apenas o A .

De tcpdump , podemos ver isso:

  • -> A? dois pedidos são enviados no início
  • -> AAAA? (solicitando endereço IPv6)
  • <- AAAA reply
  • -> A? solicitando novamente o endereço IPv4
  • <- A obteve resposta
  • -> AAAA? solicitando novamente o IPv6
  • <- AAAA reply

Uma A resposta é descartada por algum motivo, essa é a mensagem de erro:

error sending response: host unreachable

Ainda não está claro para mim por que há uma necessidade de segunda consulta AAAA .

Para verificar se você está com o mesmo problema, atualize o tempo limite em /etc/resolv.conf :

options timeout:3

como descrita aqui :

$ 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

Existem duas outras opções relacionadas em man resolv.conf :

single-request (since glibc 2.10) sets RES_SNGLKUP in _res.options. By default, glibc performs IPv4 and IPv6 lookups in parallel since version 2.9. Some appliance DNS servers cannot handle these queries properly and make the requests time out. This option disables the behavior and makes glibc perform the IPv6 and IPv4 requests sequentially (at the cost of some slowdown of the resolving process).

single-request-reopen (since glibc 2.9) The resolver uses the same socket for the A and AAAA requests. Some hardware mistakenly sends back only one reply. When that happens the client system will sit and wait for the second reply. Turning this option on changes this behavior so that if two requests from the same port are not handled correctly it will close the socket and open a new one before sending the second request.

Problemas relacionados:

por 21.06.2016 / 13:48
4

Como diz @Tartart, o atraso se deve à espera do tempo limite de resolução do IPv6.

Outro curso de ação possível está dando precedência ao IPv4 em /etc/gai.conf

De comentários em /etc/gai.conf

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

Depois de alterar gai.conf , você precisa reiniciar qualquer aplicativo usando a biblioteca de resolução de DNS para que a alteração entre em vigor.

Lembre-se de que, se você estiver usando um servidor BIND sem conectividade IPv6, aconselho a desabilitar o IPv6 em named e a partir dos endereços IPv6 das dicas de raiz. Obviamente, ele ainda tentará resolver os endereços AAAA.

Então, para a configuração do BIND,

Em / etc / default / bind9, adicione -4 para endereços IPv4:

OPTIONS="-4 -u bind"

e em /etc/bind/db.root , exclua todas as linhas com raízes de DNS AAAA.

    
por 21.06.2016 / 22:05
2

Eu tive um problema semelhante ao usar o BIND9. Para corrigir isso, precisei adicionar:

filter-aaaa-on-v4 yes;
Opção

para meu named.conf .

( Mais informações )

    
por 28.11.2017 / 22:00