Zum Hauptinhalt springen

6. Verbindungsbehandlung (Connection Handling)

6.1. Aktuelle Praktiken (Current Practices)

Abschnitt 4.2.2 von [RFC1035] besagt:

  • Der Server sollte davon ausgehen, dass der Client die Verbindungsschließung initiiert, und sollte das Schließen seines Endes der Verbindung verzögern, bis alle ausstehenden Client-Anfragen erfüllt wurden.

  • Wenn der Server eine ruhende Verbindung schließen muss, um Ressourcen zurückzugewinnen, sollte er warten, bis die Verbindung für einen Zeitraum in der Größenordnung von zwei Minuten im Leerlauf war. Insbesondere sollte der Server zulassen, dass die SOA- und AXFR-Anfragesequenz (die eine Aktualisierungsoperation beginnt) über eine einzige Verbindung erfolgt. Da der Server ohnehin nicht in der Lage wäre, Abfragen zu beantworten, kann anstelle eines ordnungsgemäßen Schließens ein einseitiges Schließen oder Zurücksetzen verwendet werden.

Andere modernere Protokolle (z. B. HTTP/1.1 [RFC7230], HTTP/2 [RFC7540]) unterstützen standardmäßig persistente TCP-Verbindungen für alle Anfragen. Verbindungen werden dann normalerweise über ein 'Verbindung schließen'-Signal von einer Partei geschlossen.

Die Beschreibung in [RFC1035] ist eindeutig, dass Server Verbindungen als persistent betrachten sollten (insbesondere nach Erhalt eines SOA), bietet aber leider nicht genügend Details für eine eindeutige Interpretation des Client-Verhaltens für andere Abfragen als ein SOA. Darüber hinaus verfügt DNS noch nicht über einen Signalisierungsmechanismus für Verbindungs-Timeout oder -Schließung, obwohl einige vorgeschlagen wurden.

6.1.1. Clients

Es gibt heute in keinem RFC eine klare Anleitung, wann ein DNS-Client eine TCP-Verbindung schließen sollte, und es gibt keine spezifischen Empfehlungen bezüglich der Leerlauf-Timeouts von DNS-Clients. Zum Zeitpunkt des Schreibens ist es jedoch gängige Praxis, dass Clients die TCP-Verbindung nach dem Senden einer einzigen Anfrage schließen (abgesehen vom SOA/AXFR-Fall).

6.1.2. Server

Viele DNS-Server-Implementierungen verwenden ein langes festes Leerlauf-Timeout und sind standardmäßig auf eine kleine Anzahl von TCP-Verbindungen eingestellt. Sie bieten auch wenig Optionen für das TCP-Verbindungsmanagement. Die Nachteile davon sind:

  • Die Betriebserfahrung hat gezeigt, dass lange Server-Timeouts unter hoher Last leicht zu Ressourcenerschöpfung und schlechter Antwort führen können.

  • Das absichtliche Öffnen vieler Verbindungen und das Leerlauflassen derselben kann trivialerweise einen TCP-Denial-of-Service (DoS)-Angriff erzeugen, da viele DNS-Server schlecht ausgerüstet sind, um sich dagegen zu verteidigen, indem sie ihre Leerlauf-Timeouts oder andere Verbindungsmanagement-Richtlinien ändern.

  • Eine bescheidene Anzahl von Clients, die alle gleichzeitig versuchen, persistente Verbindungen mit Leerlauf-Timeouts ungleich Null zu einem solchen Server zu verwenden, könnte unbeabsichtigt dasselbe DoS-Problem verursachen.

Beachten Sie, dass dieses DoS nur auf dem TCP-Dienst liegt. In diesen Fällen betrifft es jedoch nicht nur Clients, die TCP aus betrieblichen Gründen für ihre Abfragen verwenden möchten, sondern alle Clients, die sich entscheiden, nach Erhalt eines TC=1-Flags von UDP auf TCP zurückzugreifen.

6.2. Empfehlungen (Recommendations)

