Zapret: what's new

В 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.
Любая ошибка при сборке вызывает немедленную отмену реассемблирования, отсылку задержанных пакетов и отмену десинхронизации.