Valná většina DNS komunikace probíhá protokolem UDP. Nic složitějšího není třeba, protože typicky zahrnuje výměnu dvou paketů – klient pošle jeden paket s dotazem a server mu jedním paketem odpoví. Navazovat kvůli tomu TCP spojení je jasné plýtvání. Než si oba účastníci trojicí paketů potvrdí pořadová čísla pro potvrzování, má UDP hotovo.
S částečným použitím složitějšího protokolu se ovšem v DNS počítalo už od samých začátků. Jeho prostřednictvím probíhají zónové přenosy mezi autoritativními servery. Tam se vyměňují větší objemy dat, takže je spolehlivé TCP zcela na místě. Kromě toho autoři protokolu DNS počítali s možností, že odpověď bude na jeden paket příliš dlouhá. V takovém případě v ní server nastaví příznak TC, kterým signalizuje, že data nejsou kompletní. Od klienta se očekává, že zkrácenou odpověď zahodí, položí dotaz po TCP a server mu několika pakety odpoví.
Vývoj DNS ovšem k delším odpovědím jednoznačně směřuje. Objevují se objemnější záznamy a především se postupně zavádí zabezpečení DNSSEC, které k běžným záznamům přidává digitální podpisy (čtěte „spoustu dat“). Pravda, ruku v ruce s ním kráčí EDNS0 a umožňuje po UDP přenášet i delší pakety než původních 512 B. Nicméně i tak míra využití TCP postupně roste.
Druhým faktorem posilujícím postavení TCP ve světě DNS je bezpečnost. Hlavní motivací jsou DDoS útoky, k nimž je DNS hojně zneužíváno. Autoritativnímu serveru se pošle regulérní dotaz, ovšem s falešnou adresou odesilatele. Server pak svou odpověď adresuje nic netušící oběti. A když se dotazy volí tak, aby odpovědi byly velké (čili pokud možno podepsané), a pošle se jich různým serverům hodně, sejde se na adrese oběti provoz, který ji dostane do kolen.
Obrana proti tomuto typu útoků je triviální poblíž místa odeslání dotazu (hlídají se zdrojové adresy paketů podle BCP 38), ale složitá na straně DNS serveru, který je proti své vůli do útoku zavlečen. A jelikož řada správců BCP 38 ignoruje, zneužívání trvá. Většina DNS serverů dnes umožňuje omezit frekvenci odpovědí zasílaných na jednu adresu, tím se ovšem problém řeší jen částečně.
Vede to k úvahám, jestli pro potřeby DNS více nevyužívat TCP. Tam útok tohoto typu není možný, protože se nejprve malými pakety navazuje spojení a teprve pak se posílají vlastní data. Při padělané adrese odesilatele se spojení nepodaří navázat a tím celá komunikace skončí.
Výsledkem je, že TCP je ve světě DNS považováno za čím dál tím důležitější. Projevilo se to mimo jiné v RFC 5966, které bylo nedávno nahrazeno RFC 7766. Tyto dokumenty zavádějí požadavky na implementaci TCP v programech pro DNS. Lze je stručně shrnout do následujících bodů:
-
Podpora TCP je povinná ve všech typech programů – autoritativních serverech (tam byla nutná vždy kvůli zónovým přenosům), rekurzivních serverech i jednoduchých klientech.
-
Oba protokoly jsou rovnocenné. Klient se může volně rozhodnout, kterým z nich položí dotaz. Dříve musel nejprve položit dotaz po UDP a k TCP se obrátit, až když odpověď obsahovala příznak zkrácení.
-
Programy pro DNS by měly podporovat opakované využití TCP spojení, kdy se po jednom spojení vyřizuje několik dotazů. Tohle je velmi lákavé, protože režie TCP se rozloží mezi více dotazů a přestává být významnou.
Právě dlouhodobější spojení jsou v novém RFC 7766 podrobněji rozvedena. Jasně definuje, že s dotazy mají obě strany zacházet, jako by byly přepravovány po UDP. Čili klient s dalšími dotazy nemusí čekat na vyřízení předchozích. Jakmile chce položit dotaz a má otevřené TCP spojení s daným serverem, jednoduše jej po něm odešle. Server má dotazy přicházející TCP spojením řešit paralelně a odpovědi posílat v libovolném pořadí, jakmile je má k dispozici. Klient je pozná podle identifikátorů, které jsou standardní součástí DNS zpráv.
Celkem rozumně se požaduje, aby odpověď byla vždy odeslána protokolem a spojením, jímž dorazil příslušný dotaz. TCP spojení mohou uzavřít obě strany, ale server by tak měl učinit až po zodpovězení všech dotazů, které jím obdržel. Výjimku představují situace, kdy si uzavření vynutí vnější okolnosti (přetížení nebo vypínání serveru).
Jelikož je počet současných TCP spojení omezený, řeší specifikace i omezování jejich počtu. Klient by měl otevírat co nejméně spojení, pokud možno ke každému serveru jen jedno pro běžné dotazy, a případně po jednom pro další účely – zónové přenosy, TLS a podobně. Server je pak oprávněn omezovat počet spojení akceptovaných z jedné adresy (tohle omezení ovšem velmi komplikují NATy) a uzavírat je v případě potřeby.
Aby spojení nezůstávala navázána příliš dlouho, počítá se s určitým časovým limitem. Pokud se během této doby neobjeví další dotaz, klient by měl spojení uzavřít. Výchozí hodnota není určena, nicméně doporučuje se, aby byla v řádu sekund (RFC 1035 původně počítalo se dvěma minutami).
Nově pak byla v RFC 7828 definována volba edns-tcp-keepalive pro EDNS0, která umožňuje dohodnout se na časovém limitu. Přidává se pouze k dotazům a odpovědím přenášeným po TCP. Její přítomnost v dotazu znamená, že DNS klient má zájem toto spojení zachovat pro budoucí dotazy. Pokud je i server nakloněn trvalému spojení, zařadí ji do odpovědi a oznámí klientovi časový limit pro nečinnost. Případně může nulovým limitem požádat o co nejrychlejší ukončení spojení, pokud se později dostane do kapacitních problémů.
U prostého TCP to ovšem zdaleka nemusí skončit. Mimo jiné se pracuje na zapojení protokolu TLS, kterým by se šifrovala DNS komunikace. Hlavním cílem je ochrana soukromí uživatelů, ovšem navíc by bylo možné autentizovat DNS servery a přidat tak další faktor k posílení důvěryhodnosti poskytovaných dat.
Přichází tedy doba přechodu DNS na TCP? Až tak horké to zatím nebude. Podle statistik autoritativního serveru domény tul.cz ze sto milionů dotazů dorazilo po TCP sto tisíc, tedy jeden z tisíce. Z toho zhruba polovina byla vyvolána zkrácenými odpověďmi, kterých server rozeslal 50 tisíc. Statistiky z CESNETu vypadají podobně, také po TCP přichází zhruba jedno promile dotazů.
Nicméně ta čísla rostou a budou růst dál. Je proto dobré být připraven, což ze strany správce znamená především nezapomenout na firewallech otevřít DNS serveru port 53 nejen pro UDP, ale i pro TCP.