Fronting de domeniu bazat pe TLS 1.3

Introducere

Fronting de domeniu bazat pe TLS 1.3
Sistemele moderne de filtrare a conținutului corporativ de la producători renumiți precum Cisco, BlueCoat, FireEye au destul de multe în comun cu omologii lor mai puternici - sistemele DPI, care sunt implementate activ la nivel național. Esența muncii ambilor este de a inspecta traficul de internet de intrare și de ieșire și, pe baza listelor albe/negre, de a lua decizia de a interzice conexiunea la Internet. Și, deoarece ambii se bazează pe principii similare în bazele muncii lor, metodele de ocolire a acestora vor avea, de asemenea, multe în comun.

Una dintre tehnologiile care vă permite să ocoliți în mod destul de eficient atât sistemele DPI, cât și sistemele corporative este tehnologia care vizează domeniul. Esența ei este că mergem la o resursă blocată, ascunzându-ne în spatele altei, de domeniu public cu o bună reputație, care evident nu va fi blocată de niciun sistem, de exemplu google.com.

Despre această tehnologie au fost deja scrise destul de multe articole și au fost date multe exemple. Cu toate acestea, popularele și recent discutate tehnologii DNS-over-HTTPS și criptat-SNI, precum și noua versiune a protocolului TLS 1.3, fac posibilă luarea în considerare a unei alte opțiuni pentru fronting de domeniu.

Înțelegerea tehnologiei

În primul rând, să definim câteva concepte de bază, astfel încât toată lumea să înțeleagă cine este cine și de ce este nevoie de toate acestea. Am menționat mecanismul eSNI, a cărui funcționare va fi discutată în continuare. Mecanismul eSNI (encrypted Server Name Indication) este o versiune securizată a SNI, disponibilă numai pentru protocolul TLS 1.3. Ideea principală este de a cripta, printre altele, informații despre ce domeniu este trimisă cererea.

Acum să vedem cum funcționează mecanismul eSNI în practică.

Să presupunem că avem o resursă de Internet care este blocată de o soluție DPI modernă (să luăm, de exemplu, celebrul tracker torrent rutracker.nl). Când încercăm să accesăm site-ul web al unui tracker torrent, vedem stub-ul standard al furnizorului care indică faptul că resursa este blocată:

Fronting de domeniu bazat pe TLS 1.3

Pe site-ul web RKN, acest domeniu este de fapt listat în listele de oprire:

Fronting de domeniu bazat pe TLS 1.3

Când interogați whois, puteți vedea că domeniul în sine este „ascuns” în spatele furnizorului de cloud Cloudflare.

Fronting de domeniu bazat pe TLS 1.3

Dar spre deosebire de „specialiștii” de la RKN, angajații mai pricepuți din punct de vedere tehnic de la Beeline (sau învățați de experiența amară a celebrului nostru regulator) nu au interzis în mod prostesc site-ul după adresa IP, ci au adăugat numele domeniului la lista de oprire. Puteți verifica cu ușurință acest lucru dacă vă uitați la ce alte domenii sunt ascunse în spatele aceleiași adrese IP, vizitați unul dintre ele și vedeți că accesul nu este blocat:

Fronting de domeniu bazat pe TLS 1.3

Cum se întâmplă asta? De unde știe DPI-ul furnizorului în ce domeniu se află browserul meu, deoarece toate comunicările au loc prin protocolul https și nu am observat încă înlocuirea certificatelor https de la Beeline? Este clarvăzător sau sunt urmărit?

Să încercăm să răspundem la această întrebare privind traficul prin wireshark

Fronting de domeniu bazat pe TLS 1.3

Captura de ecran arată că mai întâi browserul obține adresa IP a serverului prin DNS, apoi are loc o strângere de mână TCP standard cu serverul de destinație, iar apoi browserul încearcă să stabilească o conexiune SSL cu serverul. Pentru a face acest lucru, trimite un pachet SSL Client Hello, care conține numele domeniului sursă în text clar. Acest câmp este cerut de serverul frontend cloudflare pentru a ruta corect conexiunea. Aici ne prinde furnizorul DPI, rupându-ne conexiunea. În același timp, nu primim niciun stub de la furnizor și vedem eroarea standard de browser ca și cum site-ul este dezactivat sau pur și simplu nu funcționează:

Fronting de domeniu bazat pe TLS 1.3

Acum să activăm mecanismul eSNI în browser, așa cum este scris în instrucțiunile pentru Firefox :
Pentru a face acest lucru deschidem pagina de configurare Firefox about: config și activați următoarele setări:

network.trr.mode = 2;
network.trr.uri = https://mozilla.cloudflare-dns.com/dns-query
network.security.esni.enabled = true

După aceasta, vom verifica dacă setările funcționează corect pe site-ul web cloudflare. legătură și să încercăm din nou trucul cu tracker-ul nostru de torrent.

Fronting de domeniu bazat pe TLS 1.3

Voila. Trackerul nostru preferat s-a deschis fără VPN sau servere proxy. Să ne uităm acum la groapa de trafic din Wireshark pentru a vedea ce s-a întâmplat.

Fronting de domeniu bazat pe TLS 1.3

De data aceasta, pachetul ssl client hello nu conține în mod explicit domeniul de destinație, ci în schimb, un câmp nou a apărut în pachet - encrypted_server_name - aici este conținută valoarea rutracker.nl și numai serverul frontend cloudflare poate decripta acest lucru. camp. Și dacă da, atunci furnizorul DPI nu are de ales decât să se spele pe mâini și să permită un astfel de trafic. Nu există alte opțiuni cu criptare.

Deci, ne-am uitat la modul în care funcționează tehnologia în browser. Acum să încercăm să o aplicăm la lucruri mai specifice și mai interesante. Și mai întâi, vom învăța același curl să folosească eSNI pentru a lucra cu TLS 1.3 și, în același timp, vom vedea cum funcționează fronting-ul de domeniu bazat pe eSNI.

Fronting domeniu cu eSNI

Datorită faptului că curl folosește biblioteca standard openssl pentru a se conecta prin protocolul https, în primul rând trebuie să oferim suport eSNI acolo. Încă nu există suport eSNI în ramurile master openssl, așa că trebuie să descarcăm o ramură specială openssl, să o compilam și să o instalăm.

Clonăm depozitul din GitHub și compilăm ca de obicei:

$ git clone https://github.com/sftcd/openssl
$ cd openssl
$ ./config

$ make
$ cd esnistuff
$ make

Apoi, clonăm depozitul cu curl și configuram compilarea acestuia folosind biblioteca noastră openssl compilată:

$ 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

Aici este important să specificați corect toate directoarele în care se află openssl (în cazul nostru, acesta este /opt/openssl/) și să vă asigurați că procesul de configurare decurge fără erori.

Dacă configurarea are succes, vom vedea linia:

AVERTISMENT: esni ESNI activat dar marcat EXPERIMENTAL. Utilizați cu prudență!

$ make

După construirea cu succes a pachetului, vom folosi un fișier bash special de la openssl pentru a configura și a rula curl. Să-l copiem în directorul cu curl pentru comoditate:

cp /opt/openssl/esnistuff/curl-esni 

și faceți o cerere de testare https către serverul cloudflare, în timp ce înregistrați simultan pachetele DNS și TLS în Wireshark.

$ ESNI_COVER="www.hello-rkn.ru" ./curl-esni https://cloudflare.com/

În răspunsul serverului, pe lângă multe informații de depanare de la openssl și curl, vom primi un răspuns HTTP cu codul 301 de la 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/

ceea ce indică faptul că cererea noastră a fost livrată cu succes la serverul de destinație, ascultată și procesată.

Acum să ne uităm la groapa de trafic din wireshark, adică. ceea ce a văzut furnizorul DPI în acest caz.

Fronting de domeniu bazat pe TLS 1.3

Se poate observa că curl a apelat mai întâi la serverul DNS pentru o cheie eSNI publică pentru serverul cloudflare - o solicitare TXT DNS către _esni.cloudflare.com (pachetul nr. 13). Apoi, folosind biblioteca openssl, curl a trimis o cerere TLS 1.3 către serverul cloudflare în care câmpul SNI a fost criptat cu cheia publică obținută în pasul anterior (pachetul #22). Dar, pe lângă câmpul eSNI, pachetul SSL-hello a inclus și un câmp cu SNI obișnuit - deschis, pe care îl putem specifica în orice ordine (în acest caz - www.hello-rkn.ru).

Acest câmp SNI deschis nu a fost luat în considerare în niciun fel atunci când a fost procesat de serverele cloudflare și a servit doar ca mască pentru furnizorul DPI. Serverul cloudflare a primit pachetul nostru ssl-hello, a decriptat eSNI-ul, a extras SNI-ul original de acolo și l-a procesat ca și cum nimic nu s-ar fi întâmplat (a făcut totul exact așa cum era planificat la dezvoltarea eSNI).

Singurul lucru care poate fi prins în acest caz din punct de vedere DPI este cererea DNS primară către _esni.cloudflare.com. Dar am deschis cererea DNS doar pentru a arăta cum funcționează acest mecanism din interior.

Pentru a scoate în sfârșit covorul de sub DPI, folosim mecanismul DNS-over-HTTPS deja menționat. O mică explicație - DOH este un protocol care vă permite să vă protejați împotriva unui atac man-in-the-middle prin trimiterea unei cereri DNS prin HTTPS.

Să executăm din nou cererea, dar de data aceasta vom primi chei publice eSNI prin protocolul https, nu DNS:

ESNI_COVER="www.hello-rkn.ru" DOH_URL=https://mozilla.cloudflare-dns.com/dns-query ./curl-esni https://cloudflare.com/

Dump-ul de trafic al solicitării este afișat în captura de ecran de mai jos:

Fronting de domeniu bazat pe TLS 1.3

Se vede că curl accesează mai întâi serverul mozilla.cloudflare-dns.com prin protocolul DoH (conexiune https la serverul 104.16.249.249) pentru a obține de la aceștia valorile cheilor publice pentru criptarea SNI, iar apoi către destinație server, ascuns în spatele domeniului www.hello-rkn.ru.

În plus față de rezolutorul DoH de mai sus mozilla.cloudflare-dns.com, putem folosi și alte servicii DoH populare, de exemplu, de la celebra corporație diabolică.
Să rulăm următoarea interogare:

ESNI_COVER="www.kremlin.ru" DOH_URL=https://dns.google/dns-query ./curl-esni https://rutracker.nl/

Și primim răspunsul:

< 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

Fronting de domeniu bazat pe TLS 1.3

În acest caz, am apelat la serverul blocat rutracker.nl, folosind rezolutorul DoH dns.google (aici nu este greșeală de tipar, acum celebra corporație are propriul domeniu de prim nivel) și ne-am acoperit cu un alt domeniu, care este strict interzisă blocării tuturor DPI-urilor sub pedeapsa morții. Pe baza răspunsului primit, puteți înțelege că solicitarea noastră a fost procesată cu succes.

Ca o verificare suplimentară că DPI-ul furnizorului răspunde la SNI-ul deschis, pe care îl transmitem ca acoperire, putem face o cerere către rutracker.nl sub masca unei alte resurse interzise, ​​de exemplu, un alt tracker de torrent „bun”:

$ ESNI_COVER="rutor.info" DOH_URL=https://dns.google/dns-query ./curl-esni https://rutracker.nl/

Nu vom primi un răspuns de la server, deoarece... cererea noastră va fi blocată de sistemul DPI.

O scurtă concluzie la prima parte

Deci, am putut să demonstrăm funcționalitatea eSNI folosind openssl și curl și să testăm funcționarea fronting-ului de domeniu pe baza eSNI. În același mod, putem adapta instrumentele noastre preferate care folosesc biblioteca openssl pentru a funcționa „sub masca” altor domenii. Mai multe detalii despre acest lucru în următoarele articole.

Sursa: www.habr.com

Adauga un comentariu