Wéi schützt Dir Är ëffentlech Websäit mat ESNI

Hallo Habr, mäin Numm ass Ilya, ech schaffen am Plattformteam bei Exness. Mir entwéckelen an implementéieren d'Kärinfrastrukturkomponenten déi eis Produktentwécklungsteams benotzen.

An dësem Artikel géif ech gär meng Erfahrung vun der Ëmsetzung vun verschlësselte SNI (ESNI) Technologie an der Infrastruktur vun ëffentleche Websäiten ze deelen.

Wéi schützt Dir Är ëffentlech Websäit mat ESNI

D'Benotzung vun dëser Technologie wäert den Niveau vun der Sécherheet erhéijen wann Dir mat enger ëffentlecher Websäit schafft an entsprécht intern Sécherheetsnormen, déi vun der Firma ugeholl goufen.

Als éischt wëll ech drop hiweisen datt d'Technologie net standardiséiert ass an nach ëmmer am Entworf ass, awer CloudFlare a Mozilla ënnerstëtzen et scho (an Entworf 01). Dëst huet eis fir esou en Experiment motivéiert.

E bësse vun der Theorie

ESNI ass eng Extensioun vum TLS 1.3 Protokoll deen SNI Verschlësselung am TLS Handshake "Client Hallo" Message erlaabt. Hei ass wéi Client Hello mat ESNI Support ausgesäit (amplaz vum üblechen SNI gesi mir ESNI):

Wéi schützt Dir Är ëffentlech Websäit mat ESNI

 Fir ESNI ze benotzen, braucht Dir dräi Komponenten:

  • DNS; 
  • Client Ënnerstëtzung;
  • Server Säit Ënnerstëtzung.

DNS

Dir musst zwee DNS records addéieren - Aan txt (Den TXT Rekord enthält den ëffentleche Schlëssel mat deem de Client SNI verschlëssele kann) - kuckt hei ënnen. Ausserdeem muss et Ënnerstëtzung ginn DoH (DNS iwwer HTTPS) well verfügbare Clienten (kuckt hei ënnen) net ESNI Ënnerstëtzung ouni DoH aktivéieren. Dëst ass logesch, well ESNI implizéiert Verschlësselung vum Numm vun der Ressource déi mir zougoen, dat heescht, et mécht kee Sënn fir Zougang zu DNS iwwer UDP ze kréien. Ausserdeem, d'Benotzung DNSSEC erlaabt Iech géint Cache Vergëftung Attacken an dësem Szenario ze schützen.

Momentan verfügbar verschidde DoH Ubidder, ënnert hinnen:

CloudFlare deklaréiert (Check My Browser → Encrypted SNI → Learn More) datt hir Server scho ESNI ënnerstëtzen, dat heescht, fir CloudFlare Serveren an der DNS hu mir op d'mannst zwee records - A an TXT. Am Beispill hei drënner froe mir Google DNS (iwwer HTTPS): 

А Entrée:

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 Rekord, Ufro gëtt no enger Schabloun generéiert _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."
}

Also, aus enger DNS Perspektiv, sollte mir DoH benotzen (virun allem mat DNSSEC) an zwee Entréen derbäi. 

Client Ënnerstëtzung

Wa mir iwwer Browser schwätzen, dann am Moment Ënnerstëtzung gëtt nëmmen a FireFox implementéiert. et ass Hei sinn Instruktioune wéi Dir ESNI an DoH Support am FireFox aktivéiert. Nodeems de Browser konfiguréiert ass, sollte mir eppes wéi dat gesinn:

Wéi schützt Dir Är ëffentlech Websäit mat ESNI

Link de Browser ze kontrolléieren.

Natierlech muss TLS 1.3 benotzt ginn fir ESNI z'ënnerstëtzen, well ESNI eng Extensioun op TLS 1.3 ass.

Fir den Zweck de Backend mat ESNI Support ze testen, hu mir de Client implementéiert op go, Awer méi iwwer dat spéider.

Server Säit Ënnerstëtzung

De Moment gëtt ESNI net vu Webserver wéi nginx/apache, etc. ënnerstëtzt, well se mat TLS iwwer OpenSSL/BoringSSL schaffen, déi net offiziell ESNI ënnerstëtzen.

Dofir hu mir décidéiert eisen eegene Front-End Komponent (ESNI Reverse Proxy) ze kreéieren, deen TLS 1.3 Terminatioun mat ESNI a Proxy HTTP(S) Traffic op den Upstream ënnerstëtzt, deen net ESNI ënnerstëtzt. Dëst erlaabt d'Technologie an enger scho bestehender Infrastruktur ze benotzen, ouni d'Haaptkomponenten z'änneren - dat ass, aktuell Webserver ze benotzen déi ESNI net ënnerstëtzen. 

Fir Kloerheet, hei ass en Diagramm:

Wéi schützt Dir Är ëffentlech Websäit mat ESNI

Ech bemierken datt de Proxy mat der Fäegkeet entworf gouf eng TLS Verbindung ouni ESNI z'ënnerbriechen, fir Clienten ouni ESNI z'ënnerstëtzen. Och de Kommunikatiounsprotokoll mat Upstream kann entweder HTTP oder HTTPS mat enger TLS Versioun manner wéi 1.3 sinn (wann Upstream net 1.3 ënnerstëtzt). Dëse Schema gëtt maximal Flexibilitéit.

Ëmsetzung vun ESNI Ënnerstëtzung op go mir geléint vun CloudFlare. Ech wëll direkt bemierken datt d'Ëmsetzung selwer zimlech net trivial ass, well et Ännerungen an der Standardbibliothéik implizéiert Krypto/tls an dofir erfuerdert "Patchen" GOROOT virun der Assemblée.

Fir ESNI Schlësselen ze generéieren hu mir benotzt esnitool (och de Brainchild vu CloudFlare). Dës Schlëssele gi fir SNI Verschlësselung / Entschlësselung benotzt.
Mir hunn de Build mat go 1.13 getest Linux (Debian, Alpine) a MacOS. 

E puer Wierder iwwer operationell Funktiounen

ESNI Reverse Proxy liwwert Metriken am Prometheus Format, sou wéi rps, Upstream Latenz & Äntwert Coden, gescheitert / erfollegräich TLS Handshake & TLS Handshake Dauer. Op den éischte Bléck schéngt dëst genuch ze evaluéieren wéi de Proxy de Traffic handhabt. 

Mir hunn och Lasttest virum Gebrauch gemaach. Resultater ënnert:

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 

Mir hunn reng qualitativ Belaaschtungstest gemaach fir de Schema mat ESNI Reverse Proxy ze vergläichen an ouni. Mir hunn den Traffic lokal "gegoss" fir "Interferenz" an Zwëschenkomponenten ze eliminéieren.

Also, mat ESNI Ënnerstëtzung a Proxying op Upstream vum HTTP, hu mir ongeféier ~550 rps vun enger Instanz kritt, mam duerchschnëttleche CPU / RAM Konsum vum ESNI Reverse Proxy:

  • 80% CPU-Auslastung (4 vCPU, 4 GB RAM-Hosten, Linux)
  • 130 MB Mem RSS

Wéi schützt Dir Är ëffentlech Websäit mat ESNI

Zum Verglach, RPS fir deeselwechten Nginx Upstream ouni TLS (HTTP Protokoll) Terminatioun ass ~ 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 

D'Präsenz vun Timeouts weist drop hin, datt et e Manktem u Ressourcen gëtt (mir hunn 4 vCPU, 4 GB RAM Hosts benotzt, Linux), an tatsächlech ass de potenziellen RPS méi héich (mir hunn Zuelen vu bis zu 2700 RPS op méi staark Ressourcen kritt).

Zum Schluss notéieren ech datt d'ESNI Technologie ganz villverspriechend ausgesäit. Et ginn nach vill oppe Froen, zum Beispill, d'Froen vum ëffentlechen ESNI Schlëssel am DNS ze späicheren an ESNI Schlësselen rotéieren - dës Themen ginn aktiv diskutéiert, an déi lescht Versioun vum ESNI Entworf (zu Schreiwen) ass scho 7.

Source: will.com

Kaaft zouverlässeg Hosting fir Site mat DDoS Schutz, VPS VDS Server 🔥 Kaaft zouverléissegt Websäithosting mat DDoS-Schutz, VPS VDS Server | ProHoster