Wyszukiwanie DNS czasami zajmuje 5 sekund

11

Mam maszynę wirtualną z uruchomionym systemem Debian Wheezy, na której wyszukiwanie niektórych nazw hostów zajmuje kilka sekund, mimo że resolver odpowiada natychmiast. O dziwo, wyszukiwania getaddrinfo()mają wpływ, ale gethostbyname()nie jest.

Przełączyłem się na resolwery Google, aby wykluczyć możliwość uszkodzenia lokalnych, więc /etc/resolv.confwygląda to tak:

search my-domain.com
nameserver 8.8.4.4
nameserver 8.8.8.8

Mój nsswitch.confma linię:

hosts: files dns

a mój /etc/hostsnie zawiera niczego niezwykłego.

Jeśli spróbuję telnet webserver 80, zawiesi się na kilka sekund przed uzyskaniem rozdzielczości nazwy. ltraceWyjście [1] pokazuje, że jest w Hang getaddrinfo()rozmowy:

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

Jednak tcpdumpujawnia, że ​​serwer nazw odpowiedział natychmiast, i tylko druga odpowiedź została telnetodblokowana. Odpowiedzi wyglądają identycznie:

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)

Sprawdziłem dzienniki zapory hosta i nic na porcie 53 nie jest blokowane.

Co powoduje, że pierwsza odpowiedź DNS jest ignorowana?

[1] Dodałem kilka linii do mojego, ltrace.confaby móc zajrzeć do addrinfostruktury.

Flup
źródło
Jak wygląda konfiguracja NIC maszyny wirtualnej? Zmostkowane? NAT?
slm
Jest NATted. Nie jestem pewien, gdzie dokładnie jest zastosowany NAT (czy to przez ESX, czy dalej w górę); Mogę dowiedzieć się, czy uważasz, że to może mieć znaczenie.
Flup
Podejrzewam, że na to wpływa NAT + VM.
slm
Mogłoby być - patrz moje komentarze do odpowiedzi Kempniu poniżej.
Flup
To było sieciowe, ale nie powodowało tego NAT - patrz moja odpowiedź poniżej.
Flup

Odpowiedzi:

13

Pierwsza odpowiedź DNS nie jest ignorowana. getaddrinfo()nie powrócił, dopóki nie otrzymał odpowiedzi na pierwsze zapytanie AAAA (ID: 26090). Tak więc prawdziwym problemem jest to, dlaczego twoja maszyna nie otrzymała natychmiast odpowiedzi na zapytanie AAAA, podczas gdy otrzymała odpowiedź na zapytanie A (ID: 54755).

Jedną z różnic między getaddrinfo()i gethostbyname()jest to, że ta pierwsza obsługuje zarówno IPv4, jak i IPv6, podczas gdy druga obsługuje tylko IPv4. Więc kiedy zadzwonić getaddrinfo()z ai_familyzestawem do 0 ( AF_UNSPEC), to nie wróci, dopóki nie dostaje odpowiedź (lub uderza timeout) dla obu zapytań A oraz AAAA dla nazwy domeny usług. gethostbyname()tylko zapytania o rekord A.

Trudno jest zdalnie określić, co może być przyczyną problemu, zwłaszcza że wycięto trochę tcpdumpdanych wyjściowych. Coś może selektywnie filtrować / upuszczać ruch DNS między maszyną wirtualną a usługami rozpoznawania nazw Google Public DNS. Próbowałem odtworzyć twój problem za pomocą KVM Debian Wheezy VM, ale telnet ifconfig.meprawie natychmiast wydrukowałem Trying <IP_address_here>...linię (co oznacza, że ​​do tej pory nazwa została już rozwiązana).

