Paano protektahan ang iyong pampublikong website gamit ang ESNI

Kumusta Habr, ang pangalan ko ay Ilya, nagtatrabaho ako sa pangkat ng platform sa Exness. Binubuo at ipinapatupad namin ang mga pangunahing bahagi ng imprastraktura na ginagamit ng aming mga team sa pagbuo ng produkto.

Sa artikulong ito, nais kong ibahagi ang aking karanasan sa pagpapatupad ng naka-encrypt na teknolohiyang SNI (ESNI) sa imprastraktura ng mga pampublikong website.

Paano protektahan ang iyong pampublikong website gamit ang ESNI

Ang paggamit ng teknolohiyang ito ay magpapataas ng antas ng seguridad kapag nagtatrabaho sa isang pampublikong website at sumusunod sa mga panloob na pamantayan ng seguridad na pinagtibay ng Kumpanya.

Una sa lahat, nais kong ituro na ang teknolohiya ay hindi pamantayan at nasa draft pa rin, ngunit sinusuportahan na ito ng CloudFlare at Mozilla (sa burador01). Ito ang nag-udyok sa amin para sa gayong eksperimento.

Isang kaunting teorya

ESNI ay isang extension sa TLS 1.3 protocol na nagbibigay-daan sa SNI encryption sa TLS handshake na "Client Hello" na mensahe. Narito ang hitsura ng Client Hello sa suporta ng ESNI (sa halip na ang karaniwang SNI na nakikita natin sa ESNI):

Paano protektahan ang iyong pampublikong website gamit ang ESNI

 Upang magamit ang ESNI, kailangan mo ng tatlong bahagi:

  • DNS; 
  • Suporta sa kliyente;
  • Suporta sa gilid ng server.

DNS

Kailangan mong magdagdag ng dalawang tala ng DNS – AAt TXT (Ang tala ng TXT ay naglalaman ng pampublikong key kung saan maaaring i-encrypt ng kliyente ang SNI) - tingnan sa ibaba. Bilang karagdagan, dapat mayroong suporta DoH (DNS over HTTPS) dahil hindi pinapagana ng mga available na kliyente (tingnan sa ibaba) ang suporta sa ESNI nang walang DoH. Ito ay lohikal, dahil ang ESNI ay nagpapahiwatig ng pag-encrypt ng pangalan ng mapagkukunan na aming ina-access, iyon ay, walang saysay na i-access ang DNS sa UDP. Bukod dito, ang paggamit DNSSEC nagbibigay-daan sa iyo na protektahan laban sa mga pag-atake ng pagkalason sa cache sa sitwasyong ito.

Kasalukuyang magagamit ilang provider ng DoH, sa kanila:

CloudFlare nagpapahayag (Tingnan ang Aking Browser β†’ Naka-encrypt na SNI β†’ Matuto Nang Higit Pa) na sinusuportahan na ng kanilang mga server ang ESNI, ibig sabihin, para sa mga server ng CloudFlare sa DNS mayroon kaming hindi bababa sa dalawang talaan - A at TXT. Sa halimbawa sa ibaba ni-query namin ang Google DNS (sa HTTPS): 

А entry:

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, ang kahilingan ay nabuo ayon sa isang template _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."
}

Kaya, mula sa pananaw ng DNS, dapat nating gamitin ang DoH (mas mabuti na may DNSSEC) at magdagdag ng dalawang entry. 

Suporta sa Customer

Kung pinag-uusapan natin ang tungkol sa mga browser, sa ngayon Ang suporta ay ipinapatupad lamang sa FireFox. Dito Narito ang mga tagubilin kung paano i-activate ang suporta ng ESNI at DoH sa FireFox. Matapos ma-configure ang browser, dapat nating makita ang isang bagay na tulad nito:

Paano protektahan ang iyong pampublikong website gamit ang ESNI

Link upang suriin ang browser.

Siyempre, dapat gamitin ang TLS 1.3 upang suportahan ang ESNI, dahil ang ESNI ay isang extension sa TLS 1.3.

Para sa layunin ng pagsubok sa backend na may suporta sa ESNI, ipinatupad namin ang kliyente sa go, Ngunit higit pa tungkol diyan mamaya.

Suporta sa gilid ng server

Sa kasalukuyan, ang ESNI ay hindi sinusuportahan ng mga web server tulad ng nginx/apache, atbp., dahil gumagana ang mga ito sa TLS sa pamamagitan ng OpenSSL/BoringSSL, na hindi opisyal na sumusuporta sa ESNI.

Samakatuwid, nagpasya kaming gumawa ng sarili naming front-end na bahagi (ESNI reverse proxy), na susuportahan ang TLS 1.3 na pagwawakas sa ESNI at proxy HTTP(S) na trapiko sa upstream, na hindi sumusuporta sa ESNI. Pinapayagan nito ang teknolohiya na magamit sa isang umiiral nang imprastraktura, nang hindi binabago ang mga pangunahing bahagi - iyon ay, gamit ang kasalukuyang mga web server na hindi sumusuporta sa ESNI. 

Para sa kalinawan, narito ang isang diagram:

Paano protektahan ang iyong pampublikong website gamit ang ESNI

Tandaan ko na ang proxy ay idinisenyo na may kakayahang wakasan ang isang koneksyon sa TLS nang walang ESNI, upang suportahan ang mga kliyente na walang ESNI. Gayundin, ang protocol ng komunikasyon sa upstream ay maaaring HTTP o HTTPS na may bersyon ng TLS na mas mababa sa 1.3 (kung hindi sinusuportahan ng upstream ang 1.3). Nagbibigay ang scheme na ito ng maximum na flexibility.

Pagpapatupad ng suporta sa ESNI sa go hiniram namin CloudFlare. Gusto kong tandaan kaagad na ang mismong pagpapatupad ay medyo hindi mahalaga, dahil nagsasangkot ito ng mga pagbabago sa karaniwang library crypto/tls at samakatuwid ay nangangailangan ng "patching" GOROOT bago ang pagpupulong.

Para makabuo ng mga ESNI key na ginamit namin esnitool (ang brainchild din ng CloudFlare). Ang mga key na ito ay ginagamit para sa SNI encryption/decryption.
Sinubukan namin ang build gamit ang go 1.13 sa Linux (Debian, Alpine) at MacOS. 

Ang ilang mga salita tungkol sa mga tampok sa pagpapatakbo

Nagbibigay ang ESNI reverse proxy ng mga sukatan sa format na Prometheus, gaya ng rps, upstream latency at mga response code, nabigo/matagumpay na TLS handshake at TLS handshake na tagal. Sa unang tingin, ito ay tila sapat upang suriin kung paano pinangangasiwaan ng proxy ang trapiko. 

Nagsagawa din kami ng pagsubok sa pagkarga bago gamitin. Mga resulta sa ibaba:

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 

Nagsagawa kami ng puro qualitative load testing para ikumpara ang scheme gamit ang ESNI reverse proxy at wala. "Ibinuhos" namin ang trapiko nang lokal upang maalis ang "panghihimasok" sa mga intermediate na bahagi.

Kaya, sa suporta ng ESNI at pag-proxy sa upstream mula sa HTTP, nakakuha kami ng humigit-kumulang ~550 rps mula sa isang pagkakataon, na may average na pagkonsumo ng CPU/RAM ng ESNI reverse proxy:

  • 80% Paggamit ng CPU (4 vCPU, 4 GB RAM host, Linux)
  • 130 MB Mem RSS

Paano protektahan ang iyong pampublikong website gamit ang ESNI

Para sa paghahambing, ang RPS para sa parehong nginx upstream na walang TLS (HTTP protocol) na pagwawakas ay ~ 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 

Ang pagkakaroon ng mga timeout ay nagpapahiwatig na may kakulangan ng mga mapagkukunan (gumamit kami ng 4 na vCPU, 4 GB RAM host, Linux), at sa katunayan ang potensyal na RPS ay mas mataas (nakatanggap kami ng mga figure na hanggang 2700 RPS sa mas malakas na mapagkukunan).

Sa konklusyon, tandaan ko mukhang promising ang teknolohiyang ESNI. Marami pa ring bukas na tanong, halimbawa, ang mga isyu sa pag-imbak ng pampublikong ESNI key sa DNS at pag-ikot ng ESNI key - ang mga isyung ito ay aktibong tinatalakay, at ang pinakabagong bersyon ng ESNI draft (sa oras ng pagsulat) ay nasa 7.

Pinagmulan: www.habr.com

Magdagdag ng komento