ESNI көмегімен жалпыға қолжетімді веб-сайтты қалай қорғауға болады

Сәлем Хабр, менің атым Илья, мен Exness платформасында жұмыс істеймін. Біз өнімді әзірлеу командалары пайдаланатын негізгі инфрақұрылым құрамдастарын әзірлеп, енгіземіз.

Бұл мақалада мен жалпыға қолжетімді веб-сайттардың инфрақұрылымында шифрланған SNI (ESNI) технологиясын енгізу тәжірибесімен бөліскім келеді.

ESNI көмегімен жалпыға қолжетімді веб-сайтты қалай қорғауға болады

Бұл технологияны пайдалану жалпыға қолжетімді веб-сайтпен жұмыс істеу кезінде қауіпсіздік деңгейін арттырады және Компания қабылдаған ішкі қауіпсіздік стандарттарына сәйкес келеді.

Ең алдымен, технологияның стандартталмағанын және әлі жобада екенін атап өткім келеді, бірақ CloudFlare және Mozilla оны қазірдің өзінде қолдайды (ішінде жоба01). Бұл бізді осындай экспериментке ынталандырды.

Біраз теория

ESNI TLS 1.3 протоколының кеңейтімі болып табылады, ол TLS қол алысу «Клиент Сәлем» хабарында SNI шифрлауға мүмкіндік береді. ESNI қолдауымен Client Hello келесідей көрінеді (әдеттегі SNI орнына біз ESNI көреміз):

ESNI көмегімен жалпыға қолжетімді веб-сайтты қалай қорғауға болады

 ESNI пайдалану үшін сізге үш компонент қажет:

  • DNS; 
  • Клиенттерді қолдау;
  • Сервер жағынан қолдау.

DNS

Сізге екі DNS жазбасын қосу керек - Aмен TXT (TXT жазбасында клиент SNI шифрлай алатын ашық кілт бар) - төменде қараңыз. Сонымен қатар, қолдау болуы керек DoH (HTTPS арқылы DNS), себебі қол жетімді клиенттер (төменде қараңыз) DoHсіз ESNI қолдауын қоспайды. Бұл қисынды, өйткені ESNI біз қатынасатын ресурс атауын шифрлауды білдіреді, яғни UDP арқылы DNS-ке қол жеткізудің мағынасы жоқ. Оның үстіне пайдалану DNSSEC осы сценарийде кэшті улану шабуылдарынан қорғауға мүмкіндік береді.

Қазіргі уақытта қолжетімді бірнеше DoH провайдерлері, олардың ішінде:

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 көмегімен жалпыға қолжетімді веб-сайтты қалай қорғауға болады

байланыс шолғышты тексеру үшін.

Әрине, TLS 1.3 ESNI қолдауы үшін пайдаланылуы керек, өйткені ESNI TLS 1.3 кеңейтімі болып табылады.

ESNI қолдауымен серверді сынау мақсатында біз клиентті іске асырдық go, Бірақ бұл туралы кейінірек.

Сервер жағынан қолдау

Қазіргі уақытта ESNI-ге nginx/apache, т.б. сияқты веб-серверлер қолдау көрсетпейді, өйткені олар ESNI-ді ресми түрде қолдамайтын OpenSSL/BoringSSL арқылы TLS-пен жұмыс істейді.

Сондықтан, біз ESNI-мен TLS 1.3 тоқтатуды және ESNI-ге қолдау көрсетпейтін жоғары ағынға HTTP(S) прокси трафигін қолдайтын өзіміздің жеке алдыңғы компонентті (ESNI кері прокси) жасауды шештік. Бұл технологияны негізгі құрамдастарды өзгертпей, яғни ESNI қолдамайтын ағымдағы веб-серверлерді пайдаланбай, бұрыннан бар инфрақұрылымда пайдалануға мүмкіндік береді. 

Түсінікті болу үшін мына диаграмма:

ESNI көмегімен жалпыға қолжетімді веб-сайтты қалай қорғауға болады

Прокси TLS қосылымын ESNIсыз тоқтату, 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 rpps алдық:

  • 80% CPU пайдалану (4 vCPU, 4 ГБ жедел жады хосттары, Linux)
  • 130 МБ жад 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 ГБ жедел жады хосттары, Linux пайдаландық) және шын мәнінде әлеуетті RPS жоғарырақ (біз қуатты ресурстарда 2700 RPS-ке дейінгі сандарды алдық).

Қорытындылай келе, атап өтемін бұл ESNI технологиясы өте перспективалы болып көрінеді. Көптеген ашық сұрақтар бар, мысалы, DNS жүйесінде ашық ESNI кілтін сақтау және ESNI кілттерін айналдыру мәселелері - бұл мәселелер белсенді түрде талқылануда және ESNI жобасының соңғы нұсқасы (жазу кезінде) қазірдің өзінде 7.

Ақпарат көзі: www.habr.com

пікір қалдыру