Kuidas kaitsta oma avalikku saiti ESNI-ga

Tere, Habr! Minu nimi on Ilja, ma töötan Exnessi platvormimeeskonnas. Me arendame ja rakendame põhistruktuuri komponente, mida kasutavad meie toote arendusmeeskonnad.

Selles artiklis soovin jagada kogemusi tehnoloogia encrypted SNI (ESNI) rakendamise kohta avalike veebisaitide infrastruktuuris.

Kuidas kaitsta oma avalikku saiti ESNI-ga

Selle tehnoloogia kasutamine võimaldab suurendada avaliku veebisaidi turvalisust ja vastata organisatsiooni sissepoliitilistele turvastandarditele.

Enne kui alustan, tahan märkida, et tehnoloogia ei ole veel standardiseeritud ja on ikka veel mustand, kuid CloudFlare ja Mozilla toetavad seda juba ( draft01). See motiveeris meid selliseks eksperimendiks.

Natuke teooriat

ESNI on TLS 1.3 protokolli laiendus, mis võimaldab SNI-d krüpteerida TLS handshake'i "Client Hello" sõnumis. Nii näeb välja Client Hello, mis toetab ESNI-d (tavapärase SNI asemel näeme ESNI-d):

Kuidas kaitsta oma avalikku saiti ESNI-ga

 ESNI kasutamiseks on vajalik kolm koostisosade:

  • DNS; 
  • Kliendi poolne tugi;
  • Serveri poolne tugi.

DNS

On vaja lisada kaks DNS kanta - A, ja TXT (TXT-kirje sisaldab avalikku võtit, millega klient saab SNI-d krüpteerida) – vt allpool. Lisaks peab olema tugi DoH (DNS üle HTTPS), kuna saadaval olevad kliendid (vt allpool) ei aktiveeri ESNI tuge ilma DoH-ta. See on mõistlik, kuna ESNI eeldab ressurssi nime krüpteerimist, millega me ühendust võtame, seega pole mõtet pöörduda DNS-i poole UDP kaudu. Veelgi enam,  kasutamine DNSSEC aitab kaitsta 'cache poisoning' rünnakute eest selles stsenaariumis.

Praeguseks on saadaval mitmed DoH teenusepakkujad, nende hulgas:

CloudFlare väidab (Check My Browser → Encrypted SNI → Learn More), et nende serverid toetavad juba praegu ESNI-d, st CloudFlare'i serverite jaoks DNS-is on vähemalt kaks kirjet – A ja TXT. Allolevas näites küsime Google DNS-i (HTTPS-i kaudu): 

A kirje:

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 kirje, päring koostatakse mallil _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."
}

Seega, DNS-i seisukohalt peame kasutama DoH (eelistatavalt DNSSEC-iga) ja lisama kaks kirjet. 

Kliendi tugi

Kui räägime brauseritest, siis hetkel on tugi realiseeritud ainult FireFoxis.. Siit Siin on juhised, kuidas aktiveerida ESNI ja DoH tugi FireFoxis. Kui brauser on konfigureeritud, peaksime nägema umbes sellist pilti:

Kuidas kaitsta oma avalikku saiti ESNI-ga

Ling brauseri kontrollimiseks.

Muidugi peab ESNI toe tagamiseks olema kasutusel TLS 1.3, kuna ESNI on TLS 1.3 laiendus.

ESNI toe edendamiseks oleme realiseerinud kliendi go, kuid sellest natuke hiljem.

Serveri tugi

Praegu ei toeta ESNI veebiserverid nagu nginx/apache jne, kuna need töötavad TLS-iga OpenSSL/BoringSSL kaudu, kus ESNI ametlikult ei ole toetatud.

Seetõttu otsustasime luua oma front-end komponendi (ESNI tagasiproks), mis toetaks TLS 1.3 terminaatorit koos ESNI-ga ning HTTP(S) liikluse silumist allavoolu, mis ei toeta ESNI-d. See võimaldab tehnoloogia rakendamist juba olemasolevas infrastruktuuris, ilma põhikomponente muutes — st kasutada olemasolevaid veebiservereid, mis ei toeta ESNI-d. 

Toome selguse huvides välja skeemi:

Kuidas kaitsta oma avalikku saiti ESNI-ga

