Das Auflösen des Hostnamens dauert 5 Sekunden

Das Auflösen des Hostnamens dauert 5 Sekunden

Ich habe einen Master- bind9DNS-Server und zwei Slave-Server, die auf IPv4 (Debian Jessie) laufen, und verwende /etc/bind/named.conf:

listen-on-v6 { none; };

Wenn ich versuche, eine Verbindung von verschiedenen Servern herzustellen, dauert jede Verbindung mindestens 5 Sekunden (ich verwendeJosephs Zeitinformationenzum 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

Laut curldauert die Suche am meisten, Standard nslookupist jedoch sehr schnell:

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

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

Nach der erzwungenen curlVerwendung von IPv4 wird es deutlich 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

das Problem besteht jedoch weiterhin. Ich habe versucht, es auszuführen, straceum herauszufinden, was der Grund für die 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 Bind-Protokollen erscheint häufig diese Meldung:

error sending response: host unreachable

Allerdings wird jede Abfrage irgendwann beantwortet (es dauert nur 5 Sekunden). Alle Maschinen sind physische Server (das liegt nicht an NAT), es ist wahrscheinlicher, dass Pakete von einem Router blockiert werden. Hier ist eine wahrscheinlich verwandte Frage:DNS-Lookups dauern manchmal 5 Sekunden.

Antwort1

Kurze Antwort:

Eine Problemumgehung besteht darin, glibcdie Wiederverwendung eines Sockets zum Nachschlagen der AAAAund A-Datensätze zu erzwingen, indem folgende Zeile hinzugefügt wird /etc/resolv.conf:

options single-request-reopen

Die tatsächliche Ursache dieses Problems könnte sein:

Lange Antwort:

Programme mögen curloder wgetverwenden die Funktion von glibcgetaddrinfo(), das versucht, sowohl mit IPv4 als auch mit IPv6 kompatibel zu sein, indem es beide DNS-Einträge parallel abfragt. Es gibt kein Ergebnis zurück, bis beide Einträge empfangen wurden (es gibtmehrere Probleme im Zusammenhang mit diesem Verhalten) - dies erklärt das straceoben genannte. Wenn IPv4 erzwungen wird, wie curl -4intern, gethostbyname()das nur nach Datensätzen fragt A.

Daraus tcpdumpkönnen wir ersehen, dass:

  • -> A?Zu Beginn werden zwei Anfragen gesendet
  • -> AAAA?(IPv6-Adresse anfordern)
  • <- AAAAAntwort
  • -> A?Erneute Anforderung einer IPv4-Adresse
  • <- Ahabe eine Antwort bekommen
  • -> AAAA?IPv6 erneut anfordern
  • <- AAAAAntwort

Eine AAntwort wird aus irgendeinem Grund gelöscht. Es handelt sich um diese Fehlermeldung:

error sending response: host unreachable

AAAAMir ist jedoch nicht klar, warum eine zweite Abfrage erforderlich ist .

Um zu überprüfen, ob bei Ihnen dasselbe Problem vorliegt, können Sie das Timeout in folgendem Format aktualisieren /etc/resolv.conf:

options timeout:3

Erstellen Sie zunächst eine Textdatei mitbenutzerdefinierte Zeitberichtskonfiguration:

cat >./curl-format.txt  <<-EOF
   time_namelookup: %{time_namelookup}\n
      time_connect: %{time_connect}\n
   time_appconnect: %{time_appconnect}\n
     time_redirect: %{time_redirect}\n
  time_pretransfer: %{time_pretransfer}\n
time_starttransfer: %{time_starttransfer}\n
                    ----------\n
time_total: %{time_total}\n
EOF

dann senden Sie eine Anfrage:

$ 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:

Einzelanfrage (seit Glibc 2.10)setzt RES_SNGLKUP in _res.options. Standardmäßig führt glibc seit Version 2.9 IPv4- und IPv6-Lookups parallel durch. Einige Appliance-DNS-Server können diese Abfragen nicht richtig verarbeiten und verursachen Zeitüberschreitungen bei den Anfragen. Diese Option deaktiviert dieses Verhalten und veranlasst glibc, die IPv6- und IPv4-Anfragen sequenziell 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-Anfragen. Manche Hardware sendet fälschlicherweise nur eine Antwort zurück. In diesem Fall wartet das Clientsystem auf die zweite Antwort. Durch Aktivieren dieser Option wird dieses Verhalten geändert, sodass bei nicht korrekter Verarbeitung zweier Anfragen vom selben Port der Socket geschlossen und ein neuer geöffnet wird, bevor die zweite Anfrage gesendet wird.

Verwandte Themen:

Antwort2

Wie @Tombart sagt, ist die Verzögerung auf das Warten auf das Timeout der IPv6-Auflösung zurückzuführen.

Eine weitere Möglichkeit besteht darin, IPv4 in /etc/gai.conf den Vorrang zu geben.

Aus Kommentaren in /etc/gai.conf

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

Nach der Änderung gai.confmüssen Sie alle Apps, die die DNS-Resolver-Bibliothek verwenden, neu starten, damit die Änderung wirksam wird.

Beachten Sie, dass ich Ihnen empfehle, IPv6 zu deaktivieren und IPv6-Adressen aus den Root-Hinweisen zu verwenden, wenn Sie einen BIND-Server ohne IPv6-Konnektivität verwenden named. Natürlich wird weiterhin versucht, AAAA-Adressen aufzulösen.

Für die BIND-Konfiguration:

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

OPTIONS="-4 -u bind"

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

Antwort3

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

filter-aaaa-on-v4 yes;

Option zu meinem named.conf.

(Mehr Informationen)

Antwort4

Falls jemand nach der Datei curl-format.txt sucht: Fügen Sie diese in Ihre Shell ein und die Formatdatei wird für Sie erstellt. Der ursprüngliche Link hat bei mir nicht funktioniert. Ich habe dieses Beispiel gefundenHier

cat >./curl-format.txt  <<-EOF
   time_namelookup: %{time_namelookup}\n
      time_connect: %{time_connect}\n
   time_appconnect: %{time_appconnect}\n
     time_redirect: %{time_redirect}\n
  time_pretransfer: %{time_pretransfer}\n
time_starttransfer: %{time_starttransfer}\n
                    ----------\n
time_total: %{time_total}\n
EOF

verwandte Informationen