DNS, TCP und 512 Bytes

Diese Seite beschreibt ein Problem mit Microsoft Teams und Anrufen, welches sich nach der Analyse als DNS-Problem herausgestellt hat, welche aber durch eine Firewall verursacht wurde.

DNS ist essentiell

Die Namenauflösung von Computernamen oder auch anderer Dienstinformationen per DNS ist heute essentiell für die Funktion von einem Netzwerk. Klassisch bekommt ein Client per DHCP den DNS-Server, der bei den meisten Firmen wohl auf einem Windows Domaincontroller quasi "AD-Integriert" mit läuft. DNS-Anfragen werden üblicherweise per UDP gestellt und auch beantwortet. DNS über TCP ist auch möglich und wird z.B. bei klassischen Zonen-Transfers zwischen DNS-Servern genutzt. Wenn die Zonen aber im Active Directory liegen, dann entfällt dies.

512 Byte Limit und große Namen

Pakete auf dem Ethernet haben meist eine maximal Größe von 1514 Bytes, von denen ca. 34 Bytes für Ethernet-Frame und IPv4-Overhead abgezogen werden können. In den Anfangszeiten des Internet gab es aber auch noch jede Menge andere Übertragungstechniken (Datex-P, FDDI, TokenRing etc.) und daher hat man 576 Bytes als Grenze angenommen, bis zu der Pakete sicher über alle Teilstrecken ohne Fragmentierung durch Router übertragen werden können. Da auch hier noch ein Overhead eingerechnet werden muss, wurde für DNS ein Limit bei 512 Bytes angenommen.


Quelle: https://www.rfc-editor.org/rfc/rfc5966#section-1

Diese Grenze führte damals auch dazu, das man Anfangs nur 13 "Root-Server" betrieben hat. Allerdings gibt es mittlerweile ein Update:


RFC 7766 https://datatracker.ietf.org/doc/html/rfc7766#page-6

Diese Limits gelten heute nicht mehr, da die RootServer mittels Anycast DNS betrieben werden und neben UDP auch der Support für TCP schon lange zum Standard gehört:

Nur weil der Client DNS over TCP nutzt und der Server DNS/TCP verstehen würde, gibt es immer noch Firewalls als Spielverderber.

Über die Größe eines Hostnamens finden wir in RFC1123 eine Angabe:

Host software MUST handle host names of up to 63 characters and SHOULD handle host names of up to 255 characters.
https://www.rfc-editor.org/rfc/rfc1123#section-2

Nun erwarte ich nicht, das ein Hostname schon die 512 Bytes überschreitet, selbst wenn er als FQDN schon recht lange sein kann. Warum sollte denn das 512-Bytes Limit bei einer DNS-Anfrage ein Problem sein? Eine DNS-Antwort enthält aber weit mehr als nur eine IP-Adresse. Wenn ich z.B. die Mailserver über die Anfrage des "MX-Records" geliefert bekomme, dann können das durchaus mehrere Mailserver sein, die auch noch mehrere IP-Adressen haben könnten.

DNS mit Wireshark

Zur weiteren Fehlersuche müssen wir mal wieder tiefer auf dem Kabel nachschauen. Mittels WireShark können wir sehr einfach die DNS-Anfragen mitschneiden, da Sie in den meisten Fällen immer noch unverschlüsselt über Port 53 übertragen werden. Am einfachsten aktivieren sie schon beim Mitschnitt einen Filter auf "Port 53". So bekommen Sie DNS Abfragen über UDP und TCP mit. Ich verzichte hier auf den Mitschnitt des alternativen Ports 5353.

Dann verwirft Wireshark alle anderen Pakete, sie können sich auf DNS fokussieren und nebenbei ersparen Sie den Computer die Pufferung überflüssiger Daten. Ich starte mit einem einfachen NSLOOKUP auf einen längeren Namen, der in den Fall auch die Probleme verursacht hatte.

nslookup -q=A api-emea.flightproxy.teams.microsoft.com

