orm@doc-tcpip.org

Erstellt: November 2000 - Letzte Modifikation: November 2003

[ Main | Local ]


Debugging named - Ein Beispiel

IPv6/IPv4

Das Problem

Der Name-Server ist von BIND4 auf BIND8 angehoben worden. Bei den Tests wurde festgestellt, das ein Telnet von Maschine hostA nach Maschine hostB einen Timeout von mehr als einer Minute aufweist. Das passiert nur, wenn der externe Nameserver, der als Ziel des Forwardings eingetragen ist, nicht erreichbar ist.

Zum Debuggen wurde der named per Signal in den Debug Level 2 gebracht und der Telnet nocheinmal gestartet. Da der Server recht aktiv war, wurde das named.run sehr groß. Mit den Namen der Maschinen und den IDs der Nachrichten war es jedoch leicht, die wichtigen Pakete zu erhalten.

Die im Trace referenzierten Klassen, Typen etc. finden sich in der Datei /usr/include/arpa/nameser.h. Dort stehen alle Default-Werte sowie Rückgabewerte.

Hier der Trace mit Kommentaren.

Das Telnet Kommando wird auf der Maschine hostA abgesetzt (tn hostB). Daraufhin versucht zuerst die Maschine hostA den Namen "hostB" aufzulösen:

 
datagram from [10.14.2.3].33517, fd 20, len 40
req: nlookup(hostB.orm.org) id 20347 type=28 class=1
req: found 'hostB.orm.org' as 'hostB.orm.org' (cname=0)
free_rrecp: update transaction succeeded, cleaning up
ns_req: answer -> [10.14.2.3].33517 fd=20 id=20347 size=103 rc=0

Der NS empfängt von hostA (10.14.2.3) vom Port 33517 ein Paket von 40 Byte. Der Filedescriptor 20 bezeichnet ein Interface (die Belegung wird beim Starten des Debuggens angezeigt, ist hier gekürzt). Die Anfrage lautet auf hostB.orm.org, da auf dem Client in der /etc/resolv.conf eine search-Liste mit dem Einträgen orm.org grant.de inhold.de existiert. Diese Anfrage hat eine ID-Nummer, damit der Resolver die Antwort einordnen kann. Der Typ der Anfrage ist 28, das ist IPv6 Format - womit sich unser Problem schon andeutet. Man hätte hier Typ 1 erwartet. Die Klasse ist 1, also ein Namens-Record (IN).

Der Server schaut nun in seine Datenbank, findet einen Resource Record für die Anfrage (dieser Record hat keine Aliase, es verweist also kein CNAME Record auf diesen Record). Er nimmt jetzt die Daten auf der rechten Seite des Records und sendet eine Antwort auf diese Anfrage an den Resolver des Client. Die Größe der Nachricht, das Interface, die ID und der Return-Code sind auch angegeben - der Return-Code ist 0, das heißt, der Server hat seine Arbeit erfolgreich abgeschloßen.

 
datagram from [10.14.2.3].33518, fd 20, len 43
req: nlookup(hostB.grant.de) id 20348 type=28 class=1
req: found 'hostB.grant.de' as 'grant.de' (cname=0)
ns_req: answer -> [10.14.2.3].33518 fd=20 id=20348 size=109 rc=3

Dieses Paket überrascht jetzt ein wenig, denn eigentlich sollte der Client ja seine Antwort haben. Er war aber offensichtlich nicht zufrieden, und probiert die search-Liste jetzt durch.

Offensichtlich war die Antwort vom Server IPv6 mäßig umgeformt, oder der Client-Resolver hat selbst versucht, die IPv4 Adresse in eine IPv6 umzubiegen - jedenfalls konnte er mit der Antwort nichts anfangen.

Die neue Anfrage wird ganz schnell mit dem Return-Code 3 (NXDOMAIN, der Hostname existiert in dieser Domäne nicht) beschieden. Es ist wieder eine IPv6 Anfrage.

 
datagram from [10.14.2.3].33519, fd 20, len 35
req: nlookup(hostB.inhold.de) id 20349 type=28 class=1
req: found 'hostB.inhold.de' as 'inhold.de' (cname=0)
ns_req: answer -> [10.14.2.3].33519 fd=20 id=20349 size=93 rc=3

Der dritte Eintrag in der search-Liste.

 
datagram from [10.14.2.3].33520, fd 20, len 23
req: nlookup(hostB) id 20350 type=28 class=1
req: missed 'hostB' as '' (cname=0)
evSetTimer(ctx 0x20067fa8, func 0x20016f7c, uap 0, due 1068561662.000000000, inter 0.000000000)
forw: forw -> [62.16.2.3].53 ds=5 nsid=61263 id=20350 -1ms retry 60sec

Da alles nicht funktioniert hat, versucht der Resolver nun noch den blanken Namen, so wie der User ihn getippt hat. Das findet der NS natürlich nicht in seiner Datenbank, und die Domäne "nichts" kennt er auch nicht. Daher leitet er die Anfrage an den externen Nameserver 62.16.2.3 weiter - diesen hat er als Forwarder konfiguriert bekommen.

Dabei vergibt der NS eine neue ID (nsid) und setzt einen Zeitstempel für eine eventuelle Wiederholung.

Dummerweise ist der externe Nameserver gerade down, es ist also keine Antwort zu erwarten.

 
datagram from [10.14.2.3].33522, fd 20, len 23
req: nlookup(hostB) id 20350 type=28 class=1
req: missed 'hostB' as '' (cname=0)
fvSetTimer(ctx 0x20067fa8, func 0x20016f7c, uap 0, due 1068561662.000000000, inter 0.000000000)
forw: forw -> [62.16.2.3].53 ds=5 nsid=51918 id=20350 -1ms retry 60sec

Der Client wird ungeduldig und fragt nocheinmal. Der NS bucht diese neue Anfrage unter der weitergeleiteten, die noch unterwegs ist, und schickt noch eine Anfrage heraus.

 
datagram from [10.14.2.3].33524, fd 20, len 23
req: nlookup(hostB) id 20350 type=28 class=1
req: missed 'hostB' as '' (cname=0)
evSetTimer(ctx 0x20067fa8, func 0x20016f7c, uap 0, due 1068561678.000000000, inter 0.000000000)
forw: forw -> [62.16.2.3].53 ds=5 nsid=33990 id=20350 -1ms retry 60sec

Und eine weitere Anfrage. Jetzt ist eine lange Pause. Das Log ist ziemlich gekürzt.

 
datagram from [10.14.2.3].33526, fd 20, len 23
req: nlookup(hostB) id 20350 type=28 class=1
req: missed 'hostB' as '' (cname=0)
evSetTimer(ctx 0x20067fa8, func 0x20016f7c, uap 0, due 1068561685.000000000, inter 0.000000000)
forw: forw -> [62.16.2.3].53 ds=5 nsid=44465 id=20350 -1ms retry 60sec

Und eine letzte Anfrage. Man könnte die Zeitstempel auswerten.

 
datagram from [10.14.2.3].33528, fd 20, len 40
req: nlookup(hostB.orm.org) id 20351 type=1 class=1
req: found 'hostB.orm.org' as 'hostB.orm.org' (cname=0)
free_rrecp: update transaction succeeded, cleaning up
ns_req: answer -> [10.14.2.3].33528 fd=20 id=20351 size=108 rc=0

Jetzt sind auf Seiten des Resolvers alle Timeouts abgelaufen. Er hat jetzt erkannt, daß er mit IPv6 Anfragen nicht weiter kommt, und macht eine IPv4 Anfragen: type=1. Diese wird sofort beantwortet (Return-Code 0). Diesmal kann der Resolver mit der Antwort was anfangen, das Telnet geht jetzt durch.

 
datagram from [10.11.2.145].33250, fd 20, len 40
req: nlookup(3.2.14.10.in-addr.arpa) id 1917 type=12 class=1
req: found '3.2.14.10.in-addr.arpa' as '3.2.14.10.in-addr.arpa' (cname=0)
free_rrecp: update transaction succeeded, cleaning up
ns_req: answer -> [10.11.2.145].33250 fd=20 id=1917 size=128 rc=0

Diese Anfrage kommt jetzt vom inetd der Maschine hostB. Diese versucht, den Namen zur IP der anfragenden Maschine zu finden. Diese Anfrage ist unabhängig von irgendwelchen IPv4/IPv6 Problemen und wird sofort beantwortet.

Die Lösung des Problemes

Diese ist in diesem Fall sehr einfach. Der Resolver auf dem Telnet Client muß lernen, daß er keine IPv6 Anfragen stellen soll. Das geschieht einfach durch Editieren/Erzeugen der Datei /etc/netsvc.conf mit dem Eintrag hosts=bind4,local.


[ Main | Local ]

[ Allgemein | UNIX | AIX | TCP-IP | TCP | ROUTING | DNS | NTP | NFS | FreeBSD | Linux | RPi | SMTP | Tracing | GPS | LW ]

Copyright 2001-2021 by Orm Hager - Es gilt die GPL
Feedback bitte an: Orm Hager (orm@doc-tcpip.org )