Tere, Habr, minu nimi on Ilja ja ma töötan Exnessi platvormimeeskonnas. Me arendame ja rakendame põhilisi infrastruktuuri komponente, mida meie tootearendusmeeskonnad kasutavad.
Selles artiklis tahaksin jagada oma kogemust krüpteeritud SNI (ESNI) tehnoloogia rakendamisel avalike veebisaitide infrastruktuuris.

Selle tehnoloogia kasutamine suurendab avaliku veebisaidiga töötamise turvalisuse taset ja vastab ettevõtte poolt vastuvõetud sisemistele turvastandarditele.
Esiteks tahan märkida, et tehnoloogia ei ole standardiseeritud ja on alles mustandijärgus, kuid CloudFlare ja Mozilla toetavad seda juba (sissejuhatuses). ). See ajendas meid sellist katset läbi viima.
Natuke teooriat
ESNI – on TLS 1.3 protokolli laiendus, mis võimaldab krüpteerida SNI-d TLS-i käepigistuse sõnumis "Client Hello". Nii näeb välja ESNI toega Client Hello (tavapärase SNI asemel näeme ESNI-d):

ESNI kasutamiseks on vaja kolme komponenti:
- DNS;
- Klienditugi;
- Serveripoolne tugi.
DNS
Peate lisama kaks DNS-kirjet – AJa TXT (TXT-kirje sisaldab avalikku võtit, millega klient saab SNI-d krüpteerida) – vt allpool. Lisaks peaks olema tugi Kas (DNS HTTPS-i kaudu), kuna saadaolevad kliendid (vt allpool) ei aktiveeri ESNI tuge ilma DoH-ita. See on loogiline, kuna ESNI eeldab meie poolt ligipääsetava ressursi nime krüptimist, st DNS-ile UDP kaudu juurdepääs pole mõttekas. Lisaks, kasutades võimaldab sellisel juhul kaitsta vahemälu mürgitamise rünnakute eest.
Praegu saadaval , nende hulgas:
CloudFlare (Vaata minu brauserit → krüptitud SNI → lisateave), et nende serverid juba toetavad ESNI-d, see tähendab, et CloudFlare'i serverite jaoks on DNS-is vähemalt kaks kirjet - A ja TXT. Allolevas näites taotleme Google DNS-i (HTTPS-i kaudu):
А kirje:
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 kirje, päring genereeritakse malli järgi _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."
}
Seega DNS-i vaatenurgast peaksime kasutama DoH-i (eelistatavalt koos DNSSEC-iga) ja lisama kaks kirjet.
Klienditugi
Kui me räägime brauseritest, siis hetkel . Juhised ESNI ja DoH toe aktiveerimiseks Firefoxis on toodud. Pärast brauseri seadistamist peaksime nägema midagi sellist:

brauseri kontrollimiseks.
Loomulikult tuleb ESNI toetamiseks kasutada TLS 1.3, kuna ESNI on TLS 1.3 laiendus.
ESNI toega taustaprogrammi testimiseks rakendasime kliendi saidil go, Aga sellest lähemalt hiljem.
Serveripoolne tugi
Praegu ei toeta ESNI-d sellised veebiserverid nagu nginx/apache jne, kuna need töötavad TLS-iga OpenSSL/BoringSSL-i kaudu, mis ametlikult ESNI-d ei toeta.
Seepärast otsustasime luua oma esiotsa komponendi (ESNI pöördproksi), mis toetaks TLS 1.3 lõpetamist ESNI-ga ja HTTP(S) liikluse proksimist ülesvoolu, mis ESNI-d ei toeta. See võimaldab tehnoloogiat kasutada juba olemasolevas infrastruktuuris ilma põhikomponente muutmata – st kasutada olemasolevaid veebiservereid, mis ESNI-d ei toeta.
Selguse huvides on siin diagramm:

Tahaksin märkida, et puhverserver on loodud võimalusega lõpetada TLS-ühendus ilma ESNI-ta, et toetada kliente ilma ESNI-ta. Samuti saab ülesvooluga suhtlemise protokolliks olla kas HTTP või HTTPS, mille TLS-i versioon on alla 1.3 (kui ülesvool ei toeta 1.3). See skeem pakub maksimaalset paindlikkust.
ESNI toetuse rakendamine go me laenasime Märgin kohe ära, et teostus ise on üsna mittetriviaalne, kuna see eeldab muudatusi standardteegis. crypto/tls ja seetõttu vajab "lappimist" GOROOT enne kokkupanekut.
ESNI võtmete genereerimiseks kasutasime (samuti CloudFlare'i looming). Neid võtmeid kasutatakse SNI krüpteerimiseks/dekrüpteerimiseks.
Testisime ehitust, kasutades go 1.13 Linux (Debian, Alpine) ja macOS.
Mõned sõnad operatiivsete omaduste kohta
ESNI pöördproksi pakub mõõdikuid Prometheuse vormingus, näiteks rps, ülesvoolu latentsus ja vastusekoodid, ebaõnnestunud/edukad TLS-käepigistused ja TLS-käepigistuse kestus. Esmapilgul tundus see piisav, et hinnata, kuidas proksi liiklust haldab.
Enne kasutamist tegime ka koormustesti. Tulemused on allpool:
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
Skeemi võrdlemiseks ESNI pöördproksiga ja ilma selleta viisime läbi puhtkvalitatiivse koormustesti. Vahekomponentide "häirete" kõrvaldamiseks "valasime" liiklust lokaalselt.
Seega ESNI toe ja HTTP-ga ülesvoolu puhverserveri abil saime ühest eksemplarist umbes ~550 rpm, kusjuures ESNI pöördproksi keskmine protsessori/RAM-i tarbimine oli järgmine:
- 80% protsessori kasutus (4 vCPU-d, 4 GB RAM-i hostid, Linux)
- 130 MB mälu RSS

Võrdluseks, sama nginxi ülesvoolu RPS ilma TLS-terminatsioonita (HTTP-protokoll) on ~ 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
Ajalõppude olemasolu näitab ressursside puudust (kasutasime 4 vCPU-d, 4 GB RAM-i hoste, Linux) ja tegelikult on potentsiaalne RPS suurem (võimsamate ressursside puhul saime näitajaid kuni 2700 RPS).
Kokkuvõtteks tahaksin märkida, et et ESNI tehnoloogia tundub üsna paljutõotav. Paljud küsimused on endiselt lahtised, näiteks avaliku ESNI võtme DNS-is salvestamise ja ESNI võtmete roteerimise küsimused – neid küsimusi arutatakse aktiivselt ja ESNI mustandi uusim versioon (kirjutamise ajal) on juba olemas. .
Allikas: www.habr.com
