Das Auflösen des Hostnamens dauert 5 Sekunden


8

Ich habe einen Master- bind9DNS-Server und 2 Slave-Server, die unter IPv4 (Debian Jessie) ausgeführt werden /etc/bind/named.conf.

listen-on-v6 { none; };

Wenn ich versuche, eine Verbindung von verschiedenen Servern herzustellen, dauert jede Verbindung mindestens 5 Sekunden (ich verwende Josephs Timing-Informationen zum Debuggen):

$ 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

Demnach curldauert die Suche die meiste Zeit, der Standard nslookupist jedoch sehr schnell:

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

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

Nach dem Erzwingen curlder Verwendung von IPv4 wird es viel besser:

$ 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

Ich habe IPv6 auf dem Host deaktiviert:

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

obwohl das Problem weiterhin besteht. Ich habe versucht zu rennen, straceum herauszufinden, was der Grund für Zeitüberschreitungen ist:

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)

Es scheint kein Firewall-Problem zu sein, da nslookup(oder curl -4) dieselben DNS-Server verwendet werden. Irgendeine Idee, was falsch sein könnte?

Hier ist tcpdumpvom Gastgeber 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)

BEARBEITEN: In Bindungsprotokollen wird häufig die folgende Meldung angezeigt:

error sending response: host unreachable

Jede Anfrage wird jedoch irgendwann beantwortet (es dauert nur 5 Sekunden). Alle Computer sind physische Server (es liegt nicht an NAT). Es ist wahrscheinlicher, dass Pakete von einem Router blockiert werden. Hier ist sehr wahrscheinlich eine verwandte Frage: DNS-Suchvorgänge dauern manchmal 5 Sekunden .


1
strace -ttwürde die Ablaufverfolgung informativer machen, wenn Verzögerungen aufgespürt werden.
JigglyNaga

Danke, in diesem Fall hilft es nicht viel. Es scheint in einem Blick stecken zu bleiben, während dieselbe Verbindung mit zunehmendem Timeout wiederholt wird poll(0, 0, 1000) = 0 (Timeout). Auf der DNS-Serverseite erhalte ich häufig Fehler, error sending response: host unreachabledie so aussehen, als ob das ausgehende Paket blockiert ist (aber nicht für nslookup).
Tombart

Das sieht ähnlich aus
Jeff Schaller

Antworten:


9

Kurze Antwort:

Eine Abhilfe zwingt glibceine Buchse zum Look der wiederzuverwenden AAAAund AAufzeichnungen, die von einer Linie zur Zugabe /etc/resolv.conf:

options single-request-reopen

Die wahre Ursache für dieses Problem könnte sein:

Lange Antwort:

Programme wie curloder wgetverwenden die Funktion getaddrinfo () von glibc , die versucht, mit IPv4 und IPv6 kompatibel zu sein, indem beide DNS-Einträge parallel gesucht werden. Das Ergebnis wird erst zurückgegeben, wenn beide Datensätze empfangen wurden (es gibt verschiedene Probleme im Zusammenhang mit einem solchen Verhalten ) - dies erklärt das straceObige. Wenn IPv4 erzwungen wird, wie curl -4intern, gethostbyname()welche Abfragen nur zur AAufzeichnung.

Daran können tcpdumpwir sehen:

  • -> A? Zu Beginn werden zwei Anfragen gesendet
  • -> AAAA? (IPv6-Adresse anfordern)
  • <- AAAA Antworten
  • -> A? erneutes Anfordern der IPv4-Adresse
  • <- A bekam eine Antwort
  • -> AAAA? IPv6 erneut anfordern
  • <- AAAA Antworten

Eine AAntwort wird aus irgendeinem Grund gelöscht, das ist diese Fehlermeldung:

error sending response: host unreachable

Mir ist jedoch unklar, warum eine zweite AAAAAbfrage erforderlich ist .

Um zu überprüfen, ob Sie dasselbe Problem haben, können Sie das Zeitlimit in /etc/resolv.conffolgenden Schritten aktualisieren :

options timeout:3

wie hier beschrieben :

$ 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

Es gibt zwei weitere verwandte Optionen in man resolv.conf:

Einzelanforderung (seit glibc 2.10) setzt RES_SNGLKUP ein _res.options. Standardmäßig führt glibc seit Version 2.9 IPv4- und IPv6-Lookups parallel durch. Einige DNS-Server der Appliance können diese Abfragen nicht ordnungsgemäß verarbeiten und das Zeitlimit für die Anforderungen überschreiten. Diese Option deaktiviert das Verhalten und veranlasst glibc, die IPv6- und IPv4-Anforderungen nacheinander auszuführen (auf Kosten einer gewissen Verlangsamung des Auflösungsprozesses).

single-request-reopen (seit glibc 2.9) Der Resolver verwendet denselben Socket für die A- und AAAA-Anforderungen. Einige Hardware sendet fälschlicherweise nur eine Antwort zurück. In diesem Fall wartet das Client-System auf die zweite Antwort. Durch Aktivieren dieser Option wird dieses Verhalten geändert. Wenn zwei Anforderungen von demselben Port nicht korrekt verarbeitet werden, wird der Socket geschlossen und eine neue geöffnet, bevor die zweite Anforderung gesendet wird.

Verwandte Themen:


@RuiFRibeiro Nur aufgrund der Aufwärtsbewegung schien es, dass Benutzer die andere Antwort hilfreicher fanden. Nichts für ungut.
Tombart

4

Wie @Tombart sagt, ist die Verzögerung darauf zurückzuführen, dass auf das Zeitlimit für die IPv6-Auflösung gewartet wird.

Eine andere mögliche Vorgehensweise besteht darin, IPv4 in /etc/gai.conf Vorrang einzuräumen

Aus Kommentaren in /etc/gai.conf

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

Nach dem Ändern gai.confmüssen Sie jede App mithilfe der DNS-Resolver-Bibliothek neu starten, damit die Änderung wirksam wird.

Beachten Sie jedoch, dass Sie bei Verwendung eines BIND-Servers ohne IPv6-Konnektivität empfehlen, IPv6 zu deaktivieren namedund IPv6-Adressen aus den Stammhinweisen zu übernehmen. Offensichtlich wird immer noch versucht, AAAA-Adressen aufzulösen.

Also für die BIND-Konfiguration,

Fügen Sie in / etc / default / bind9 -4 für IPv4-Adressen hinzu:

OPTIONS="-4 -u bind"

und in /etc/bind/db.rootlöschen Sie alle Zeilen mit AAAA-DNS-Roots.


2

Ich hatte ein ähnliches Problem bei der Verwendung von BIND9. Um dies zu beheben, musste ich hinzufügen:

filter-aaaa-on-v4 yes;

Option zu meinem named.conf.

( Weitere Informationen )

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.