Kempniu
źródło
Dziękuję za szczegółową odpowiedź. Nie wyciąłem niczego z tcpdump, wstawiłem tylko linię, aby było jasne, gdzie jest przerwa. Zdecydowanie dałeś mi jednak coś do kontynuowania; Nie zdawałem sobie sprawy z istotnej różnicy między tymi dwoma wywołaniami biblioteki.
Flup
Jeśli na twoim komputerze nie ma już pakietów związanych z DNS, prawdopodobnie coś filtruje jego ruch (niekoniecznie celowo). W każdym razie, jeśli znajdziesz rozwiązanie, czy mógłbyś je tutaj udostępnić?
Kempniu
1
Rzeczywiście będę. Po skonfigurowaniu resolvera testów widzę ostatecznie, że jeden pakiet odpowiedzi - ten z mojego pytania - jest odrzucany za każdym razem. Podejrzewam, że robi to coś w infrastrukturze VMware lub w jej pobliżu, więc skontaktowałem się z moim odpowiednikiem, który troszczy się o tę stronę. Kiedy dojdę do sedna, wrócę i dodam szczegóły. Dzięki jeszcze raz!
Flup
Rozwiązanie dodane w mojej własnej odpowiedzi. Jeszcze raz wielkie dzięki za pomoc.
Flup
9

Było to spowodowane zbyt restrykcyjnym zestawem reguł w zaporze sieciowej Juniper, która znajduje się przed infrastrukturą VMware.

Zbudowałem testowy resolver, aby widzieć obie strony rozmowy, a brakujący pakiet zidentyfikowany przez Kempniu w jego doskonałej odpowiedzi rzeczywiście został gdzieś porzucony. Jak zaznaczono w tej odpowiedzi, getaddrinfo()bez określenia rodziny adresów będzie czekać na odpowiedzi dotyczące wszystkich obsługiwanych rodzin przed powrotem (lub, w moim przypadku, przekroczeniem limitu czasu).

Zauważył to mój kolega, który prowadzi sieć

Domyślnym zachowaniem zapory ogniowej Juniper jest zamknięcie sesji związanej z DNS, gdy tylko otrzyma odpowiedź DNS pasującą do tej sesji.

Zapora widziała odpowiedź IPv4, zauważając, że odpowiedziała na zapytanie maszyny wirtualnej, i zamknęła ścieżkę wejściową dla tego portu. Następujący pakiet odpowiedzi IPv6 został zatem usunięty. Nie mam pojęcia, dlaczego oba pakiety przeszły po raz drugi, ale wyłączenie tej funkcji w zaporze rozwiązało problem.

Oto pokrewny wyciąg z Juniper KB:

Oto scenariusz, w którym upuszczane są pakiety odpowiedzi DNS:

  1. Sesja dla ruchu DNS jest tworzona, gdy pierwszy pakiet zapytań DNS uderza w zaporę i skonfigurowane są zasady zezwolenia. Domyślny limit czasu to 60 sekund.
  2. Bezpośrednio przed zamknięciem sesji przesyłane jest nowe zapytanie DNS, a ponieważ pasuje ono do istniejącej sesji (ponieważ para port źródłowy i docelowy / IP są zawsze takie same), jest przekazywane dalej przez zaporę ogniową. Pamiętaj, że limit czasu sesji nie jest odświeżany zgodnie z każdym nowo przybywającym pakietem.
  3. Utworzona sesja DNS jest wygasana, gdy pierwsza odpowiedź (odpowiedź) zapytania DNS dotrze do urządzenia, bez względu na to, ile czasu pozostało.
  4. Gdy odpowiedź DNS jest przekazywana przez zaporę, sesja jest przedawniona.
  5. Wszystkie kolejne odpowiedzi DNS są odrzucane przez zaporę, ponieważ nie istnieje żadna sesja.

Jeśli zastanawiasz się nad poprawieniem tej odpowiedzi, poproś również o odpowiedź Kempniu. Bez tego nadal bym się kręcił, próbując znaleźć jakiś problem z konfiguracją na maszynie wirtualnej.

Flup
źródło
1
Te same objawy wystąpiły w Debianie 8.2. Nasze były spowodowane inną przyczyną, a „rozwiązanie” było inne (po stronie klienta). Napisałem na blogu o naszym konkretnym problemie i bardziej ogólnym problemie: philippecloutier.com/ ... Chcę podziękować Flupowi i Kempniu, ponieważ twoje pytania i odpowiedzi wprawiły mnie we właściwy sposób.
Philippe Cloutier