Die DNS-Anfrage selbst enthält den gewünschten Eintrag und Typ und vielleicht noch ein paar weitere Parameter und Flags. So ein Paket ist meist um die 100 Bytes groß und im Grund unkritisch.

Ich aber hier schon extra mit "api-emea.flightproxy.teams.microsoft.com" einen Namen genutzt, der etwas länger ist. Mittels NSLOOKUP/RESOLVEDNS Ich habe vier gängige DNS-Server gefragt und ich bin schon fast an die 512 Bytes herangekommen.

Die Antwort ist nicht immer gleich, da die verschiedenen DNS-Server an unterschiedlichen geografischen Standorten im Internet stehen und Microsoft mittels GeoDNS unterschiedliche Antworten liefert- Das Paket ist so groß, weil in der Antwort nicht nur die gewünschte IP-Adresse steht, sondern der komplette Pfad der Auflösung.

Die Details sehen Sie auch mit der PowerShell in "Resolve-DNSName".

Ich weiß nicht, ob Microsoft dies schon auf dem Radar hat aber selbst mit der Verkettung über mehrere CNAME-Einträge kommen wir nahe an die 512 Bytes ran aber sind noch nicht drüber. In der Kundenumgebung kam aber keine Antwort zurück.

DNS mit über 512 Bytes

Ich habe dann nach Einträgen gesucht, die vielleicht mehr als 512 Bytes ergeben und wurde mit der Microsoft Domain fündig. Über folgenden Befehl habe ich die Nameserver von Microsoft in Erfahrungen bringen wollen:

PS C:\> Resolve-DnsName -type NS microsoft.com. -Server a.root-servers.net

In Wireshark sehen wir die direkte Anfrage an den Root-Server aber auch eine Antwort mit 533 Bytes.

Nutzen Sie bitte nicht den Displayfilter "dns", weil sie dann nicht die TCP-Connections sehen.

Wenn ich davon aber den Ethernet und IP-Header von ca. 34 Bytes abziehe, dann wäre ich wieder unter 512 Bytes. Dennoch ist hier zu sehen, das der Resolver die Anfrage noch einmal per TCP sendet und die so erhaltene Antwort (Paket 7) schon 883 Bytes groß ist. Als muss in der UDP-Antwort (Paket 2) auf die erste Frage die Ursache für die zweite TCP-basierte Anfrage zu finden sein. In den Flags sehe ich, dass das Paket "Truncated" wurde:

Damit weiß der Client, dass er eine partielle Antwort hat und er die Anfrage am besten noch einmal per TCP stellt. Es soll Clients geben, die sich auch mit der partiellen UDP-Anfrage zufrieden geben. Wenn Sie einmal gezielt nach diesen Paketen schauen wollen, dann nutzen Sie folgenden Filter:

"dns.flags.truncated == True"

Sie können auch das Feld als Spalte in Wireshark addieren, indem Sie in den Paketdetails das Feld anwählen und als Spalte addieren:

Daher ist es wichtig, dass eine DNS-Anfrage nicht nur per UDP sondern auch per TCP durchgeführt werden kann.

Zum Glück machen die meisten DNS-Dienste sowohl UDP als auch TCP, wenn nicht eine Firewall sich dazwischengeschaltet hat und z.B. DNS/TCP vergessen wurde.

DNS 53/TCP Testen

Damit ich in Zukunft einfacher die Funktion testen kann, habe ich mir einen passenden DNS-Eintrag angelegt. Ein TXT-Record ist relativ unproblematisch und kann bis zu 255 Zeichen lang sein. Für längere Einträge muss der Wert mehrfach eingegeben werden. Hier mein Eintrag:

Diesen Eintrag können Sie einfach abfragen und ihr DNS-Server sollte ihnen diesen per TCP liefern.

REM Abfrage per CMD
nslookup -q=TXT dns512.msxfaq.net
# Abfrage per PowerShell
Resolve-DNSName -Type TXT dns512.msxfaq.net

