zapret v.23

Для чего это надо
-----------------

Обойти блокировки веб сайтов http.

Как это работает
----------------

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

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

Как это реализовать на практике в системе 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 connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:5 -m set --match-set zapret dst -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

nfqws
-----

Эта программа - модификатор пакетов и обработчик очереди NFQUEUE.
Она берет следующие параметры :
 --daemon		; демонизировать прогу
 --qnum=200		; номер очереди
 --wsize=4		; менять tcp window size на указанный размер
 --hostcase		; менять регистр заголовка "Host:" по умолчанию на "host:".
 --hostnospace		; убрать пробел после "Host:" и переместить его в конец значения "User-Agent:" для сохранения длины пакета
 --hostspell=HoST	; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
Параметры манипуляции могут сочетаться в любых комбинациях.

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:".
 --hostspell=HoST	; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
 --hostdot		; добавление точки после имени хоста : "Host: kinozal.tv."
 --hosttab		; добавление табуляции после имени хоста : "Host: kinozal.tv\t"
 --hostnospace		; убрать пробел после "Host:"
 --methodspace		; добавить пробел после метода : "GET /" => "GET  /"
 --methodeol		; добавить перевод строки перед методом  : "GET /" => "\r\nGET  /"
 --unixeol		; конвертировать 0D0A в 0A и использовать везде 0A
 --hostlist=<filename>  ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются. в файле должен быть хост на каждой строке.
			; список читается 1 раз при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
			; для списка РКН может потребоваться система с 128 Mb памяти ! расчитывайте требование RAM для процесса как 3-5 кратный размер файла списка.
			; по сигналу HUP список будет перечитан при следующем принятом соединении
Параметры манипуляции могут сочетаться в любых комбинациях.
Есть исключения : split-pos заменяет split-http-req. hostdot и hosttab взаимоисключающи.

Способы получения списка заблокированных 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 мб памяти ее не хватит, и будут проблемы. В этом случае используйте
следующий скрипт.
get_reestr.sh может использовать мультипоточный ресолвер mdig (собственная разработка) или
стандартный однопоточный dig от bind. При наличии скомпилированного mdig или скопированного в zapret/mdig бинарика
используется он, в противном случае dig.
Реестр РКН уже настолько огромен, что однопоточный ресолв займет вечность, а многопоточный хоть и тоже много времени,
но хотя бы оно конечно. В скрипте можно настроить количество потоков.

3) ipset/get_anizapret.sh. быстро и без нагрузки на роутер получает лист с antizapret.prostovpn.org.

4) ipset/get_combined.sh. для провайдеров, которые блокируют по IP https, а остальное по DPI. IP https заносится в ipset ipban, остальные в ipset zapret.
Поскольку скачивается большой список РКН, требования к месту в /tmp аналогичны 2)

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

5) ipset/get_config.sh. этот скрипт вызывает то, что прописано в переменной GETLIST из файла config
Если переменная не определена, то никаких действий не выполняется.

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

Принудительное обновление ipset выполняет скрипт ipset/create_ipset.sh.
Список РКН уже достиг внушительных размеров в сотни тысяч IP адресов. Поэтому для оптимизации ipset
применяется утилита ip2net. Она берет список отдельных IP адресов и пытается в нем найти подсети максимального размера (от /22 до /30),
в которых заблокировано более 3/4 адресов. ip2net написан на языке C, поскольку операция ресурсоемкая. Иные способы роутер может не потянуть.
Если ip2net скомпилирован или в каталог ip2net скопирован бинарик, то скрипт create_ipset.sh использует ipset типа hash:net, прогоняя список через ip2net.
В противном случае используется ipset типа hash:ip, список загружается как есть.
Соответственно, если вам не нравится ip2net, просто уберите из каталога ip2net бинарик.

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

Фильтрация по именам доменов
----------------------------

Альтернативой ipset является использование tpws со списком доменов.
Список доменов РКН может быть получен скриптом ipset/get_hostlist.sh - кладется в ipset/zapret-hosts.txt.
Этот скрипт автоматически добавляет к списку РКН домены из zapret-hosts-user.txt.
tpws должен запускаться без фильтрации по ipset. Весь трафик http идет через tpws, и он решает нужно ли
применять дурение в зависимости от поля Host: в http запросе.
Это создает повышенную нагрузку на систему.
Сам поиск по доменам работает очень быстро, нагрузка связана с прокачиванием объема данных через процесс.
Вариант хорошо подходит для тех, у кого быстрая система с 128+ Мб памяти и провайдер применяет DPI.

