ESNI ашиглан олон нийтийн вэбсайтаа хэрхэн хамгаалах вэ

Сайн уу Хабр, намайг Илья гэдэг, би Exness-ийн платформын багт ажилладаг. Бид бүтээгдэхүүн боловсруулах багийнхаа ашигладаг дэд бүтцийн үндсэн бүрэлдэхүүн хэсгүүдийг боловсруулж хэрэгжүүлдэг.

Энэ нийтлэлд би олон нийтийн вэбсайтуудын дэд бүтцэд шифрлэгдсэн SNI (ESNI) технологийг нэвтрүүлсэн туршлагаасаа хуваалцахыг хүсч байна.

ESNI ашиглан олон нийтийн вэбсайтаа хэрхэн хамгаалах вэ

Энэхүү технологийг ашигласнаар олон нийтийн вэбсайттай ажиллахдаа аюулгүй байдлын түвшинг дээшлүүлж, Компанийн баталсан дотоод аюулгүй байдлын стандартыг дагаж мөрдөх болно.

Юуны өмнө, технологи нь стандартчилагдаагүй, одоо ч төсөлд байгаа боловч CloudFlare болон Mozilla үүнийг аль хэдийн дэмжсэн гэдгийг би онцлон хэлмээр байна. төсөл 01). Энэ нь биднийг ийм туршилт хийхэд түлхэц өгсөн.

Онол бага байна

ESNI нь TLS гар барих "Клиент Сайн байна уу" зурваст SNI шифрлэх боломжийг олгодог TLS 1.3 протоколын өргөтгөл юм. Client Hello нь ESNI дэмжлэгтэйгээр хэрхэн харагдахыг эндээс харж болно (ердийн SNI-ийн оронд бид ESNI-г хардаг):

ESNI ашиглан олон нийтийн вэбсайтаа хэрхэн хамгаалах вэ

 ESNI-г ашиглахын тулд танд гурван бүрэлдэхүүн хэсэг хэрэгтэй:

  • DNS; 
  • Үйлчлүүлэгчийн дэмжлэг;
  • Сервер талын дэмжлэг.

DNS

Та хоёр DNS бичлэг нэмэх хэрэгтэй - Aболон TXT (TXT бичлэг нь үйлчлүүлэгч SNI-г шифрлэх боломжтой нийтийн түлхүүрийг агуулдаг) - доороос үзнэ үү. Үүнээс гадна дэмжлэг байх ёстой ХА (HTTPS дээр DNS) учир нь боломжтой үйлчлүүлэгчид (доороос харна уу) ЭМГ-гүйгээр ESNI дэмжлэгийг идэвхжүүлдэггүй. Энэ нь логик юм, учир нь ESNI нь бидний хандаж буй нөөцийн нэрийг шифрлэхийг хэлдэг, өөрөөр хэлбэл UDP-ээр DNS-д хандах нь утгагүй юм. Үүнээс гадна хэрэглээ DNSSEC Энэ хувилбарт кэшийн хордлогын халдлагаас хамгаалах боломжийг танд олгоно.

Одоогоор боломжтой хэд хэдэн ЭМГ үйлчилгээ үзүүлэгчид, тэдгээрийн дотор:

CloudFlare тунхаглаж байна (Миний хөтчийг шалгана уу → Шифрлэгдсэн SNI → Илүү ихийг мэдэж аваарай) тэдний серверүүд ESNI-г аль хэдийн дэмждэг, өөрөөр хэлбэл DNS дахь CloudFlare серверүүдийн хувьд бид дор хаяж хоёр бүртгэлтэй байдаг - A ба TXT. Доорх жишээнд бид Google DNS (HTTPS-ээр) асуудаг. 

А нэвтрэх:

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-тэй илүү тохиромжтой) ашиглаж, хоёр оруулга нэмэх хэрэгтэй. 

Хэрэглэгчийн дэмжлэг

Хэрэв бид хөтөчийн тухай ярьж байгаа бол яг одоо дэмжлэгийг зөвхөн FireFox дээр хэрэгжүүлдэг. энд FireFox дээр ESNI болон DoH дэмжлэгийг хэрхэн идэвхжүүлэх тухай зааврыг эндээс үзнэ үү. Хөтөчийг тохируулсны дараа бид дараах зүйлийг харах болно.

ESNI ашиглан олон нийтийн вэбсайтаа хэрхэн хамгаалах вэ

холбоос хөтөчийг шалгахын тулд.

Мэдээжийн хэрэг, 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 ашиглан олон нийтийн вэбсайтаа хэрхэн хамгаалах вэ

Прокси нь ESNIгүйгээр TLS холболтыг таслах, ESNI-гүй үйлчлүүлэгчдийг дэмжих чадвартай байхаар бүтээгдсэн гэдгийг би тэмдэглэж байна. Мөн дээд урсгалтай харилцах протокол нь 1.3-аас доош TLS хувилбартай HTTP эсвэл HTTPS байж болно (хэрэв дээд урсгал нь 1.3-ыг дэмждэггүй бол). Энэ схем нь хамгийн их уян хатан байдлыг өгдөг.

ESNI дэмжлэгийг хэрэгжүүлэх нь дээр go бид зээлсэн CloudFlare. Стандарт номын санд өөрчлөлт оруулдаг тул хэрэгжилт нь өөрөө маш энгийн зүйл биш гэдгийг би нэн даруй тэмдэглэхийг хүсч байна. крипто/тлс Тиймээс "засвар хийх" шаардлагатай ГОРООТ угсралтын өмнө.

ESNI түлхүүрүүдийг үүсгэхийн тулд бид ашигласан esnitool (мөн CloudFlare-ийн санаа юм). Эдгээр түлхүүрүүдийг SNI шифрлэлт/шифр тайлахад ашигладаг.
Бид 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 санах ой

ESNI ашиглан олон нийтийн вэбсайтаа хэрхэн хамгаалах вэ

Харьцуулбал, 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 төслийн хамгийн сүүлийн хувилбар (бичих үед) аль хэдийн гарсан байна. 7.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх