Bug im DHCPv6-Client von Windows Vista?
Ich habe mit der Einrichtung von IPv6 in meinem privaten Netzwerk und auf diesem Server begonnen. Zu diesem Thema werde ich später sicherlich noch mehr schreiben. Hier soll es nun um (einen) mögliche(n) Fehler in der Implementierung des DHCPv6-Clienten von Windows Vista gehen.
Aber der Reihe nach. Die Story beginnt damit, dass ich auf meiner NAS (Debian Sid auf einem ARM-Gerät) einen IPv6-Tunnel mit SixXS eingerichtet habe. Über SixXS habe ich nun auch ein /48-er IPv6-Präfix. Aus einem /64-er Subnetz soll ein DHCPv6-Server auf dem NAS nun Adressen an Clients verteilen und teilweise gleich noch ein Update des DNS-Servers vornehmen, so dass die Namensauflösung für die dynamisch zugewiesenen Adressen auch funktioniert.
Beim DHCPv6-Server habe ich mich für Dibbler entschieden. Leider funktioniert Dibbler hier nicht korrekt auf dem NAS. Der Server kann die von Vista gesendete Solicit-Message nicht interpretieren. Auch Wireshark markiert diese Message als "malformed packet". Ich habe mich dann an die Dibbler-User-Mailingliste gewandt. Der Entwickler von Dibbler, Tomasz Mrugalski, ist beim Durchsehen meiner tcpdumps über den Grund für die "malformed packets" gestolpert: Ein Bug im DHCPv6-Client von Windows Vista.
DHCPv6 [RFC3315] sieht vor, dass der Client den gewünschten FQDN oder einen Teil davon (z.B. einen bestimmten Hostname) anfordern kann [RFC4704]. Für solche Domain Namen wird ein ganz bestimmtes Format gefordert, Abschnitt 8 des zuvorgenannten RFC3315 verweist dazu auf Abschnitt 3.1 der Domain Name Specification [RFC1035].
Um die folgenden Ausführungen besser verstehen zu können, sollte zunächst beleuchtet werden, wie Domain Namen syntaktisch grundsätzlich aufgebaut sind. Dazu zitiere ich die entsprechende rekursive Definition aus dem RFC1035:
<domain> ::= <subdomain> | " "
<subdomain> ::= <label> | <subdomain> "." <label>
<label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
<let-dig-hyp> ::= <let-dig> | "-"
<let-dig> ::= <letter> | <digit>
<letter> ::= any one of the 52 alphabetic characters A through Z in upper case and a through z in lower case
<digit> ::= any one of the ten digits 0 through 9
Damit sind noch nicht alle Regeln abgedeckt, aber die gründsätzliche Struktur passt. Wichtig ist hier insbesondere die Konstruktion (bzw. Bezeichnung), dass eine (Sub-)Domain aus einer Reihe von Labels besteht, die durch Punkte getrennt werden. Im oben genannten Abschnitt 3.1 des RFC1035 steht nun, wie Domain Namen in Nachrichten (auch in DHCPv6) kodiert werden sollen.
Domain names in messages are expressed in terms of a sequence of labels. Each label is represented as a one octet length field followed by that number of octets. Since every domain name ends with the null label of the root, a domain name is terminated by a length byte of zero. The high order two bits of every length octet must be zero, and the remaining six bits of the length field limit the label to 63 octets or less.
Ein Domain Name wird also in seine einzelnen Labels zerlegt. Die Kodierung erfolgt nun so, dass ein Label durch ein Byte, welches die Länge des Labels angibt, und dann die Bytes, die dem Label entsprechen (gemäß ASCII), kodiert wird. Jeder Domain Name endet mit dem null-Label der Root-Domain. Daher folgt zum Schluss ein Längen-Byte mit Wert Null.
Beispiel:
| b | l | o | g | . | m | i | l | i | n | d | u | r | . | d | e | |||
| hex | 04 | 62 | 6c | 6f | 67 | 08 | 6d | 69 | 6c | 69 | 6e | 64 | 75 | 72 | 02 | 64 | 56 | 00 |
Der DHCPv6-Client von Windows Vista arbeitet hier aber offenbar fehlerhaft, denn Vista trägt im FQDN-Optionsfeld der Solicit- und Request-Message die Domain einfach nur als null-terminierten String ein.
Beispiel:
| b | l | o | g | . | m | i | l | i | n | d | u | r | . | d | e | ||
| hex | 62 | 6c | 6f | 67 | 2e | 6d | 69 | 6c | 69 | 6e | 64 | 75 | 72 | 2e | 64 | 56 | 00 |
Diese Kodierung verstößt gegen RFC1035. Ein DHCPv6-Server (bzw. -Relay), der sich an den RFC hält, wird damit erhebliche Schwierigkeiten haben und wird diese Option (oder gar die ganze Message) nicht verarbeiten können.
Fatal wird die Angelegenheit jedoch bei der folgenden Betrachtung. Vista kodiert den Domain Name nicht nur bei den Solicit- und Request-Messages, die an den DHCPv6-Server gesendet werden, fehlerhaft, sondern interpretiert z.B. auch Domain Namen in den Advertise- und Reply-Messages, die vom DHCPv6-Server an den Client gesendet werden, falsch.
Über die Domain Search List kann der DHCPv6-Server dem Client mitteilen, welche Suchdomains verwendet werden sollen. Diese Suchdomains kann der Client an unvollständige Hostnamen dranhängen, um ihn zu vervollständigen.
Beispiel:
Einem Client wird die Suchdomain "cs.uni-dortmund.de" übermittelt. So sind nun alle Hosts, die sich in der Domain "cs.uni-dortmund.de" befinden, direkt über den Hostname ansprechbar. So wird bei Zugriff auf "www" automatisch auf "www.cs.uni-dortmund.de" zugegriffen.
Aber wie gesagt interpretiert Vista die Domain Search List falsch. Ein RFC-konform arbeitender Server kodiert die Domain Namen wie oben beschrieben. Vista setzt die Labels jedoch nicht zu einem einem einzelnen Domain Namen zusammen, sondern interpretiert jedes Label als eigene Domain - mit unangenehmen Folgen.
Beispiel:
Dem Client wird wieder die Suchdomain "cs.uni-dortmund.de" übermittelt. Vista interpretiert dies so, dass es die Suchdomains "cs", "uni-dortmund" und "de" verwenden soll. Bei Zugriff auf "www" wird nun versucht auf "www.cs", "www.uni-dortmund" und "www.de" zuzugreifen. Irgendetwas davon wird sicherlich existieren, aber es handelt sich dabei sicher nicht um "www.cs.uni-dortmund.de".
Nun, das soll erstmal dazu reichen. Wo bzw. wie kann man eigentlich einen Bug an Microsoft berichten?
Abschließend sei nochmal ausdrücklich darauf hingewiesen, dass Tomasz Mrugalski diesen Bug gefunden und mich darauf hingewiesen hat. Ich habe das ganze hier nur ausführlicher beschrieben und weiter "erforscht" (Domain Search List).
Artikel drucken
