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.conf
wygląda to tak:
search my-domain.com
nameserver 8.8.4.4
nameserver 8.8.8.8
Mój nsswitch.conf
ma linię:
hosts: files dns
a mój /etc/hosts
nie zawiera niczego niezwykłego.
Jeśli spróbuję telnet webserver 80
, zawiesi się na kilka sekund przed uzyskaniem rozdzielczości nazwy. ltrace
Wyjś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 tcpdump
ujawnia, że serwer nazw odpowiedział natychmiast, i tylko druga odpowiedź została telnet
odblokowana. 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.conf
aby móc zajrzeć do addrinfo
struktury.
Odpowiedzi:
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()
igethostbyname()
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()
zai_family
zestawem 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ę
tcpdump
danych 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, aletelnet ifconfig.me
prawie natychmiast wydrukowałemTrying <IP_address_here>...
linię (co oznacza, że do tej pory nazwa została już rozwiązana).źródło
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ć
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:
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.
źródło