Domain fronting bazat pe TLS 1.3

Introducere

Domain fronting bazat pe TLS 1.3
Sistemele moderne de filtrare a conținutului pentru întreprinderi, de la producători renumiți precum Cisco, BlueCoat, FireEye, au multe asemănări cu omologii lor mai puternici — sistemele DPI, care sunt intens implementate la nivel național. Esența acestei lucrări, atât pentru unii, cât și pentru alții, este de a inspecta traficul internetului de intrare și ieșire și, pe baza listelor negre/glezi albe, a decide asupra interzicerii conexiunii la internet. Și, având în vedere că ambele se bazează pe principii similare, metodele de ocolire a acestora vor avea, de asemenea, multe în comun.

Una dintre tehnologiile care permite ocolirea destul de eficientă atât a DPI-ului, cât și a sistemelor corporate, este tehnologia domain-fronting. Esența acesteia constă în faptul că accesăm o resursă blocată, ascunzându-ne în spatele unui alt domeniu public, cu o reputație bună, care nu va fi niciodată blocat de vreo sistem, de exemplu google.com.

S-au scris deja destule articole despre această tehnologie și s-au adus multe exemple. Cu toate acestea, tehnologiile populare și discutate recent DNS-over-HTTPS și encrypted-SNI, precum și noua versiune a protocolului TLS 1.3 oferă posibilitatea de a lua în considerare încă o variantă de domain-fronting.

Să ne familiarizăm cu tehnologia

La început, să ne clarificăm unele concepte de bază, astfel încât toată lumea să înțeleagă cine este cine și de ce este totul necesar. Am menționat mecanismul eSNI, al cărui funcționare va fi discutată mai departe. Mecanismul eSNI (encrypted Server Name Indication) – o variantă securizată a SNI, disponibilă doar pentru protocolul TLS 1.3. Esența principală – criptarea, printre altele, a informațiilor despre domeniul către care este trimisă cererea.

Acum să analizăm în practică funcționarea mecanismului eSNI.

Presupunem că avem o resursă internet care este blocată de o soluție DPI modernă (să luăm ca exemplu celebrul tracker de torrente — rutracker.nl). Când încercăm să accesăm site-ul tracker-ului de torrente — vedem mesajul standard de interzicere al providerului, care indică faptul că resursa este blocată:

Domain fronting bazat pe TLS 1.3

Pe site-ul RKN, acest domeniu este într-adevăr listat pe listele de blocare:

Domain fronting bazat pe TLS 1.3

La cererea whois — se poate observa că domeniul în sine este "ascuns" în spatele providerului cloud Cloudflare.

Domain fronting bazat pe TLS 1.3

Dar, spre deosebire de "specialiștii" din RKN, angajații din Beeline, mai bine pregătiți tehnic (sau învățați din experiența amară a celebrului nostru regulator), nu au blocat pur și simplu site-ul după adresa IP, ci l-au inclus în lista de blocare exact pe numele de domeniu. Este ușor de verificat, dacă ne uităm ce alte domenii se ascund în spatele acestuia adresa IP, vizităm unul dintre ele și vedem că accesul nu este blocat:

Domain fronting bazat pe TLS 1.3

Cum este posibil așa ceva? Cum știe DPI-ul providerului pe care dintre domenii navighează browserul meu, având în vedere că toate comunicațiile se desfășoară prin protocolul https, iar substituirea certificatelor https de către Beeline nu a fost observată până acum? Oare este vorba de fațadă sau cineva mă urmărește?

Să încercăm să răspundem la această întrebare, aruncând o privire asupra traficului prin wireshark

Domain fronting bazat pe TLS 1.3

În captura de pe ecran se vede că, mai întâi, browserul primește adresa IP a serverului prin DNS, apoi are loc procesul standard de handshake TCP cu serverul de destinație, iar apoi browserul încearcă să stabilească o conexiune ssl cu serverul. Pentru aceasta, trimite un pachet SSL Client Hello, care conține numele domeniului sursă în format deschis. Acest câmp este necesar serverului frontend cloudflare pentru a putea ruteze corespunzător conexiunea. Aici ne prinde DPI-ul providerului, întrerupând conexiunea. În acest timp, nu primim niciun mesaj de eroare de la provider și vedem o eroare standard a browserului, ca și cum site-ul ar fi dezactivat sau pur și simplu nu funcționează:

Domain fronting bazat pe TLS 1.3

Acum să activăm mecanismul eSNI în browser, așa cum este descris în instrucțiunile pentru Firefox :
Pentru aceasta, deschidem pagina de configurare Firefox about:config și activăm 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 corectitudinea funcționării setărilor pe site-ul cloudflare la linkul și vom încerca din nou trucul cu tracker-ul nostru de torrent.

Domain fronting bazat pe TLS 1.3

Voilà. Tracker-ul nostru favorit s-a deschis, fără VPN-uri sau servere proxy. Să aruncăm acum o privire asupra dump-ului de trafic în wireshark, ce s-a întâmplat.

Domain fronting bazat pe TLS 1.3

De data aceasta, pachetul ssl client hello nu conține în mod explicit domeniul de destinație, iar în schimb a apărut un nou câmp - encrypted_server_name - acesta conține valoarea rutracker.nl, iar decriptarea acestui câmp poate fi realizată doar de serverul frontend cloudflare. Iar, în acest caz, DPI-ul providerului nu are altă opțiune decât să se spele pe mâini și să permită acest tip de trafic. Și nu există alte opțiuni de criptare.

Deci, cum funcționează tehnologia în browser — am văzut. Acum să încercăm să o aplicăm pentru lucruri mai specifice și interesante. Pentru început, vom învăța cum să folosim aceeași comanda curl cu eSNI pentru a lucra cu TLS 1.3, și în același timp vom explora cum funcționează frontarea domeniului bazată pe eSNI.

Frontarea domeniului cu eSNI

Având în vedere că curl folosește biblioteca standard openssl pentru a se conecta prin protocolul https, trebuie să ne asigurăm întâi că eSNI este suportat acolo. În ramurile master ale openssl, suportul pentru eSNI nu este încă disponibil, așa că trebuie să descărcăm o ramură specială openssl, să o compilăm și să o instalăm.

Clonăm repository-ul de pe GitHub și îl compilăm ca de obicei:

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

$ make
$ cd esnistuff
$ make

Apoi, clonăm repository-ul curl și configurăm compilarea utilizând 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

Este important să specificăm corect toate directoarele în care se află openssl (în cazul nostru — este /opt/openssl/) și să ne asigurăm că procesul de configurare s-a desfășurat fără erori.

În cazul unei configurări reușite — vom vedea linia:

WARNING: esni ESNI enabled but marked EXPERIMENTAL. Use with caution!

$ make

După compilarea cu succes a pachetului, vom folosi un fișier bash special din pachetul openssl pentru a configura și a rula curl. Îl vom copia în directorul cu curl pentru comoditate:

cp /opt/openssl/esnistuff/curl-esni 

și vom efectua o cerere https de testare către serverul cloudflare, în același timp înregistrând pachetele DNS și TLS în Wireshark.

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

În răspunsul serverului, pe lângă multitudinea de 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 către serverul de destinație, a fost auzită și procesată.

Acum să analizăm dump-ul de trafic în Wireshark, adică ce a văzut în acest caz DPI-ul furnizorului.

Domain fronting bazat pe TLS 1.3

Se observă că, mai întâi, curl a solicitat serverului DNS cheia publică eSNI pentru serverul cloudflare — o interogare TXT DNS pentru _esni.cloudflare.com (pachetul nr. 13). Apoi, folosind biblioteca openssl, curl a trimis o interogare TLS 1.3 către serverul cloudflare în care câmpul SNI a fost criptat cu cheia publică obținută în etapa anterioară (pachetul nr. 22). Dar, pe lângă câmpul eSNI, în pachetul SSL-hello a fost 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 de SNI deschis nu a fost luat în considerare în procesarea serverelor cloudflare și a fost doar un camuflaj pentru DPI-ul furnizorului. Serverul cloudflare a acceptat pachetul nostru ssl-hello, a decriptat eSNI, a extras din el SNI-ul original și l-a tratat ca și cum nimic nu s-ar fi întâmplat (a făcut totul exact cum era planificat la dezvoltarea eSNI).

Singurul aspect la care ne putem agăța din perspectiva DPI este solicitarea DNS inițială pentru _esni.cloudflare.com. Dar am făcut interogarea DNS deschisă doar pentru a arăta cum funcționează acest mecanism din interior.

Pentru a elimina în totalitate baza de sub DPI, folosim deja menționatul mecanism DNS-over-HTTPS. O mică explicație – DOH – este un protocol care permite protecția împotriva atacului «omul din mijloc» prin trimiterea interogării DNS prin protocolul HTTPS.

Vom efectua din nou interogarea, dar de data aceasta vom obține cheile 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 traficului solicitării este prezentat în captura de ecran de mai jos:

Domain fronting bazat pe TLS 1.3

Se observă că, mai întâi, curl se adresează serverului mozilla.cloudflare-dns.com prin protocolul DoH (conexiune https către serverul 104.16.249.249), pentru a obține valorile cheilor publice pentru criptarea SNI, iar apoi se îndreaptă spre serverul de destinație, ascunzându-se în spatele domeniului www.hello-rkn.ru.

Pe lângă resolverul DoH menționat anterior mozilla.cloudflare-dns.com, putem utiliza și alte servicii populare DoH, de exemplu, cele de la celebra corporație a răului.
Să executăm o astfel de solicitare:

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

Și vom primi 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

Domain fronting bazat pe TLS 1.3

În acest caz, am contactat serverul blocat rutracker.nl, folosind un rezolvator DoH dns.google (nu este o greșeală, acum compania renumită are un domeniu de prim nivel) și ne-am ascuns sub un alt domeniu, blocarea căruia este strict interzisă tuturor DPI-urilor sub pedeapsa capitală. Din răspunsul primit, putem înțelege că solicitarea noastră a fost procesată cu succes.

Ca verificare suplimentară a faptului că DPI-ul providerului reacționează la SNI-ul deschis, pe care îl trimitem ca acoperire — putem face o solicitare către rutracker.nl ascunzându-ne sub un alt resurs interzis, cum ar fi un alt tracker de torente „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 solicitarea noastră va fi blocată de sistemul DPI.

O mică concluzie pentru prima parte

Așadar, am reușit să demonstrăm funcționalitatea eSNI folosind openssl și curl și să verificăm funcționarea domain-fronting-ului bazat pe eSNI. În același mod, putem adapta instrumentele noastre preferate care folosesc biblioteca openssl pentru a funcționa „sub acoperirea” altor domenii. Mai multe detalii despre acest lucru — în articolele noastre următoare.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster