Zapret: what's new

Перевел тест tpws в blockcheck на использование socks, выкинув всю муть с перенаправлением трафика через фаервол.
Раньше от этого отказывался, потому что невозможно управлять версией ip (ipv4/ipv6), когда CURL работает через прокси.
Пришлось вынести ресолвер отдельно. mdig ресолвит домен, далее курлу подсовывается ключ --connect-to. Он доступен с версии 7.49, следовательно совсем уж древние курлы старее мая 2016 отваливаются , равно как и старые дистрибутивы ОС в варианте “из коробки”. Если у вас такой древнющий курл, можно собрать самому или взять готовый статический бинарик.
В openwrt с LEDE 17 версия curl достаточно новая.
В итоге tpws теперь можно тестировать в openbsd и pfsense, а код скрипта упростился

В blockcheck добавлена проверка на обход QUIC. Для нее требуется curl с поддержкой опции --http3-only.
Сейчас пока это диковинка, родной curl скорее всего не умеет
Тут есть статики для разных платформ : Releases · stunnel/static-curl · GitHub

Десинхронизация udp на nftables тоже переведена на POSTNAT схему вместе с TCP.
Этот вариант позволяет задействовать любые атаки, в том числе ломающие NAT, однако при включенном masquerade для проходного трафика может использоваться только через nftables.
Например, вариант ipfrag2 работает на многих сайтах для обхода блокировки QUIC.
Сеть очень плохо относится к фрагментации tcp на уровне IP. Это ненормальная ситуация, поэтому как правило такое режется.
Но к фрагментации udp сеть относится относительно лояльно. Есть ситуации, когда это вообще нормально.
IP фрагментация используется в IKE. В IKE уже изобрели свой метод фрагментации сообщений на уровне L7, но старые ОС об этом не знают. windows 7 отсылает фрагментированные udp, windows 10 - несколько нефрагментированных udp. Именно поэтому на некоторых VPS вам упорно не удастся подключиться к вашему strongwan с win7, и все лишь потому, что у вас слишком упертый хостер, который решил подрезать фрагментированные пакеты полностью.
Фрагментация QUIC по сути тоже ненормальна, но мало кто будет лезть так глубоко и анализировать udp payload (который еще надо суметь собрать).
cloudflare и bbc.com обходятся через ipfrag2, на facebook режут.

Новый метод десинхронизации нулевой фазы SYNDATA.
Термин нулевой фазы относится к десинхронизации на этапе TCP 3 way handshake.
К ней неприменимы фильтры на основе hostlist.
Этот тот случай, когда в --dpi-desync может быть 3 параметра через запятую.
Можно так : --dpi-desync=syndata,fake,split2

Суть в добавлении данных в пакет SYN. ОС принимают такие SYN пакеты, но данные игнорируют, а некоторые DPI их принимают. Кое-где работает на наших ТСПУ, но только для http.
На https может работать, если в параметре --dpi-desync-fake-syndata передать файл, содержащий TLS client hello с незаблокированным доменом. Фактически это аналог fake, поскольку расчет на то, что DPI принимает этот пейлоад как часть tcp stream, а сервер - нет.
Некоторые российские ТСПУ/DPI на http впадают в проблемы с синхронизацией sequence numbers, что приводит только к зависанию соединения.
Ломает некоторые сайты, видимо из-за собственных систем antiddos, которые плохо реагируют на аномалии

Поскольку ограничить хостлистом или аутохостлистом невозможно, применять с осторожностью

Главная цель этого режима десинхронизации - не атака на веб сайты, а атака на произвольные протоколы на конкретном сервере без применения техники split.
Сейчас наблюдается такая тема на ТСПУ. Если какой-то VPN сервис или другой сервис начинает применять техники обхода блокировок, связанные с сегментацией, то ТСПУ их обнаруживает и сразу блокирует соединение. Делается это обычно на ограниченных диапазонах IP.
В условиях жестких блокировок и противодействия техникам их обхода, ценна может быть каждая дырочка на свой сервер.
На udp это может быть ipfrag2, а на tcp - syndata.

