Сайн уу Хабр, намайг Илья гэдэг, би Exness-ийн платформын багт ажилладаг. Бид бүтээгдэхүүн боловсруулах багийнхаа ашигладаг дэд бүтцийн үндсэн бүрэлдэхүүн хэсгүүдийг боловсруулж хэрэгжүүлдэг.
Энэ нийтлэлд би олон нийтийн вэбсайтуудын дэд бүтцэд шифрлэгдсэн SNI (ESNI) технологийг нэвтрүүлсэн туршлагаасаа хуваалцахыг хүсч байна.
Энэхүү технологийг ашигласнаар олон нийтийн вэбсайттай ажиллахдаа аюулгүй байдлын түвшинг дээшлүүлж, Компанийн баталсан дотоод аюулгүй байдлын стандартыг дагаж мөрдөх болно.
Юуны өмнө, технологи нь стандартчилагдаагүй, одоо ч төсөлд байгаа боловч CloudFlare болон Mozilla үүнийг аль хэдийн дэмжсэн гэдгийг би онцлон хэлмээр байна.
Онол бага байна
ESNI нь TLS гар барих "Клиент Сайн байна уу" зурваст SNI шифрлэх боломжийг олгодог TLS 1.3 протоколын өргөтгөл юм. Client Hello нь ESNI дэмжлэгтэйгээр хэрхэн харагдахыг эндээс харж болно (ердийн SNI-ийн оронд бид ESNI-г хардаг):
ESNI-г ашиглахын тулд танд гурван бүрэлдэхүүн хэсэг хэрэгтэй:
- DNS;
- Үйлчлүүлэгчийн дэмжлэг;
- Сервер талын дэмжлэг.
DNS
Та хоёр DNS бичлэг нэмэх хэрэгтэй - Aболон TXT (TXT бичлэг нь үйлчлүүлэгч SNI-г шифрлэх боломжтой нийтийн түлхүүрийг агуулдаг) - доороос үзнэ үү. Үүнээс гадна дэмжлэг байх ёстой ХА (HTTPS дээр DNS) учир нь боломжтой үйлчлүүлэгчид (доороос харна уу) ЭМГ-гүйгээр ESNI дэмжлэгийг идэвхжүүлдэггүй. Энэ нь логик юм, учир нь ESNI нь бидний хандаж буй нөөцийн нэрийг шифрлэхийг хэлдэг, өөрөөр хэлбэл UDP-ээр DNS-д хандах нь утгагүй юм. Үүнээс гадна хэрэглээ
Одоогоор боломжтой
CloudFlare
А нэвтрэх:
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 бүртгэл, хүсэлтийг загварын дагуу үүсгэнэ _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."
}
Тиймээс, DNS-ийн үүднээс авч үзвэл бид DoH-г (DNSSEC-тэй илүү тохиромжтой) ашиглаж, хоёр оруулга нэмэх хэрэгтэй.
Хэрэглэгчийн дэмжлэг
Хэрэв бид хөтөчийн тухай ярьж байгаа бол яг одоо
Мэдээжийн хэрэг, ESNI нь TLS 1.3-ийн өргөтгөл учраас ESNI-г дэмжихийн тулд TLS 1.3-г ашиглах ёстой.
ESNI дэмжлэгтэйгээр арын хэсгийг турших зорилгоор бид үйлчлүүлэгчийг хэрэгжүүлсэн go, Гэхдээ энэ талаар дараа дэлгэрэнгүй.
Сервер талын дэмжлэг
Одоогоор ESNI-г албан ёсоор дэмждэггүй OpenSSL/BoringSSL-ээр TLS-тэй ажилладаг тул nginx/apache гэх мэт вэб серверүүд дэмжигдээгүй байна.
Тиймээс бид ESNI-г дэмждэггүй TLS 1.3-ийг ESNI-ээр дуусгавар болгох, ESNI-г дэмждэггүй HTTP(S) урсгалыг дээд тал руу чиглүүлэх проксиг дэмжих өөрийн урд талын бүрэлдэхүүн хэсгийг (ESNI урвуу прокси) үүсгэхээр шийдсэн. Энэ нь үндсэн бүрэлдэхүүн хэсгүүдийг өөрчлөхгүйгээр, өөрөөр хэлбэл ESNI-г дэмждэггүй одоогийн вэб серверүүдийг ашиглахгүйгээр технологийг аль хэдийн байгаа дэд бүтцэд ашиглах боломжийг олгодог.
Тодорхой болгохын тулд энд диаграмм байна:
Прокси нь ESNIгүйгээр TLS холболтыг таслах, ESNI-гүй үйлчлүүлэгчдийг дэмжих чадвартай байхаар бүтээгдсэн гэдгийг би тэмдэглэж байна. Мөн дээд урсгалтай харилцах протокол нь 1.3-аас доош TLS хувилбартай HTTP эсвэл HTTPS байж болно (хэрэв дээд урсгал нь 1.3-ыг дэмждэггүй бол). Энэ схем нь хамгийн их уян хатан байдлыг өгдөг.
ESNI дэмжлэгийг хэрэгжүүлэх нь дээр go бид зээлсэн
ESNI түлхүүрүүдийг үүсгэхийн тулд бид ашигласан
Бид Linux (Debian, Alpine) болон MacOS дээр go 1.13 ашиглан уг бүтээцийг туршиж үзсэн.
Үйл ажиллагааны онцлогуудын талаар хэдэн үг хэлье
ESNI урвуу прокси нь Prometheus форматаар хэмжигдэхүүнийг өгдөг, тухайлбал rps, дээд талын хоцролт, хариу код, амжилтгүй/амжилттай TLS гар барих, TLS гар барих хугацаа. Эхлээд харахад энэ нь прокси нь траффикийг хэрхэн зохицуулж байгааг үнэлэхэд хангалттай юм шиг санагдсан.
Мөн бид хэрэглэхийн өмнө ачааллын туршилт хийсэн. Доорх үр дүн:
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
Бид ESNI урвуу прокси ашиглан схемийг харьцуулахын тулд цэвэр чанарын ачааллын туршилт хийсэн. Бид завсрын бүрэлдэхүүн хэсгүүдийн "хөндлөнгөөс" арилгахын тулд орон нутгийн урсгалыг "цутгасан".
Тиймээс, ESNI-ийн дэмжлэг болон HTTP-ээс дээш урсгал руу прокси хийснээр бид ESNI урвуу прокси-ийн дундаж CPU/RAM зарцуулалттай нэг жишээнээс ~550 rps-ийг авсан:
- 80% CPU-ийн хэрэглээ (4 vCPU, 4 GB RAM хост, Linux)
- 130 MB RSS санах ой
Харьцуулбал, TLS (HTTP протокол) дуусгаваргүй ижил nginx-ийн RPS нь ~ 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 ГБ RAM хост, Линукс ашигласан) бөгөөд үнэндээ боломжит RPS илүү өндөр байна (бид илүү хүчирхэг нөөц дээр 2700 RPS хүртэлх тоонуудыг авсан).
Дүгнэж хэлэхэд би тэмдэглэж байна ESNI технологи нь нэлээд ирээдүйтэй харагдаж байна. Олон нээлттэй асуултууд байсаар байна, жишээлбэл, нийтийн ESNI түлхүүрийг DNS-д хадгалах, ESNI түлхүүрүүдийг эргүүлэх зэрэг асуудлууд - эдгээр асуудлууд идэвхтэй хэлэлцэгдэж байгаа бөгөөд ESNI төслийн хамгийн сүүлийн хувилбар (бичих үед) аль хэдийн гарсан байна.
Эх сурвалж: www.habr.com