J'ai une machine virtuelle exécutant Debian Wheezy sur laquelle certaines recherches de nom d'hôte prennent plusieurs secondes, même si le résolveur répond immédiatement. Étrangement, les recherches avec getaddrinfo()
sont affectées, mais ce gethostbyname()
n'est pas le cas.
Je suis passé aux résolveurs Google pour exclure la possibilité que les résolveurs locaux soient cassés, donc mon /etc/resolv.conf
apparence ressemble à:
search my-domain.com
nameserver 8.8.4.4
nameserver 8.8.8.8
Mon nsswitch.conf
a la ligne:
hosts: files dns
et mon /etc/hosts
ne contient rien d'inhabituel.
Si j'essaye telnet webserver 80
, il se bloque pendant plusieurs secondes avant d'obtenir une résolution de nom. Une ltrace
sortie [1] montre que le blocage est en cours d' getaddrinfo()
appel:
getaddrinfo("ifconfig.me", "telnet", { AI_CANONNAME, 0, SOCK_STREAM, 0, 0, NULL, '\000', NULL }, 0x7fffb4ffc160) = 0 <5.020621>
Cependant, tcpdump
révèle que le serveur de noms a répondu immédiatement, et ce n'est que sur la deuxième réponse qui a telnet
débloqué. Les réponses semblent identiques:
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)
J'ai vérifié les journaux du pare-feu de l'hôte et rien sur le port 53 n'est bloqué.
Qu'est-ce qui fait que la première réponse DNS est ignorée?
[1] J'ai ajouté quelques lignes à mon ltrace.conf
afin que je puisse voir l'intérieur de la addrinfo
structure.
Réponses:
La première réponse DNS n'est pas ignorée.
getaddrinfo()
n'est retourné qu'après avoir reçu la réponse à la première requête AAAA (ID: 26090). Donc, le vrai problème ici est pourquoi votre machine n'a pas immédiatement reçu la réponse à la requête AAAA, alors qu'elle a reçu la réponse pour la requête A (ID: 54755).L'une des différences entre
getaddrinfo()
etgethostbyname()
est que le premier prend en charge IPv4 et IPv6, tandis que le dernier ne prend en charge que IPv4. Ainsi, lorsque vous appelezgetaddrinfo()
avecai_family
set à 0 (AF_UNSPEC
), il ne reviendra pas tant qu'il n'aura pas de réponse (ou atteindra un délai) pour les requêtes A et AAAA pour le nom de domaine fourni.gethostbyname()
recherche uniquement un enregistrement A.Il est difficile de déterminer à distance ce qui peut être à l'origine de votre problème, en particulier si vous avez coupé certaines
tcpdump
sorties. Quelque chose pourrait filtrer / supprimer sélectivement le trafic DNS entre votre machine virtuelle et les résolveurs DNS publics de Google. J'ai essayé de reproduire votre problème en utilisant une machine virtuelle Debian Wheezy KVM, mais j'aitelnet ifconfig.me
presque immédiatement imprimé laTrying <IP_address_here>...
ligne (ce qui signifie qu'il a déjà résolu le nom d'ici là).la source
Cela était dû à un ensemble de règles trop restrictif sur un pare-feu Juniper qui se trouve en face de l'infrastructure VMware.
J'ai construit un résolveur de test pour que je puisse voir les deux côtés de la conversation, et le paquet manquant identifié par Kempniu dans son excellente réponse était en effet abandonné quelque part en cours de route. Comme indiqué dans cette réponse,
getaddrinfo()
sans adresse spécifiée, la famille attendra les réponses concernant toutes les familles prises en charge avant de revenir (ou, dans mon cas, expirer).Mon collègue qui dirige le réseau a noté que
Le pare-feu voyait donc la réponse IPv4, notant qu'il répondait à la requête de la machine virtuelle et fermant le chemin entrant pour ce port. Le paquet de réponse IPv6 suivant a donc été supprimé. Je ne sais pas pourquoi les deux paquets ont réussi la deuxième fois, mais la désactivation de cette fonctionnalité sur le pare-feu a résolu le problème.
Il s'agit d'un extrait connexe de la base de connaissances Juniper:
Si vous songez à voter pour cette réponse, veuillez également voter pour la réponse de Kempniu. Sans cela, je serais toujours en train d'essayer de trouver un problème de configuration sur la machine virtuelle.
la source