Zapret: what's new

Исправлен существенный косяк blockcheck.
На curl, собранном с использованием версии openssl с quic (quictls), библиотека не определялась как openssl и не включался параметр tls-max.
Поэтому все запросы шли реально на tls1.3, что давало искаженную картину.

Добавлен специфический seqovl тест на подсовывание полного ClientHello от iana.org. Аналог fake,split2 , только в одном флаконе.
ТСПУ отстает от такого TLS 1.2 запроса, не проверяя ответ сервера, и поэтому не нужен --wssize , снижающий скорость

- checking nfqws --dpi-desync=split2 --dpi-desync-split-seqovl=1 --dpi-desync-split-pos=2
curl: (35) Recv failure: Connection reset by peer
UNAVAILABLE code=35
- checking nfqws --dpi-desync=split2 --dpi-desync-split-seqovl=336 --dpi-desync-split-seqovl-pattern=/opt/zapret/files/fake/tls_clienthello_iana_org.bin
!!!!! AVAILABLE !!!!!

336 потому, что остаток до 517 байт заполнен нулями. ТСПУ их игнорирует. У нас же пойдет начало реального запроса вместо нулей. По умолчанию 2 байта.

В zapret-win-bundle еще косяк. Не положил files/fake. Из-за этого все тесты, их использующие, не работали.
/bin/sh был копией /bin/bash. Заменено на dash. dash в несколько раз быстрее bash. blockcheck стал бегать повеселее

В winws в добавок к ssid-filter сделан NLM filter.

--nlm-filter=net1[,net2,net3,...] ; включать winws только когда подключена любая из указанных сетей NLM
--nlm-list[=all] ; вывести список сетей NLM. по умолчанию только подключенных, all - всех.

–nlm-filter аналогичен --ssid-filter, но работает с именами или GUIDами сетей Network List Manager (NLM). Это те сети, которые вы видите в панели управления в разделе “Центр управления сетями и общим доступом”. Под сетью подразумевается не конкретный адаптер, а именно сетевое окружение конкретного подключения. Обычно проверяется mac адрес шлюза. К сети можно подключиться через любой адаптер, и она останется той же самой. Если подключиться, допустим, к разными роутерам по кабелю, то будут разные сети. А если к одному роутеру через 2 разных сетевых карточки на том же компе - будет одна сеть. NLM абстрагирует типы сетевых адаптеров. Он работает как с wifi, так и с ethernet и любыми другими. Поэтому это более универсальный метод, чем ssid фильтр.

В режим autohostlist внесен дополнительный механизм избегания ложных срабатываний.
Раньше чтобы добавить в лист домен нужно было, чтобы он фейлился столько-то раз на протяжении такого-то времени. При этом могло быть так. Плохо, хорошо, плохо, хорошо, хорошо, плохо. Это вызывало попадание в лист. Сейчас “хорошо” сразу же сбрасывает счетчик “плохо”. Цель - обнаружить постоянное “плохо”. Если оно через раз, значит либо это проблемы самого сайта (перегруз, например), либо ваша стратегия обхода неустойчива.
Работает и в nfqws, и в tpws.
Под “хорошо” понимается прием любых данных от сервера, не содержащих http redirect на другой домен (заглушку), либо отсыл любого пакета с sequence number, выходящим за пределы TLS ClientHello (то есть процесс пошел дальше, значит клиент принял что-то от сервера, и это уже не затык на DPI)

В blockcheck сделана корректная зачистка при обрыве терминала. Например, отвалился ssh.

Из git удалены все изменяемые файлы. Это config, init.d/{macos,sysv,openwrt}/custom, ipset/zapret-hosts-user*.txt
Они переименованы с расширением .default.
Инсталятор если увидит отсутствие этих файлов скопирует их с .default
blockcheck скопирует только config
zapret-hosts-user-ipban.txt и zapret-hosts-user.txt удалены. они заполняются кодом в инсталяторе.

Это сделано чтобы можно было не парясь накатывать файлы поверх имеющейся инсталяхи или делать git pull не парясь о нестыковках.

Распространенная проблема, связанная с ютубе,

Чел сканирует блокчеком, находит стратегию с TTL. Она обходит большинство заблокированных ресурсов.
Чел добавляет googlevideo.com. Он ломается.
Догадайтесь почему. <вступает в силу необходимость понимать что пишешь, а не копировать>

Спойлер