Оказывается, старый добрый фейк на http и https может не работать в оригинальном виде.
Когда ты лезешь на http и шлешь фейк http iana.org, это может не сработать. Но если послать ерунду типа нулей, то может сработать. На syndata может быть наоборот. Ерунда не работает на https, а tls fake от iana.org - работает.

В связи с этим обновлен blockcheck на предмет поиска новых заковыристых стратегий

Еще немного по поводу SYNDATA.
На самом деле не запрещено по стандарту слать данные прямо в SYN. Поэтому такие пакеты без проблем проходят NAT и могут учитываться DPI.
Оригинальный стандарт запрещает передавать данные из SYN в сокет до полного прохождения tcp handshake. Но фактически по крайней мере linux, freebsd и windows данные в SYN игнорируют. При этом все последующие пакеты идут с сиквенсами, как будто бы SYN был пустой. То есть данные в SYN просто отбрасываются на стандартных сокетах.

Но есть еще более новый стандарт TCP fast open. В нем как раз отсылка данных в процессе хэндшейка - это нормально. Однако, для задействования функционала требуется особое программирование специально для поддержки fast open. Это должен уметь и серверный процесс, и клиентский.

Хотя некоторые веб сервера и умеют, и даже некоторые броузеры на некоторых платформах умеют, мало кто сейчас озабочен этим fast open. У меня нет статистики где и на каких ОС и на скольких сайтах он включен по умолчанию. Но как я понимаю немного где. Это уже устаревшая технология. Сейчас актуален QUIC. Он решает в том числе и проблему RTT.

Но если вдруг SYNDATA будет использован именно на fast open соединении, несомненно оно сломается. Поэтому соединения с признаками fast open не трогаются.

Сделал автоматическое перечитывание autohostlist другими процессами nfqws/tpws при модификации файла.
Выдал, допустим, блокчек 4 разных стратегии для http/https/ipv4/ipv6.
Юзер тупо вписал это в конфиг. Запущено 4 процесса.
Дернул https ipv4. Отлично, занеслось в аутолист.
Потом не работает. Почему ? Да потому что полезло по ipv6, а там не обновилось.

Реализован режим quick в blockcheck.
Его цель - найти хоть что-то работающее максимально быстро.
Изначально blockcheck создавался не как делатель волшебных пиллюль для копипасты в определенное место как на картинке. Это инструмент исследования DPI на предмет техник обхода блокировок.
Но юзера некоторые ниче не понимают, они все равно копипастят, и это их единственный шанс, чтобы оно заработало. Иначе им только отказываться от продукта, потому что не могут понять что там за буковки и что с ними делать.
В том числе для них может пригодиться этот режим, потому что все равно лишние буковки для них бесполезны.

Суть его в чем

  1. Отказ от тестов tpws. Все равно он как правило не обеспечивает должный уровень обхода. Чтобы вернуть используйте переменную SKIP_TPWS=0
  2. Поиск идет до первой рабочей стратегии
  3. При нескольких попытках любой фейл приводит к концу серии попыток. Ведь все равно будет итоговый фейл

По умолчанию все равно оставляю standard, чтобы основная цель скрипта оставалась неизменной

Из blockcheck убраны тесты ipfrag tcp, поскольку современная сеть практически не оставляет никаких шансов этому варианту.

Немного наблюдений по поводу протокола QUIC.
Если кратко, то на DPI он обрабатывается криво. Алгоритмы несовершенны.
Поведение DPI может зависеть от типа клиентской библиотеки.
quiche может пробивать блокировку и без средств обхода.
Пакеты initial от разных библиотек могут не собираться DPI, и он может не извлекать host.
curl с nghttp3 может долго (1-3 сек) выполнять запрос с пробивкой по fake. Там то ли теряются, то ли искажаются пакеты от сервера, вынуждая клиент еще раз слать initial.
При этом firefox может сразу и быстро открывать этот же сайт по quic, если количество пробивочных пакетов 5 и выше, и подвисать на QUIC, если меньше.
Аналогично у них реализуется и блокировка wireguard udp и openvpn udp. Для пробивки нужно слать 5 фейков.
DPI по-прежнему не может корректно сечь разбросанный на несколько пакетов initial. В хромах уже начали включать кибер по умолчанию, так что 50/50. Рандомизирует сигнатуру. То в первый пакет SNI попадет, то во 2-й
Вообщем, сложная эта штука QUIC, и curl test может не отражать реальной специфики как поведет себя броузер

В tpws реализованы фильтры протоколов для disorder и oob.
Параметр oob претерпел несовместимое изменение. Теперь наравне с disorder он берет название протокола http или tls. Если без параметра - применяется дурение ко всем протоколам. Если с параметром - только к этому протоколу.
Может быть несколько --disorder или --oob. Например, можно сказать ему сделать oob для tls и http, но не делать для остальных, при условии что задано --split-any-protocol.
Байт OOB перенесен в параметр --oob-data. Это нужно, потому что в tpws стали появляться стратегии, которые нужны для одних протоколов, но могут ломать другие.
Для http есть отдельный split --split-http-req. Он имеет приоритет над --split-pos.
Если это не http, то применяется --split-pos. Получается, можно двумя этими параметрами задать разный сплит для http и tls.
Но вот disorder может сломать http на ТСПУ. В скриптах запуска можно было этот вопрос решить как с nfqws - сделать несколько параметров для http,https,http6,https6.
Но tpws еще ценен наличием режима socks, а там такое сделать не выйдет, потому что в прогах нет 4 поля socks для разных вариантов. Потому принято решение идти по пути обьединения стратегий в 1 процесс.
Кстати, это еще один пример, что вот так просто взять копипастнуть как на картинке может не получиться. Если вы захотите пойти путем tpws, то там только 1 поле, а стратегии выдал blockcheck две разные. И все, вы тут встряли, если вы - копипастер. А на самом деле это сделано потому, что все можно запихать в 1 стратегию, если их обьеденить, но это не для копипастеров. И, конечно, чтобы не ломать достоинство socks.
tpws в текущих реалиях в России работает, но ограниченно.
Как правило он может пробить http, а https только на tls 1.3.
Не поддерживающие tls 1.3 заблокированные сайты пробить не получится.

Худой, но как-то работающий способ пробить TLS1.2 на tpws. Не везде, но много где. Не особо качественно. Но лучше, чем ничего.

–mss устанавливает опцию сокета TCP_MAXSEG. Клиент выдает это значение в tcp опциях SYN пакета.
Сервер в ответ в SYN,ACK выдает свой MSS. На практике сервера обычно снижают размеры отсылаемых ими пакетов, но они все равно не вписываются в низкий MSS, указанный клиентом. Обычно чем больше указал клиент, тем больше шлет сервер. На TLS 1.2 если сервер разбил заброс так, чтобы домен из сертификата не попал в первый пакет, это может обмануть DPI, секущий ответ сервера.
Схема может значительно снизить скорость и сработать не на всех сайтах.
Несовместимо с фильтром по hostlist. Невозможен фильтр по версии TLS.
Взамен имеется фильтр по портам --mss-pf. --mss-pf=443 применяет дурение только к https.
Применяя данную опцию к сайтам TLS1.3, если броузер тоже поддерживает TLS1.3, то вы делаете только хуже.
Но нет способа автоматически узнать когда надо применять, когда нет, поскольку MSS идет только в
3-way handshake еще до обмена данными, а версию TLS можно узнать только по ответу сервера, который может привести к реакции DPI.
Использовать только когда нет ничего лучше или для отдельных ресурсов.
Работает только на linux, не работает на BSD и MacOS.

В tpws ликвидировано узкое место, связанное с ресолвером хостов.
У socks proxy есть режим переадресации по IP адресу и по хосту.
В curl за выбор режима отвечают параметр --socks5 или --socks5-hostname. Можно использовать параметр --proxy socks5://… и --proxy socks5h://… . socks5h - это как раз ресолвинг через прокси.

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

Сейчас это больше не так. Задача по ресолвингу решается в отдельных потоках, организованных в виде thread pool. Есть очередь запросов, а потоки их по мере возможности разгребают. На время ресолвинга соединение ставится на паузу, не прерывая процессинг всего остального.

Количество потоков ресолвера выбирается по умолчанию как 5+max_conn/50. По умолчанию max_conn=512, следовательно потоков 15. Можно переопределить в параметре --resolver-threads.

Да, можно было использовать какую-то отдельную библиотеку для асинхронных ресолвингов, ведь libc в общем случае такой возможности не имеет. Имеет только glibc, а musl и другие - нет. Но это зависимости, это тяжесть процесса, которую хочется избежать.

Помимо прямого назначения, это нововведение несет в себе и другую цель. Использование tpws в socks режиме с удаленным ресолвингом хостов дает tpws возможность узнать hostname еще до подключения к серверу. Следовательно, задействуется механизм, ограничивающий дурение по MSS через hostlist. В любом другом режиме MSS будет применяться неограниченно ко всем соединениям.

Как задействовать socks в броузерах.
В хромиум подобных вызвать chrome так : chrome.exe --proxy-server=“socks5://localhost:1111” . Они сразу начинают задействовать режим remote_dns.
В firefox можно глобально задать в about:flags параметр network.proxy.socks_remote_dns=true. А можно использовать расширение foxyproxy. Оно позволяет оперативно переключать прокси, и можно задать remote_dns для каждого прокси отдельно.

WSL 1. Подсистема linux на win10/11 и windows server.
Эмуляция вызовов ядра linux, позволяющая запускать бинарики linux.
Но, естественно, в реализации есть кривизна.

Проверял на windows server 2022. Оказалось глючат linux pipes.
Делаешь splice в pipe. Возвращает, что записал 8192 байт.
Делаешь splice из pipe в сокет. B хрен вам. EAGAIN. Как будто ничего нет в этом пайпе.
Делаешь read из пайпа - тоже самое. То есть там действительно пусто.
Проблема не в сокете. Если в него слать send-ом, то ошибки нет, уходит.
Получается суешь в пайп, и это куда-то пропадает неизвестно куда.
Логика неблокирующих сокетов приводит к зацикливанию процесса, сьедая целое ядро.

Сколько ни тестировал на linux, такого нет, а в винде воспроизводится на раз два.

Лечение - параметр --nosplice. Обход глюка винды

Исправлен целый ряд проблем, все же имевшихся в схеме postnat.
Десинхронизация на первый пакет (syndata на tcp или первый пакет udp, quic, например) несет в себе проблему. Если дропать в очереди первый пакет, то ломается запись в conntrack. Его нельзя дропать.
Потому было сделано особое уродование первого оригинального пакета, чтобы его пропускать в очереди.
TTL использовать нельзя, поскольку linux сечет expired icmp и ресетает сокет.
Использованы следующие схемы :

ipv4 - портим L3 чексумму ipv4 хедера. с порченой чексуммой пакет будет отброшен первым же роутером
tcp - в SYN пакете сбрасываем все флаги и этим самым так же портим чексумму L4
udp - в первом пакете обрезаем все данные после udp хедера, делаем длину в udp хедере нулевой (минимум 8 требуется - длина самого хедера), портим чексумму L4

эти меры призваны достичь результата, даже если вдруг сетевой адаптер на все делает чексум оффлоад
главная цель - чтобы этот пакет никем по возможности не был воспринят как что-то значимое. ни DPI, ни сервером. но в то же время не испортилась бы запись в коннтрак

Для дурения произвольных протоколов в nfqws добавлен параметр --dpi-desync-start.

