Šifrování se nezadržitelně šíří internetem, přispívá k důvěryhodnosti, bezpečnosti a také k soukromí uživatelů. Pokud šifrujete, není možné po trase číst přenášená data. Stále ovšem existuje několik děr, které o vás dokáží například prozradit, které domény navštěvujete.
DNS dotazy je možné před zraky ukrýt pomocí šifrování, například pomocí DNS over TLS (DoT) nebo DNS over HTTPS (DoH). IP adresu cíle zamlžíte tím, že službu spustíte na sdíleném hostingu nebo budete obsah doručovat pomocí CDN. Stále je tu ale jedna díra, která se nachází přímo v šifrovacím protokolu. Díra se jmenuje SNI.
Proč potřebujeme SNI?
Před tím, než se v průběhu minulého desetiletí začalo pomalu prosazovat SNI, museli správci serverů řešit nepříjemný problém. Pokud chtěli na nějaký web nasadit HTTPS, museli pro něj vyhradit speciální IP adresu. Platilo totiž, že co šifrovaný web, to jedna adresa.
Důvod je jednoduchý: informace o navštěvovaném webu (hlavička Host) se objeví až v průběhu HTTP komunikace se serverem. Ještě předtím se ale navazuje TLS spojení, které o doméně nic neví, protože funguje přibližně na transportní vrstvě OSI modelu. Server ale při navazování spojení musí vybrat z disku správný certifikát a předat ho klientovi.
Bez SNI ale netuší, s jakým webem bude chtít klient později mluvit, proto musí mít k dispozici jen jediný certifikát nebo bude prostě hádat. To ale obvykle nedopadá dobře, protože pak v mnoha případech předá klientovi certifikát pokrývající jiná doménová jména a problém je na světě.
Proto přišlo rozšíření SNI, které už při navazování TLS předá serveru informaci o doméně. Protože ale v tu chvíli neprobíhá žádné šifrování a obě strany se na něm teprve dohadují, prochází tato informace v otevřené podobě. Útočník sledující úvod naší komunikace se tedy přesně dozví, na jakou doménu míříme. Užitečné, ale kompromitující.
Zašifrujme to
Řešením je samozřejmě informaci zašifrovat. S původním nápadem přišel před časem Matthew Prince ze společnosti Cloudflare. Úvodní myšlenka byla jednoduchá: server předá klientovi veřejný klíč, kterým pak klient zašifruje doménu předávanou v upraveném protokolu ESNI.
K vývoji se rychle přidaly další firmy včetně Apple, Fastly či Mozilly a vznikl návrh otevřeného standardu, který se nyní diskutuje v pracovní skupině TLS při IETF. Implementaci to ale nezdrželo a Cloudflare včera na svých serverech podporu ESNI spustil. Mozilla během tohoto týdne zařadí podporu do své vývojářské verze (Nightly) a ostatní tvůrci prohlížečů prý mají taky velký zájem. Existuje už i webový test, na kterém si můžete podporu ve svém prohlížeči ověřit.
Původní myšlenka „prostě pošleme klíč a zašifruje se to“ byla samozřejmě rozpracována do výrazně komplexnějšího mechanismu, který ve svém podrobném článku na blogu Cloudflare rozebral Alessandro Ghedini.
Kde vezmeme klíč?
Proč nemohlo být dříve SNI šifrované a teď už může? Protože u klasického SNI se informace posílá ještě předtím než se mezi stranami vyjedná podoba šifrovacího klíče. Klíčová otázka tedy je: kde vezmeme důvěryhodný klíč? Odpověď je prostá: v DNS.
Zjednodušeně tedy klient kromě obvyklé odpovědi na A/AAAA záznamy získá také z DNS záznam s veřejným klíčem. Ten použije k zašifrování SNI záznamu, tím vznikne ESNI, které je schopen si server svým privátním klíčem dešifrovat.
Podstatné také je, že ESNI je rozšířením nového protokolu TLS 1.3. Ve starších verzích nedává smysl informaci ze SNI šifrovat, protože se stejně na začátku komunikace posílá certifikát nešifrovaně. V certifikátu je uvedeno doménové jméno, takže útočník si jej může vyčíst právě odtud. Nová verze TLS přesouvá přenos certifikátu až do šifrované části komunikace, takže se útočník nedozví nic.
# dig _esni.cloudflare.com TXT ;; ANSWER SECTION: _esni.cloudflare.com. 3600 IN TXT "/wEJUWJmACQAHQAg4qDSY1OR1RTAcTO/BgeLTry0XVSCxp3I73xSXqmaXwUAAhMBAQQAAAAAW6XaYAAAAABbrcNgAAA="
ESNI pak kromě samotné domény obsahuje také klientův veřejný klíč, informace o použité šifře a část DNS záznamu serveru. Server zase použije svou privátní část klíče a klientský veřejný klíč k tomu, aby informaci dešifroval. To vše proto, aby byla informace svázaná s konkrétním TLS spojením, aby nebylo možné ji znovu použít v dalším spojení (replay attack). Pak by totiž útočník tuto zašifrovanou zprávu nahrál, přehrál ji naslepo serveru a ten by mu ukázal stránku. Identita skrývané stránky by tak byla snadno odhalena.
V případě úniku serverového privátního klíče by pak mohl útočník zpětně dešifrovat předchozí ESNI zprávy. Proto konkrétně implementace použitá v Cloudflare mění klíče každou hodinu, přičemž ty staré ještě nechává chvíli v platnosti. Pokud tedy klient kvůli zpoždění v DNS zašifruje zprávu starším klíčem, vše bude fungovat bez problémů. Starší klíče se pak postupně skartují.
Tajný dotaz do DNS?
Možná vás napadlo, že na začátku komunikace musí stejně proběhnout dotaz na původní doménu, aby byl zjištěn šifrovací klíč. Tento problém řeší už zmíněné šifrování komunikace s DNS resolverem pomocí protokolů jako DNS over TLS (DoT) nebo DNS over HTTPS (DoH). Pokud navíc použijete veřejný resolver, přes který teče obrovské množství provozu od mnoha různých klientů, není možné dotazy snadno k cíli sledovat.
Proti podvržení informace na straně autoritativního serveru pak slouží samozřejmě protokol DNSSEC, který například v .CZ používá více než 50 % domén. Pokud váš resolver validuje DNSSEC (což by měl), můžete se spolehnout na to, že získané odpovědi byly skutečně vytvořeny autorizovaným správcem domény.
Pokud tedy sečteme ESNI, DNSSEC, TLS 1.3 a DoT či DoH, vyjde nám na druhé straně pomyslné rovnice šifrovaný komunikační kanál, ze kterého nejen že neunikají samotná data, ale ani metadata o navštěvované doméně.