Все дело в том, что GGC ставятся поближе к провайдеру и часто имеют длину пути ниже указанного в стратегии. Фейки доходят до сервера и ломают сеанс.
Решение - добавить ограничитель. Наиболее совместимый - --dpi-desync-fooling=md5sig
Если у вас работает --dpi-desync-fooling=datanoack, то можно избавиться от TTL полностью.
Он вероятно не будет работать через домашний роутер, но может работать с него.

другая возможная причина тупняка - не настроен обход quic
да, quic они тоже замедляют. работает --dpi-desync=fake.
его нельзя сочетать с ttl.
возможно, какие-то ТСПУ еще не научились разбирать kyber quic, потому на них дефолтный хроме может обходить замедление сам по себе. потому в сети ходит противоречивая инфа то включать quic, то выключать. GDPI quic не поддерживает.
так же известно, что у ТСПУ исторически были проблемы с пакетами quic от разных библиотек разных версий. и на протяжении истории это менялось. они что-то доделывали.
с zapret-ом , наверно, лучше все-же сделать fake на quic. хуже не станет. и kyber тоже поддерживается

Еще немного наблюдений по поводу обхода замедления ютубе.

split2 работает, но исключительно потому, что позиция по умолчанию - 2.
Работает простой сплит на позиции 1 и 2. 3 байта в начале - это маркер TLS. Если DPI видит TLS оно начинает реассемблировать пакеты до получения full tls client hello. Внедрение кибера не оставила вариантов цензорам. Приходится реассемблить.
Поэтому простые сплиты на позиции более 2 не срабатывают.
Но работает практически любая мишура. fake, disorder2, oob, split.

Написал краткий FAQ по поводу обхода youtube средствами zapret :

Оказывается, не так все просто с windows 7 и готовым winws из комплекта zapret.

Требования к подписи драйверов windows изменились в 2021 году. Официальные бесплатные обновления windows 7 закончились в 2020. После этого несколько лет продолжали идти платные обновления по программе ESU. Именно в этих ESU обновлениях находится обновление ядра windows 7, позволяющиее загрузить драйвер windivert 2.2.2-A, который идет в поставке zapret.
Поэтому варианты следующие :

  1. Взять windivert64.sys и windivert.dll версии 2.2.0-C или 2.2.0-D отсюда : Index of /download/
    и заменить эти 2 файла. В zapret-win-bundle есть отдельных 2 места, где находится winws : zapret-winws и blockcheck/zapret/nfq. Надо менять в обоих местах. Этот вариант проверен и должен работать. Тем не менее патч 10 летней давности, который включает SHA256 сигнатуры, все еще необходим.

  2. Взломать ESU : Windows 7 ESU Patching · HackAndPwn
    Скрипт для установки и интеграции платных обновлений (ESU)
    и обновить систему

  3. Использовать UpdatePack7R2 от simplix : https://blog.simplix.info
    Но с этим паком есть проблема. Автор из Украины, он очень обиделся на русских. Если в панели управления стоит регион RU или BY, появляется неприятный диалог. Чтобы эту проблему обойти, можно поставить временно любой другой регион, потом вернуть. Так же нет никаких гарантий, что автор не насовал туда какой-то зловредный код. Использовать на свой страх и риск.
    Более безопасный вариант - скачать последнюю нормальную версию : 22.2.10
    Набор обновлений UpdatePack7R2 для Windows 7 SP1 и Server 2008 R2 SP1 22.2.10 [Multi/Ru] :: NNM-Club
    Ее достаточно, чтобы windivert 2.2.2-A заработал на windows 7.

Оказалось, что утечки памяти ядра и падения кинетика при использовании nfqws к zapret отношения не имеют. Кинетик использует старое ядро с багом, который давно пофиксили, но в кинетике непатченная версия. Разрабы собираются выкатывать патч в новых прошивках

Очередное обновление.

Почистили немного C код по результатам статического и динамического анализа

В dvtws больше не используются raw сокеты для отсылки ipv4 пакетов. Вместо них используется divert. Поэтому “not sockarg” в правилах ipfw больше не нужно. Так же это призвано наладить совместимость с древними версиями BSD, где sockarg еще нет ( я не проверял, но кто-то писал issue, у него были проблемы из-за этого в freebsd 7.4, вышедшей в 2011 году ).
Но главной целью этого изменения было попробовать завести divert через divert-to в pf. Увы, попытка провалилась, идет зацикливание. Механизм предотвращения зацикливания divert в pf сломан в FreeBSD и как следствие в pf/opn sense включая версию ядра 14-RELEASE.
Кто-то выкатывал патч для ядра BSD, но видимо его еще не накатили в релизе.
А ipfw иногда глючит с pf вместе. Потому запуск dvtws на pf/opn sense может иметь неожиданные последствия.

В nfqws и tpws исправлен детект TLS ClientHello на очень старых криптолибах, которые шлют SSL 3.0 версию в TLS record layer , а в handshake - TLS 1.2. Старые телики самсунг, например.

nfqws и tpws теперь умеют логить --debug в файл и syslog.
syslog очень удобен на openwrt, потому что там используется logd с циклическим буфером в памяти. Читать через logread.
–debug параметр можно вносить в опции NFQWS или TPWS в конфиге, но лучше в самом начале, иначе не поймаются ошибки при анализе командной строки.

В tpws добавлена опция --connect-bind-addr. В ней можно задать ipv4 или ipv6 адрес, с которого будут выполняться исходящие подключения. Для указания и v4, и v6 можно опцию повторить.
Поддерживается и нотация fe80:xxxx:xxxx:…%interface_name для v6 link locals.
Однако , это не отменяет правил маршрутизации. Пакет пойдет на тот интерфейс, куда его направит система маршрутизации ip rule/ip route и прочее. Исключение - разве что link local. Там пойдет на тот интерфейс, который будет после %. По другому и нельзя применять link locals.
Так что не ждите чуда, чтобы направить коннект на какой-то специфический интерфейс.
На openwrt используются правила маршрутизации ipv6 с from, поэтому там это может сработать.
И не стоит удивляться, если вдруг вы указали адрес VPN, а в tcpdump оно идет на обычный инет с адресом обычного инета. Если default route на обычный инет более приоритетен, то ваш IP адрес VPN превращается через MASQUERADE в адрес обычного инета.
Вообщем, эта опция не есть панацея для выбора исходящего интерфейса сама по себе.

В tpws в режиме --debug добавлено логирование с какого enpoint-а (ip:source_port) идет подключение к удаленному ресурсу. Это может быть полезно для соотнесения лога tpws с дампом wireshark или tcpdump.

Немного переписана логика закрытия соединений в tpws.

Обнаружена такая проблема, что если клиент инициирует shutdown соединения, и нет неотосланных данных, tpws сразу же бросает оба конекта, не давая серверу дослать оставшиеся данные. Получается, клиент ждет последнего ответа, а ему приходит FIN, как будто сервер ничего не прислал.
Логика этой ситуации переписана с использованием вызова shutdown().
Теперь соединение через tpws должно корректно перекачивать все байтики до конца.
Так же сделан детект обрыва соединения через RST и воспроизведение RST на другом конце (leg).
Это секут броузеры. Если им приходит RST, они пытаются что-то делать еще, а если FIN, то могут посчитать, что сервер прислал пустышку (ошибка протокола).

В результате этих изменений могут появляться надолго подвисшие конекты через tpws, если один из концов принял соединение и повис, не отвечая на FIN.
Эта ситуация разрешается через FIN_WAIT timeout. Через какое-то время (до нескольких минут на BSD) соединения закроются.

Для смягчения вышеописанного недостатка с FIN_TIMEOUT на linux и macos сделал поддержку tcp user timeout. FreeBSD и OpenBSD не поддерживают.

–local-tcp-user-timeout и --remote-tcp-user-timeout устанавливают значение таймаута в секундах
для соединений клиент-прокси и прокси-сервер. Этот таймаут соответствует опции сокета linux
TCP_USER_TIMEOUT. Под таймаутом подразумевается время, в течение которого буферизированные данные не переданы или на переданные данные не получено подтверждение (ACK) от другой стороны.
Этот таймаут никак не касается времени отсутствия какой-либо передачи через сокет лишь потому,
что данных для передачи нет. Полезно для сокращения время закрытия подвисших соединений.
Поддерживается только на Linux и MacOS.

По умолчанию - 10 сек для local leg, 20 сек - для remote leg.
Если сделать 0, то setsockopt не будет выполнен, оставляя системное значение.

Проверил на эмуляторе android youtube app от google.
Тупит, не загружается.
Тупит на youtubei.googleapis.com и *.googlevideo.com
Остальное превьюшки - и еще что-то.
yt3.ggpht.com у меня вообще был заблокирован - зависание или RST

googlevideo.com
youtubei.googleapis.com
i.ytimg.com
yt3.ggpht.com

После задуривания всех этих доменов в режиме как на обход блокировок приложение работает нормально.