Kuinka suojata julkista verkkosivustoasi ESNI:n avulla

Hei Habr, nimeni on Ilja, työskentelen Exnessin alustatiimissä. Kehitämme ja toteutamme tuotekehitystiimimme käyttämiä infrastruktuurin ydinkomponentteja.

Tässä artikkelissa haluaisin jakaa kokemukseni salatun SNI (ESNI) -tekniikan käyttöönotosta julkisten verkkosivustojen infrastruktuurissa.

Kuinka suojata julkista verkkosivustoasi ESNI:n avulla

Tämän tekniikan käyttö lisää turvallisuustasoa työskennellessäsi julkisen verkkosivuston kanssa ja noudattaa Yhtiön hyväksymiä sisäisiä turvallisuusstandardeja.

Ensinnäkin haluan huomauttaa, että tekniikkaa ei ole standardoitu ja se on vielä luonnoksessa, mutta CloudFlare ja Mozilla tukevat sitä jo ( luonnos01). Tämä motivoi meitä tällaiseen kokeiluun.

Hieman teoria

ESNI on TLS 1.3 -protokollan laajennus, joka sallii SNI-salauksen TLS-kättelyn "Client Hello" -viestissä. Tältä Client Hello näyttää ESNI-tuella (tavallisen SNI:n sijaan näemme ESNI):

Kuinka suojata julkista verkkosivustoasi ESNI:n avulla

 ESNI:n käyttämiseen tarvitaan kolme osaa:

  • DNS; 
  • Asiakastuki;
  • Palvelinpuolen tuki.

DNS

Sinun on lisättävä kaksi DNS-tietuetta - AJa TXT (TXT-tietue sisältää julkisen avaimen, jolla asiakas voi salata SNI:n) - katso alla. Lisäksi pitää olla tukea Doh (DNS HTTPS:n kautta), koska käytettävissä olevat asiakkaat (katso alla) eivät ota ESNI-tukea käyttöön ilman DoH:ta. Tämä on loogista, koska ESNI tarkoittaa käyttämämme resurssin nimen salausta, eli ei ole järkevää käyttää DNS:ää UDP:n kautta. Lisäksi käyttö DNSSEC voit suojautua välimuistin myrkytyshyökkäyksiltä tässä skenaariossa.

Saatavana tällä hetkellä useat DoH-palveluntarjoajat, heidän joukossa:

CloudFlare valtiot (Tarkista My Browser → Encrypted SNI → Lisätietoja), että heidän palvelimensa tukevat jo ESNI:tä, eli DNS:n CloudFlare-palvelimille meillä on vähintään kaksi tietuetta - A ja TXT. Alla olevassa esimerkissä teemme kyselyn Google DNS:stä (HTTPS:n yli): 

А merkintä:

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 tietue, pyyntö luodaan mallin mukaan _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."
}

Joten DNS-näkökulmasta meidän pitäisi käyttää DoH:ta (mieluiten DNSSEC:n kanssa) ja lisätä kaksi merkintää. 

Asiakaspalvelu

Jos puhumme selaimista, niin tällä hetkellä tuki on toteutettu vain FireFoxissa. Täällä Tässä on ohjeet ESNI- ja DoH-tuen aktivoimiseen FireFoxissa. Kun selain on määritetty, meidän pitäisi nähdä jotain tällaista:

Kuinka suojata julkista verkkosivustoasi ESNI:n avulla

Linkki tarkistaaksesi selaimen.

Tietenkin TLS 1.3:a on käytettävä ESNI:n tukemiseen, koska ESNI on TLS 1.3:n laajennus.

ESNI-tuen taustajärjestelmän testaamista varten otimme asiakkaan käyttöön go, Mutta siitä lisää myöhemmin.

Palvelinpuolen tuki

Tällä hetkellä verkkopalvelimet, kuten nginx/apache jne., eivät tue ESNI:tä, koska ne toimivat TLS:n kanssa OpenSSL/BoringSSL:n kautta, jotka eivät virallisesti tue ESNI:tä.