Проверка провайдера
-------------------

Перед настройкой нужно провести исследование какую бяку устроил вам ваш провайдер.

Нужно выяснить не подменяет ли он DNS и какой метод обхода DPI работает.
В этом вам поможет скрипт https://github.com/ValdikSS/blockcheck.

Если DNS подменяется, но провайдер не перехватывает обращения к сторонним DNS, поменяйте DNS на публичный.
Например : 8.8.8.8, 8.8.4.4, 1.1.1.1, 1.0.0.1, 9.9.9.9
Если DNS подменяется и провайдер перехватывает обращения к сторонним DNS, настройте dnscrypt.

Проанализируйте какие методы дурения DPI работают, в соответствии с ними настройте /opt/zapret/config.


Выбор параметров
----------------

Файл /opt/zapret/config используется различными компонентами системы и содержит основные настройки.
Его нужно просмотреть и при необходимости отредактировать.
Выберите MODE :

nfqws_ipset - использовать nfqws для модификации трафика на порт 80 только на IP из ipset "zapret"
nfqws_ipset_https - использовать nfqws для модификации трафика на порты 80 и 443 только на IP из ipset "zapret"
nfqws_all - использовать nfqws для модификации трафика на порт 80 для всех IP
nfqws_all_https - использовать nfqws для модификации трафика на порты 80 и 443 для всех IP
tpws_ipset - использовать tpws для модификации трафика на порт 80 только на IP из ipset "zapret"
tpws_ipset_https - использовать tpws для модификации трафика на порты 80 и 443 только на IP из ipset "zapret"
tpws_all - использовать tpws для модификации трафика на порт 80 для всех IP
tpws_all_https - использовать tpws для модификации трафика на порты 80 и 443 для всех IP
tpws_hostlist - пропускать через tpws весь трафик на порт 80. tpws применяет дурение только к хостам из hostlist.
ipset - только заполнить ipset. ipset может быть применен для заворота трафика на прокси или на VPN
custom - нужно самому запрограммировать запуск демонов в init скрипте и правила iptables

Можно изменить опции дурения, применяемые демонами nfqws и tpws :

NFQWS_OPT="--wsize=3 --hostspell=HOST"
TPWS_OPT_HTTP="--hostspell=HOST --split-http-req=method"
TPWS_OPT_HTTPS="--split-pos=3"

Если ваша система не openwrt и работает как роутер, то нужно раскомментировать параметр SLAVE_ETH и вписать в него
название внутреннего сетевого интерфейса (LAN).

Параметр GETLIST указывает инсталятору install_easy.sh какой скрипт дергать
для обновления списка заблокированных ip или хостов.
Он же вносится в crontab.
Поместите сюда название скрипта, который будете использовать для обновления листов.
Если не нужно, то параметр следует закомментировать.

Пример установки на debian-подобную систему
-------------------------------------------

На debian основано большое количество дистрибутивов linux, включая ubuntu.
Здесь рассматриваются прежде всего Debian 8+ и Ubuntu 16+.
Но с большой вероятностью может сработать и на производных от них.
Главное условие - наличие systemd, apt и нескольких стандартных пакетов в репозитории.

Установить пакеты :
 apt-get update
 apt-get install ipset curl dnsutils git

Скопировать директорию zapret в /opt или скачать через git :
 cd /opt
 git clone https://github.com/bol-van/zapret

Запустить автоинсталятор бинариков. Он сам определит рабочую архитектуру и настроит все бинарики.
 /opt/zapret/install_bin.sh
АЛЬТЕРНАТИВА : зайти в tpws,nfq,ip2net,mdig, в каждом выполнить make. Получите динамические бинарики под вашу ось.

Скопировать скрипт запуска :
 cp /opt/zapret/init.d/sysv/zapret /etc/init.d

Настроить параметры согласно разделу "Выбор параметров".

Принять изменения скрипта в systemd :
 systemctl daemon-reload

Включить автозапуск службы :
 systemctl enable zapret

Удалить старые листы, если они были созданы ранее :
 rm /opt/zapret/ipset/zapret-ip.txt /opt/zapret/ipset/zapret-ip-user.txt /opt/zapret/ipset/zapret-ip-ipban.txt /opt/zapret/ipset/zapret-ip-user-ipban.txt /opt/zapret/ipset/zapret-hosts.txt
По желанию прописать в /opt/zapret/ipset/zapret-hosts-user.txt свои домены.
Выполнить скрипт обновления листа :
 /opt/zapret/ipset/get_config.sh
Зашедулить задание обновления листа :
 crontab -e
 Создать строчку  "0 12 * * */2 /opt/zapret/ipset/get_config.sh"

Запустить службу :
 systemctl start zapret

Попробовать зайти куда-нибудь : http://ej.ru, http://kinozal.tv, http://grani.ru.
Если не работает, то остановить службу zapret, добавить правило в iptables вручную,
запустить nfqws или tpws в терминале под рутом с нужными параметрами.
Пытаться подключаться к заблоченым сайтам, смотреть вывод программы.
Если нет никакой реакции, значит скорее всего указаны неверные параметры или ip назначения нет в ipset.
Если реакция есть, но блокировка не обходится, значит параметры обхода подобраны неверно, или это средство
не работает в вашем случае на вашем провайдере.
Никто и не говорил, что это будет работать везде.
Попробуйте снять дамп в wireshark или "tcpdump -vvv -X host <ip>", посмотрите действительно ли первый
сегмент TCP уходит коротким и меняется ли регистр "Host:".

Шпаргалка по управлению службой :

enable auto start : systemctl enable zapret
disable auto start : systemctl disable zapret
start : sytemctl start zapret
stop : systemctl stop zapret
status, output messages : systemctl status zapret
После изменения /etc/init.d/zapret : systemctl daemon-reload
delete service : systemctl disable zapret ; systemctl stop zapret ; rm /etc/init.d/zapret

Centos 7+, Fedora
-----------------

Centos с 7 версии и более-менее новые федоры построены на systemd.
В качестве пакетного менеджера используется yum.

Установить пакеты :
 yum install -y curl ipset dnsutils git daemonize

Далее все аналогично debian.

OpenSUSE
--------

Новые OpenSUSE основаны на systemd и менеджере пакетов zypper.

Установить пакеты :
 zypper install curl ipset

Далее все аналогично debian.

Простая установка
-----------------

Ты простой юзер ? Не хочешь ни во что вникать, а хочешь нажать и чтобы сразу заработало ?
Пользуешься ubuntu, debian , centos , fedora, opensuse ? Тогда этот вариант для тебя.
Есть шансы, что оно заработает с минимумом усилий. Запусти терминал и в нем вбивай команды :

# su
<введи пароль рута>
# apt-get update
# apt-get install git
# cd /opt
# git clone https://github.com/bol-van/zapret
# zapret/install_easy.sh

Надоело ?

# /opt/zapret/uninstall_easy.sh
# rm -r /opt/zapret

Это самый необходимый миниум действий.
Если zapret уже куда-то был скачан, то можно запустить install_easy.sh прямо оттуда.
Инсталятор сам запросит рута, скопирует файлы куда надо.
Можно даже запускать инсталятор из "проводника" через функцию "запустить в терминале", если
"проводник" такое позволяет.

Для более гибкой настройки перед запуском инсталятора следует выполнить раздел "Выбор параметров".

Эти скрипты будут работать и на других системах на базе systemd при условии, что
systemd собран с поддержкой sysvinit и имеется следующий файл :
/lib/systemd/system-generators/systemd-sysv-generator
ИЛИ
/usr/lib/systemd/system-generators/systemd-sysv-generator
К сожалению, некоторые дистрибутивы имеют systemd без sysvinit support (arch linux).
А так же есть необходимые программы :
ipset
curl
Их можно установить вручную при помощи менеджера пакетов вашей ОС.


Другие linux системы
--------------------

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

Фаерволлы
---------

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

Что делать с openwrt/LEDE
-------------------------

Установить дополнительные пакеты :
opkg update
opkg install iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt ipset curl
(для новых LEDE) opkg install kmod-ipt-raw
(опционально) opkg install bind-tools

ЭКОНОМИЯ МЕСТА :

bind-tools содержит dig (ресолвер dns от bind). он достаточно емкий по занимаемому месту, но mdig его
полностью заменяет. при наличии mdig bind-tools не нужны.
iptables-mod-nfqueue можно выкинуть, если не будем пользоваться nfqws
curl можно выкинуть, если для получения ip листа будет использоваться только get_user.sh
ipset можно выкинуть, если не будем пользоваться ipset-тами, а будем, например, использовать tpws
со списком доменов.

Самая главная трудность - скомпилировать программы на C. Это можно сделать на linux x64 при помощи SDK, который
можно скачать с официального сайта openwrt или LEDE. Но процесс кросс компиляции - это всегда сложности.
Недостаточно запустить make как на традиционной linux системе.
Поэтому в binaries имеются готовые статические бинарики для всех самых распространенных архитектур.
Статическая сборка означает, что бинарик не зависит от типа libc (glibc, uclibc или musl) и наличия установленных so.
Его можно использовать сразу. Лишь бы подходил тип CPU. У ARM и MIPS есть несколько версий.
Скорее всего найдется рабочий вариант. Если нет - вам придется собирать самостоятельно.

Скопировать директорию "zapret" в /opt на роутер.

Запустить автоинсталятор бинариков. Он сам определит рабочую архитектуру и настроит все бинарики.
 /opt/zapret/install_bin.sh

Скопировать скрипт запуска :
 cp /opt/zapret/init.d/openwrt/zapret /etc/init.d

Настроить параметры согласно разделу "Выбор параметров".

Удалить старые листы, если они были созданы ранее :
 rm /opt/zapret/ipset/zapret-ip.txt /opt/zapret/ipset/zapret-ip-user.txt /opt/zapret/ipset/zapret-ip-ipban.txt /opt/zapret/ipset/zapret-ip-user-ipban.txt /opt/zapret/ipset/zapret-hosts.txt
По желанию прописать в /opt/zapret/ipset/zapret-hosts-user.txt свои домены.
Выполнить скрипт обновления листа :
 /opt/zapret/ipset/get_config.sh
Зашедулить задание обновления листа :
 crontab -e
 Создать строчку  "0 12 * * */2 /opt/zapret/ipset/get_config.sh"

Включить автозапуск службы и запустить ее :
 /etc/init.d/zapret enable
 /etc/init.d/zapret start

В зависимости от выбранного в файле config MODE скопировать нужный файл настроек фаервола :
 cp /opt/zapret/init.d/openwrt/firewall.zapret.$MODE /etc/firewall.zapret
Например :
 cp /opt/zapret/init.d/openwrt/firewall.zapret.tpws_ipset_https /etc/firewall.zapret
Проверить была ли создана ранее запись о firewall include :
 uci show firewall | grep firewall.zapret
Если ничего не вывело, значит добавить :
 uci add firewall include
 uci set firewall.@include[-1].path="/etc/firewall.zapret"
 uci set firewall.@include[-1].reload="1"
 uci commit firewall
Перезапустить фаервол :
 fw3 restart
Посмотреть через iptables -nL или через luci вкладку "firewall" появились ли нужные правила.

ЭКОНОМИЯ МЕСТА : если его мало, то можно оставить в директории zapret лишь подкаталог ipset и файл config.
Далее нужно создать подкаталоги с реально используемыми бинариками (ip2net, mdig, tpws, nfq)
и скопировать туда из binaries рабочие executables.
Рекомендуется оставить ip2net и mdig. Из tpws и nfq оставить лишь тот, что был выбран в config.

ЕСЛИ ВСЕ ПЛОХО С МЕСТОМ : тогда берите SDK и собирайте динамические бинарики. они весят меньше.
откажитесь от работы со списком РКН. используйте только get_user.sh

ЕСЛИ СОВСЕМ ВСЕ УЖАСНО С МЕСТОМ : не надо устанавливать дополнительные пакеты через opkg.
оставьте лишь /opt/zapret/tpws/tpws, /opt/zapret/config, /etc/init.d/zapret, /etc/firewall.zapret
используйте MODE=tpws_all или tpws_all_https
такой вариант потребует около 100 кб места и полностью статичен.
отсутствуют любые загрузки, обновления, изменения файлов.
tpws без ipset использует всего лишь DNAT, который есть по умолчанию

СОВЕТ : Покупайте только роутеры с USB. В USB можно воткнуть флэшку и вынести на нее корневую файловую систему
или использовать ее в качестве оверлея. Не надо мучать себя, запихивая незапихиваемое в 8 мб встроенной флэшки.
Для комфортной работы с zapret нужен роутер с 16 Mb встроенной памяти или USB разъемом и 64 (а лучше 128) Mb RAM.
Списки РКН растут, скоро уже и 16 Mb не будет хватать (если уже не).


Простая установка на openwrt
----------------------------

Работает только если у вас на роутере достаточно много места.
Схема примерно такая же, как и на десктопе. Помещаем на роутер /opt/zapret,
выполняем раздел "Выбор параметров", запускаем install_easy.sh

Если места достаточно, можно прямо на роутер установить git и скачать с github :

opkg update
opkg install git-http
mkdir /opt
cd /opt
git clone https://github.com/bol-van/zapret

Для экономии места перед запуском инсталятора читаем комментарии предыдущего раздела.
Простому инсталятору требуется следующий минимум :

config
install_easy.sh
uninstall_easy.sh
install_bin.sh
init.d/openwrt
ipset/*
binaries/<ваша архитектура>/{tpws,nfqws,ip2net,mdig}

Если вы закачаете zapret не в /opt/zapret, а, например, в /tmp, и запустите install_easy.sh оттуда,
то инсталятор сам скопирует только необходимый минимум в /opt/zapret.


Другие прошивки
---------------

Для статических бинариков не имеет значения на чем они запущены : PC, android, приставка, роутер, любой другой девайс.
Подойдет любая прошивка, дистрибутив linux. Статические бинарики запустятся на всем.
Им нужно только ядро с необходимыми опциями сборки или модулями.
Но кроме бинариков в проекте используются еще и скрипты, в которых задействуются некоторые
стандартные программы.

Основные причины почему нельзя просто так взять и установить эту систему на что угодно :
 * отсутствие доступа к девайсу через shell
 * отсутствие рута
 * отсутствие раздела r/w для записи и энергонезависимого хранения файлов
 * отсутствие возможности поставить что-то в автозапуск
 * отсутствие cron
 * недостаток модулей ядра или опций его сборки
 * недостаток модулей iptables (/usr/lib/iptables/lib*.so)
 * недостаток стандартных программ (типа ipset, curl) или их кастрированность (облегченная замена)
 * кастрированный или нестандартный шелл sh

Если в вашей прошивке есть все необходимое, то вы можете адаптировать zapret под ваш девайс в той или иной степени.
Может быть у вас не получится поднять все части системы, однако вы можете хотя бы попытаться
поднять tpws и завернуть на него через -j REDIRECT весь трафик на порт 80.
Если вам есть куда записать tpws, есть возможность выполнять команды при старте, то как минимум
это вы сделать сможете. Скорее всего поддержка REDIRECT в ядре есть. Она точно есть на любом роутере,
на других устройствах под вопросом. NFQUEUE, iptable_raw, ipset на большинстве прошивок отсутствуют из-за ненужности.

Пересобрать ядро или модули для него будет скорее всего достаточно трудно.
Для этого вам необходимо будет по крайней мере получить исходники вашей прошивки.
User mode компоненты могут быть привнесены относительно безболезненно, если есть место куда их записать.
Специально для девайсов, имеющих область r/w, существует проект entware.
Некоторые прошивки даже имеют возможность его облегченной установки через веб интерфейс.
entware содержит репозиторий user-mode компонент, которые устанавливаются в /opt.
С их помощью можно компенсировать недостаток ПО основной прошивки, за исключением ядра.

Подробное описание настроек для других прошивок выходит за рамки данного проекта.

Openwrt является одной из немногих относительно полноценных linux систем для embedded devices.
Она характеризуется следующими вещами, которые и послужили основой выбора именно этой прошивки :
 * полный root доступ к девайсу через shell. на заводских прошивках чаще всего отсутствует, на многих альтернативных есть
 * корень r/w. это практически уникальная особенность openwrt. заводские и большинство альтернативных прошивок
   построены на базе squashfs root (r/o), а конфигурация хранится в специально отформатированной области
   встроенной памяти, называемой nvram.  не имеющие r/w корня системы сильно кастрированы. они не имеют
   возможности доустановки ПО из репозитория без специальных вывертов и заточены в основном
   на чуть более продвинутого, чем обычно, пользователя и управление имеющимся функционалом через веб интерфейс,
   но функционал фиксированно ограничен. альтернативные прошивки как правило могут монтировать r/w раздел
   в какую-то область файловой системы, заводские обычно могут монтировать лишь флэшки, подключенные к USB,
   и не факт, что есть поддержка unix файловых системы. может быть поддержка только fat и ntfs.
 * возможность выноса корневой файловой системы на внешний носитель (extroot) или создания на нем оверлея (overlay)
 * наличие менеджера пакетов opkg и репозитория софта
 * в репозитории есть все модули ядра, их можно доустановить через opkg. ядро пересобирать не нужно.
 * в репозитории есть все модули iptables, их можно доустановить через opkg
 * в репозитории есть огромное количество стандартных программ и дополнительного софта
 * наличие SDK, позволяющего собрать недостающее

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

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

ИНОГДА (но нечасто) работает трюк со сплитом tls handshake на 2 части.
Это можно сделать все теми же средствами. nfqws или tpws с параметром --split-pos.
--split-pos - единственный параметр, который работает на не-HTTP трафике, все остальное работать не будет.
Попробуйте, может вам повезет.

Почему стоит вложиться в покупку VPS
------------------------------------

VPS - это виртуальный сервер. Существует огромное множество датацентров, предлагающих данную услугу.
На VPS могут выполняться какие угодно задачи. От простого веб сайта до навороченной системы собственной разработки.
Можно использовать VPS и для поднятия собственного vpn или прокси.
Сама широта возможных способов применения , распространенность услуги сводят к минимуму возможности
регуляторов по бану сервисов такого типа. Да, если введут белые списки, то решение загнется, но это будет уже другая
реальность, в которой придется изобретать иные решения.
Пока этого не сделали, никто не будет банить хостинги просто потому , что они предоставляют хостинг услуги.
Вы как индивидуум скорее всего никому не нужны. Подумайте чем вы отличаетесь от известного VPN провайдера.
VPN провайдер предоставляет _простую_ и _доступную_ услугу по обходу блокировок для масс.
Этот факт делает его первоочередной целью блокировки. РКН направит уведомление, после отказа сотрудничать
заблокирует VPN. Предоплаченная сумма пропадет.
У регуляторов нет и никогда не будет ресурсов для тотальной проверки каждого сервера в сети.
Возможен китайский расклад, при котором DPI выявляет vpn протоколы и динамически банит IP серверов,
предоставляющих нелицензированный VPN. Но имея знания, голову, вы всегда можете обфусцировать
vpn трафик или применить другие типы VPN, более устойчивые к анализу на DPI или просто менее широкоизвестные,
а следовательно с меньшей вероятностью обнаруживамые регулятором.
У вас есть свобода делать на вашем VPS все что вы захотите, адаптируясь к новым условиям.
Да, это потребует знаний. Вам выбирать учиться и держать ситуацию под контролем, когда вам ничего запретить
не могут, или покориться системе.

VPS можно прибрести в множестве мест. Существуют специализированные на поиске предложений VPS порталы.
Например, вот этот : https://vps.today/
Для персонального VPN сервера обычно достаточно самой минимальной конфигурации, но с безлимитным трафиком или
с большим лимитом по трафику (терабайты). Важен и тип VPS. Openvz подойдет для openvpn, но
вы не поднимете на нем wireguard, ipsec, то есть все, что требует kernel mode.
Для kernel mode требуется тип виртуализации, предполагающий запуск полноценного экземпляра ОС linux
вместе с ядром. Подойдут kvm, xen, hyper-v, vmware. 

По цене можно найти предложения, которые будут дешевле готовой VPN услуги, но при этом вы сам хозяин в своей лавке
и не рискуете попасть под бан регулятора, разве что "заодно" под ковровую бомбардировку с баном миллионов IP.
Кроме того, если вам совсем все кажется сложным, прочитанное вызывает ступор, и вы точно знаете, что ничего
из описанного сделать не сможете, то вы сможете хотя бы использовать динамическое перенаправление портов ssh
для получения шифрованного socks proxy и прописать его в броузер. Знания linux не нужны совсем.
Это вариант наименее напряжный для чайников, хотя и не самый удобный в использовании.
