úvod
Moderní systémy pro filtrování firemního obsahu od renomovaných výrobců jako Cisco, BlueCoat, FireEye mají poměrně hodně společného se svými výkonnějšími protějšky - DPI systémy, které jsou aktivně implementovány na národní úrovni. Podstatou práce obou je kontrola příchozího a odchozího internetového provozu a na základě černých/bílých listin rozhodnout o zákazu připojení k internetu. A protože oba v základech své práce spoléhají na podobné principy, budou mít i způsoby jejich obcházení mnoho společného.
Jednou z technologií, která umožňuje poměrně efektivně obejít DPI i podnikové systémy, je technologie doménového frontování. Jeho podstatou je, že přejdeme na zablokovaný zdroj, který se skrývá za jiným, veřejným vlastnictvím, s dobrou pověstí, který samozřejmě nebude blokován žádným systémem, například google.com.
O této technologii již bylo napsáno poměrně dost článků a bylo uvedeno mnoho příkladů. Populární a v poslední době diskutované technologie DNS-over-HTTPS a encrypted-SNI, stejně jako nová verze protokolu TLS 1.3, však umožňují uvažovat o další možnosti doménového frontingu.
Pochopení technologie
Nejprve si definujme trochu základních pojmů, aby každý pochopil, kdo je kdo a proč je to všechno potřeba. Zmínili jsme mechanismus eSNI, o jehož fungování bude řeč dále. Mechanismus eSNI (encrypted Server Name Indication) je zabezpečená verze SNI, dostupná pouze pro protokol TLS 1.3. Hlavní myšlenkou je zašifrovat mimo jiné informace o tom, na jakou doménu je požadavek odeslán.
Nyní se podívejme, jak mechanismus eSNI funguje v praxi.
Řekněme, že máme internetový zdroj, který je blokován moderním řešením DPI (vezměme si například slavný torrent tracker rutracker.nl). Když se pokusíme vstoupit na webovou stránku sledovače torrentů, uvidíme standardní útržek poskytovatele, který označuje, že zdroj je blokován:
Na webu RKN je tato doména skutečně uvedena v seznamech zastávek:
Při dotazu na whois můžete vidět, že samotná doména je „skrytá“ za cloudovým poskytovatelem Cloudflare.
Ale na rozdíl od „specialistů“ z RKN technicky zdatnější zaměstnanci z Beeline (nebo poučení hořkou zkušeností našeho slavného regulátora) web hloupě nezakázali podle IP adresy, ale přidali název domény na stoplist. Můžete si to snadno ověřit, když se podíváte, jaké další domény se skrývají za stejnou IP adresou, navštívíte jednu z nich a uvidíte, že přístup není blokován:
Jak se to stane? Jak DPI poskytovatele pozná, na které doméně je můj prohlížeč, protože veškerá komunikace probíhá přes protokol https a zatím jsme nezaznamenali náhradu https certifikátů od Beeline? Je jasnovidec nebo mě sledují?
Pokusme se na tuto otázku odpovědět pohledem na provoz přes wireshark
Snímek obrazovky ukazuje, že nejprve prohlížeč získá IP adresu serveru prostřednictvím DNS, poté proběhne standardní TCP handshake s cílovým serverem a poté se prohlížeč pokusí navázat spojení SSL se serverem. K tomu odešle paket SSL Client Hello, který obsahuje název zdrojové domény ve formě prostého textu. Toto pole je vyžadováno frontendovým serverem cloudflare, aby bylo připojení správně směrováno. Zde nás zastihne poskytovatel DPI a přeruší naše připojení. Zároveň od poskytovatele nedostáváme žádný útržek a vidíme standardní chybu prohlížeče, jako by byl web deaktivován nebo jednoduše nefunguje:
Nyní povolme mechanismus eSNI v prohlížeči, jak je napsáno v pokynech pro
K tomu otevřeme konfigurační stránku Firefoxu about: config a aktivujte následující nastavení:
network.trr.mode = 2;
network.trr.uri = https://mozilla.cloudflare-dns.com/dns-query
network.security.esni.enabled = true
Poté zkontrolujeme, zda nastavení na webu cloudflare funguje správně.
Voila. Náš oblíbený tracker se otevřel bez VPN nebo proxy serverů. Pojďme se nyní podívat na dopravní skládku v wireshark, abychom viděli, co se stalo.
Tentokrát balíček ssl client hello neobsahuje explicitně cílovou doménu, ale místo toho se v balíčku objevilo nové pole - encrypted_server_name - zde je obsažena hodnota rutracker.nl a dešifrovat ji může pouze frontend server cloudflare pole. A pokud ano, tak poskytovateli DPI nezbývá, než si umýt ruce a takový provoz povolit. U šifrování nejsou žádné další možnosti.
Podívali jsme se tedy, jak tato technologie funguje v prohlížeči. Nyní to zkusme aplikovat na konkrétnější a zajímavější věci. A nejprve naučíme stejný curl používat eSNI pro práci s TLS 1.3 a zároveň uvidíme, jak funguje samotný fronting domény na bázi eSNI.
Fronting domény s eSNI
Vzhledem k tomu, že curl používá pro připojení přes protokol https standardní knihovnu openssl, musíme tam v první řadě zajistit podporu eSNI. V hlavních větvích openssl zatím není podpora eSNI, takže si musíme stáhnout speciální větev openssl, zkompilovat a nainstalovat.
Klonujeme úložiště z GitHubu a kompilujeme jako obvykle:
$ git clone https://github.com/sftcd/openssl
$ cd openssl
$ ./config
$ make
$ cd esnistuff
$ make
Dále naklonujeme úložiště pomocí curl a nakonfigurujeme jeho kompilaci pomocí naší zkompilované knihovny openssl:
$ cd $HOME/code
$ git clone https://github.com/niallor/curl.git curl-esni
$ cd curl-esni
$ export LD_LIBRARY_PATH=/opt/openssl
$ ./buildconf
$ LDFLAGS="-L/opt/openssl" ./configure --with-ssl=/opt/openssl --enable-esni --enable-debug
Zde je důležité správně specifikovat všechny adresáře, kde se openssl nachází (v našem případě je to /opt/openssl/) a ujistit se, že konfigurační proces proběhne bez chyb.
Pokud je konfigurace úspěšná, uvidíme řádek:
VAROVÁNÍ: esni ESNI povoleno, ale označeno jako EXPERIMENTÁLNÍ. Používejte opatrně!
$ make
Po úspěšném sestavení balíčku použijeme speciální bash soubor z openssl ke konfiguraci a spuštění curl. Zkopírujeme to do adresáře s curl pro pohodlí:
cp /opt/openssl/esnistuff/curl-esni
a proveďte testovací https požadavek na server cloudflare a současně zaznamenejte pakety DNS a TLS ve Wiresharku.
$ ESNI_COVER="www.hello-rkn.ru" ./curl-esni https://cloudflare.com/
V odpovědi serveru kromě spousty ladicích informací z openssl a curl obdržíme HTTP odpověď s kódem 301 od cloudflare.
HTTP/1.1 301 Moved Permanently
< Date: Sun, 03 Nov 2019 13:12:55 GMT
< Transfer-Encoding: chunked
< Connection: keep-alive
< Cache-Control: max-age=3600
< Expires: Sun, 03 Nov 2019 14:12:55 GMT
< Location: https://www.cloudflare.com/
což znamená, že náš požadavek byl úspěšně doručen na cílový server, vyslyšen a zpracován.
Nyní se podíváme na dopravní skládku ve wireshark, tzn. co v tomto případě viděl poskytovatel DPI.
Je vidět, že curl se nejprve obrátil na DNS server pro veřejný eSNI klíč pro cloudflare server - TXT DNS požadavek na _esni.cloudflare.com (balíček č. 13). Poté curl pomocí knihovny openssl odeslal požadavek TLS 1.3 na server cloudflare, ve kterém bylo pole SNI zašifrováno veřejným klíčem získaným v předchozím kroku (paket #22). Ale kromě pole eSNI paket SSL-hello obsahoval také pole s obvyklým - otevřeným SNI, které můžeme zadat v libovolném pořadí (v tomto případě -
Toto otevřené pole SNI nebylo při zpracování cloudflare servery nijak zohledněno a sloužilo pouze jako maska pro poskytovatele DPI. Server cloudflare přijal náš paket ssl-hello, dešifroval eSNI, extrahoval odtud původní SNI a zpracoval jej, jako by se nic nestalo (při vývoji eSNI udělal vše přesně podle plánu).
Jediné, čeho se lze v tomto případě z pohledu DPI chytit, je primární DNS požadavek na _esni.cloudflare.com. Požadavek DNS jsme však otevřeli pouze proto, abychom ukázali, jak tento mechanismus funguje zevnitř.
Abychom konečně vytáhli kobereček zpod DPI, používáme již zmíněný mechanismus DNS-over-HTTPS. Malé vysvětlení – DOH je protokol, který umožňuje chránit se před útokem typu man-in-the-middle odesláním DNS požadavku přes HTTPS.
Proveďme požadavek znovu, ale tentokrát obdržíme veřejné klíče eSNI přes protokol https, nikoli DNS:
ESNI_COVER="www.hello-rkn.ru" DOH_URL=https://mozilla.cloudflare-dns.com/dns-query ./curl-esni https://cloudflare.com/
Výpis provozu požadavku je zobrazen na níže uvedeném snímku obrazovky:
Je vidět, že curl nejprve přistupuje k serveru mozilla.cloudflare-dns.com přes protokol DoH (připojení https k serveru 104.16.249.249), aby od nich získal hodnoty veřejných klíčů pro šifrování SNI, a poté do cíle server, který se skrývá za doménou
Kromě výše uvedeného DoH resolveru mozilla.cloudflare-dns.com můžeme využít další oblíbené DoH služby, například od známé zlé korporace.
Spusťte následující dotaz:
ESNI_COVER="www.kremlin.ru" DOH_URL=https://dns.google/dns-query ./curl-esni https://rutracker.nl/
A dostáváme odpověď:
< HTTP/1.1 301 Moved Permanently
< Date: Sun, 03 Nov 2019 14:10:22 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: __cfduid=da0144d982437e77b0b37af7d00438b1a1572790222; expires=Mon, 02-Nov-20 14:10:22 GMT; path=/; domain=.rutracker.nl; HttpOnly; Secure
< Location: https://rutracker.nl/forum/index.php
< CF-Cache-Status: DYNAMIC
< Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< Server: cloudflare
< CF-RAY: 52feee696f42d891-CPH
V tomto případě jsme se obrátili na zablokovaný server rutracker.nl pomocí DoH resolveru dns.google (není zde žádný překlep, nyní má slavná korporace vlastní doménu první úrovně) a pokryli jsme se jinou doménou, která je striktně zakázáno všem DPI blokovat pod trestem smrti. Na základě obdržené odpovědi můžete pochopit, že naše žádost byla úspěšně zpracována.
Jako další kontrolu, zda DPI poskytovatele odpovídá otevřenému SNI, které vysíláme jako krytí, můžeme požádat rutracker.nl pod rouškou jiného zakázaného zdroje, například jiného „dobrého“ sledovače torrentů:
$ ESNI_COVER="rutor.info" DOH_URL=https://dns.google/dns-query ./curl-esni https://rutracker.nl/
Od serveru nedostaneme odpověď, protože... náš požadavek bude systémem DPI zablokován.
Krátký závěr prvního dílu
Takže jsme byli schopni demonstrovat funkčnost eSNI pomocí openssl a curl a otestovat fungování frontingu domény založeného na eSNI. Stejně tak můžeme přizpůsobit naše oblíbené nástroje, které využívají knihovnu openssl, aby fungovaly „pod rouškou“ jiných domén. Podrobněji o tom v našich dalších článcích.
Zdroj: www.habr.com