Versleuteld DNS-verkeer sneller en efficiënter met nieuw DNS-over-QUIC-protocol

Eerste brede implementaties onderweg

Dit voorjaar is DNS-over-QUIC (DoQ) gestandaardiseerd als RFC 9250. Daarmee komen de voordelen van native QUIC – namelijk snellere responsetijden en een hogere efficiëntie – ook direct beschikbaar voor versleuteld DNS-transport. Vergeleken met DNS-over-HTTPS/2 en DNS-over-TLS – die beide over TCP lopen – gaat het om een sterke verbetering. Ten opzichte van DNS-over-HTTPS/3 – dat al over UDP loopt – gaat het om een beperktere efficiëntieslag.

In dit artikel behandelen we de werking en voordelen van het QUIC-transportprotocol, dat tot nu toe alleen als onderdeel van HTTP/3 gebruikt werd. Gevolgd door een bespreking van deze nieuwe native mapping van DNS op QUIC.

TCP/2

QUIC is ontwikkeld als vervanger voor TCP, en dan in eerste instantie voor gebruik onder HTTP(S)-verbindingen. Het probleem dat QUIC oplost is het (tijdelijke) blokkeren van de netwerkverbinding als een TCP-pakket onderweg verloren gaat of vertraagd wordt. Kenmerkend onderscheid van TCP ten opzichte van UDP is immers dat de inhoud van TCP-pakketten compleet en in volgorde afgeleverd wordt bij het ontvangende eindpunt (waarmee er sprake is van een echte, doorlopende dataverbinding).

TCP maakt daarvoor gebruik van het 'sliding window'-mechanisme: De zender stuurt een bepaald aantal bytes vooruit vanaf het laatste byte(nummer) waarvoor hij bevestiging heeft teruggekregen. De ontvanger zet de binnenkomende data in een buffer, bevestigt die naar de zender (met een ACK-bericht), en geeft daarbij steeds aan wat het oudste byte(nummer) is dat hij nog niet heeft ontvangen. Is er een gedeelte verloren gegaan, dan stuurt de zender na het bereiken van zijn window-breedte (het aantal bytes dat hij maximaal mag hebben uitstaan zonder bevestiging) dat specifieke gedeelte opnieuw, waarmee de ontvanger het volgende deel van zijn inkomende datastroom compleet kan maken.

Visualisatie van het TCP 'sliding window'-mechanisme.

Multiplexing en HOL blocking

Hoewel dit mechanisme prima werkt voor enkelvoudige datastromen, is dat niet het geval voor gemultiplexte verbindingen, waarbij meerdere datastromen gecombineerd worden verstuurd over een en dezelfde verbinding. Ga maar na: Terwijl de ontvanger wacht op een bepaald segment behorend bij een bepaalde datastroom, blijven de segmenten voor andere datastromen gewoon binnenkomen. Maar omdat op TCP-niveau niet bekend is bij welke datastroom de individuele segmenten horen – inherent aan de scheiding tussen transportlaag en applicatielaag – kan de verwerking van andere, in principe niet-aangedane datastromen tijdelijk ook geen doorgang vinden. De segmenten daarvoor bevinden zich immers (ononderscheidbaar) in hetzelfde window als het ontbrekende pakket.

HTTP/2, de HTTP-standaard van dit moment, bevat het multiplexen van afzonderlijke datastromen als een van zijn belangrijkste nieuwe features. En daarmee lijdt dit protocol aan het zojuist beschreven 'Head-Of-Line (HOL) blocking'-probleem. Saillant is dat multiplexing destijds juist geïntroduceerd is om HOL blocking (in dit geval op applicatieniveau in HTTP/1.1) te voorkomen: Een browser die een webpagina opent haalt naast de HTML-code zelf vaak ook tientallen plaatjes en JavaScript-bestanden binnen. Was het maximaal aantal uitgaande verbindingen bereikt, dan moest de browser wachten voordat weer nieuwe downloads konden worden gestart. Door verbindingen naar dezelfde server te combineren in één gemultiplexte verbinding, werd het HTTP-protocol zowel sneller als efficiënter. Maar tegelijkertijd werd het HOL blocking-probleem hiermee dus verplaatst van de applicatielaag naar de transportlaag (waar het wel veel minder impact heeft).

Alleen een gedeelde TLS-handshake

QUIC, net als HTTP/2 bedacht door Google, trekt de datastromen die eerder in HTTP/2 op applicatieniveau waren gecombineerd weer uit elkaar op transportniveau. Het protocol staat niet op zichzelf naast TCP en UDP, maar maakt gebruik van UDP om zijn datapakketten te versturen. Daarbovenop zorgt QUIC dan voor het samenstellen van de datastromen binnen een verbinding (nu per individuele datastroom), waarbij de TLS-handshake voor alle datastromen binnen dezelfde QUIC-verbinding wel maar één keer uitgevoerd hoeft te worden. Na de eerdere versnelling van multiplexing in HTTP/2 (SPDY), krijgen HTTP-verbindingen met QUIC dus opnieuw een boost.