Wenn TCP nicht offen sein sollten, bekommen Sie keine Daten oder einen Fehler oder vieleicht nur eine Teilmenge.

PowerShell und DNS/TCP

Bei der Fehleranalyse ist mir ein weiterer Effekt aufgefallen. NSLOOKUP und Resolve-DNSName verhalten sich unterschiedlich, wenn ich die Root-Server nach meiner Domain abfrage. NSLOOKUP liefert die Information, dass der Root-Server die Information nicht hat aber mich zu den Server der "DE"-Domain verweist.

C:\> nslookup -q=a msxfaq.de a.root-servers.net
Server:  UnKnown
Address:  198.41.0.4

Name:    msxfaq.de
Served by:
- a.nic.de
          194.0.0.53
          2001:678:2::53
          de
- l.de.net
          77.67.63.105
          2001:668:1f:11::105
          de
- s.de.net
          195.243.137.26
          2003:8:14::53
          de
- f.nic.de
          81.91.164.5
          2a02:568:0:2::53
          de
- z.nic.de
          194.246.96.1
          2a02:568:fe02::de
          de
- n.de.net
          194.146.107.6
          2001:67c:1011:1::53
          de

NSLOOKUP müsste nun natürlich noch einmal diese Server fragen und wird dann zum DNS-Provider der MSXFAQ.DE verwiesen, die dann hoffentlich eine Adresse liefern.

NSLOOKUP macht selbst aber keine Rekursion. Das überlässt NSLOOKUP dem angefragten DNS-Server

Das gleiche Ergebnis habe ich auch mit der PowerShell. Hier bekomme ich aber direkt einen "DNS-Fehler":

PS C:\> Resolve-DNSName -Type A msxfaq.de -Server a.root-servers.net

Allerdings ist das der Antwort der Root-Server geschuldet, die mir nicht die IP-Adresse liefern, sondern einen Verweis auf die DNS-Server der DE-Domain. Im Wireshark ist dies gut zu sehen.

Der Inhalt der Antwort passt noch problemlos in 512 Bytes, so dass das Paket nicht fragmentiert ist

Resolve-DNSName bekommt über den Weg eine Antwort aber das ist nicht die erwartete Antwort auf die Anfrage nach der "A"-Adresse und eine Rekursion scheint Resolve-DNSName in dem Fall nicht zu machen. Daher liefert es einen Fehler. Wenn ich die gleiche Frage mit "-TCPOnly", dann bekomme ich die Liste der Server angezeigt:

In beiden Fällen ist per Wireshark aber zu sehen, dass die Antwort sowohl über UDP als auch TCP komplett und identisch ist

In diesem Fall ist die Antwort per UDP als auch TCP gleich und Resolve-DNSName könnte beide male die gleiche Antwort liefert, d.h. entweder den gleichen Fehler oder die Liste der Nameserver. Zumal es auch einen Parameter "-NoRecursion" gibt.

Ich hätte erwartet, dass Resolve-DNSName mittels Rekusion mir die finale Antwort liefert und bei Angabe von "NoRecursion" nur die NS-Einträge liefert. Stattdessen bekomme ich einen Fehler abbricht und die NS-Liste nur bei Angabe von "-TCPOnly" und Rekursion findet nicht statt.

Ursache ist hier aber einfach die Tatsache, dass ich nicht den eigenen und "freundlichen" DNS-Server gefragt habe, der für mich die Rekursion ausgeführt und nur das Ergebnis geliefert hätte, sondern einen fremden DNS-Server, der natürlich nur eingeschränkte Dienste für fremde Client anbietet. Im Grund funktionieren schon Abfragen mit großen Antworten, die dann per TCP geliefert werden.

DNS/TCP und Provider

