Hoe kinne jo jo iepenbiere webside beskermje mei ESNI

Hallo Habr, myn namme is Ilya, ik wurkje yn it platfoarmteam by Exness. Wy ûntwikkelje en implementearje de kearnynfrastruktuerkomponinten dy't ús produktûntwikkelingsteams brûke.

Yn dit artikel wol ik myn ûnderfining diele mei it ymplementearjen fan fersifere SNI (ESNI) technology yn 'e ynfrastruktuer fan iepenbiere websiden.

Hoe kinne jo jo iepenbiere webside beskermje mei ESNI

It gebrûk fan dizze technology sil it nivo fan feiligens ferheegje by it wurkjen mei in iepenbiere webside en foldwaan oan ynterne feiligensnoarmen oannommen troch it bedriuw.

Alderearst wol ik derop wize dat de technology net standerdisearre is en noch yn it ûntwerp is, mar CloudFlare en Mozilla stypje it al (yn konsept01). Dit motivearre ús foar sa'n eksperimint.

In bytsje teory

ESNI is in útwreiding foar it TLS 1.3-protokol dat SNI-fersifering mooglik makket yn it TLS-handshake "Client Hello"-berjocht. Hjir is hoe Client Hello derút sjocht mei ESNI-stipe (ynstee fan 'e gewoane SNI sjogge wy ESNI):

Hoe kinne jo jo iepenbiere webside beskermje mei ESNI

 Om ESNI te brûken, hawwe jo trije komponinten nedich:

  • DNS; 
  • Client stipe;
  • Server side stipe.

DNS

Jo moatte twa DNS-records tafoegje - Aen TXT (It TXT-record befettet de iepenbiere kaai wêrmei de kliïnt SNI kin fersiferje) - sjoch hjirûnder. Dêrneist moat der stipe komme DoH (DNS oer HTTPS) om't beskikbere kliïnten (sjoch hjirûnder) ESNI-stipe net ynskeakelje sûnder DoH. Dit is logysk, om't ESNI fersifering ymplisearret fan 'e namme fan' e boarne dy't wy tagong krije, dat is, it hat gjin sin om tagong te krijen ta DNS fia UDP. Boppedat, it gebrûk DNSSEC kinne jo beskermje tsjin cache fergiftiging oanfallen yn dit senario.

Op it stuit beskikber ferskate DoH-oanbieders, ûnder harren:

CloudFlare ferklearret (Kontrolearje Myn blêder → Fersifere SNI → Mear ynformaasje) dat har servers al ESNI stypje, dat is, foar CloudFlare-tsjinners yn 'e DNS hawwe wy op syn minst twa records - A en TXT. Yn it foarbyld hjirûnder freegje wy Google DNS (oer HTTPS): 

А yngong:

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 record, fersyk wurdt oanmakke neffens in sjabloan _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."
}

Dat, út in DNS-perspektyf, moatte wy DoH brûke (leafst mei DNSSEC) en twa yngongen tafoegje. 

Klanteservice

As wy it oer browsers hawwe, dan op it stuit stipe wurdt allinich yn FireFox ymplementearre. it is Hjir binne ynstruksjes oer hoe't jo ESNI- en DoH-stipe kinne aktivearje yn FireFox. Sadree't de browser is konfigureare, soene wy ​​wat as dit moatte sjen:

Hoe kinne jo jo iepenbiere webside beskermje mei ESNI

link om de browser te kontrolearjen.

Fansels moat TLS 1.3 brûkt wurde om ESNI te stypjen, om't ESNI in útwreiding is foar TLS 1.3.

Foar it doel fan it testen fan 'e backend mei ESNI-stipe, hawwe wy de klant ymplementearre op go, Mar dêr letter mear oer.

Server side stipe

Op it stuit wurdt ESNI net stipe troch webservers lykas nginx/apache, ensfh., Om't se wurkje mei TLS fia OpenSSL/BoringSSL, dy't ESNI net offisjeel stypje.

