Ich habe einen Master- bind9
DNS-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 curl
dauert die Suche am meisten, Standard nslookup
ist jedoch sehr schnell:
$ time nslookup example.com > /dev/null 2>&1
real 0m0.018s
user 0m0.016s
sys 0m0.000s
Nach der erzwungenen curl
Verwendung 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, strace
um 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 tcpdump
vom 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, glibc
die Wiederverwendung eines Sockets zum Nachschlagen der AAAA
und 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:
- falsch konfigurierte Firewall oder ein Router (z.B. einDie Konfiguration der Juniper-Firewall wird hier beschrieben), was zum Verlust
AAAA
von DNS-Paketen führt - Fehler im DNS-Server
Lange Antwort:
Programme mögen curl
oder wget
verwenden 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 strace
oben genannte. Wenn IPv4 erzwungen wird, wie curl -4
intern, gethostbyname()
das nur nach Datensätzen fragt A
.
Daraus tcpdump
können wir ersehen, dass:
-> A?
Zu Beginn werden zwei Anfragen gesendet-> AAAA?
(IPv6-Adresse anfordern)<- AAAA
Antwort-> A?
Erneute Anforderung einer IPv4-Adresse<- A
habe eine Antwort bekommen-> AAAA?
IPv6 erneut anfordern<- AAAA
Antwort
Eine A
Antwort wird aus irgendeinem Grund gelöscht. Es handelt sich um diese Fehlermeldung:
error sending response: host unreachable
AAAA
Mir 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.conf
mü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.root
lö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
.
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