Le ricerche DNS a volte impiegano 5 secondi


11

Ho una VM che esegue Debian Wheezy su cui alcune ricerche di nomi host impiegano diversi secondi per completare, anche se il risolutore risponde immediatamente. Stranamente, le ricerche con getaddrinfo()sono interessate, ma gethostbyname()non lo è.

Sono passato ai resolver di Google per escludere la possibilità che quelli locali siano rotti, quindi il mio /etc/resolv.confaspetto è:

search my-domain.com
nameserver 8.8.4.4
nameserver 8.8.8.8

Il mio nsswitch.confha la linea:

hosts: files dns

e il mio /etc/hostsnon contiene nulla di insolito.

Se provo telnet webserver 80, si blocca per alcuni secondi prima di ottenere una risoluzione del nome. Un ltraceoutput [1] mostra che l'hang è in una getaddrinfo()chiamata:

getaddrinfo("ifconfig.me", "telnet", { AI_CANONNAME, 0, SOCK_STREAM, 0, 0, NULL, '\000', NULL }, 0x7fffb4ffc160) = 0 <5.020621>

Tuttavia, tcpdumprivela che il nameserver ha risposto immediatamente, ed è stato solo sulla seconda risposta che è stata telnetsbloccata. Le risposte sembrano identiche:

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)

Ho controllato i log del firewall host e nulla sulla porta 53 è stato bloccato.

Cosa causa l'ignoramento della prima risposta DNS?

[1] Ho aggiunto un paio di righe al mio in ltrace.confmodo da poter vedere all'interno della addrinfostruttura.


Come si configura la NIC della VM? Ponte? NAT?
slm

È NATted. Non sono sicuro di dove sia applicato il NAT (sia da ESX o più a monte); Posso scoprire se pensi che possa importare.
Flup,

Sospetto che sia la NAT + VM a influenzare questo.
slm

Potrebbe anche essere - vedi i miei commenti sulla risposta di Kempniu di seguito.
Flup,

Era un problema di rete, ma non in particolare il NAT lo causava - vedi la mia risposta qui sotto.
Flup,

Risposte:


13

La prima risposta DNS non viene ignorata. getaddrinfo()non è tornato fino a quando non ha ricevuto la risposta alla prima query AAAA (ID: 26090). Quindi il vero problema qui è perché il tuo computer non ha ricevuto immediatamente la risposta alla query AAAA, mentre ha ricevuto la risposta per la query A (ID: 54755).

Una delle differenze tra getaddrinfo()e gethostbyname()è che il primo supporta sia IPv4 che IPv6, mentre il secondo supporta solo IPv4. Pertanto, quando chiami getaddrinfo()con ai_familyset su 0 ( AF_UNSPEC), non tornerà fino a quando non ottiene una risposta (o non raggiunge un timeout) per le query A e AAAA per il nome di dominio fornito. gethostbyname()solo query per un record A.

È difficile determinare da remoto ciò che potrebbe causare il tuo problema, in particolare che hai tagliato un po 'di tcpdumpoutput. Qualcosa potrebbe filtrare / eliminare selettivamente il traffico DNS tra la tua VM e i resolver DNS pubblici di Google. Ho provato a riprodurre il tuo problema usando una KVM Debian Wheezy VM, ma ho telnet ifconfig.mequasi immediatamente stampato la Trying <IP_address_here>...linea (il che significa che ha già risolto il nome da allora).


Grazie per la tua risposta dettagliata. Non ho tagliato nulla dal tcpdump, ho inserito solo una riga per chiarire dove si trovava la pausa. Mi hai sicuramente dato qualcosa da fare comunque; Non ho realizzato la differenza significativa tra le due chiamate in libreria.
Flup,

Se non ci sono più pacchetti relativi al DNS che colpiscono la tua macchina, qualcosa probabilmente sta filtrando il suo traffico (non necessariamente di proposito). Ad ogni modo, se trovi una soluzione, la condivideresti qui?
Kempniu,

1
Lo farò davvero. Avendo impostato un risolutore di test, posso vedere definitivamente che un pacchetto di risposte - quello della mia domanda - viene eliminato ogni volta. Ho il sospetto che qualcosa all'interno o vicino all'infrastruttura VMware lo stia facendo, quindi ho contattato la mia controparte che si occupa di quel lato delle cose. Quando arrivo in fondo tornerò e aggiungerò dettagli. Grazie ancora!
Flup,

Soluzione aggiunta nella mia risposta. Mille grazie ancora per il tuo aiuto.
Flup,

9

Ciò è stato causato da un set di regole eccessivamente restrittivo su un firewall Juniper che si trova di fronte all'infrastruttura VMware.

Ho creato un risolutore di test in modo da poter vedere entrambi i lati della conversazione e il pacchetto mancante identificato da Kempniu nella sua eccellente risposta veniva effettivamente lasciato cadere da qualche parte lungo la strada. Come indicato in quella risposta, getaddrinfo()senza indirizzo specificato la famiglia attenderà le risposte relative a tutte le famiglie supportate prima di tornare (o, nel mio caso, scadere).

Il mio collega che gestisce la rete lo ha notato

Il comportamento predefinito sul firewall Juniper è di chiudere una sessione relativa al DNS non appena viene ricevuta una risposta DNS corrispondente a quella sessione.

Quindi il firewall stava vedendo la risposta IPv4, notando che rispondeva alla query della VM e chiudendo il percorso in entrata per quella porta. Il seguente pacchetto di risposta IPv6 è stato quindi eliminato. Non ho idea del perché entrambi i pacchetti abbiano superato la seconda volta, ma la disabilitazione di questa funzione sul firewall ha risolto il problema.

Questo è un estratto correlato dal KB di Juniper:

Ecco uno scenario in cui vengono eliminati i pacchetti di risposta DNS:

  1. Una sessione per il traffico DNS viene creata quando il primo pacchetto di query DNS colpisce il firewall e viene configurato un criterio di autorizzazione. Il timeout predefinito è 60 sec.
  2. Immediatamente prima della chiusura della sessione, viene trasmessa una nuova query DNS e poiché corrisponde a una sessione esistente (poiché la coppia di porte / IP di origine e destinazione è sempre la stessa), viene inoltrata dal firewall. Si noti che il timeout della sessione non viene aggiornato in base a qualsiasi pacchetto appena arrivato.
  3. La sessione DNS creata diventa obsoleta quando la prima risposta alla query DNS (risposta) colpisce il dispositivo, indipendentemente dalla durata del timeout.
  4. Quando una risposta DNS viene passata attraverso il firewall, la sessione è scaduta.
  5. Tutte le successive risposte DNS vengono eliminate dal firewall, poiché non esiste alcuna sessione.

Se stai pensando di votare questa risposta, per favore vota anche la risposta di Kempniu. Senza di essa, continuerei a tentare di trovare qualche problema di configurazione nella VM.


1
Abbiamo riscontrato gli stessi sintomi su Debian 8.2. La nostra era dovuta a una causa diversa e la "soluzione" era diversa (lato client). Ho scritto un blog sul nostro problema specifico e sul problema più generale: philippecloutier.com/… Voglio ringraziare Flup e Kempniu, poiché la tua domanda e le risposte mi hanno messo sulla strada giusta.
Philippe Cloutier,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.