Dêrom hawwe wy besletten om ús eigen front-end komponint te meitsjen (ESNI reverse proxy), dy't TLS 1.3 beëiniging soe stypje mei ESNI en proxy HTTP(S) ferkear nei de streamop, dy't ESNI net stipet. Hjirmei kinne jo de technology brûke yn in al besteande ynfrastruktuer, sûnder de haadkomponinten te feroarjen - dat is, brûk aktuele webservers dy't ESNI net stypje. 

Foar dúdlikens is hjir in diagram:

Hoe kinne jo jo iepenbiere webside beskermje mei ESNI

Ik merk op dat de proxy is ûntwurpen mei de mooglikheid om in TLS-ferbining sûnder ESNI te beëinigjen, om kliïnten sûnder ESNI te stypjen. Ek kin it kommunikaasjeprotokol mei streamop of HTTP of HTTPS wêze mei in TLS-ferzje leger as 1.3 (as streamop 1.3 net stipet). Dit skema jout maksimale fleksibiliteit.

Ymplemintaasje fan ESNI-stipe op go wy liend fan CloudFlare. Ik wol direkt opmerke dat de ymplemintaasje sels frij net-triviaal is, om't it feroaringen yn 'e standertbibleteek giet krypto/tls en fereasket dêrom "patching" GOROOT foar gearkomste.

Om ESNI-kaaien te generearjen hawwe wy brûkt esnitool (ek it brainchild fan CloudFlare). Dizze kaaien wurde brûkt foar SNI-fersifering / dekodearring.
Wy hawwe de build testen mei go 1.13 op Linux (Debian, Alpine) en MacOS. 

In pear wurden oer operasjonele funksjes

ESNI omkearde proxy leveret metriken yn Prometheus-formaat, lykas rps, streamôfwerts latency en antwurdkoades, mislearre / suksesfolle TLS-handshakes en TLS-handshake-duer. Op it earste each, dit like genôch om te evaluearjen hoe't de proxy omgiet ferkear. 

Wy hawwe ek load testen útfierd foar gebrûk. Resultaten hjirûnder:

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 

Wy hawwe suver kwalitative loadtesten útfierd om it skema te fergelykjen mei ESNI reverse proxy en sûnder. Wy "goaten" ferkear lokaal om "ynterferinsje" yn tuskenkomponinten te eliminearjen.

Dat, mei ESNI-stipe en proxying nei streamop fan HTTP, krigen wy sawat ~ 550 rps fan ien eksimplaar, mei it gemiddelde CPU / RAM-konsumpsje fan ESNI reverse proxy:

  • 80% CPU-gebrûk (4 vCPU, 4 GB RAM-hosts, Linux)
  • 130 MB Mem RSS

Hoe kinne jo jo iepenbiere webside beskermje mei ESNI

Foar fergeliking is RPS foar deselde nginx streamop sûnder TLS (HTTP-protokol) beëiniging ~ 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 

De oanwêzigens fan time-outs jout oan dat der in tekoart oan boarnen is (wy brûkten 4 vCPU, 4 GB RAM hosts, Linux), en eins is de potinsjele RPS heger (wy krigen sifers oant 2700 RPS op machtiger boarnen).

Ta beslút, ik notearje dat ESNI technology sjocht der hiel kânsryk. D'r binne noch in protte iepen fragen, bygelyks de problemen fan it bewarjen fan de iepenbiere ESNI-kaai yn 'e DNS en rotearjende ESNI-kaaien - dizze problemen wurde aktyf besprutsen, en de lêste ferzje fan it ESNI-ûntwerp (op it momint fan skriuwen) is al 7.

Boarne: www.habr.com

Keapje betroubere hosting foar siden mei DDoS-beskerming, VPS VDS-tsjinners 🔥 Keapje betroubere websidehosting mei DDoS-beskerming, VPS VDS-tsjinners | ProHoster