Die folgenden Abschnitte enthalten Empfehlungen, die zu konsistenteren und skalierbareren Implementierungen von DNS-über-TCP führen sollen.

6.2.1. Verbindungswiederverwendung (Connection Reuse)

Ein wahrgenommener Nachteil von DNS über TCP ist die zusätzliche Latenz beim Verbindungsaufbau, die im Allgemeinen einem RTT entspricht. Um die Kosten für den Verbindungsaufbau zu amortisieren, SOLLTEN (SHOULD) sowohl Clients als auch Server die Verbindungswiederverwendung unterstützen, indem sie mehrere Abfragen und Antworten über eine einzige persistente TCP-Verbindung senden.

Beim Senden mehrerer Abfragen über eine TCP-Verbindung DÜRFEN Clients die DNS-Nachrichten-ID einer laufenden Abfrage auf dieser Verbindung NICHT (MUST NOT) wiederverwenden, um Kollisionen von Nachrichten-IDs zu vermeiden. Dies ist besonders wichtig, wenn der Server eine Außer-Reihenfolge-Verarbeitung durchführen könnte (siehe Abschnitt 7).

6.2.1.1. Abfrage-Pipelining (Query Pipelining)

Aufgrund der historischen Verwendung von TCP hauptsächlich für Zonentransfers und abgeschnittene Antworten diskutiert kein bestehender RFC die Idee des Pipelining von DNS-Abfragen über eine TCP-Verbindung.

Um eine Leistung auf dem Niveau von UDP zu erreichen, SOLLTEN (SHOULD) DNS-Clients ihre Abfragen pipelinen. Wenn ein DNS-Client mehrere Abfragen an einen Server sendet, SOLLTE (SHOULD) er nicht auf eine ausstehende Antwort warten, bevor er die nächste Abfrage sendet. Clients SOLLTEN (SHOULD) TCP und UDP gleich behandeln, wenn sie den Zeitpunkt für das Senden einer bestimmten Abfrage in Betracht ziehen.

Es ist wahrscheinlich, dass DNS-Server Pipelining-Abfragen gleichzeitig verarbeiten und auch Antworten außerhalb der Reihenfolge über TCP senden müssen, um das Leistungsniveau zu erreichen, das mit UDP-Transport möglich ist. Wenn die TCP-Leistung von Bedeutung ist, finden Clients es möglicherweise nützlich, Serververarbeitungszeiten als Eingabe für Server- und Transportauswahlalgorithmen zu verwenden.

DNS-Server (insbesondere rekursive) MÜSSEN (MUST) erwarten, Pipelining-Abfragen zu empfangen. Der Server SOLLTE (SHOULD) TCP-Abfragen gleichzeitig verarbeiten, genau wie er es für UDP tun würde. Der Server SOLLTE (SHOULD) alle Pipelining-Abfragen beantworten, auch wenn sie in schneller Folge empfangen werden. Die Behandlung von Antworten auf Pipelining-Abfragen wird in Abschnitt 7 behandelt.

6.2.2. Gleichzeitige Verbindungen (Concurrent Connections)

Um das Risiko einer unbeabsichtigten Serverüberlastung zu mindern, MÜSSEN (MUST) DNS-Clients darauf achten, die Anzahl der gleichzeitigen TCP-Verbindungen zu einem einzelnen Server zu minimieren. Es wird EMPFOHLEN (RECOMMENDED), dass es für jede gegebene Client/Server-Interaktion nicht mehr als eine Verbindung für reguläre Abfragen, eine für Zonentransfers und eine für jedes Protokoll geben SOLLTE (SHOULD), das auf TCP verwendet wird (z. B. wenn der Resolver TLS verwendet). Es wird jedoch darauf hingewiesen, dass bestimmte Primär-/Sekundärkonfigurationen mit vielen stark frequentierten Zonen aus betrieblichen Gründen möglicherweise mehr als eine TCP-Verbindung für Zonentransfers verwenden müssen (z. B. um gleichzeitige Transfers mehrerer Zonen zu unterstützen).

Ebenso KÖNNEN (MAY) Server Beschränkungen für die Anzahl der gleichzeitigen TCP-Verbindungen auferlegen, die für eine bestimmte Client-IP-Adresse oder ein Subnetz behandelt werden. Diese Beschränkungen SOLLTEN (SHOULD) viel lockerer sein als die obigen Client-Richtlinien, da der Server beispielsweise nicht weiß, ob eine Client-IP-Adresse zu einem einzelnen Client gehört, ob es sich um mehrere Resolver auf einer einzigen Maschine handelt oder ob es sich um mehrere Clients hinter einem Gerät handelt, das Network Address Translation (NAT) durchführt.

6.2.3. Leerlauf-Timeouts (Idle Timeouts)

Um das Risiko einer unbeabsichtigten Serverüberlastung zu mindern, MÜSSEN (MUST) DNS-Clients darauf achten, die Leerlaufzeit etablierter DNS-über-TCP-Sitzungen zu einem einzelnen Server zu minimieren. DNS-Clients SOLLTEN (SHOULD) die TCP-Verbindung einer Leerlaufsitzung schließen, es sei denn, ein Leerlauf-Timeout wurde unter Verwendung eines anderen Signalisierungsmechanismus festgelegt, z. B. [edns-tcp-keepalive].

Um das Risiko einer unbeabsichtigten Serverüberlastung zu mindern, wird EMPFOHLEN (RECOMMENDED), dass die standardmäßige Leerlaufzeit auf Serveranwendungsebene in der Größenordnung von Sekunden liegt, es wird jedoch kein bestimmter Wert angegeben. In der Praxis kann die Leerlaufzeit dynamisch variieren, und Server KÖNNEN (MAY) zulassen, dass Leerlaufverbindungen über längere Zeiträume geöffnet bleiben, wenn die Ressourcen dies zulassen. Ein Timeout von mindestens einigen Sekunden ist für den normalen Betrieb ratsam, um diejenigen Clients zu unterstützen, die erwarten, dass die SOA- und AXFR-Anfragesequenz über eine einzige Verbindung erfolgt, wie ursprünglich in [RFC1035] spezifiziert. Server KÖNNEN (MAY) Null-Timeouts verwenden, wenn sie unter hoher Last stehen oder angegriffen werden.

DNS-Nachrichten, die über TCP zugestellt werden, können in mehreren Segmenten eintreffen. Ein DNS-Server, der sein Leerlauf-Timeout nach dem Empfang eines einzelnen Segments zurücksetzt, könnte anfällig für einen "Slow-Read-Angriff" sein. Aus diesem Grund SOLLTEN (SHOULD) Server das Leerlauf-Timeout beim Empfang einer vollständigen DNS-Nachricht zurücksetzen, anstatt beim Empfang eines Teils einer DNS-Nachricht.

6.2.4. Abbau (Teardown)

Im normalen Betrieb initiieren DNS-Clients typischerweise das Schließen der Verbindung bei Leerlaufverbindungen; DNS-Server können die Verbindung jedoch schließen, wenn das durch die lokale Richtlinie festgelegte Leerlauf-Timeout überschritten wird. Außerdem können Verbindungen von beiden Seiten unter ungewöhnlichen Bedingungen geschlossen werden, wie z. B. bei der Verteidigung gegen einen Angriff oder bei einem Systemausfall/Neustart.

DNS-Clients SOLLTEN (SHOULD) unbeantwortete Abfragen erneut versuchen, wenn die Verbindung geschlossen wird, bevor alle ausstehenden Antworten empfangen wurden. In diesem Dokument wird kein spezifischer Wiederholungsalgorithmus spezifiziert.

Wenn ein DNS-Server feststellt, dass ein DNS-Client eine TCP-Sitzung geschlossen hat (oder wenn die Sitzung anderweitig unterbrochen wurde), bevor alle ausstehenden Antworten gesendet wurden, DARF der Server NICHT (MUST NOT) versuchen, diese Antworten zu senden. Natürlich KANN (MAY) der DNS-Server diese Antworten zwischenspeichern.