Auch ihr Internetprovider kann ihnen böse streiche Spielen. Im Jun 2024 bin ich zuhause über eine Fritz!Box7590 und Glasfaser ins Internet gegangen. Mein Provider war zu der Zeit "Deutsche Glasfaser" mit einem nativen IPv6-Anschuss und Carrier Grade NAT (CGN). Wenn ich einfach per NSLOOKUP meinen dns512-Namen aufgelöst habe, bekam ich weder über IPv6 noch IPv4 eine Antwort:

Das fand ich dann schon etwas suspekt und habe mir über die Einstellungen der Fritz!Box die von ihr genutzten DNS-Server geholt:

Aber auch die direkte Abfrage per NSLOOKUP gegen die beiden IPv4-Server lieferte per Reverse-Lookup zwar deren Namen (dnscache001.dg-w.de und dnscache002.dg-w.de) aber per Wireshark konnte ich auch hier sehen, dass die Antworten per UDP ankommen aber per TCP keine Verbindung zustande kommt:

Zuerst versucht der Client den Namen per IPv4 und UDP aufzulösen aber im Paket 7 kommt dann eine leere Antwort, die aber zumindest ein "Message is truncated" enthält:

Der Client wechselt dann auf TCP und da stellen sich beide DNS-Server taub und stumm. Der TCP-Handshake (TCP SYN ACK RES) kommt nicht zustande.

Das bedeutet, dass ich auch bei mir zuhause die gleichen Probleme bei der Teams Telefonie sehen würde, wenn mein Tenant solche URLs nutzt, die per DNS über 512 Bytes ergeben.

Vieleicht können Sie mir bei der Komplettierung der Liste behilflich sei, da die DNS-Server eines Providers in der Regel nur die Kunden des Providers erreichen können: Starten Sie einfach in einer CMD-Shell einen:

# Abfrage des Standard DNS-Servers
Resolve-DnsName -Type TXT dns512.msxfaq.net

#Prüfen Sie immer noch mal einen externen DNS-Server, ob nicht eine Firewall die DNS/TCP-Verbindung blockt. Folgendes sollte immer funktionieren
Resolve-DnsName -Type TXT dns512.msxfaq.net -Server 8.8.8.8