Он полностью аналогичен --dpi-desync-cutoff, но работает как начальный ограничитель. cutoff - конечный ограничитель.
Таким образом дублируется функционал connbytes FROM:TO на уровне nfqws. Можно вырезать по номеру пакета (n), смещению позиции данных (s), а так же отсутствующий в connbytes режим - по номеру пакета данных (d). d от n отличается только тем, что считаются пакеты с непустым data payload.
Этот фильтр помогает решить вопрос с отсутствующим connbytes на BSD системах или на прошивочках linux с покоцаным ядром, где нет матча connbytes.
При наличии connbytes лучше это делать средствами iptables/nftables. Тогда не будет лишних редиректов user mode, скорость будет выше в разы.
Если надо ограничить дурение в d режиме, игнорируя непонятное количество пустых ACK, то делаем ограничитель connbytes на максимум возможных пакетов, где нам надо что-то поймать, дальше уточняющий ограничитель в d режиме на nfqws.

В tpws уже реализована пара похожих параметров --tamper-start, --tamper-cutoff

В nfqws теперь обязателен параметр --qnum. Раньше был номер очереди по умолчанию 0.
Сделано во избежание неверного использования, вызванного непониманием как оно работает.
В iptables, кстати, NFQUEUE тоже имеет по умолчанию номер очереди 0. То есть если раньше кто-то писал iptables без queue-num, а nfqws запускал без qnum, то это работало, а теперь перестанет. Вернуть этот вариант можно через nfqws --qnum 0

В nfqws сделана система задержки пакетов.
Начиная с chrome 124 по умолчанию включена пост-квантовая криптография kyber. Это раздувает TLS ClientHello до 2 пакетов, QUIC initial до 2 или 3 пакетов. Может быть и больше при низком MTU.
Ранее nfqws умел реассемблировать TLS ClientHello, но проводил десинхронизацию на тот сегмент TCP, где появилось SNI и все последующие. Допустим, имеется 5 пакетов, в 3-м из которых SNI. Получается, мы имеем : tls1,tls2,fake,tls3,fake,tls4,fake,tls5. Не слишком корректное поведение. QUIC же вообще никак не реассемблировался.
Теперь введена система задержки пакетов. Мы получаем tls1…tls5, но в сеть не шлем, а только запоминаем. По приходу последнего tls5 выполняется десинхронизация tls1 на основании полностью собранного запроса. Выходит так : fake,tls1,tls2,tls3,tls4,tls5. Что куда более корректно, ведь суть фейка - вынудить DPI отстать от запроса. Но как он от него отстанет в предыдущем варианте, если он сначала видит tls1. Он начинает реассемблировать вплоть до tls5. И получает испорченный блок данных где-то посередине. Такое тоже обычно срабатывает для обхода, но все же это не достигает изначальной цели fake.
Для QUIC производится аналогичная процедура, только с дешифровкой каждого куска, конкатенацией расшифрованных данных до тех пор, пока из них не соберется полный ClientHello.
Любая ошибка при сборке вызывает немедленную отмену реассемблирования, отсылку задержанных пакетов и отмену десинхронизации.

Реализован nfqws для windows - winws.
Это фактически замена GoodbyeDPI с up-to-date функциями из nfqws.
Работает практически все.
Из ограничений : нет ipset, не поддерживается проходящий трафик (расшаривание соединения)
Поддерживается blockcheck, но он требует установки cygwin.
Сам winws установки cygwin не требует.

Читайте docs/windows.txt, docs/quick_start_windows.txt

Это дебют, так что welcome тестировать.

Создан bundle для ускоренного и упрощенного запуска blockcheck под windows. Его достаточно для полноценного развертывания winws.

Адаптирована инструкция из основного репозитория docs/quick_start_windows.txt

Сделан запуск в виде windows служб.
См service_*.cmd
Можно запускать и через планировщик, и как службы. Как вам больше нравится.