Siksi päätimme luoda oman etupään komponentin (ESNI-käänteinen välityspalvelin), joka tukee TLS 1.3 -päättämistä ESNI:llä ja välityspalvelimen HTTP(S)-liikennettä ylävirtaan, joka ei tue ESNI:tä. Tämä mahdollistaa teknologian käytön jo olemassa olevassa infrastruktuurissa muuttamatta pääkomponentteja - eli käyttämällä nykyisiä verkkopalvelimia, jotka eivät tue ESNI:tä. 

Selvyyden vuoksi tässä on kaavio:

Kuinka suojata julkista verkkosivustoasi ESNI:n avulla

Huomaan, että välityspalvelin on suunniteltu siten, että se pystyy katkaisemaan TLS-yhteyden ilman ESNI:tä, tukemaan asiakkaita ilman ESNI:tä. Myös viestintäprotokolla ylävirran kanssa voi olla joko HTTP tai HTTPS, jonka TLS-versio on pienempi kuin 1.3 (jos ylävirtaan ei tue 1.3:a). Tämä järjestelmä tarjoaa maksimaalisen joustavuuden.

ESNI-tuen käyttöönotto go lainasimme CloudFlare. Haluan heti huomauttaa, että toteutus itsessään on melko ei-triviaali, koska se sisältää muutoksia vakiokirjastoon krypto/tls ja siksi vaatii "paikannuksen" GOROOT ennen kokoonpanoa.

Käytimme ESNI-avaimien luomiseen esnitool (myös CloudFlaren idea). Näitä avaimia käytetään SNI-salaukseen/salauksen purkamiseen.
Testasimme koontiversiota go 1.13:lla Linuxissa (Debian, Alpine) ja MacOS:ssa. 

Muutama sana toiminnallisista ominaisuuksista

ESNI-käänteinen välityspalvelin tarjoaa mittareita Prometheus-muodossa, kuten rps, ylävirran latenssi- ja vastauskoodit, epäonnistuneet/onnistuneet TLS-kättelyt ja TLS-kättelyn kesto. Ensi silmäyksellä tämä vaikutti riittävältä arvioidakseen, kuinka välityspalvelin käsittelee liikennettä. 

Teimme myös kuormitustestauksen ennen käyttöä. Tulokset alla:

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 

Teimme puhtaasti kvalitatiivisen kuormitustestauksen vertaillaksemme järjestelmää käyttämällä ESNI-käänteisvälityspalvelinta ja ilman. "Kaatoimme" liikennettä paikallisesti eliminoidaksemme "häiriöt" välikomponenteissa.

Joten ESNI-tuella ja välityspalvelimella ylävirtaan HTTP:n avulla saimme noin 550 rps yhdestä esiintymästä ESNI-käänteisen välityspalvelimen keskimääräisellä CPU/RAM-kulutuksella:

  • 80 % suorittimen käyttö (4 vCPU, 4 Gt RAM-isännät, Linux)
  • 130 MB muisti RSS

Kuinka suojata julkista verkkosivustoasi ESNI:n avulla

Vertailun vuoksi: RPS samalle nginxille ylävirtaan ilman TLS (HTTP-protokolla) -päätettä 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 

Aikakatkaisujen esiintyminen osoittaa resurssien puutteen (käytimme 4 vCPU:ta, 4 Gt RAM-isäntiä, Linuxia), ja itse asiassa potentiaalinen RPS on suurempi (saimme jopa 2700 RPS:n lukuja tehokkaammilla resursseilla).

Lopuksi huomautan että ESNI-tekniikka näyttää varsin lupaavalta. Vielä on monia avoimia kysymyksiä, esimerkiksi kysymykset julkisen ESNI-avaimen tallentamisesta DNS:ään ja ESNI-avaimien kiertämisestä - näistä asioista keskustellaan aktiivisesti, ja ESNI-luonnoksen uusin versio (kirjoitettaessa) on jo 7.

Lähde: will.com

Lisää kommentti