Përshëndetje Habr, unë quhem Ilya, punoj në ekipin e platformave të kompanisë Exness. Ne zhvillojmë dhe zbatojmë komponentët bazë të infrastrukturës që përdorin ekipet tona të zhvillimit të produkteve.
Në këtë artikull do të doja të ndaja përvojën time në implementimin e teknologjisë së enkriptuar SNI (ESNI) në infrastrukturën e faqeve publike.

Përdorimi i kësaj teknologjie do të rrisë nivelin e sigurisë gjatë punës me një faqe publike dhe do të përputhet me standardet e brendshme të sigurisë, të pranuara në kompaninë tonë.
Së pari, dëshiroj të theksoj se teknologjia nuk është standartizuar dhe ende është në draft, megjithatë CloudFlare dhe Mozilla tashmë e mbështesin atë (në ). Kjo na motivoi për një eksperiment të tillë.
Pak teori
ESNI është një zgjerim i protokollit TLS 1.3, i cili lejon enkriptimin e SNI në mesazhin 'Client Hello' të negociatës TLS. Këtu është se si duket Client Hello me mbështetje për ESNI (në vend të SNI të zakontë shohim ESNI):

 Për të përdorur ESNI, nevojiten tri përbërës:
- DNS;Â
- Mbështetje nga klienti;
- Mbështetje nga serveri.
DNS
Duhet tĂ« shtoni dy registre DNS â A, dhe TXT (TXT regjistrimi pĂ«rmban çelĂ«sin publik, me ndihmĂ«n e tĂ« cilit klienti mund tĂ« enkriptojĂ« SNI) â shih mĂ« poshtĂ«. PĂ«r mĂ« tepĂ«r, duhet tĂ« ketĂ« mbĂ«shtetje DoH (DNS mbi HTTPS), pasi klientĂ«t e disponueshĂ«m (shih mĂ« poshtĂ«) nuk aktivizojnĂ« mbĂ«shtetje pĂ«r ESNI pa DoH. Kjo Ă«shtĂ« logjike, pasi ESNI nĂ«nkupton enkriptimin e emrit tĂ« burimit qĂ« po i drejtohemi, domethĂ«nĂ« Ă«shtĂ« pa kuptim tĂ« drejtohemi nĂ« DNS pĂ«rmes UDP. MĂ« shumĂ« se kaq, pĂ«rdorimi lejon mbrojtjen nga sulmet e "cache poisoning" nĂ« kĂ«tĂ« skenar.
Në këtë moment janë të disponueshme , midis të cilëve:
CloudFlare (Kontrolloni shfletuesin tim â SNI i enkriptuar â MĂ«so mĂ« shumĂ«), qĂ« serverĂ«t e tyre tani mbĂ«shtesin ESNI, pra pĂ«r serverĂ«t CloudFlare nĂ« DNS kemi tĂ« paktĂ«n dy regjistrime â A dhe TXT. NĂ« shembullin mĂ« poshtĂ«, ne po kĂ«rkojmĂ« DNS-in e Google (pĂ«rmes HTTPS):Â
Dhe regjistrimi:
curl 'https://dns.google.com/resolve?name=www.cloudflare.com&type=A'
-s -H 'accept: application/dns+json'
{
"Status": 0,
"TC": false,
"RD": true,
"RA": true,
"AD": true,
"CD": false,
"Question": [
{
"name": "www.cloudflare.com.",
"type": 1
}
],
"Answer": [
{
"name": "www.cloudflare.com.",
"type": 1,
"TTL": 257,
"data": "104.17.210.9"
},
{
"name": "www.cloudflare.com.",
"type": 1,
"TTL": 257,
"data": "104.17.209.9"
}
]
}
TXT regjistrimi, kërkesa formohet sipas modelit _esni.FQDN:
curl 'https://dns.google.com/resolve?name=_esni.www.cloudflare.com&type=TXT'
-s -H 'accept: application/dns+json'
{
"Status": 0,
"TC": false,
"RD": true,
"RA": true,
"AD": true,
"CD": false,
"Question": [
{
"name": "_esni.www.cloudflare.com.",
"type": 16
}
],
"Answer": [
{
"name": "_esni.www.cloudflare.com.",
"type": 16,
"TTL": 1799,
"data": ""/wEUgUKlACQAHQAg9SiAYQ9aUseUZr47HYHvF5jkt3aZ5802eAMJPhRz1QgAAhMBAQQAAAAAXtUmAAAAAABe3Q8AAAA=""
}
],
"Comment": "Response from 2400:cb00:2049:1::a29f:209."
}Prandaj, nga pikĂ«pamja e DNS, ne duhet tĂ« pĂ«rdorim DoH (preferohet me DNSSEC) dhe tĂ« shtojmĂ« dy regjistra.Â
Përkrahja nga klienti
Nëse flasim për shfletuesit, aktualisht . Këtu është udhëzimi si të aktivizoni përkrahjen për ESNI dhe DoH në FireFox. Pasi shfletuesi është konfiguruar, duhet të shohim diçka të tillë:

për të kontrolluar shfletuesin.
Sigurisht, përkrahja e ESNI kërkon përdorimin e TLS 1.3, sepse ESNI është një zgjerim për TLS 1.3.
Për qëllime testimi të backendit me përkrahje për ESNI, ne realizuam një klient në go, por për këtë do të flasim më vonë.
Përkrahja nga serveri
Aktualisht, ESNI nuk mbështetet nga serverët web si nginx/apache, etj., pasi ata punojnë me TLS përmes OpenSSL/BoringSSL, në të cilat ESNI zyrtarisht nuk mbështetet.
Prandaj ne vendosĂ«m tĂ« krijonim komponentin tonĂ« front-end (proxy invertimi ESNI), i cili mbĂ«shtet terminimin e TLS 1.3 me ESNI dhe proksimin e trafikut HTTP(S) nĂ« upstream, qĂ« nuk mbĂ«shtet ESNI. Kjo lejon aplikimin e teknologjisĂ« nĂ« njĂ« infrastrukturĂ« tĂ« vendosur tashmĂ«, pa ndryshuar komponentĂ«t kryesorĂ« â domethĂ«nĂ«, duke pĂ«rdorur serverĂ«t aktualĂ« web, qĂ« nuk mbĂ«shtesin ESNI.Â
Për qartësi, do të japim një skemë:

Dua të theksoj se proksi është menduar me mundësinë për të përfunduar lidhjen TLS pa ESNI, për të mbështetur klientët pa ESNI. Gjithashtu, protokolli i komunikimit me upstream mund të jetë si HTTP ashtu edhe HTTPS me versionin TLS më poshtë 1.3 (nëse upstream nuk e mbështet 1.3). Kjo skemë ofron fleksibilitet maksimal.
Implementimin e mbështetjes ESNI në go e kemi marrë nga . Do të theksoj se vetë implementimi është mjaft jo trivial, pasi nënkupton ndryshime në bibliotekën standarde crypto/tls dhe prandaj kërkon "patching" GOROOT para ndërtimit.
Për gjenerimin e çelësave ESNI, ne përdorëm (po ashtu një krijim nga CloudFlare). Këta çelësa përdoren për enkriptimin/dekriptimin e SNI.
Ne e testuam ndĂ«rtimin duke pĂ«rdorur go 1.13 nĂ« Linux (Debian, Alpine) dhe MacOS.Â
Një fjalë për veçoritë operative
ProProxy ESNI ofron metrika nĂ« formatin Prometheus, si pĂ«r shembull, rps, latenca upstream & kodet e pĂ«rgjigjeve, dorĂ«zime tĂ« dĂ«shtuara/suksesshme TLS & kohĂ«zgjatja e dorĂ«zimit TLS. NĂ« pamje tĂ« parĂ«, kjo duket e mjaftueshme pĂ«r tĂ« vlerĂ«suar se si proxy e menaxhon trafikun.Â
Gjithashtu, para përdorimit, ne kemi kryer teste ngarkese. Rezultatet janë më poshtë:
wrk -t50 -c1000 -d360s 'https://esni-rev-proxy.npw:443' --timeout 15s
Po ekzekutohet testi 6 minutash @ https://esni-rev-proxy.npw:443
 50 thjesht dhe 1000 lidhje
 Statistikat e Thjesht:  Mesatare   Stdev   Maks  +/- Stdev
    Latenca   1.77s   1.21s  7.20s  65.43%
    Kërkesa/Sek  13.78   8.84  140.00   83.70%
  206357 kërkesa në 6.00m, 6.08GB të lexuara
Kërkesa/sek:  573.07
Transferimi/sek:   17.28MB Ne kemi kryer teste ngarkese të pastra, për të krahasuar skemat me përdorimin e ESNI reverse proxy dhe pa të. Ne 'derdhëm' trafik lokal për të përjashtuar 'pengesat' në komponentët ndërmjetës.
Pra, me mbështetje ESNI dhe proksimin në upstream me HTTP, ne arritëm rreth ~ 550 rps me një instancë, ndërkohë që mesatarja e konsumit të CPU/RAM të ESNI reverse proxy ishte:
- 80% Përdorimi i CPU (4 vCPU, 4 GB RAM hoste, Linux)
- 130 MB Mem RSS

Për krahasim, RPS për të njëjtin upstream nginx pa terminim TLS (protokolli HTTP) ~ 1100:
wrk -t50 -c1000 -d360s 'http://lb.npw:80' --timeout 15s
Running 6m test @ http://lb.npw:80
50 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.11s 2.30s 15.00s 90.94%
Req/Sec 23.25 13.55 282.00 79.25%
393093 requests in 6.00m, 11.35GB read
Socket errors: connect 0, read 0, write 0, timeout 9555
Non-2xx or 3xx responses: 8111
Requests/sec: 1091.62
Transfer/sec: 32.27MB Prania e kohëve të pritjes tregon se ka mungesë burimesh (ne përdorëm hoste me 4 vCPU, 4 GB RAM, Linux), dhe në fakt potenciali RPS është më i lartë (ne morëm numra deri në 2700 RPS me burime më të fuqishme).
Si pĂ«rfundim, do tĂ« theksoj se teknologjia ESNI duket mjaft premtuese. Ka ende shumĂ« pyetje tĂ« hapura, siç janĂ« pyetjet pĂ«r ruajtjen e çelĂ«sit publik ESNI nĂ« DNS dhe rotacionin e çelĂ«save tĂ« ESNI â kĂ«to pyetje janĂ« duke u diskutuar aktivisht, dhe versioni mĂ« i fundit i draftit (nĂ« momentin e shkrimit) tĂ« ESNI tashmĂ« .
Burimi: habr.com
