Исследование механизма блокировки сайтов Ростелекомом и способы ее обхода

В этом посте я приведу небольшое исследование механизма блокировки сайтов Ростелекомом, а также покажу способы ее обхода без применения различных туннелей до сторонних хостов (прокси, vpn и пр.). Вероятно это применимо и к некоторым другим провайдерам.Результат работы блокировкиHTTP-сайты РТ уже некоторое время блокирует по URL, а не по IP.При блокировке в ответ приходит редирект вида 95.167.13.50/? st=0&dt=&rs=, где — IP, к которому подключался браузер, — URL, который он запрашивал. Если просмотреть передаваемый трафик, то становится видно, что перезаписывается лишь начало ответа сервера, остальное остается как есть. Это выглядит примерно так HTTP/1.1 302 Found Connection: close Location: http://95.167.13.50/? st=0&dt=192.237.142.117&rs=grani.ru/

f-8 Transfer-Encoding: chunked Connection: keep-alive

6d7

Грани.Ру: Главное … Реальный ответ сайта HTTP/1.1 200 OK Server: nginx/1.2.1 Date: Sun, 01 Feb 2015 17:34:03 GMT Content-Type: text/html; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive

6d7

Грани.Ру: Главное … Т.е. найдя способ восстановить заголовки, можно обходить блокировку. Очевидно, это не самый доступный способ.Что и как блокируется Очевидно, что блокировки сайтов у РТ на ручном контроле.Не все сайты из реестра блокируются. Как минимум, есть несколько HTTPS-сайтов, которые никак не блокируются.Обычно HTTPS-сайты блокируются по IP, иногда провайдер лезет и в HTTPS, подставляя свой сертификат, в таком случае происходит блокировка по URL.Иногда HTTPS-сайт из реестра блокируется только по HTTP (соответственно по URL, а не по IP) и спокойно доступен по HTTPS.Исследуем глубже В ходе ряда экспериментов были выявлены следующие принципы работы блокировки: В первой строке запроса ищется название HTTP-метода, пробел, URL, пробел или? или /.Реагирует на методы GET, POST, HEAD, DELETE, OPTIONS, TRACE. Метод PUT видимо забыли, его пропускает :) Прочие названия методов тоже пропускает. Названия методов с измененным регистром символов тоже пропускает.Проверка происходит только в первой строке, если в начало запроса вставить пустую строку, то запрос проходит.Если URL равен »/», то ищется только название метода.При добавлении лишнего пробела после названия метода запрос также проходит без проблем, если URL не равен »/».По всей видимости считается, что URL закончился, когда встречаются символы пробел,»?» или »/». Если дописать к URL какой-то иной символ, то запрос проходит. В том числе, если дописать символ перевода строки, т.е. убрать » HTTP/1.1» из запроса. Кодирование URL (urlencode) не помогает преодолеть цензуру, в том числе в разных регистрах. Даже если закодировать начальный слэш (%2F), то запрос блокируется, хотя веб-сервер такого уже не понимает. Далее ищется заголовок Host.Причем ищется в том же пакете.Причем ищется с обязательным соответствием виду «Host: ». Любой лишний символ или изменение регистра названия заголовка (host, HOST) позволяет запросу пройти.Изменение регистра символов самого домена однако не помогает, блокировка срабатывает. Способы обхода Таким образом, приходим к следующим способам обхода: Добавление пустой строки в начало запроса. Не все веб-серверы понимают, в частности nginx не понимает. Добавление пробела перед URL. Это понимают популярные веб-серверы. Однако могут быть проблемы в редких случаях (например как здесь) Добавление какого-то символа после URL. Очевидно, это должен быть какой-то символ, который проигнорирует веб-сервер, но цензурный агрегат решит, что это часть URL. Я не смог найти такого символа. Убрать название протокола и версию (» HTTP/1.1»). В таком случае запрос воспринимается веб-сервером как HTTP/1.0, а в этой версии протокола не было заголовка Host, поэтому со многими сайтами это работать не будет. Отправка URL и Host разными пакетами.Можно просто сначала вызвать send для первой строки запроса (HTTP-метод и URL), а затем обычным образом отправлять остальную часть запроса.Можно добавить какой-то достаточно большой заголовок (порядка 1530 байт, чтобы наверняка заполнить весь пакет) между этими строками.Проблем с веб-серверами в таких случаях не выявлено. Модификация заголовка Host.Можно менять регистр, добавлять пробелы перед доменом и после него.Проблем с веб-серверами в таких случаях не выявлено. Практическая реализация Я выбрал реализацию на базе 3proxy. В его состав входит плагин, который позволяет модифицировать все передаваемые данные на основе регулярных выражений. При этом прокси довольно легкий и нетребовательный, возможна установка на обычный роутер.В соответствии с вышеизложенным наиболее удобными вариантами на практике представляются добавление лишнего заголовка перед Host и модификация заголовка Host. Очевидно, модификация Host предпочтительнее, т.к. не увеличивает размер запроса. Я регулярно использую этот метод для того, чтобы самому решать какую информацию мне можно потреблять.Но вообще оба варианта легко настраиваются: Добавление лишнего заголовка pcre_rewrite cliheader dunno «Host:» «X-Something: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\r\nHost:» Модификация заголовка pcre_rewrite cliheader dunno «Host:» «HOST:» Базовый конфиг # dns-сервера nserver 77.88.8.8 nserver 8.8.8.8 # кэшируем dns nscache 65536 # работе в фоне daemon # подключение плагина, стоит указать полный путь plugin PCREPlugin.ld.so pcre_plugin # одно из правил описанных выше pcre_rewrite … # запуск прокси, опция -a позволяет избавиться от заголовков Forwarded-For и Via proxy -a -p8080

© Habrahabr.ru