Combineer je grofweg het HTTP/2-protocol en TLS versie 1.3 met QUIC, dan krijg je HTTP/3, de HTTP-versie die nu sterk in opkomst is.

DNS-over-QUIC

Hoewel QUIC in eerste instantie is ontwikkeld met HTTP(S) in het achterhoofd, betreft het een generiek protocol dat door allerlei applicatieprotocollen gebruikt kan worden. Het nu in RFC 9250 gestandaardiseerde DNS-over-QUIC (DoQ) is zo'n toepassing.

Het uitgangspunt van DoQ is hetzelfde als dat van DNS-over-HTTPS (DoH) en DNS-over-TLS (DoT), die beide sterk in opkomst zijn: namelijk het beschermen van de vertrouwelijkheid van het DNS-verkeer. Het belangrijkste voordeel daarbij is dat DoQ de DNS-uitwisseling zo veel mogelijk zijn oude snelheid weer teruggeeft uit de tijd dat klassiek DNS-verkeer zonder DNSSEC en zonder transportversleuteling volledig over UDP plaatsvond. Tegelijkertijd wordt als onderdeel van de QUIC-handshake wel een 'source address'-verificatie uitgevoerd die bij het originele DNS over UDP ontbreekt en onder andere IP-adres spoofing en amplificatie-aanvallen mogelijk maakt.

Native mapping

DoQ kan op allerlei manieren ingezet worden voor beveiligde DNS-uitwisselingen: van stub naar recursieve resolver, van recursieve resolver naar autoritatieve nameserver, en voor zone transfers tussen nameservers. Oplettende lezers merken natuurlijk gelijk op dat DoQ principieel niet verschilt van DoH-over-HTTP/3 (sinds kort ondersteund in Android 11). De auteurs van de RFC betogen echter dat een "dunne" native mapping direct van DNS op QUIC om redenen van efficiëntie gerechtvaardigd is (de bescherming van de privacy van de eindgebruiker is een ander argument om HTTP ertussenuit te halen).

Net als bij "HTTP(S) over QUIC" (HTTP/3), stuurt DoQ elk van zijn DNS-queries over een afzonderlijke datastroom binnen de bestaande TLS-verbinding. Daarmee wordt HOL blocking van DNS-responses zoals dat bij gebruik van DoT/DoH kan optreden voorkomen. Het protocol maakt gebruik van well-known UDP-poortnummer 853 (inderdaad hetzelfde nummer als DoT, dat alleen de TCP-ingang gebruikt). De mapping van DNS op QUIC zoals die in de RFC staat beschreven is verder recht-toe-recht-aan.

Implementaties

Voor de brede ondersteuning van DoQ in DNS- en browser-software is het nog te vroeg. Degene die het hardst aan de implementatie van DoQ heeft getrokken is AdGuard [1, 2]. Anderhalf jaar geleden hebben zij DoQ ingebouwd in zowel hun publieke DNS-dienst als hun Home resolver en apps/plugins. Zolang de DoQ-standaard nog in ontwikkeling was, hebben zij echter DoT als default ingesteld laten staan, waardoor slechts 1 procent van het binnenkomende verkeer op hun servers over DoQ liep. Nu het standaardisatieproces is afgerond willen zij die default binnenkort naar DoQ omschakelen. Omdat AdGuard zijn software vooral in de programmeertaal Go schrijft, zijn hun implementaties echter maar beperkt inzetbaar door de rest van de wereld.

Een andere DNS-server die DoQ al ondersteund is NextDNS. Zij hebben hun nameservers onlangs opgewaardeerd naar de definitieve standaard van DoQ.

Volgens senior PowerDNS engineer Peter van Dijk wordt (uitgaande) DoQ als eerste ingebouwd in hun dnsdist load balancer [1, 2], die in de meeste gevallen voor de PowerDNS server-software wordt geplaatst. Dat inbouwen gebeurt dit najaar als onderdeel van Google's Summer of Code (GSoC 2022). Daarna volgen inkomende DoQ voor dnsdist en ondersteuning in de Recursor. Voor dat laatste zijn de ontwikkelaars afhankelijk van implementatie in de nghttp/ngtcp2 library [1, 2], die binnenkort de niet langer ontwikkelde h2o library [1, 2] zal vervangen in de PowerDNS-servers. Nadeel van deze (noodzakelijke) stap is dat iedereen in de DNS-wereld dan diezelfde nghttp/ngtcp2 library gebruikt: omdat het hier om software gaat waar clients direct mee communiceren, levert een eventueel lek dan gelijk een groot probleem op (vanwege een gebrek aan diversiteit).

Ook voor de Unbound resolver geldt dat aan de ondersteuning van DoQ op dit moment nog gewerkt wordt door de mensen van NLnet Labs.