Как обойти блокировку сайта роcкомнадзором с помощью DPI

Мы прекрассно знаем что цензура это плохо. Но не смотря на старания властей усилить свое влияние в сети, они все также слабы и часто глупы. Мы уже рассказывали как обойти блокировку рутрекера. Сегодня мы познакомим вас с еще одним способом обхода блокировки сайта при помощи технологии обхода DPI(deep packet inspection)

обойти блокировку сайта

У провайдеров в DPI бывают бреши. Они случаются от того, что правила DPI пишут дляобычных пользовательских программ, опуская все возможные случаи, допустимые по стандартам.
Это делается для простоты и скорости. Нет смысла ловить хакеров, которых 0.01%, ведь все равно эти блокировки обходятся довольно просто даже обычными пользователями.

Некоторые DPI не могут распознать http запрос, если он разделен на TCP сегменты.
Например, запрос вида «GET / HTTP/1.1rnHost: kinozal.tv……»
мы посылаем 2 частями : сначала идет «GET «, затем «/ HTTP/1.1rnHost: kinozal.tv…..».
Другие DPI спотыкаются, когда заголовок «Host:» пишется в другом регистре : например, «host:».
Кое-где работает добавление дополнительного пробела после метода : «GET /» => «GET  /» или добавление точки в конце имени хоста : «Host: kinozal.tv.»

[ad name=»Responbl»]

Как реализовать обход б на практике в системе linux

Как заставить систему разбивать запрос на части ? Можно прогнать всю TCP сессию
через transparent proxy, а можно подменить поле tcp window size на первом входящем TCP пакете с SYN,ACK.
Тогда клиент подумает, что сервер установил для него маленький window size и первый сегмент с данными отошлет не более указанной длины. В последующих пакетах мы не будем менять ничего.

Дальнейшее поведение системы по выбору размера отсылаемых пакетов зависит от реализованногов ней алгоритма. Опыт показывает, что linux первый пакет всегда отсылает не более указанной в window size длины, остальные пакеты до некоторых пор шлет не более max(36,указанный_размер).

После некоторого количества пакетов срабатывает механизм window scaling и начинает учитываться фактор скалинга, размер пакетов становится не более max(36,указанный_рамер << scale_factor).

Не слишком изящное поведение, но поскольку на размеры входящик пакетов мы не влияем, а объем принимаемых по http данных обычно гораздо выше объема отсылаемых, то визуально появятся лишь небольшие задержки.

Windows ведет себя в аналогичном случае гораздо более предсказуемо. Первый сегмент уходит указанной длины, дальше window size меняется в зависимости от значения, присылаемого в новых tcp пакетах. То есть скорость почти сразу же восстанавливается до возможного максимума.

Перехватить пакет с SYN,ACK не представляет никакой сложности средствами iptables. Однако, возможности редактирования пакетов в iptables сильно ограничены. Просто так поменять window size стандартными модулями нельзя.
Для этого мы воспользуемся средством NFQUEUE. Это средство позволяет
передавать пакеты на обработку процессам, работающим в user mode.
Процесс, приняв пакет, может его изменить, что нам и нужно.

iptables -t raw -I PREROUTING -p tcp --sport 80 --tcp-flags SYN,ACK SYN,ACK -j NFQUEUE --queue-num 200 --queue-bypass

Будет отдавать нужные нам пакеты процессу, слушающему на очереди с номером 200. Он подменит window size. PREROUTING поймает как пакеты, адресованные самому хосту, так и маршрутизируемые пакеты. То есть решение одинаково работает как на клиенте, так и на роутере. На роутере на базе PC или на базе OpenWRT.
В принципе этого достаточно.

Однако, при таком воздействии на TCP будет небольшая задержка. Чтобы не трогать хосты, которые не блокируются провайдером, можно сделать такой ход.

Создать список заблоченых доменов или скачать его с rublacklist.
Заресолвить все домены в ipv4 адреса. Загнать их в ipset с именем «zapret».
Добавить в правило :

iptables -t raw -I PREROUTING -p tcp --sport 80 --tcp-flags SYN,ACK SYN,ACK -m set --match-set zapret src -j NFQUEUE --queue-num 200 --queue-bypass

Такии образом воздействие будет производиться только на ip адреса, относящиеся к заблокированным сайтам. Список можно обновлять через cron раз в несколько дней.
Если обновлять через rublacklist, то это займет довольно долго. Более часа. Но ресурсов этот процесс не отнимает, так что никаких проблем это не вызовет, особенно, если система работает постоянно.

Если DPI не обходится через разделение запроса на сегменты, то иногда срабатывает изменение «Host:» на «host:». В этом случае нам может не понадобится замена window size, поэтому цепочка PREROUTING нам не нужна. Вместо нее вешаемся на исходящие пакеты в цепочке POSTROUTING :

iptables -t mangle -I POSTROUTING -p tcp --dport 80 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass

В этом случае так же возможны дополнительные моменты. DPI может ловить только первый http запрос, игнорируя последующие запросы в keep-alive сессии. Тогда можем уменьшить нагрузку на проц, отказавшись от процессинга ненужных пакетов.

iptables -t mangle -I POSTROUTING -p tcp --dport 80 -m set --match-set zapret dst -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:5 -j NFQUEUE --queue-num 200 --queue-bypass

Случается так, что провайдер мониторит всю HTTP сессию с keep-alive запросами. В этом случае недостаточно ограничивать TCP window при установлении соединения. Необходимо посылать отдельными TCP сегментами каждый новый запрос. Эта задача решается через полное проксирование трафика через transparent proxy (TPROXY или DNAT). TPROXY не работает с соединениями, исходящими с локальной системы, так что это решение применимо только на роутере. DNAT работает и с локальными соединениеми, но имеется опасность входа в бесконечную рекурсию, поэтому демон запускается под отдельным пользователем, и для этого пользователя отключается DNAT через «-m owner». Полное проксирование требует больше ресурсов процессора, чем манипуляция с исходящими пакетами без реконструкции TCP соединения.

iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to 127.0.0.1:1188
iptables -t nat -I OUTPUT -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to 127.0.0.1:1188

[ad name=»Responbl»]

Использование модификатора пакетов NFQWS

Эта программа — модификатор пакетов и обработчик очереди NFQUEUE.
Она берет следующие параметры :
—daemon        ; демонизировать прогу
 —qnum=200        ; номер очереди
 —wsize=4        ; менять tcp window size на указанный размер
—hostcase        ; менять регистр заголовка «Host:»
Параметры манипуляции могут сочетаться в любых комбинациях.

Использование transparent proxy TPWS

tpws — это transparent proxy.
 —bind-addr        ; на каком адресе слушать. может быть ipv4 или ipv6 адрес. если не указано, то слушает на всех адресах ipv4 и ipv6
—port=<port>        ; на каком порту слушать
 —daemon               ; демонизировать прогу
—user=<username>    ; менять uid процесса
—split-http-req=method|host    ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host
—split-pos=<offset>    ; делить все посылы на сегменты в указанной позиции. Если отсыл длинее 8Kb (размер буфера приема), то будет разделен каждый блок по 8Kb.
—hostcase             ; замена «Host:» => «host:»
—hostdot        ; добавление точки после имени хоста : «Host: kinozal.tv.»
—methodspace        ; добавить пробел после метода : «GET /» => «GET  /»
Параметры манипуляции могут сочетаться в любых комбинациях.
Есть исключение : split-pos заменяет split-http-req.

[ad name=»Responbl»]

Обход блокировки сайтов у конкретных провайдеров.

mns.ru : нужна замена window size на 4
beeline (corbina) : нужна замена регистра «Host:» на протяжении всей http сессии.
dom.ru : нужно проксирование HTTP сессий через tpws с заменой регистра «Host:» и разделение TCP сегментов на хедере «Host:».
Ахтунг ! Домру блокирует все поддомены заблоченого домена. IP адреса всевозможных поддоменов узнать невозможно из реестра
блокировок, поэтому если вдруг на каком-то сайте вылезает блокировочный баннер, то идите в консоль firefox, вкладка network.

Загружайте сайт и смотрите куда идет редирект. Потом вносите домен в zapret-hosts-user.txt. Например, на kinozal.tv имеются 2 запрашиваемых поддомена : s.kinozal.tv и st.kinozal.tv с разными IP адресами.
sknt.ru : проверена работа с tpws с параметром «—split-http-req=method». возможно, будет работать nfqueue, пока возможности проверить нет.

tkt : помогает разделение http запроса на сегменты, настройки mns.ru подходят
ТКТ был куплен ростелекомом, используется фильтрация ростелекома.
Поскольку DPI не отбрасывает входящую сессию, а только всовывает свой пакет, который приходит раньше ответа от настоящего сервера, блокировки так же обходятся без применения «тяжелой артиллерии» следующим правилом :

  iptables -t raw -I PREROUTING -p tcp --sport 80 -m string --hex-string "|0D0A|Location: http://95.167.13.50" --algo bm -j DROP --from 40 --to 200

Ростелеком : см tkt

tiera : сама тиера до последнего ничего не банила. Похоже, что банит вышестоящий оператор, возможно telia. Требуется сплит http запросов в течение всей сессии.

Способы получения списка заблокированных IP

1) Внесите заблокирванные домены в ipset/zapret-hosts-user.txt и запустите ipset/get_user.sh
На выходе получите ipset/zapret-ip-user.txt с IP адресами.

2) ipset/get_reestr.sh получает список доменов от rublacklist и дальше их ресолвит в ip адреса в файл ipset/zapret-ip.txt. В этом списке есть готовые IP адреса, но судя во всему они там в точности в том виде, что вносит в реестр РосКомПозор. Адреса могут меняться, позор не успевает их обновлять, а провайдеры редко банят по IP : вместо этого они банят http запросы с «нехорошим» заголовком «Host:» вне зависимости от IP адреса. Поэтому скрипт ресолвит все сам, хотя это и занимает много времени.

Дополнительное требование — объем памяти в /tmp для сохранения туда скачанного файла, размер которого несколько Мб и продолжает расти. На роутерах openwrt /tmp представляет собой tmpfs , то есть ramdisk.
В случае роутера с 32 мб памяти ее может не хватить, и будут проблемы. В этом случае используйте следующий скрипт.

3) ipset/get_anizapret.sh. быстро и без нагрузки на роутер получает лист с https://github.com/zapret-info .

Все варианты рассмотренных скриптов автоматически создают и заполняют ipset.

Варианты 2 и 3 дополнительно вызывают вариант 1.

На роутерах не рекомендуется вызывать эти скрипты чаще раза за 2 суток, поскольку сохранение идет либо во внутреннюю флэш память роутера, либо в случае extroot — на флэшку. В обоих случаях слишком частая запись может убить флэшку, но если это произойдет с внутренней флэш памятью, то вы просто убьете роутер.

Принудительное обновление ipset выполняет скрипт ipset/create_ipset.sh

Можно внести список доменов в ipset/zapret-hosts-user-ipban.txt. Их ip адреса будут помещены в отдельный ipset «ipban». Он может использоваться для принудительного завертывания всех соединений на прозрачный proxy «redsocks».

Пример обхода блокировки сайта на debian 7

Debian 7 изначально содержит ядро 3.2. Оно не умеет делать DNAT на localhost.
Конечно, можно не привязывать tpws к 127.0.0.1 и заменить в правилах iptables «DNAT 127.0.0.1» на «REDIRECT», но лучше установить более свежее ядро. Оно есть в стабильном репозитории :

 apt-get update
 apt-get install linux-image-3.16

Установить пакеты :

 apt-get update
 apt-get install libnetfilter-queue-dev ipset curl

Скопировать директорию «zapret» в /opt.
Собрать nfqws :

 cd /opt/zapret/nfq
 make

Собрать tpws :

 cd /opt/zapret/tpws
 make

Скопировать /opt/zapret/init.d/debian7/zapret в /etc/init.d.
В /etc/init.d/zapret выбрать пераметр «ISP». В зависимости от него будут применены нужные правила.
Там же выбрать параметр SLAVE_ETH, соответствующий названию внутреннего сетевого интерфейса.
Включить автостарт : chkconfig zapret on
(опционально) Вручную первый раз получить новый список ip адресов : /opt/zapret/ipset/get_antizapret.sh
Зашедулить задание обновления листа :

crontab -e

Создать строчку  «0 12 * * */2 /opt/zapret/ipset/get_antizapret.sh». Это значит в 12:00 каждые 2 дня обновлять список.

Запустить службу : service zapret start
Попробовать зайти куда-нибудь : http://ej.ru, http://kinozal.tv, http://grani.ru.
Если не работает, то остановить службу zapret, добавить правило в iptables вручную,
запустить nfqws в терминале под рутом с нужными параметрами.
Пытаться подключаться к заблоченым сайтам, смотреть вывод программы.
Если нет никакой реакции, значит скорее всего указан неверный номер очереди или ip назначения нет в ipset.

Если реакция есть, но блокировка не обходится, значит параметры обхода подобраные неверно, или это средство не работает в вашем случае на вашем провайдере.

Никто и не говорил, что это будет работать везде.
Попробуйте снять дамп в wireshark или «tcpdump -vvv -X host <ip>», посмотрите действительно ли первый сегмент TCP уходит коротким и меняется ли регистр «Host:».

Пример обхода блокировки сайта на ubuntu 12,14

Имеется готовый конфиг для upstart : zapret.conf. Его нужно скопировать в /etc/init и настроить по аналогии с debian.
Запуск службы : «start zapret»
Останов службы : «stop zapret»
Ubuntu 12 так же, как и debian 7, оснащено ядром 3.2. См замечание в разделе «debian 7″.
[ad name=»Responbl»]

Пример обхода блокировки сайта на ubuntu 16,debian 8

Процесс аналогичен debian 7, однако требуется зарегистрировать init скрипты в systemd после их копирования в /etc/init.d.
install : /usr/lib/lsb/install_initd zapret
remove : /usr/lib/lsb/remove_initd zapret
[ad name=»Responbl»]

Пример обхода блокировки сайта на других linux системах.

Существует несколько основных систем запуска служб : sysvinit, upstart, systemd.
Настройка зависит от системы, используемой в вашем дистрибутиве.
Типичная стратегия — найти скрипт или конфигурацию запуска других служб и написать свой по аналогии, при необходимости почитывая документацию по системе запуска. Нужные команды можно взять из предложенных скриптов.

Настройка файрвола для обхода блокировок сайтов.

Если вы используете какую-то систему управления фаерволом, то она может вступать в конфликт с имеющимся скриптом запуска. В этом случае правила для iptables должны быть прикручены к вашему фаерволу отдельно от скрипта запуска tpws или nfqws.
Именно так решается вопрос в случае с openwrt, поскольку там своя система управления фаерволом.
При повторном применении правил она могла бы поломать настройки iptables, сделанные скриптом из init.d.

Что делать с openwrt для обхода блокировок сайта.

Установить дополнительные пакеты :

opkg update
opkg install iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt ipset curl bind-tools

Самая главная трудность — скомпилировать программы на C.
Это можно сделать средствами кросс-компиляции на любой традиционной linux системе.
Читайте compile/build_howto_openwrt.txt.
Ваша задача — получить ipk файлы для tpws и nfqws.
Скопировать директорию «zapret» в /opt на роутер.
Установить ipk. Для этого сначала копируем на роутер ipk в /tmp, потом

opkg install /tmp/*.ipk.

Смотрим, что появились исполняемые файлы /opt/zapret/tpws/tpws, /opt/zapret/nfq/nfqws.
Скопировать /opt/zapret/init.d/zapret в /etc/init.d.
В /etc/init.d/zapret выбрать пераметр «ISP». В зависимости от него будут применены нужные правила.

/etc/init.d/zapret enable
/etc/init.d/zapret start

В зависимости от вашего провайдера внести нужные записи в /etc/firewall.user.

/etc/init.d/firewall restart

Посмотреть через iptables -L или через luci вкладку «firewall» появились ли нужные правила.

Зашедулить задание обновления листа :

 crontab -e

Создать строчку  «0 12 * * */2 /opt/zapret/ipset/get_antizapret.sh». Это значит в 12:00 каждые 2 дня обновлять список.

Если у вас linux x64, то вместо компиляции toolchain можно использовать пре-компилированный SDK от разработчиков openwrt.
https://downloads.openwrt.org/
Найдите вашу версию openwrt, найдите вашу архитектуру, скачайте файл «OpenWrt-SDK-*».
Фактически это тот же buildroot, только в нем уже подготовлен toolchain для нужной версии openwrt, нужной target архитектуры и хост-системы linux x64.

Прекомпилированые бинарики

Компилировать для роутеров может быть непростой задачей, требующей изучения вопроса и гугления «глюков из коробки» в openwrt SDK.
Нет кое-каких бинариков, нет кое-каких линков, в результате из коробки SDK может выдавать ошибки. Для самых распространенных архитектур собраны статические бинарики. См binaries.

Статическая сборка означает, что бинарик не зависит от типа libc (uclibc или musl) и наличия установленных so — его можно использовать сразу.
Лишь бы подходил тип CPU. У ARM и MIPS есть несколько версий. Если на вашей версии выдаются ошибки при запуске — придется собирать самостоятельно под вашу систему.

[ad name=»Responbl»]

Обход блокировки https

Как правило трюки с DPI не помогают для обхода блокировки https.
Приходится перенаправлять трафик через сторонний хост. Предлагается использовать прозрачный редирект через socks5 посредством iptables+redsocks, либо iptables+iproute+openvpn. Настройка варианта с redsocks на openwrt описана в https.txt.

Все исходники данного способа можно найти тут — https://github.com/bol-van/zapret

Click to rate this post!
[Total: 15 Average: 4.3]

Специалист в области кибер-безопасности. Работал в ведущих компаниях занимающихся защитой и аналитикой компьютерных угроз. Цель данного блога - простым языком рассказать о сложных моментах защиты IT инфраструктур и сетей.

1 comments On Как обойти блокировку сайта роcкомнадзором с помощью DPI

Leave a reply:

Your email address will not be published.