Kuidas kaitsta oma avalikku veebisaiti ESNI-ga

Tere Habr, minu nimi on Ilja, töötan Exnessi platvormimeeskonnas. Arendame välja ja juurutame infrastruktuuri põhikomponente, mida meie tootearendusmeeskonnad kasutavad.

Selles artiklis soovin jagada oma kogemusi krüptitud SNI (ESNI) tehnoloogia rakendamisel avalike veebisaitide infrastruktuuris.

Kuidas kaitsta oma avalikku veebisaiti ESNI-ga

Selle tehnoloogia kasutamine tõstab avaliku veebisaidiga töötamisel turvalisuse taset ja järgib ettevõtte poolt vastu võetud sisemisi turvastandardeid.

Kõigepealt tahan märkida, et tehnoloogia ei ole standarditud ja on alles mustandis, kuid CloudFlare ja Mozilla juba toetavad seda (s mustand01). See ajendas meid selliseks katseks.

Natuke teooriat

ESNI on TLS 1.3 protokolli laiendus, mis võimaldab SNI-krüptimist TLS-i käepigistuse sõnumis "Klient Tere". Client Hello näeb välja ESNI toega (tavalise SNI asemel näeme ESNI-t):

Kuidas kaitsta oma avalikku veebisaiti ESNI-ga

 ESNI kasutamiseks vajate kolme komponenti:

  • DNS; 
  • Klienditugi;
  • Serveripoolne tugi.

DNS

Peate lisama kaks DNS-kirjet – AJa TXT (TXT-kirje sisaldab avalikku võtit, millega klient saab SNI-d krüpteerida) – vt allpool. Lisaks peab olema toetus Kas (DNS HTTPS-i kaudu), kuna saadaolevad kliendid (vt allpool) ei võimalda ESNI tuge ilma DoH-ita. See on loogiline, kuna ESNI eeldab juurdepääsetava ressursi nime krüptimist, see tähendab, et pole mõtet DNS-ile juurde pääseda UDP kaudu. Veelgi enam, kasutamine DNSSEC võimaldab teil selle stsenaariumi korral kaitsta vahemälu mürgistusrünnakute eest.

Hetkel saadaval mitu DoH pakkujat, nende hulgas:

CloudFlare deklareerib (Kontrollige Minu brauserit → Krüpteeritud SNI → Lisateave), et nende serverid juba toetavad ESNI-d, see tähendab, et DNS-i CloudFlare'i serverite jaoks on meil vähemalt kaks kirjet - A ja TXT. Allolevas näites küsime Google DNS-i (üle HTTPS-i): 

А sissekanne:

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 genereeritakse malli järgi _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 peaksime DNS-i vaatenurgast kasutama DoH-i (eelistatavalt koos DNSSEC-iga) ja lisama kaks kirjet. 

Klienditugi

Kui me räägime brauseritest, siis hetkel tugi on rakendatud ainult FireFoxis. see on Siin on juhised ESNI ja DoH toe aktiveerimiseks FireFoxis. Pärast brauseri konfigureerimist peaksime nägema midagi sellist:

Kuidas kaitsta oma avalikku veebisaiti ESNI-ga

Link brauseri kontrollimiseks.

Loomulikult tuleb ESNI toetamiseks kasutada TLS 1.3, kuna ESNI on TLS 1.3 laiendus.

ESNI toega taustaprogrammi testimiseks juurutasime kliendi veebilehel go, Aga sellest lähemalt hiljem.

Serveripoolne tugi

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

Seetõttu otsustasime luua oma esiotsa komponendi (ESNI pöördpuhverserver), mis toetaks TLS 1.3 lõpetamist ESNI-ga ja puhverserveri HTTP(S) liiklust ülesvoolu, mis ESNI-d ei toeta. See võimaldab teil kasutada tehnoloogiat juba olemasolevas infrastruktuuris ilma põhikomponente muutmata – see tähendab kasutada praeguseid veebiservereid, mis ESNI-d ei toeta. 

Selguse huvides on siin diagramm:

Kuidas kaitsta oma avalikku veebisaiti ESNI-ga

Märgin, et puhverserver oli loodud võimalusega katkestada TLS-ühendus ilma ESNI-ta, et toetada kliente ilma ESNI-ta. Samuti võib ülesvooluga sideprotokoll olla kas HTTP või HTTPS TLS-i versiooniga alla 1.3 (kui ülesvoolu ei toeta 1.3). See skeem annab maksimaalse paindlikkuse.

ESNI toetuse rakendamine on go me laenasime CloudFlare. Tahaksin kohe märkida, et juurutamine ise on üsna mittetriviaalne, kuna see hõlmab muudatusi standardses teegis crypto/tls ja seetõttu on vaja "lappimist" GOROOT enne kokkupanekut.

ESNI võtmete genereerimiseks kasutasime esnitool (samuti CloudFlare'i vaimusünnitus). Neid võtmeid kasutatakse SNI krüptimiseks/dekrüpteerimiseks.
Testisime konstruktsiooni versiooniga go 1.13 Linuxis (Debian, Alpine) ja MacOS-is. 

Paar sõna tööfunktsioonide kohta

ESNI pöördpuhverserver pakub Prometheuse-vormingus mõõdikuid, nagu rps, ülesvoolu latentsus- ja vastusekoodid, ebaõnnestunud/edukad TLS-i käepigistused ja TLS-i käepigistuse kestus. Esmapilgul tundus see piisav, et hinnata, kuidas puhverserver liiklust haldab. 

Enne kasutamist tegime ka koormustesti. Tulemused allpool:

wrk -t50 -c1000 -d360s 'https://esni-rev-proxy.npw:443' --timeout 15s
Running 6m test @ https://esni-rev-proxy.npw:443
  50 threads and 1000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.77s     1.21s    7.20s    65.43%
    Req/Sec    13.78      8.84   140.00     83.70%
  206357 requests in 6.00m, 6.08GB read
Requests/sec:    573.07
Transfer/sec:     17.28MB 

Skeemi võrdlemiseks viisime läbi puhtalt kvalitatiivse koormustesti, kasutades ESNI pöördpuhverserverit ja ilma. "Valasime" liikluse lokaalselt, et välistada vahekomponentide "häireid".

Seega saime ESNI toega ja HTTP-st ülesvoolu puhverserveri abil ühest eksemplarist umbes 550 pööret sekundis ESNI pöördpuhverserveri keskmise CPU/RAM-i tarbimisega:

  • 80% protsessori kasutus (4 vCPU, 4 GB RAM-i hostid, Linux)
  • 130 MB mälu RSS

Kuidas kaitsta oma avalikku veebisaiti ESNI-ga

Võrdluseks, sama nginxi ülesvoolu RPS ilma TLS-i (HTTP-protokoll) lõpetamiseta on ~ 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 

Aegumiste olemasolu näitab, et ressursse napib (kasutasime 4 vCPU-d, 4 GB RAM-i hoste, Linuxit) ja tegelikult on potentsiaalne RPS suurem (võimsamatel ressurssidel saime kuni 2700 RPS-i).

Kokkuvõtteks märgin et ESNI tehnoloogia tundub üsna paljulubav. Lahtisi on veel palju küsimusi, näiteks avaliku ESNI võtme DNS-is salvestamise ja ESNI-võtmete pöörlemise küsimused - neid küsimusi arutatakse aktiivselt ning ESNI mustandi uusim versioon (kirjutamise ajal) on juba käes. 7.

Allikas: www.habr.com

Lisa kommentaar