Hai Habr, nami abdi Ilya, sareng abdi damel di tim platform di Exness. Urang ngamekarkeun jeung nerapkeun komponén infrastruktur inti dipaké ku tim ngembangkeun produk urang.
Dina tulisan ieu, kuring hoyong ngabagi pangalaman kuring dina nerapkeun téknologi SNI (ESNI) énkripsi dina infrastruktur situs wéb umum.

Pamakéan téknologi ieu bakal ningkatkeun tingkat kaamanan nalika damel sareng situs wéb umum sareng saluyu sareng standar kaamanan internal anu diadopsi ku Perusahaan.
Anu mimiti, kuring hoyong nunjukkeun yén téknologi henteu standar sareng masih aya dina draf, kumaha ogé, CloudFlare sareng Mozilla parantos ngadukung éta (dina ). Ieu anu ngamotivasi kami pikeun ngalaksanakeun percobaan sapertos kitu.
Bit téori
ESNI - mangrupa extension kana protokol TLS 1.3 nu ngaktipkeun enkripsi SNI dina "klien Hello" pesen sasalaman TLS. Kieu kumaha Client Hello kalayan dukungan ESNI (gaganti SNI biasa, urang tingali ESNI):

Pikeun ngagunakeun ESNI, tilu komponén diperyogikeun:
- DNS;
- rojongan customer;
- Pangrojong sisi server.
DNS
Anjeun kedah nambihan dua rékaman DNS - Ajeung TXT (Catatan TXT ngandung konci umum nu klien bisa encrypt SNI) - tingali di handap. Sajaba ti éta, kudu aya rojongan DoH (DNS leuwih HTTPS), saprak klien sadia (tempo di handap) teu ngaktipkeun rojongan ESNI tanpa DoH. Ieu logis, saprak ESNI merlukeun enkripsi tina ngaran sumberdaya urang ngakses, hartina teu make akal pikiran pikeun ngakses DNS leuwih UDP. Leuwih ti éta, ngagunakeun ngidinan Anjeun ngajaga ngalawan serangan karacunan cache dina skenario ieu.
Ayeuna aya , diantara aranjeunna:
CloudFlare (Pariksa My Browser → Encrypted SNI → Learn More) yén server maranéhanana geus ngarojong ESNI, hartina server CloudFlare urang boga sahenteuna dua rékaman DNS-A jeung TXT. Dina conto di handap, urang nuju querying Google DNS (ngaliwatan HTTPS):
А entri:
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 rékaman, pamundut dihasilkeun nurutkeun citakan _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."
}
Janten, tina sudut pandang DNS, urang kedah nganggo DoH (preferably sareng DNSSEC) sareng nambihan dua rékaman.
rojongan customer
Lamun urang ngobrol ngeunaan browser, teras di momen . Ieu pitunjuk ngeunaan cara ngaktipkeun dukungan ESNI sareng DoH dina Firefox. Sakali browser geus ngonpigurasi, Anjeun kudu ningali hal kawas kieu:

pikeun mariksa browser.
Tangtosna, TLS 1.3 kedah dianggo pikeun ngadukung ESNI, sabab ESNI mangrupikeun ekstensi pikeun TLS 1.3.
Pikeun kaperluan nguji backend kalawan rojongan ESNI, kami dilaksanakeun klien on go, Tapi nu langkung lengkep ihwal nu engké.
rojongan server-sisi
Ayeuna, ESNI henteu dirojong ku pangladén wéb sapertos nginx/apache, jsb., sabab tiasa dianggo sareng TLS via OpenSSL/BoringSSL, anu henteu sacara resmi ngadukung ESNI.
Ku alatan éta, urang mutuskeun nyieun komponén hareup-tungtung urang sorangan (ESNI reverse proxy) nu bakal ngarojong TLS 1.3 terminasi kalawan ESNI jeung proxy HTTP(S) lalulintas ka server hulu nu teu ngarojong ESNI. Hal ieu ngamungkinkeun urang ngagunakeun téknologi dina infrastruktur anu tos aya tanpa ngarobih komponén inti-nyaéta, ngagunakeun pangladén wéb anu tos aya anu henteu ngadukung ESNI.
Pikeun kajelasan, ieu diagram:

Perhatos yén proxy dirancang kalayan kamampuan pikeun ngeureunkeun sambungan TLS tanpa ESNI, pikeun ngadukung klien tanpa ESNI. Ogé, protokol komunikasi hulu tiasa HTTP atanapi HTTPS sareng versi TLS sahandapeun 1.3 (upami hulu henteu ngadukung 1.3). Desain ieu nyadiakeun kalenturan maksimum.
Palaksanaan rojongan ESNI on go urang injeuman ti Kuring gé nunjuk kaluar langsung yén palaksanaan sorangan rada non-trivial, sabab ngalibatkeun parobahan perpustakaan baku. crypto/tls ku kituna merlukeun "patching" GOROOT saméméh assembly.
Pikeun ngahasilkeun konci ESNI kami dipaké (ogé kreasi CloudFlare). Konci ieu dianggo pikeun énkripsi / ngadekrip SNI.
Мы протестировали сборку с использованием go 1.13 на Linux (Debian, Alpine) и MacOS.
Sababaraha kecap ngeunaan fitur operasional
Proksi sabalikna ESNI nyayogikeun métrik dina format Prometheus, sapertos RPS, latency hulu sareng kode réspon, sasalaman TLS anu gagal/suksés, sareng durasi sasalaman TLS. Dina glance kahiji, ieu sigana cukup keur assessing kumaha proxy handles lalulintas.
Kami ogé ngalaksanakeun tés beban sateuacan dianggo. Hasilna aya di handap:
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
Kami ngalaksanakeun uji beban kualitatif murni pikeun ngabandingkeun setelan sareng sareng tanpa proxy sabalikna ESNI. Urang nyuntik lalulintas lokal pikeun ngaleungitkeun gangguan ti komponén panengah.
Janten, kalayan dukungan ESNI sareng proksi hulu sareng HTTP, kami ngagaduhan sakitar ~ 550 rps tina hiji conto, kalayan rata-rata konsumsi CPU / RAM tina proxy sabalikna ESNI:
- 80% CPU Usage (4 vCPU, 4 GB RAM хосты, Linux)
- 130 MB Mem RSS

Pikeun babandingan, RPS pikeun nginx hulu anu sami tanpa terminasi TLS (protokol HTTP) nyaéta ~ 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
Наличие таймаутов говорит о том, что есть нехватка ресурсов (мы использовали 4 vCPU, 4 GB RAM хосты, Linux), и по факту потенциальный RPS выше (мы получали цифры до 2700 RPS на более мощных ресурсах).
Dina kacindekan, abdi hoyong dicatet yén Téknologi ESNI katingalina cukup ngajangjikeun. Masih seueur patarosan anu kabuka, sapertos nyimpen konci ESNI umum dina DNS sareng muterkeun konci ESNI — masalah ieu nuju dibahas sacara aktip, sareng versi draf panganyarna (dina waktos nyerat) ESNI parantos aya. .
sumber: www.habr.com
