Sveiki, Habr, mani sauc Iļja, es strādāju Exness platformas komandā. Mēs izstrādājam un ieviešam galvenos infrastruktūras komponentus, ko izmanto mūsu produktu izstrādes komandas.
Šajā rakstā vēlos dalīties pieredzē par šifrētas SNI (ESNI) tehnoloģijas ieviešanu publisko vietņu infrastruktūrā.

Šīs tehnoloģijas izmantošana paaugstinās drošības līmeni, strādājot ar publisku vietni, un atbildīs Sabiedrības pieņemtajiem iekšējās drošības standartiem.
Pirmkārt, vēlos norādīt, ka tehnoloģija nav standartizēta un joprojām ir melnrakstā, bet CloudFlare un Mozilla to jau atbalsta (in ). Tas mūs motivēja šādam eksperimentam.
Mazliet teorija
ESNI ir TLS 1.3 protokola paplašinājums, kas ļauj SNI šifrēt TLS rokasspiediena ziņojumā “Client Hello”. Lūk, kā Client Hello izskatās ar ESNI atbalstu (parastā SNI vietā mēs redzam ESNI):

Lai izmantotu ESNI, jums ir nepieciešami trīs komponenti:
- DNS;
- Klientu atbalsts;
- Servera puses atbalsts.
DNS
Jums jāpievieno divi DNS ieraksti - AUn TXT (TXT ieraksts satur publisko atslēgu, ar kuru klients var šifrēt SNI) - skatiet tālāk. Turklāt ir jābūt atbalstam DoH (DNS, izmantojot HTTPS), jo pieejamie klienti (skatiet tālāk) neiespējo ESNI atbalstu bez DoH. Tas ir loģiski, jo ESNI nozīmē tā resursa nosaukuma šifrēšanu, kuram mēs piekļūstam, tas ir, nav jēgas piekļūt DNS, izmantojot UDP. Turklāt lietošana ļauj aizsargāties pret kešatmiņas saindēšanās uzbrukumiem šajā scenārijā.
Šobrīd pieejams , starp viņiem:
CloudFlare (Pārbaudiet Mana pārlūkprogramma → Šifrēts SNI → Uzziniet vairāk), ka viņu serveri jau atbalsta ESNI, tas ir, CloudFlare serveriem DNS ir vismaz divi ieraksti - A un TXT. Tālāk esošajā piemērā mēs vaicājam Google DNS (izmantojot HTTPS):
А ieraksts:
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 ieraksts, pieprasījums tiek ģenerēts saskaņā ar veidni _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."
}
Tātad, no DNS viedokļa, mums vajadzētu izmantot DoH (vēlams ar DNSSEC) un pievienot divus ierakstus.
Klientu atbalsts
Ja mēs runājam par pārlūkprogrammām, tad šobrīd . Šeit ir norādījumi par ESNI un DoH atbalsta aktivizēšanu FireFox. Kad pārlūkprogramma ir konfigurēta, mums vajadzētu redzēt kaut ko līdzīgu:

lai pārbaudītu pārlūkprogrammu.
Protams, ESNI atbalstam ir jāizmanto TLS 1.3, jo ESNI ir TLS 1.3 paplašinājums.
Lai pārbaudītu aizmugursistēmu ar ESNI atbalstu, mēs ieviesām klientu uz go, Bet par to vairāk vēlāk.
Servera puses atbalsts
Pašlaik ESNI neatbalsta tīmekļa serveri, piemēram, nginx/apache utt., jo tie darbojas ar TLS, izmantojot OpenSSL/BoringSSL, kas oficiāli neatbalsta ESNI.
Tāpēc mēs nolēmām izveidot savu priekšgala komponentu (ESNI reverso starpniekserveri), kas atbalstītu TLS 1.3 izbeigšanu ar ESNI un starpniekservera HTTP(S) trafiku uz augšupstraumi, kas neatbalsta ESNI. Tas ļauj tehnoloģiju izmantot jau esošā infrastruktūrā, nemainot galvenās sastāvdaļas - tas ir, izmantojot pašreizējos tīmekļa serverus, kas neatbalsta ESNI.
Skaidrības labad šeit ir diagramma:

Es atzīmēju, ka starpniekserveris tika izstrādāts ar iespēju pārtraukt TLS savienojumu bez ESNI, lai atbalstītu klientus bez ESNI. Arī saziņas protokols ar augšupeju var būt HTTP vai HTTPS ar TLS versiju, kas ir zemāka par 1.3 (ja augšupējais neatbalsta 1.3). Šī shēma nodrošina maksimālu elastību.
ESNI atbalsta ieviešana gada go aizņēmāmies no . Uzreiz vēlos atzīmēt, ka pati ieviešana ir diezgan nenozīmīga, jo tā ietver izmaiņas standarta bibliotēkā crypto/tls un tāpēc ir nepieciešama “lāpīšana” GOROOT pirms montāžas.
Lai ģenerētu ESNI atslēgas, mēs izmantojām (arī CloudFlare ideja). Šīs atslēgas tiek izmantotas SNI šifrēšanai/atšifrēšanai.
Mēs testējām būvējumu, izmantojot go 1.13 operētājsistēmā Linux (Debian, Alpine) un macOS.
Daži vārdi par darbības īpašībām
ESNI reversais starpniekserveris nodrošina metriku Prometheus formātā, piemēram, rps, augšupvērsto latentuma un atbildes kodus, neveiksmīgus/veiksmīgus TLS rokasspiedienus un TLS rokasspiediena ilgumu. No pirmā acu uzmetiena tas šķita pietiekami, lai novērtētu, kā starpniekserveris apstrādā trafiku.
Pirms lietošanas veicām arī slodzes pārbaudi. Rezultāti zemāk:
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
Mēs veicām tīri kvalitatīvu slodzes testēšanu, lai salīdzinātu shēmu, izmantojot ESNI reverso starpniekserveri un bez tā. Mēs “ielējām” satiksmi lokāli, lai novērstu “traucējumus” starpkomponentos.
Tātad, izmantojot ESNI atbalstu un starpniekserveri uz augšup no HTTP, mēs saņēmām aptuveni 550 rps no vienas instances ar ESNI reversā starpniekservera vidējo CPU/RAM patēriņu:
- 80 % centrālā procesora noslodze (4 vCPU, 4 GB RAM resursdatori, Linux)
- 130 MB atmiņas RSS

Salīdzinājumam, RPS tam pašam nginx augšpus bez TLS (HTTP protokola) pārtraukšanas ir ~ 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
Taimautu klātbūtne norāda uz resursu trūkumu (mēs izmantojām 4 vCPU, 4 GB RAM resursdatorus, Linux), un faktiski potenciālais RPS ir lielāks (jaudīgākiem resursiem mēs saņēmām skaitļus līdz 2700 RPS).
Noslēgumā es atzīmēju ka ESNI tehnoloģija izskatās diezgan daudzsološi. Joprojām ir daudz atklātu jautājumu, piemēram, jautājumi par publiskās ESNI atslēgas glabāšanu DNS un ESNI atslēgu rotāciju - šie jautājumi tiek aktīvi apspriesti, un ESNI projekta jaunākā versija (raksta tapšanas brīdī) jau ir pieejama. .
Avots: www.habr.com
