Увядзенне
Сучасныя карпаратыўныя сістэмы фільтрацыі кантэнту, ад такіх знакамітых вытворцаў як Cisco, BlueCoat, FireEye маюць даволі шмат агульнага з больш магутнымі іх субратамі – DPI сістэмамі, якія ўзмоцнена ўкараняюцца на нацыянальным узроўні. Сутнасць працы і тых і іншых у тым, каб ажыццяўляць надгляд уваходнага і выходнага інтэрнэт-трафіка і, на падставе чорных/белых спісаў, прымаць рашэнне аб забароне інтэрнэт-злучэння. А паколькі і тыя, і іншыя ў асновах сваёй працы належаць на падобныя прынцыпы, то і спосабы іх абыходу таксама будуць мець шмат агульнага.
Адной з тэхналогій, якая дазваляе дастаткова эфектыўна абыходзіць як DPI, так і карпаратыўныя сістэмы, з'яўляецца тэхналогія дамен-франтынгу. Яе сутнасць складаецца ў тым, што мы ідзем на заблакаваны рэсурс, прыкрываючыся іншым, публічным даменам, з добрай рэпутацыяй, які загадзя не будзе блакіраваны ніводнай сістэмай, напрыклад google.com.
Аб дадзенай тэхналогіі было напісана ўжо дастаткова шмат артыкулаў і прыведзена шмат прыкладаў. Аднак папулярныя і якія абмяркоўваюцца ў апошні час тэхналогіі DNS-over-HTTPS і encrypted-SNI, а таксама новая версія пратаколу TLS 1.3 даюць магчымасць разгледзець яшчэ адзін варыянт дамен-франтынгу.
Разбіраемся з тэхналогіяй
Спачатку крыху вызначымся з асноўнымі паняццямі, каб ва ўсіх было разуменне who is who і навошта ўсё гэта трэба. Мы згадалі механізм eSNI, праца якога будзе разгледжана далей. Механізм eSNI (encrypted Server Name Indication) - абаронены варыянт SNI, даступны толькі для пратаколу TLS 1.3. Асноўная сутнасць - шыфраваць у тым ліку інфармацыю аб тым, да якога дамену адпраўляецца запыт.
А зараз давайце разгледзім працу механізму eSNI на практыку.
Дапушчальны, у нас ёсць інтэрнэт-рэсурс, які блакуецца сучасным DPI рашэннем (возьмем да прыкладу, знакаміты торэнт-трэкер — rutracker.nl). Пры спробе заходу на сайт торэнт-трэкера - мы бачым стандартную заглушку правайдэра аб тым, што рэсурс блакуецца:
На сайце РКН гэта дамен сапраўды лічыцца ў стоп-лістах:
Пры запыце whois – відаць, што сам дамен «схаваны» за хмарным правайдэрам Cloudflare.
Але ў адрозненне ад «адмыслоўцаў» з РКН, больш тэхнічна падкаваныя супрацоўнікі з білайна (ці навучаныя горкім досведам нашага знакамітага рэгулятара) не сталі тупа баніць сайт па IP-адрасу, а занеслі ў стоп-ліст менавіта даменнае імя. У гэтым лёгка пераканацца, калі паглядзець, якія яшчэ дамены хаваюцца за гэтым жа IP-адрасам, наведаць адзін з іх і ўбачыць, што доступ не заблакаваны:
А як жа гэта атрымліваецца? Якім чынам правайдэрскі DPI даведаецца, на які з даменаў ідзе мой браўзэр, бо ўсе камунікацыі адбываюцца па пратаколе https, а падмены сертыфікатаў https ад білайна мы нібыта пакуль не заўважалі? Ці не празорлівы ён ці за мной ідзе сачэнне?
Паспрабуем адказаць на гэтае пытанне, зірнуўшы на трафік праз wireshark
На скрыншоце відаць, што спачатку браўзэр атрымлівае IP-адрас сервера праз DNS, потым адбываецца стандартнае TCP-поціск рукі з серверам прызначэння, а затым браўзэр спрабуе ўсталяваць ssl-злучэнне з серверам. Для гэтага ён перадае пакет SSL Client Hello, у якім прысутнічае імя зыходнага дамена ў адчыненым выглядзе. Гэтае поле неабходна фронтэнд-серверу cloudflare для таго, каб правільна маршрутызаваць злучэнне. Вось тут-то нас і ловіць правайдэрскі DPI, раздзіраючы наша злучэнне. Пры гэтым мы не атрымліваем ніякай заглушкі ад правайдэра, і бачым стандартную памылку браўзэра як быццам сайт адключаны ці проста не працуе:
Цяпер давайце ўключым механізм eSNI у браўзэры, як гэта напісана ў інструкцыі для
Для гэтага мы адчыняем старонку канфігурацыі Firefox about: config і які актывуецца наступныя налады:
network.trr.mode = 2;
network.trr.uri = https://mozilla.cloudflare-dns.com/dns-query
network.security.esni.enabled = true
Пасля гэтага мы праверым карэктнасць працы налад на сайце cloudflare па
Вуаля. Наш любімы трэкер адкрыўся, без якіх-небудзь VPN і проксі-сервераў. Давайце зараз паглядзім на дамп трафіку ў wireshark, што ж адбылося.
На гэты раз пакет ssl client hello не ўтрымоўвае ў відавочным выглядзе дамен прызначэння, а замест гэтага ў складзе пакета з'явілася новае поле - encrypted_server_name - менавіта тамака і ўтрымоўваецца значэнне rutracker.nl, і расшыфраваць гэтае поле можа толькі фронтэнд сервер cloudflare. А раз так, то правайдэрскаму DPI не застаецца нічога акрамя як умыць рукі і дазволіць такі трафік. А іншых варыянтаў з шыфраваннем і не.
Такім чынам, як працуе тэхналогія ў браўзэры - мы паглядзелі. Цяпер давайце паспрабуем прымяніць яе для больш спецыфічных і цікавых рэчаў. І для пачатку мы навучым той жа curl выкарыстоўваць eSNI для працы з TLS 1.3, а заадно паглядзім, як працуе сам дамен-франтынг на аснове eSNI.
Дамен-франтынг з eSNI
З прычыны таго, што curl для падлучэння па пратаколе https выкарыстоўвае стандартную бібліятэку openssl, найперш нам неабходна забяспечыць падтрымку eSNI менавіта там. У master-галінках openssl падтрымкі eSNI пакуль што няма, таму нам неабходна спампаваць адмысловую галінку openssl, скампіляваць і ўсталяваць яе.
Клануем рэпазітар з гітхаба і кампілюем як звычайна:
$ git clone https://github.com/sftcd/openssl
$ cd openssl
$ ./config
$ make
$ cd esnistuff
$ make
Далей — клануем рэпазітар з curl і канфігуруем яго кампіляцыю з выкарыстаннем нашай сабранай openssl бібліятэкі:
$ cd $HOME/code
$ git clone https://github.com/niallor/curl.git curl-esni
$ cd curl-esni
$ export LD_LIBRARY_PATH=/opt/openssl
$ ./buildconf
$ LDFLAGS="-L/opt/openssl" ./configure --with-ssl=/opt/openssl --enable-esni --enable-debug
Тут важна правільна паказаць усе каталогі, дзе знаходзіцца openssl (у нашым выпадку - гэта /opt/openssl/) і прасачыць, каб працэс канфігурацыі прайшоў без памылак.
У выпадку паспяховай канфігурацыі - мы ўбачым радок:
WARNING: esni ESNI enabled but marked EXPERIMENTAL. Use with caution!
$ make
Пасля паспяховай зборкі пакета мы скарыстаемся адмысловым bash-файлам са складу openssl для налады і запуску curl. Скапіюем яго ў каталог з curl для зручнасці:
cp /opt/openssl/esnistuff/curl-esni
і выканальны тэставы https-запыт на сервер cloudflare, адначасова запісаўшы DNS і TLS пакеты ў Wireshark.
$ ESNI_COVER="www.hello-rkn.ru" ./curl-esni https://cloudflare.com/
У адказе сервера апроч мноства адладкавай-інфармацыі ад openssl і curl мы атрымаем HTTP-адказ з кодам 301 ад cloudflare.
HTTP/1.1 301 Moved Permanently
< Date: Sun, 03 Nov 2019 13:12:55 GMT
< Transfer-Encoding: chunked
< Connection: keep-alive
< Cache-Control: max-age=3600
< Expires: Sun, 03 Nov 2019 14:12:55 GMT
< Location: https://www.cloudflare.com/
што сведчыць аб тым, што наш запыт быў паспяхова дастаўлены да сервера прызначэння, пачуты і апрацаваны.
Цяпер давайце паглядзім на дамп трафіку ў wireshark, г.зн. што ўбачыў у дадзеным выпадку правайдэрскі DPI.
Відаць, што спачатку curl звярнуўся да DNS сервера за публічнымі eSNI ключом для сервера cloudflare – TXT DNS запыт на _esni.cloudflare.com (пакет №13). Затым, выкарыстоўваючы openssl-бібліятэку, curl адправіў TLS 1.3 запыт на сервер cloudflare у якім поле SNI было зашыфравана публічным ключом, атрыманым на папярэднім этапе (пакет №22). Але, акрамя поля eSNI, у складзе SSL-hello пакета было ўстаўлена яшчэ і поле са звычайным – адчыненым SNI, якое мы можам паказаць у адвольным парадку (у дадзеным выпадку –
Дадзенае поле адчыненага SNI ніяк не ўлічвалася пры апрацоўцы серверамі cloudflare і толькі з'яўлялася маскіровачным для правайдэрскага DPI. Сервер cloudflare прыняў наш ssl-hello пакет, расшыфраваў eSNI, дастаў адтуль арыгінальны SNI і апрацаваў яго як ні ў чым не хаджала (зрабіў усё менавіта так, як планавалася пры распрацоўцы eSNI).
Адзінае, завошта ў дадзеным выпадку можна ўчапіцца з пункта гледжання DPI - першасны DNS запыт на _esni.cloudflare.com. Але мы зрабілі DNS запыт адчыненым толькі для таго, каб паказаць, як дадзены механізм працуе знутры.
Каб канчаткова выбіць глебу з-пад ног DPI мы выкарыстоўваем ужо згаданы механізм DNS-over-HTTPS. Невялікае тлумачэнне - DOH - пратакол, які дазваляе абараніцца ад нападу "чалавек пасярэдзіне" за рахунак адпраўкі DNS-запыту па пратаколе HTTPS.
Выканаем запыт паўторна, але ў гэты раз публічныя eSNI ключы мы атрымаем па пратаколе https, а не DNS:
ESNI_COVER="www.hello-rkn.ru" DOH_URL=https://mozilla.cloudflare-dns.com/dns-query ./curl-esni https://cloudflare.com/
Дамп трафіку запыту прадстаўлены на скрыншоце ніжэй:
Відаць, што перш curl звяртаецца да сервера mozilla.cloudflare-dns.com па пратаколе DoH (https злучэнне на сервер 104.16.249.249), каб ад іх атрымаць значэнні public ключоў для шыфравання SNI, а затым ужо да сервера прызначэння, затуляючыся пры гэтым даменам.
Апроч паказанага вышэй DoH рэзалвера mozilla.cloudflare-dns.com мы можам выкарыстоўваць і іншыя папулярныя сэрвісы DoH, напрыклад, ад знакамітай карпарацыі зла.
Выканаем такі запыт:
ESNI_COVER="www.kremlin.ru" DOH_URL=https://dns.google/dns-query ./curl-esni https://rutracker.nl/
І атрымаем адказ:
< HTTP/1.1 301 Moved Permanently
< Date: Sun, 03 Nov 2019 14:10:22 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: __cfduid=da0144d982437e77b0b37af7d00438b1a1572790222; expires=Mon, 02-Nov-20 14:10:22 GMT; path=/; domain=.rutracker.nl; HttpOnly; Secure
< Location: https://rutracker.nl/forum/index.php
< CF-Cache-Status: DYNAMIC
< Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< Server: cloudflare
< CF-RAY: 52feee696f42d891-CPH
У дадзеным выпадку мы звярнуліся на заблакаваны сервер rutracker.nl, выкарыстаўшы пры гэтым DoH-рэзалвер dns.google (тут няма памылкі друку, зараз у знакамітай карпарацыі з'явіўся свой дамен першага ўзроўня) і прычыніліся ўжо іншым даменам, блакаваць які строга забаронена ўсім DPI пад страхам смяротнага пакарання. Па атрыманым адказе можна зразумець, што наш запыт быў удала апрацаваны.
У якасці дадатковай праверкі таго, што правайдэрскі DPI рэагуе на адкрыты SNI, які мы перадаем у якасці прычынення - мы можам выканаць запыт да rutracker.nl прыкрыўшыся якім-небудзь іншым забароненым рэсурсам, напрыклад іншым "добрым" торэнт-трэкерам:
$ ESNI_COVER="rutor.info" DOH_URL=https://dns.google/dns-query ./curl-esni https://rutracker.nl/
Адказу ад сервера мы не атрымаем, т.я. наш запыт будзе заблакаваны DPI-сістэмай.
Невялікае заключэнне да першай часткі
Такім чынам, нам удалося паказаць працаздольнасць eSNI з дапамогай openssl і curl і праверыць працу дамен-франтынгу, заснаванага на eSNI. Такім жа чынам мы можам адаптаваць нашы любімыя інструменты, якія выкарыстоўваюць бібліятэку openssl, для працы "пад прыкрыццём" іншых даменаў. Больш падрабязна пра гэта - у нашых наступных артыкулах.
Крыніца: habr.com