6. Gestion des Connexions (Connection Handling)
6.1. Pratiques Actuelles (Current Practices)
La section 4.2.2 de la [RFC1035] stipule :
-
Le serveur devrait supposer que le client initiera la fermeture de la connexion, et devrait retarder la fermeture de son extrémité de la connexion jusqu'à ce que toutes les demandes clients en attente aient été satisfaites.
-
Si le serveur doit fermer une connexion inactive pour récupérer des ressources, il devrait attendre que la connexion soit inactive pendant une période de l'ordre de deux minutes. En particulier, le serveur devrait permettre que la séquence de requêtes SOA et AXFR (qui commence une opération de rafraîchissement) soit effectuée sur une seule connexion. Comme le serveur serait de toute façon incapable de répondre aux requêtes, une fermeture unilatérale ou une réinitialisation peut être utilisée au lieu d'une fermeture gracieuse.
D'autres protocoles plus modernes (par exemple, HTTP/1.1 [RFC7230], HTTP/2 [RFC7540]) prennent en charge par défaut les connexions TCP persistantes pour toutes les requêtes. Les connexions sont ensuite normalement fermées via un signal de "fermeture de connexion" de l'une des parties.
La description dans la [RFC1035] est claire sur le fait que les serveurs devraient considérer les connexions comme persistantes (en particulier après avoir reçu un SOA), mais ne fournit malheureusement pas assez de détails pour une interprétation sans ambiguïté du comportement du client pour les requêtes autres qu'un SOA. De plus, le DNS n'a pas encore de mécanisme de signalisation pour le délai d'attente ou la fermeture de connexion, bien que certains aient été proposés.
6.1.1. Clients
Il n'y a pas de directives claires aujourd'hui dans aucune RFC quant au moment où un client DNS devrait fermer une connexion TCP, et il n'y a pas de recommandations spécifiques concernant les délais d'inactivité des clients DNS. Cependant, au moment de la rédaction, il est courant que les clients ferment la connexion TCP après avoir envoyé une seule requête (sauf dans le cas SOA/AXFR).
6.1.2. Serveurs
De nombreuses implémentations de serveurs DNS utilisent un long délai d'inactivité fixe et par défaut un petit nombre de connexions TCP. Elles offrent également peu d'options de gestion des connexions TCP. Les inconvénients de cela incluent :
-
L'expérience opérationnelle a montré que de longs délais d'attente serveur peuvent facilement causer un épuisement des ressources et une mauvaise réponse sous une charge lourde.
-
Ouvrir intentionnellement de nombreuses connexions et les laisser inactives peut trivialement créer une attaque par déni de service (DoS) TCP car de nombreux serveurs DNS sont mal équipés pour se défendre contre cela en modifiant leurs délais d'inactivité ou d'autres politiques de gestion des connexions.
-
Un nombre modeste de clients qui tentent tous simultanément d'utiliser des connexions persistantes avec des délais d'inactivité non nuls vers un tel serveur pourraient involontairement causer le même problème de DoS.
Notez que ce DoS ne concerne que le service TCP. Cependant, dans ces cas, il affecte non seulement les clients qui souhaitent utiliser TCP pour leurs requêtes pour des raisons opérationnelles, mais tous les clients qui choisissent de se replier sur TCP depuis UDP après avoir reçu un drapeau TC=1.
6.2. Recommandations (Recommendations)
Les sections suivantes incluent des recommandations destinées à aboutir à des implémentations de DNS-over-TCP plus cohérentes et évolutives.
6.2.1. Réutilisation de Connexion (Connection Reuse)
Un inconvénient perçu du DNS sur TCP est la latence supplémentaire d'établissement de connexion, généralement égale à un RTT. Pour amortir les coûts d'établissement de connexion, les clients et les serveurs DEVRAIENT (SHOULD) prendre en charge la réutilisation de connexion en envoyant plusieurs requêtes et réponses sur une seule connexion TCP persistante.
Lors de l'envoi de plusieurs requêtes sur une connexion TCP, les clients NE DOIVENT PAS (MUST NOT) réutiliser l'ID de message DNS d'une requête en cours sur cette connexion afin d'éviter les collisions d'ID de message. Ceci est particulièrement important si le serveur pourrait effectuer un traitement dans le désordre (voir la section 7).
6.2.1.1. Pipelining de Requêtes (Query Pipelining)
En raison de l'utilisation historique de TCP principalement pour le transfert de zone et les réponses tronquées, aucune RFC existante ne discute de l'idée de pipelining des requêtes DNS sur une connexion TCP.
Afin d'obtenir des performances équivalentes à UDP, les clients DNS DEVRAIENT (SHOULD) pipeliner leurs requêtes. Lorsqu'un client DNS envoie plusieurs requêtes à un serveur, il NE DEVRAIT PAS (SHOULD NOT) attendre une réponse en attente avant d'envoyer la requête suivante. Les clients DEVRAIENT (SHOULD) traiter TCP et UDP de manière équivalente lorsqu'ils considèrent le moment d'envoyer une requête particulière.
Il est probable que les serveurs DNS doivent traiter les requêtes pipelinées simultanément et envoyer également des réponses dans le désordre sur TCP afin de fournir le niveau de performance possible avec le transport UDP. Si la performance TCP est importante, les clients pourraient trouver utile d'utiliser les temps de traitement du serveur comme entrée pour les algorithmes de sélection de serveur et de transport.
Les serveurs DNS (en particulier récursifs) DOIVENT (MUST) s'attendre à recevoir des requêtes pipelinées. Le serveur DEVRAIT (SHOULD) traiter les requêtes TCP simultanément, tout comme il le ferait pour UDP. Le serveur DEVRAIT (SHOULD) répondre à toutes les requêtes pipelinées, même si elles sont reçues en succession rapide. La gestion des réponses aux requêtes pipelinées est couverte dans la section 7.
6.2.2. Connexions Simultanées (Concurrent Connections)
Pour atténuer le risque de surcharge involontaire du serveur, les clients DNS DOIVENT (MUST) veiller à minimiser le nombre de connexions TCP simultanées effectuées vers un serveur individuel. Il est RECOMMANDÉ (RECOMMENDED) que pour toute interaction client/serveur donnée, il ne DEVRAIT (SHOULD) pas y avoir plus d'une connexion pour les requêtes régulières, une pour les transferts de zone, et une pour chaque protocole utilisé au-dessus de TCP (par exemple, si le résolveur utilisait TLS). Cependant, il est noté que certaines configurations primaire/secondaire avec de nombreuses zones occupées pourraient avoir besoin d'utiliser plus d'une connexion TCP pour les transferts de zone pour des raisons opérationnelles (par exemple, pour prendre en charge les transferts simultanés de plusieurs zones).
De même, les serveurs PEUVENT (MAY) imposer des limites sur le nombre de connexions TCP simultanées gérées pour une adresse IP client ou un sous-réseau particulier. Ces limites DEVRAIENT (SHOULD) être beaucoup plus lâches que les directives clients ci-dessus, car le serveur ne sait pas, par exemple, si une adresse IP client appartient à un seul client, est plusieurs résolveurs sur une seule machine, ou est plusieurs clients derrière un appareil effectuant une traduction d'adresse réseau (NAT).
6.2.3. Délais d'Inactivité (Idle Timeouts)
Pour atténuer le risque de surcharge involontaire du serveur, les clients DNS DOIVENT (MUST) veiller à minimiser le temps d'inactivité des sessions DNS-over-TCP établies vers un serveur individuel. Les clients DNS DEVRAIENT (SHOULD) fermer la connexion TCP d'une session inactive, à moins qu'un délai d'inactivité n'ait été établi à l'aide d'un autre mécanisme de signalisation, par exemple, [edns-tcp-keepalive].
Pour atténuer le risque de surcharge involontaire du serveur, il est RECOMMANDÉ (RECOMMENDED) que la période d'inactivité par défaut au niveau de l'application serveur soit de l'ordre de quelques secondes, mais aucune valeur particulière n'est spécifiée. En pratique, la période d'inactivité peut varier dynamiquement, et les serveurs PEUVENT (MAY) permettre aux connexions inactives de rester ouvertes pendant des périodes plus longues si les ressources le permettent. Un délai d'attente d'au moins quelques secondes est conseillé pour les opérations normales afin de prendre en charge les clients qui s'attendent à ce que la séquence de requêtes SOA et AXFR soit effectuée sur une seule connexion comme spécifié à l'origine dans la [RFC1035]. Les serveurs PEUVENT (MAY) utiliser des délais d'attente nuls lorsqu'ils subissent une charge lourde ou sont attaqués.
Les messages DNS livrés sur TCP peuvent arriver en plusieurs segments. Un serveur DNS qui réinitialise son délai d'inactivité après avoir reçu un seul segment pourrait être vulnérable à une "slow-read attack". Pour cette raison, les serveurs DEVRAIENT (SHOULD) réinitialiser le délai d'inactivité à la réception d'un message DNS complet, plutôt qu'à la réception d'une partie d'un message DNS.
6.2.4. Démontage (Teardown)
En fonctionnement normal, les clients DNS initient généralement la fermeture de la connexion sur les connexions inactives ; cependant, les serveurs DNS peuvent fermer la connexion si le délai d'inactivité défini par la politique locale est dépassé. De plus, les connexions peuvent être fermées par l'une ou l'autre extrémité dans des conditions inhabituelles telles que la défense contre une attaque ou une panne/redémarrage du système.
Les clients DNS DEVRAIENT (SHOULD) réessayer les requêtes sans réponse si la connexion se ferme avant de recevoir toutes les réponses en attente. Aucun algorithme de réessai spécifique n'est spécifié dans ce document.
Si un serveur DNS constate qu'un client DNS a fermé une session TCP (ou si la session a été interrompue autrement) avant que toutes les réponses en attente n'aient été envoyées, alors le serveur NE DOIT PAS (MUST NOT) tenter d'envoyer ces réponses. Bien sûr, le serveur DNS PEUT (MAY) mettre en cache ces réponses.