Eigentlich muss jeder DNS-Server ihres Providers auch DNS/TCP akzeptieren (Siehe RFC 7766 https://datatracker.ietf.org/doc/html/rfc7766#section-5) aber vielleicht tut es nicht jeder.

Provider IP-Adresse DNS_Server Name DNS-Server System Firewall Erfolg

Deutsche Glasfaser

192.168.178.1
fritz.box

Fritz 7590

OK

Nein

Deutsche Glasfaser

185.22.44.50
185.22.45.50
dnscache001.dg-w.de
dnscache002.dg-w.de

?

OK

Nein
Nein

Telekom

217.237.151.205
217.237.148.70
217.237.148.22
217.237.150.51
2003:180:2:8100::53
2003:180:2:8000::53
do-lb-a01.isp.t-ipnet.de 
d-lb-a01.isp.t-ipnet.de 
f-lb-a01.isp.t-ipnet.de
f-lb-b01.isp.t-ipnet.de
f-dnslb-a01.isp6.t-ipnet.de
f-dnslb-b01.isp6.t-ipnet.de 

?

OK

OK

Hotsplots im RRX (Bahn)

192.168.44.1

Nicht auflösbar

?

OK

Nein

Vodafone

80.69.96.12
81.210.129.4

?

?

?

?

m3connect (z.B. IPS am Flughafen DUS

10.27.64.2

Nicht auflösbar

?

Geblockt

OK

Die Spalte "Firewall" zeigt an, dass ich sehr wohl per DNS/TCP den Namen über einen anderen DNS-Server (z.B. 8.8.8.8) auflösen konnte und daher keine Firewall den Port 53/TCP blockiert.

Root Cause

Bezogen auf den Supportfall wussten wir nun, dass DNS/TCP nicht funktionierte und konnten damit in der Firewall die Regeln kontrollieren. Die Ursache fanden wir in der Art, wie die Allow-Regel definiert wurde. Folgende beiden Regeln sind unterschiedlich:

Regel Bedeutung

Firewall Allow 53/UDP

Diese Regel haben wir vorgefunden und sie hat einfach DNS per UDP erlaubt, was in 99.9% der Fälle auch ausreichend ist.

Firewall Allow DNS

Die Firewall hat aber auch einen vordefinierten "Service DNS" und in dem ist UDP und TCP inkludiert. Wenn ich dieses vorgefertigte Element nutze, dann ist auch 53/TCP erlaubt.

Wer also die DNS-Freigabe manuell einrichtet und dabei 53/TCP vergisst, kann dieses Problem nachstellen. Anscheinend gibt es einige Firewalls, die DNS over TCP nicht erlauben oder nicht versuchen.

Daher sollten Sie dies einfach mit NSLOOKUP/Resolve-DNSName testen.

Statistiken

In Verbindung mit Windows Defender können Sie z.B. auswerten, wie die Größenverteilung der DNS-Anfragen sind.

Die sehr kurzen Namen könnten z.B. Abfragen auf "msn.com" oder "google.de" sein und einige lange Anfragen sind dann <tenantname>.sharepoint.com oder worldaz.tr.teams.microsoft.com. Allerdings liefert dieser Bericht nicht die Größe der DNS-Antworten.

Die Analyse der DNS-Abfragen und Antworten anhand der Größe ist eine wichtige Funktion zur Erkennung von Angriffen. Oft ist DNS nicht besonders geschützt und was hindert eine interne Malware per DNS z.B. nach "kennword_geheim.angreiferdomain.tld" zu fragen und der entsprechende DNS-Server protokolliert einfach die angefragten Hostnamen als Nutzlast. Über die DNS-Rückantwort könnte er dann weitere Steuerungsbefehle geben.

Lernkurve

In diesem Support-Szenario hat es sich gezeigt, dass eine Firewall die Namensauflösung per TCP unterbunden hat. Dies ist lange nicht aufgefallen, da die normalen einfachen Namensauflösungen auch per UDP erfolgreich möglich waren. selbst meine Anfrage an "api-emea.flightproxy.teams.microsoft.com" wurde gerade noch so eben in den 512 Bytes beantwortet. Das war aber in meinem Netzwerk mit meinem DNS-Server und meinen Provider. Es ist aber knapp an der Grenze und es gibt sicher andere Anfragen, die 512 Bytes überschreiten.

Tipp: Leider hat hier die Firewall die TCP-Versuche nicht mit einem "RESET" abgelehnt sondern mit einem DROP unterschlagen. Mit einem RESET hätten wir im Wireshark vermutlich sehr schnell die roten "TCP-RST"-Zeilen gefunden. Bitte droppt keine Pakete von internen "Trusted" Clients sondern lehnt sie aktiv ab.

Anscheinend nutzt der Kunde einen anderen DNS-Server, der wiederrum andere Daten bekommt und noch zusätzliche Informationen in die Antwort packt, so dass die 512 Bytes überschritten werden. Wenn dann die Firewall für DNS vieleicht "Zonen-Transfers" zu lässt aber ein QUERY unterbindet, dann bekommt der Client nicht die gewünschte Information.

Es wäre ja nett, wenn wir z.B. auf einer Firewall ermitteln könnten, wann ein "Truncated" erscheint um so solche Fehler zu ermitteln. Aber wer seine Firewall-Logs betrachtet, sollte solche geblockten Versuche auch gemeldet bekommen.

Das Problem ist nicht auf Teams Telefonie alleine beschränkt. Auch Mailserver fragen z.B. SPF-Records ab, die durchaus umfangreich werden können und es gibt noch viele weitere Einträge, die per DNS bereitgestellt werden, z.B. DKIM-Schlüssel etc. Prüfen Sie in dem Zuge einfach, ob eine Namensauflösung per TCP durchgängig möglich ist.

Weitere Links