Tähtis on märkida, et proks on mõeldud TLS-i ühenduse lõpetamiseks ilma ESNI-ta, et toetada kliente, kes ei kasuta ESNI-d. Samuti võib suhtlusprotokoll allavoolu olla nii HTTP kui ka HTTPS, koos TLS-i versiooniga madalam kui 1.3 (kui allavool ei toeta 1.3). Selline skeem annab maksimaalse paindlikkuse.

ESNI toe rakendamise go me laenasime CloudFlare. Tõstaksin esile, et rakendamine on üsna keeruline, kuna see eeldab muudatusi standardraamatukogus crypto/tls ja seetõttu nõuab see 'patchimist' GOROOT enne kokkupanekut.

ESNI võtmete genereerimiseks kasutasime esnitool (mille on ka loonud CloudFlare). Need võtmed on mõeldud SNI krüpteerimiseks/dekrüpteerimiseks.
Testisime kogumist, kasutades go 1.13 Linuxis (Debian, Alpine) ja MacOS-iga. 

Mõned sõnad tööpõhimõtete kohta

ESNI pöördproksi pakub metrikat Prometheuse formaadis, näiteks rps, ülemineku latentsus & response codes, ebaõnnestunud/edukad TLS-käeulatused & TLS-käeulatused kestus. Esmapilgul tundus, et see on piisav, et hinnata, kuidas proksi liiklust haldab. 

Enne kasutamist viisime läbi koormustesti. Tulemused on järgmised:

wrk -t50 -c1000 -d360s 'https://esni-rev-proxy.npw:443' --timeout 15s
Käimas 6m test @ https://esni-rev-proxy.npw:443
  50 lõime ja 1000 ühendust
  Lõime statistika   Keskmine      Standardhälve     Max   +/– Standardhälve
    Latentsus     1.77s     1.21s    7.20s    65.43%
    Req/Sec    13.78      8.84   140.00     83.70%
  206357 päringut 6.00m jooksul, 6.08GB loetud
Päringud/s:    573.07
Ülekanded/s:     17.28MB 

Koormustesti viisime läbi puhtalt kvaliteetsete, et võrrelda skeeme kasutades ESNI pöördproksi ja ilma. Suunates liiklust kohalikult, soovisime välistada 'häireid' vahekomponentides.

Nii, ESNI toe ja HTTP ülemineku korral saime umbes ~ 550 rps ühe instantsi kohta, samal ajal kui keskmine CPU/RAM tarbimine ESNI pöördproksi oli:

  • 80% CPU kasutus (4 vCPU, 4 GB RAM hostid, Linux)
  • 130 MB Mem RSS

Kuidas kaitsta oma avalikku saiti ESNI-ga

Võrdluseks: RPS sama ülemineku nginx-i jaoks ilma TLS-terminatsiooni (HTTP protokoll) ~ 1100:

wrk -t50 -c1000 -d360s 'http://lb.npw:80' –-timeout 15s
Käivitame 6-minutilise testi aadressil http://lb.npw:80
  50 lõime ja 1000 ühendust
  Lõimete statistika  Avg      Stdev     Max    +/- Stdev
    Latentsus     1.11s     2.30s   15.00s   90.94%
    Req/Sec    23.25     13.55   282.00    79.25%
  393093 päringut 6.00 minutiga, 11.35GB loetud
  Soketivead: ühendamine 0, lugemine 0, kirjutamine 0, timeout 9555
  Mitte-2xx või 3xx vastused: 8111
Päringud/s:   1091.62
Ülekanded/s:    32.27MB 

Aegade puudumine viitab sellele, et ressursse on vähe (kasutasime 4 vCPU, 4 GB RAM hoste, Linux), ja tegelikult on potentsiaalne RPS kõrgem (oleme saanud numbreid kuni 2700 RPS võimsamates seadmete puhul).

Kokkuvõtteks märgin, et ESNI tehnoloogia näib olema päris lootustandev. On veel palju avatud küsimusi, näiteks avaliku ESNI võtme ladustamise küsimused DNS-is ja ESNI võtmete rotatsioon – neid küsimusi arutatakse aktiivselt, ja viimane projekti versioon (käesoleva kirjutamise hetkel) ESNI on juba 7.

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster