From 256c2d7e50de0f91fdec8439a08c8e22c3b3b115 Mon Sep 17 00:00:00 2001 From: bol-van Date: Mon, 18 Nov 2024 16:28:22 +0300 Subject: [PATCH] doc works --- docs/bsd.md | 14 +- docs/bsdfw.txt | 2 +- docs/changes.txt | 25 ++ docs/readme.en.md | 2 +- docs/readme.md | 596 ++++++++++++++++++++++++---------------------- 5 files changed, 349 insertions(+), 290 deletions(-) diff --git a/docs/bsd.md b/docs/bsd.md index ad57b72..56304d7 100644 --- a/docs/bsd.md +++ b/docs/bsd.md @@ -143,7 +143,7 @@ $ ipfw -q -f flush zapret, добавив в параметры `--daemon`. Например так: ```sh $ pkill ^dvtws$ -$ /opt/zapret/nfq/dvtws --port=989 --daemon --dpi-desync=split2 +$ /opt/zapret/nfq/dvtws --port=989 --daemon --dpi-desync=multisplit --dpi-desync-split-pos=2 ``` Для перезапуска фаервола и демонов достаточно будет сделать: @@ -209,7 +209,7 @@ $ ipfw delete 100 $ ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted xmit em0 # required for autottl mode only $ ipfw add 100 divert 989 tcp from any 80,443 to any tcpflags syn,ack in not diverted recv em0 -$ /opt/zapret/nfq/dvtws --port=989 --dpi-desync=split2 +$ /opt/zapret/nfq/dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2 ``` #### Трафик только на таблицу zapret, за исключением таблицы nozapret @@ -220,7 +220,7 @@ $ ipfw add 100 allow tcp from me to table\(nozapret\) 80,443 $ ipfw add 100 divert 989 tcp from any to table\(zapret\) 80,443 out not diverted not sockarg xmit em0 # required for autottl mode only $ ipfw add 100 divert 989 tcp from table\(zapret\) 80,443 to any tcpflags syn,ack in not diverted not sockarg recv em0 -$ /opt/zapret/nfq/dvtws --port=989 --dpi-desync=split2 +$ /opt/zapret/nfq/dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2 ``` @@ -317,7 +317,7 @@ sysctl net.inet6.ip6.pfil.inbound=ipfw,pf ipfw delete 100 ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted xmit em0 pkill ^dvtws$ -dvtws --daemon --port 989 --dpi-desync=split2 +dvtws --daemon --port 989 --dpi-desync=multisplit --dpi-desync-split-pos=2 # required for newer pfsense versions (2.6.0 tested) to return ipfw to functional state pfctl -d ; pfctl -e @@ -357,7 +357,7 @@ rdr pass on em1 inet6 proto tcp to port {80,443} -> fe80::20c:29ff:5ae3:4821 por ```sh $ pfctl -a zapret -f /etc/zapret.anchor $ pkill ^tpws$ -$ tpws --daemon --port=988 --enable-pf --bind-addr=127.0.0.1 --bind-iface6=em1 --bind-linklocal=force --split-http-req=method --split-pos=2 +$ tpws --daemon --port=988 --enable-pf --bind-addr=127.0.0.1 --bind-iface6=em1 --bind-linklocal=force --split-pos=2 ``` 4. После перезагрузки проверьте, что правила создались: @@ -424,7 +424,7 @@ pass out quick on em0 proto tcp to port {80,443} divert-packet port 989 no sta ```sh $ pfctl -f /etc/pf.conf -$ ./dvtws --port=989 --dpi-desync=split2 +$ ./dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2 ``` #### Трафик только на таблицу zapret, за исключением таблицы nozapret @@ -456,7 +456,7 @@ pass out quick on em0 inet6 proto tcp to port {80,443} divert-p ```sh $ pfctl -f /etc/pf.conf -$ ./dvtws --port=989 --dpi-desync=split2 +$ ./dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2 ``` diff --git a/docs/bsdfw.txt b/docs/bsdfw.txt index 2575c69..8202322 100644 --- a/docs/bsdfw.txt +++ b/docs/bsdfw.txt @@ -70,7 +70,7 @@ pass in quick on em0 proto tcp from port {80,443} flags SA/SA divert-packet por pass in quick on em0 proto tcp from port {80,443} no state pass out quick on em0 proto tcp to port {80,443} divert-packet port 989 no state pfctl -f /etc/pf.conf -./dvtws --port=989 --dpi-desync=split2 +./dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2 ; dvtws with table limitations : to zapret,zapret6 but not to nozapret,nozapret6 ; reload tables : pfctl -f /etc/pf.conf diff --git a/docs/changes.txt b/docs/changes.txt index 64d5f57..8721ddf 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -363,3 +363,28 @@ nfqws,tpws: use alternate $ sign for $ repo: binaries removed from repo. git actions binaries build in releases. uninstall_easy.sh: offer to remove dependencies in openwrt install_easy.sh: allow to download lists in autohostlist filter mode + +v69: + +nfqws, tpws: multisplit/multidisorder support. +nfqws: name change split->fakedsplit, disorder->fakeddisorder. compat : old names are synonyms +nfqws: --dpi-desync-split-http-req, --dpi-desync-split-tls deprecated. compat : these parameters add split point to multisplit. +nfqws: --dpi-desync=split2|disorder2 deprecated. compat: they are now synonyms for multisplit/multidisorder +nfqws: cancel seqovl if MTU is exceeded (linux only). cancel seqovl for disorder if seqovl>=first_part_size. +nfqws: fixed splits in multiple TLS segments. +tpws: --split-tls,--split-tls deprecated. compat : these parameters add split point to multisplit. +tpws: --tlsrec now takes pos markers. compat : old names are converted to pos markers +tpws: --tlsrec-pos deprecated. compat : sets absolute pos marker +nfqws,tpws: chown autohostlist, autohostlist debug log and debug log files after options parse +nfqws,tpws: set EXEDIR env var to use in @config (won't work for stadalone winws without /bin/sh) +dvtws: set random/increasing ip_id value in generated packets +mdig: fixed parsing of DNS reply in windows (stdin is opened as text, not binary) +tpws: support compile for android NDK api level >= 21 (Android 5.0) +repo: build for android NDK api level 21 (Android 5.0) +install_easy: support for APK package manager in openwrt +blockcheck: removed ignore CA question +blockcheck: removed IGNORE_CA, CURL_VERBOSE +blockcheck: added CURL_OPT +blockcheck: new strategies support +blockcheck: test sequence rework +blockcheck: view all working strategies in summary diff --git a/docs/readme.en.md b/docs/readme.en.md index 612ea9e..4890200 100644 --- a/docs/readme.en.md +++ b/docs/readme.en.md @@ -1,4 +1,4 @@ -# zapret v.68 +# zapret v.69 # SCAMMER WARNING diff --git a/docs/readme.md b/docs/readme.md index 0edd17c..5042fa7 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -1,4 +1,4 @@ -# zapret v.68 +# zapret v.69 # ВНИМАНИЕ, остерегайтесь мошенников @@ -22,7 +22,13 @@ zapret является свободным и open source. - [Когда это работать не будет](#когда-это-работать-не-будет) - [nfqws](#nfqws) - [АТАКА ДЕСИНХРОНИЗАЦИИ DPI](#атака-десинхронизации-dpi) + - [ФЕЙКИ](#фейки) + - [TCP СЕГМЕНТАЦИЯ](#tcp-сегментация) + - [ПЕРЕКРЫТИЕ SEQUENCE NUMBERS](#перекрытие-sequence-numbers) + - [СПЕЦИФИЧЕСКИЕ РЕЖИМЫ IPV6](#специфические-режимы-ipv6) - [КОМБИНИРОВАНИЕ МЕТОДОВ ДЕСИНХРОНИЗАЦИИ](#комбинирование-методов-десинхронизации) + - [РЕАКЦИЯ DPI НА ОТВЕТ СЕРВЕРА](#реакция-dpi-на-ответ-сервера) + - [IPTABLES ДЛЯ NFQWS](#iptables-для-nfqws) - [РЕЖИМ SYNACK](#режим-synack) - [РЕЖИМ SYNDATA](#режим-syndata) - [ВИРТУАЛЬНЫЕ МАШИНЫ](#виртуальные-машины) @@ -32,7 +38,12 @@ zapret является свободным и open source. - [IP ФРАГМЕНТАЦИЯ](#ip-фрагментация) - [МНОЖЕСТВЕННЫЕ СТРАТЕГИИ](#множественные-стратегии) - [tpws](#tpws) + - [TCP СЕГМЕНТАЦИЯ В TPWS](#tcp-сегментация-в-tpws) + - [TLSREC](#tlsrec) + - [MSS](#mss) + - [ДРУГИЕ ПАРАМЕТРЫ ДУРЕНИЯ](#другие-параметры-дурения) - [МНОЖЕСТВЕННЫЕ СТРАТЕГИИ](#множественные-стратегии-1) + - [СЛУЖЕБНЫЕ ПАРАМЕТРЫ](#служебные-параметры) - [Способы получения списка заблокированных IP](#способы-получения-списка-заблокированных-ip) - [ip2net](#ip2net) - [mdig](#mdig) @@ -265,7 +276,7 @@ dvtws, собираемый из тех же исходников (см. [док --hostnospace ; убрать пробел после "Host:" и переместить его в конец значения "User-Agent:" для сохранения длины пакета --hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase --domcase ; домен после Host: сделать таким : TeSt.cOm ---dpi-desync=[,][,,][, ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000 --dpi-desync-ttl= ; установить ttl для десинхронизирующих пакетов --dpi-desync-ttl6= ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение ttl @@ -274,10 +285,8 @@ dvtws, собираемый из тех же исходников (см. [док --dpi-desync-fooling= ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера. none md5sig badseq badsum datanoack hopbyhop hopbyhop2 --dpi-desync-repeats= ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты) --dpi-desync-skip-nosni=0|1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI ---dpi-desync-split-pos=<1..1500> ; (только для split*, disorder*) разбивать пакет на указанной позиции ---dpi-desync-split-http-req=method|host ; разбивка http request на указанном логическом месте ---dpi-desync-split-tls=sni|sniext ; разбивка tls client hello на указанном логическом месте ---dpi-desync-split-seqovl= ; использовать sequence overlap перед первым отсылаемым оригинальным tcp сегментом +--dpi-desync-split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации в режимах split и disorder +--dpi-desync-split-seqovl=N|-N|marker+N|marker-N ; единичный маркер, определяющий величину перекрытия sequence в режимах split и disorder. для split поддерживается только положительное число. --dpi-desync-split-seqovl-pattern=|0xHEX ; чем заполнять фейковую часть overlap --dpi-desync-badseq-increment= ; инкремент sequence number для badseq. по умолчанию -10000 --dpi-desync-badack-increment= ; инкремент ack sequence number для badseq. по умолчанию -66000 @@ -315,12 +324,6 @@ dvtws, собираемый из тех же исходников (см. [док --ipset-exclude= ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая. ``` -Параметры манипуляции могут сочетаться в любых комбинациях. - -> [!TIP] -> **ЗАМЕЧАНИЕ.** Параметр `--wsize` считается устаревшим и более не поддерживается в скриптах. Функции сплита выполняются в -> рамках атаки десинхронизации. Это быстрее и избавляет от целого ряда недостатков wsize. - `--debug` позволяет выводить подробный лог действий на консоль, в syslog или в файл. Может быть важен порядок следования опций. `--debug` лучше всего указывать в самом начале. Опции анализируются последовательно. Если ошибка будет при проверке опции, а до анализа `--debug` еще дело не дошло, то сообщения не будут выведены в файл или syslog. При @@ -332,18 +335,24 @@ dvtws, собираемый из тех же исходников (см. [док ### АТАКА ДЕСИНХРОНИЗАЦИИ DPI -Суть ее в следующем. После выполнения tcp 3-way handshake идет первый пакет с данными от клиента. Там обычно `GET / ...` -или TLS ClientHello. Мы дропаем этот пакет, заменяя чем-то другим. Это может быть поддельная версия с безобидным, но -валидным запросом http или https (вариант `fake`), пакет сброса соединения (варианты `rst`, `rstack`), разбитый на части -оригинальный пакет с перепутанным порядком следования сегментов + обрамление первого сегмента фейками (`disorder`), то -же самое без перепутывания порядка сегментов (`split`). fakeknown отличается от fake тем, что применяется только к -распознанному протоколу. В литературе такие атаки еще называют **TCB desynchronization** и **TCB teardown**. Надо, чтобы -фейковые пакеты дошли до DPI, но не дошли до сервера. На вооружении есть следующие возможности : установить низкий TTL, -посылать пакет с инвалидной чексуммой, добавлять tcp option **MD5 signature**, испортить sequence numbers. Все они не -лишены недостатков. +Суть ее в следующем. Берется оригинальный запрос, модифицируется, добавляется поддельная информация (фейки) +таким образом, чтобы ОС сервера передала серверному процессу оригинальный запрос в неизменном виде, а DPI увидел другое. +То, что он блокировать не станет. Сервер видит одно, DPI - другое. DPI не понимает, что передается запрещенный запрос и не блокирует его. -* `md5sig` работает не на всех серверах. Пакеты с md5 обычно отбрасывают только linux. -* `badsum` не сработает, если ваше устройство за NAT, который не пропускает пакеты с инвалидной суммой. Наиболее +Есть арсенал возможностей, чтобы достичь такого результата. +Это может быть передача фейк пакетов, чтобы они дошли до DPI, но не дошли до сервера. Может использоваться фрагментация на уровне TCP (сегментация) или на уровне IP. +Есть атаки, основанные на игре с tcp sequence numbers или с перепутыванием порядка следования tcp сегментов. +Методы могут сочетаться в различных вариантах. + +### ФЕЙКИ + +Фейки - это отдельные сгенерированные nfqws пакеты, несущие ложную информацию для DPI. +Они либо не должны дойти до сервера, либо могут дойти, но должны быть им отброшены. +Иначе получается слом tcp соединения или нарушение целостности передаваемого потока, что гарантированно приводит к поломке ресурса. +Есть ряд методов для решения этой задачи. + +* `md5sig` добавляет TCP опцию **MD5 signature**. Работает не на всех серверах. Пакеты с md5 обычно отбрасывают только linux. +* `badsum` портит контрольную сумму TCP. Не сработает, если ваше устройство за NAT, который не пропускает пакеты с инвалидной суммой. Наиболее распространенная настройка NAT роутера в Linux их не пропускает. На Linux построено большинство домашних роутеров. Непропускание обеспечивается так : настройка ядра sysctl по умолчанию `net.netfilter.nf_conntrack_checksum=1` заставляет conntrack проверять tcp и udp чексуммы входящих пакетов и @@ -359,7 +368,8 @@ dvtws, собираемый из тех же исходников (см. [док себя ведут некоторые роутеры на базе mediatek. badsum пакеты уходят с клиентской ОС, но роутером не видятся в br-lan через tcpdump. При этом если nfqws выполняется на самом роутере, обход может работать. badsum нормально уходят с внешнего интерфейса. -* Пакеты с `badseq` будут наверняка отброшены принимающим узлом, но так же и DPI, если он ориентируется на sequence +* `badseq` увеличивает TCP sequence number на определенное значение, выводя его тем самым из TCP window. + Такие пакеты будут наверняка отброшены принимающим узлом, но так же и DPI, если он ориентируется на sequence numbers. По умолчанию смещение seq выбирается -10000. Практика показала, что некоторые DPI не пропускают seq вне определенного окна. Однако, такое небольшое смещение может вызвать проблемы при существенной потоковой передаче и потере пакетов. Если вы используете `--dpi-desync-any-protocol`, может понадобится установить badseq increment @@ -383,7 +393,8 @@ dvtws, собираемый из тех же исходников (см. [док может ломать NAT и не всегда работает с iptables, если используется masquerade, даже с локальной системы (почти всегда на роутерах ipv4). На системах c iptables без masquerade и на nftables работает без ограничений. Экспериментально выяснено, что многие провайдерские NAT не отбрасывают эти пакеты, потому работает даже с внутренним провайдерским IP. - Но linux NAT оно не пройдет, так что за домашним роутером эта техника не сработает, но может сработать с него. + Но linux NAT оно не пройдет, так что за домашним роутером эта техника скорее всего не сработает, но может сработать с него. + Может сработать и через роутер, если подключение по проводу, и на роутере включено аппаратное ускорение. * `autottl`. Суть режима в автоматическом определении TTL, чтобы он почти наверняка прошел DPI и немного не дошел до сервера. Берутся базовые значения TTL 64,128,255, смотрится входящий пакет (да, требуется направить первый входящий пакет на nfqws !). Вычисляется длина пути, отнимается `delta` (1 по @@ -396,44 +407,64 @@ dvtws, собираемый из тех же исходников (см. [док Режимы дурения могут сочетаться в любых комбинациях. `--dpi-desync-fooling` берет множество значений через запятую. -Для режимов fake, rst, rstack после фейка отправляем оригинальный пакет. +### TCP СЕГМЕНТАЦИЯ -Режим disorder делит оригинальный пакет на 2 части и отправляет следующую комбинацию в указанном порядке : + * `multisplit`. нарезаем запрос на указанных в `--dpi-desync-split-pos` позициях. + * `multidisorder`. нарезаем запрос на указанных в `--dpi-desync-split-pos` позициях и отправляем в обратном порядке. + * `fakedsplit`. нарезаем запрос на 2 части, обрамляя его фейками : фейк 1-й части, 1 часть, фейк 1-й части, 2 часть + * `fakeddisorder`. нарезаем запрос на 2 части, обрамляя его фейками : 2 часть, фейк 1-й части, 1 часть, фейк 1 части. -1. 2-я часть пакета -2. поддельная 1-я часть пакета, поле данных заполнено нулями -3. 1-я часть пакета -4. поддельная 1-я часть пакета, поле данных заполнено нулями. отсылка 2-й раз. Оригинальный пакет дропается всегда. +Для определения позиций нарезки используются маркеры. -Параметр `--dpi-desync-split-pos` позволяет указать байтовую позицию, на которой происходит разбивка. По умолчанию - 2. -Если позиция больше длины пакета, позиция выбирается 1. Этой последовательностью для DPI максимально усложняется задача -реконструкции начального сообщения, по которому принимается решение о блокировке. Некоторым DPI хватит и tcp сегментов в -неправильном порядке, поддельные части сделаны для дополнительной надежности и более сложных алгоритмов реконструкции. -Режим `disorder2` отключает отправку поддельных частей. +* **Абсолютный положительный маркер** - числовое смещение внутри пакета или группы пакетов от начала. +* **Абсолютный отрицательный маркер** - числовое смещение внутри пакета или группы пакетов от следующего за концом байта. -1 указывает на последний байт. +* **Относительный маркер** - положительное или отрицательное смещение относительно логической позиции внутри пакета или группы пакетов. -Режим `split` очень похож на disorder, только нет изменения порядка следования сегментов : +Относительные позиции : -1. поддельная 1-я часть пакета, поле данных заполнено нулями -2. 1-я часть пакета -3. поддельная 1-я часть пакета, поле данных заполнено нулями. отсылка 2-й раз. -4. 2-я часть пакета Режим split2 отключает отправку поддельных частей. Он может быть использован как более быстрая - альтернатива --wsize. +* **method** - начало метода HTTP ('GET', 'POST', 'HEAD', ...). Метод обычно всегда находится на позиции 0, но поддерживается и нахождение метода после дурение методом `--methodeol` от tpws. Тогда позиция может стать 1 или 2. +* **host** - начало имени хоста в известном протоколе (http, TLS) +* **endhost** - конец имени хоста +* **sld** - начало домена 2 уровня в имени хоста +* **endsld** - конец домена 2 уровня в имени хоста +* **midsld** - середина домена 2 уровня в имени хоста +* **sniext** - начало поля данных SNI extension в TLS. Любой extension состоит из 2-байтовых полей type и length, за ними идет поле данных. -`disorder2` и `split2` не предполагают отсылку фейк пакетов, поэтому опции ttl и fooling неактуальны. +Пример списка маркеров : `100,midsld,sniext+1,endhost-2,-10`. -`seqovl` добавляет в начало первой отсылаемой части оригинального пакета (1 часть для split и 2 часть для disorder) -`seqovl` байт со смещенным в минус sequence number на величину seqovl. В случае `split2` расчет идет на то, что предыдущий -отсыл, если он был, уже попал в сокет серверного приложения, поэтому новая пришедшая часть лишь частично находится в +При разбиении пакета первым делом происходит ресолвинг маркеров - нахождение всех указанных относительных позиций и применение смещений. +Если относительная позиция отсутствует в текущем протоколе, такие позиции не применяются и отбрасываются. +Дальше происходит нормализация позиций относительно смещения текущего пакета в группе пакетов (многопакетные запросы TLS с kyber, например). +Выкидываются все позиции, выходящие за пределы текущего пакета. Оставшиеся сортируются в порядке возрастания и удаляются дубли. +В вариантах `multisplit` и `multidisorder` если не осталось ни одной позиции, разбиение не происходит. + +Варианты `fakedsplit` и `fakeddisorder` применяют только одну позицию сплита. Ее поиск среди списка `--dpi-desync-split-pos` осуществляется особым образом. +Сначала сверяются все относительные маркеры. Если среди них найден подходящий, применяется он. В противном случае сверяются все абсолютные маркеры. +Если и среди них ничего не найдено, применяется позиция 1. + +Например, можно написать `--dpi-desync-split-pos=method+2,midsld,5`. Если протокол http, разбиение будет на позиции `method+2`. +Если протокол TLS - на позиции `midsld`. Если протокол неизвестен и включено `--dpi-desync-any-protocol`, разбиение будет на позиции 5. +Чтобы все было однозначнее, можно использовать разные профили для разных протоколов и указывать только одну позицию, которая точно есть в этом протоколе. + +### ПЕРЕКРЫТИЕ SEQUENCE NUMBERS + +`seqovl` добавляет в начало одного из TCP сегментов `seqovl` байт со смещенным в минус sequence number на величину `seqovl`. +Для `split` - в начало первого сегмента, для `disorder` - в начало предпоследнего отсылаемого сегмента (второго в оригинальном порядке следования). + +В случае `split` расчет идет на то, что предыдущий отсыл, если он был, уже попал в сокет серверного приложения, поэтому новая пришедшая часть лишь частично находится в пределах текущего окна (in-window). Спереди фейковая часть отбрасывается, а оставшаяся часть содержит оригинал и начинается с начала window, поэтому попадает в сокет. Серверное приложение получает все, что реально отсылает клиент, -отбрасывая фейковую out-of-window часть. Но DPI не может этого понять, поэтому у него происходит sequence -десинхронизация. +отбрасывая фейковую out-of-window часть. Но DPI не может этого понять, поэтому у него происходит sequence десинхронизация. +Обязательно, чтобы первый сегмент вместе с `seqovl` не превысили длину MTU. Эта ситуация распознается автоматически в Linux, и `seqovl` отменяется. +В остальных системах ситуация не распознается, и это приведет к поломке соединения. Поэтому выбирайте первую позицию сплита и `seqovl` таким образом, чтобы MTU не был превышен в любом случае. +Иначе дурение может не работать или работать хаотично. -Для `disorder2` overlap идет на 2-ю часть пакета. Обязательно, чтобы `seqovl` был меньше `split_pos`, иначе -все отосланное будет передано в сокет сразу же, включая фейк, ломая протокол прикладного уровня. -При соблюдении этого условия 2-я часть пакета является полностью in-window, -поэтому серверная ОС принимает ее целиком, включая фейк. Но поскольку начальная часть данных из 1 пакета -еще не принята, то фейк и реальные данные остаются в памяти ядра, не отправляясь в серверное приложение. +Для `disorder` overlap идет на предпоследнюю отсылаемую часть пакета. +Для простоты будем считать, что разбиение идет на 2 части, шлются они в порядке "2 1" при оригинальном порядке "1 2". +Обязательно, чтобы `seqovl` был меньше позиции первого сплита, иначе все отосланное будет передано в сокет сразу же, включая фейк, ломая протокол прикладного уровня. +Такая ситуация легко обнаруживается программой, и `seqovl` отменяется. Увеличение размера пакета невозможно в принципе. +При соблюдении условия 2-я часть пакета является полностью in-window, поэтому серверная ОС принимает ее целиком, включая фейк. +Но поскольку начальная часть данных из 1 пакета еще не принята, то фейк и реальные данные остаются в памяти ядра, не отправляясь в серверное приложение. Как только приходит 1-я часть пакета, она переписывает фейковую часть в памяти ядра. Ядро получает данные из 1 и 2 части, поэтому далее идет отправка в сокет приложения. Таково поведение всех unix ОС, кроме solaris - оставлять последние принятые данные. @@ -441,7 +472,13 @@ Windows оставляет старые данные, поэтому disorder с при работе с Windows серверами. Solaris практически мертв, windows серверов очень немного. Можно использовать листы при необходимости. Метод позволяет обойтись без fooling и TTL. Фейки перемешаны с реальным данными. -`split/disorder` вместо `split2/disorder2` по-прежнему добавляют дополнительные отдельные фейки. +`fakedsplit/fakeddisorder` по-прежнему добавляют дополнительные отдельные фейки. + +`seqovl` в варианте `split` может быть только абсолютным положительным значением, поскольку применяется только в первому пакету. +В варианте `disorder` допустимо применение всех вариантов маркеров. +Они автоматически нормализуются к текущему пакету в серии. Можно сплитать на `midsld` и делать seqovl на `midsld-1`. + +### СПЕЦИФИЧЕСКИЕ РЕЖИМЫ IPV6 Режимы десинхронизации `hopbyhop`, `destopt` и `ipfrag1` (не путать с fooling !) относятся только к `ipv6` и заключается в добавлении хедера `hop-by-hop options`, `destination options` или `fragment` во все пакеты, попадающие под десинхронизацию. @@ -452,10 +489,22 @@ Windows оставляет старые данные, поэтому disorder с extension хедерам в поисках транспортного хедера. Таким образом не поймет, что это tcp или udp, и пропустит пакет без анализа. Возможно, какие-то DPI на это купятся. Может сочетаться с любыми режимами 2-й фазы, кроме варианта `ipfrag1+ipfrag2`. -Например, `hopbyhop,split2` означает разбить tcp пакет на 2 сегмента, в каждый из них добавить hop-by-hop. +Например, `hopbyhop,multisplit` означает разбить tcp пакет на несколько сегментов, в каждый из них добавить hop-by-hop. При `hopbyhop,ipfrag2` последовательность хедеров будет : `ipv6,hop-by-hop`,`fragment`,`tcp/udp`. Режим `ipfrag1` может срабатывать не всегда без специальной подготовки. См. раздел `IP фрагментация`. +### КОМБИНИРОВАНИЕ МЕТОДОВ ДЕСИНХРОНИЗАЦИИ + +В параметре dpi-desync можно указать до 3 режимов через запятую. + +* 0 фаза - предполагает работу на этапе установления соединения : `synack`, `syndata` `--wsize`, `--wssize`. +* 1 фаза - отсылка чего-либо до оригинального пакета данных : `fake`, `rst`, `rstack`. +* 2 фаза - отсылка в модифицированном виде оригинального пакета данных (например, `fakedsplit` или `ipfrag2`). + +Режимы требуют указания в порядке возрастания номеров фаз. + +### РЕАКЦИЯ DPI НА ОТВЕТ СЕРВЕРА + Есть DPI, которые анализируют ответы от сервера, в частности сертификат из ServerHello, где прописаны домены. Подтверждением доставки ClientHello является ACK пакет от сервера с номером ACK sequence, соответствующим длине ClientHello+1. В варианте disorder обычно приходит сперва частичное подтверждение (SACK), потом полный ACK. @@ -470,8 +519,7 @@ DPI может отстать от потока, если ClientHello его у Лучшее решение - включить на сервере поддержку TLS 1.3. В нем сертификат сервера передается в зашифрованном виде. Это рекомендация ко всем админам блокируемых сайтов. Включайте TLS 1.3. Так вы дадите больше возможностей преодолеть DPI. -Хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello. -Субдомены учитываются автоматически. Поддерживаются листы gzip. +### IPTABLES ДЛЯ NFQWS iptables для задействования атаки на первый пакет данных : @@ -494,19 +542,10 @@ mark нужен, чтобы сгенерированный поддельный Процесс может зависнуть. Поэтому наличие фильтра по mark в ip/nf tables можно считать обязательным. Почему --connbytes 1:6 : -1 - для работы методов десинхронизации 0-й фазы и wssize -2 - иногда данные идут в 3-м пакете 3-way handshake -3 - стандартная ситуация приема одного пакета запроса -4-6 - на случай ретрансмиссии или запроса длиной в несколько пакетов (TLSClientHello с kyber, например) - -### КОМБИНИРОВАНИЕ МЕТОДОВ ДЕСИНХРОНИЗАЦИИ - -В параметре dpi-desync можно указать до 3 режимов через запятую. -0 фаза предполагает работу на этапе установления соединения. Может быть `synack` или `syndata`. -На 0 фазу не действует фильтр по hostlist. -Последующие режимы отрабатывают на пакетах с данными. -Режим 1-й фазы может быть `fake`, `rst`, `rstack`. Режим 2-й фазы может быть `disorder`, `disorder2`, `split`, `split2`, `ipfrag2`. -Может быть полезно, когда у провайдера стоит не один DPI. +* 1 - для работы методов десинхронизации 0-й фазы и корректной работы conntrack +* 2 - иногда данные идут в 3-м пакете 3-way handshake +* 3 - стандартная ситуация приема одного пакета запроса +* 4-6 - на случай ретрансмиссии или запроса длиной в несколько пакетов (TLSClientHello с kyber, например) ### РЕЖИМ SYNACK @@ -617,10 +656,10 @@ chrome рандомизирует фингерпринт TLS. SNI может о При любой ошибке в процессе сборки задержанные пакеты немедленно отсылаются в сеть, а десинхронизация отменяется. Есть специальная поддержка всех вариантов tcp сплита для многосегментного TLS. -Если указать позицию сплита больше длины первого пакета или использовать --dpi-desync-split-tls, -то разбивка происходит не обязательно первого пакета, а того, на который пришлась итоговая позиция. -Если, допустим, клиент послал TLS ClientHello длиной 2000, а SNI начинается с 1700, -и заданы опции fake,split2, то перед первым пакетом идет fake, затем первый пакет в оригинале, +Если указать позицию сплита больше длины первого пакета, то разбивка происходит не обязательно первого пакета, а того, +на который пришлась итоговая позиция. +Если, допустим, клиент послал TLS ClientHello длиной 2000, SNI начинается с 1700, +и заданы опции `fake,multisplit`, то перед первым пакетом идет fake, затем первый пакет в оригинале, а последний пакет разбивается на 2 сегмента. В итоге имеем фейк в начале и 3 реальных сегмента. ### ПОДДЕРЖКА UDP @@ -741,99 +780,197 @@ L7 протокол становится известен обычно посл tpws - это transparent proxy. ``` -@|$ ; читать конфигурацию из файла. опция должна быть первой. остальные опции игнорируются. +@|$ ; читать конфигурацию из файла. опция должна быть первой. остальные опции игнорируются. ---debug=0|1|2|syslog|@ ; 0,1,2 = логирование на косоль : 0=тихо, 1(default)=подробно, 2=отладка. ---debug-level=0|1|2 ; указать уровень логирования для syslog и @ ---daemon ; демонизировать прогу ---pidfile= ; сохранить PID в файл ---user= ; менять uid процесса ---uid=uid[:gid] ; менять uid процесса ---bind-addr ; на каком адресе слушать. может быть ipv4 или ipv6 адрес - ; если указан ipv6 link local, то требуется указать с какого он интерфейса : fe80::1%br-lan +--debug=0|1|2|syslog|@ ; 0,1,2 = логирование на косоль : 0=тихо, 1(default)=подробно, 2=отладка. +--debug-level=0|1|2 ; указать уровень логирования для syslog и @ +--daemon ; демонизировать прогу +--pidfile= ; сохранить PID в файл +--user= ; менять uid процесса +--uid=uid[:gid] ; менять uid процесса +--bind-addr ; на каком адресе слушать. может быть ipv4 или ipv6 адрес + ; если указан ipv6 link local, то требуется указать с какого он интерфейса : fe80::1%br-lan --bind-linklocal=no|unwanted|prefer|force - ; no : биндаться только на global ipv6 - ; unwanted (default) : предпочтительно global, если нет - LL - ; prefer : предпочтительно LL, если нет - global - ; force : биндаться только на LL ---bind-iface4= ; слушать на первом ipv4 интерфейса iface ---bind-iface6= ; слушать на первом ipv6 интерфейса iface ---bind-wait-ifup= ; ждать до N секунд получения IP адреса (если задан --bind-wait-ifup - время идет после поднятия интерфейса) + ; no : биндаться только на global ipv6 + ; unwanted (default) : предпочтительно global, если нет - LL + ; prefer : предпочтительно LL, если нет - global + ; force : биндаться только на LL +--bind-iface4= ; слушать на первом ipv4 интерфейса iface +--bind-iface6= ; слушать на первом ipv6 интерфейса iface +--bind-wait-ifup= ; ждать до N секунд получения IP адреса (если задан --bind-wait-ifup - время идет после поднятия интерфейса) --bind-wait-ip-linklocal= - ; имеет смысл только при задании --bind-wait-ip - ; --bind-linklocal=unwanted : согласиться на LL после N секунд - ; --bind-linklocal=prefer : согласиться на global address после N секунд ---bind-wait-only ; подождать все бинды и выйти. результат 0 в случае успеха, иначе не 0. ---connect-bind-addr ; с какого адреса подключаться во внешнюю сеть. может быть ipv4 или ipv6 адрес - ; если указан ipv6 link local, то требуется указать с какого он интерфейса : fe80::1%br-lan - ; опция может повторяться для v4 и v6 адресов - ; опция не отменяет правил маршрутизации ! выбор интерфейса определяется лишь правилами маршрутизации, кроме случая v6 link local. ---socks ; вместо прозрачного прокси реализовать socks4/5 proxy ---no-resolve ; запретить ресолвинг имен через socks5 ---resolve-threads ; количество потоков ресолвера ---port= ; на каком порту слушать ---maxconn= ; максимальное количество соединений от клиентов к прокси ---maxfiles= ; макс количество файловых дескрипторов (setrlimit). мин требование (X*connections+16), где X=6 в tcp proxy mode, X=4 в режиме тамперинга. - ; стоит сделать запас с коэффициентом как минимум 1.5. по умолчанию maxfiles (X*connections)*1.5+16 ---max-orphan-time= ; если вы запускаете через tpws торрент-клиент с множеством раздач, он пытается установить очень много исходящих соединений, - ; большая часть из которых отваливается по таймауту (юзера сидят за NAT, firewall, ...) - ; установление соединения в linux может длиться очень долго. локальный конец отвалился, перед этим послав блок данных, - ; tpws ждет подключения удаленного конца, чтобы отослать ему этот блок, и зависает надолго. - ; настройка позволяет сбрасывать такие подключения через N секунд, теряя блок данных. по умолчанию 5 сек. 0 означает отключить функцию - ; эта функция не действует на успешно подключенные ранее соединения + ; имеет смысл только при задании --bind-wait-ip + ; --bind-linklocal=unwanted : согласиться на LL после N секунд + ; --bind-linklocal=prefer : согласиться на global address после N секунд +--bind-wait-only ; подождать все бинды и выйти. результат 0 в случае успеха, иначе не 0. +--connect-bind-addr ; с какого адреса подключаться во внешнюю сеть. может быть ipv4 или ipv6 адрес + ; если указан ipv6 link local, то требуется указать с какого он интерфейса : fe80::1%br-lan + ; опция может повторяться для v4 и v6 адресов + ; опция не отменяет правил маршрутизации ! выбор интерфейса определяется лишь правилами маршрутизации, кроме случая v6 link local. +--socks ; вместо прозрачного прокси реализовать socks4/5 proxy +--no-resolve ; запретить ресолвинг имен через socks5 +--resolve-threads ; количество потоков ресолвера +--port= ; на каком порту слушать +--maxconn= ; максимальное количество соединений от клиентов к прокси +--maxfiles= ; макс количество файловых дескрипторов (setrlimit). мин требование (X*connections+16), где X=6 в tcp proxy mode, X=4 в режиме тамперинга. + ; стоит сделать запас с коэффициентом как минимум 1.5. по умолчанию maxfiles (X*connections)*1.5+16 +--max-orphan-time= ; если вы запускаете через tpws торрент-клиент с множеством раздач, он пытается установить очень много исходящих соединений, + ; большая часть из которых отваливается по таймауту (юзера сидят за NAT, firewall, ...) + ; установление соединения в linux может длиться очень долго. локальный конец отвалился, перед этим послав блок данных, + ; tpws ждет подключения удаленного конца, чтобы отослать ему этот блок, и зависает надолго. + ; настройка позволяет сбрасывать такие подключения через N секунд, теряя блок данных. по умолчанию 5 сек. 0 означает отключить функцию + ; эта функция не действует на успешно подключенные ранее соединения ---local-rcvbuf= ; SO_RCVBUF для соединений client-proxy ---local-sndbuf= ; SO_SNDBUF для соединений client-proxy ---remote-rcvbuf= ; SO_RCVBUF для соединений proxy-target ---remote-sndbuf= ; SO_SNDBUF для соединений proxy-target ---nosplice ; не использовать splice на linux системах ---skip-nodelay ; не устанавливать в исходящих соединения TCP_NODELAY. несовместимо со split. ---local-tcp-user-timeout= ; таймаут соединений client-proxy (по умолчанию : 10 сек, 0 = оставить системное значение) ---remote-tcp-user-timeout= ; таймаут соединений proxy-target (по умолчанию : 20 сек, 0 = оставить системное значение) +--local-rcvbuf= ; SO_RCVBUF для соединений client-proxy +--local-sndbuf= ; SO_SNDBUF для соединений client-proxy +--remote-rcvbuf= ; SO_RCVBUF для соединений proxy-target +--remote-sndbuf= ; SO_SNDBUF для соединений proxy-target +--nosplice ; не использовать splice на linux системах +--skip-nodelay ; не устанавливать в исходящих соединения TCP_NODELAY. несовместимо со split. +--local-tcp-user-timeout= ; таймаут соединений client-proxy (по умолчанию : 10 сек, 0 = оставить системное значение) +--remote-tcp-user-timeout= ; таймаут соединений proxy-target (по умолчанию : 20 сек, 0 = оставить системное значение) ---split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host ---split-pos= ; делить все посылы на сегменты в указанной позиции. единственная опция, работающая на не-http. при указании split-http-req он имеет преимущество на http. ---split-any-protocol ; применять split-pos к любым пакетам. по умолчанию - только к http и TLS ClientHello ---disorder[=http|tls] ; путем манипуляций с сокетом вынуждает отправлять первым второй сегмент разделенного запроса ---oob[=http|tls] ; отправить байт out-of-band data (OOB) в конце первой части сплита ---oob-data=|0xHEX ; переопределить байт OOB. по умолчанию 0x00. ---hostcase ; менять регистр заголовка "Host:". по умолчанию на "host:". ---hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase ---hostdot ; добавление точки после имени хоста : "Host: kinozal.tv." ---hosttab ; добавление табуляции после имени хоста : "Host: kinozal.tv\t" ---hostnospace ; убрать пробел после "Host:" ---hostpad= ; добавить паддинг-хедеров общей длиной перед Host: ---domcase ; домен после Host: сделать таким : TeSt.cOm ---methodspace ; добавить пробел после метода : "GET /" => "GET /" ---methodeol ; добавить перевод строки перед методом : "GET /" => "\r\nGET /" ---unixeol ; конвертировать 0D0A в 0A и использовать везде 0A ---tlsrec=sni|sniext ; разбивка TLS ClientHello на 2 TLS records. режем между 1 и 2 символами hostname в SNI или между байтами длины SNI extension. Если SNI нет - отмена. ---tlsrec-pos= ; разбивка TLS ClientHello на 2 TLS records. режем на указанной позиции, если длина слишком мелкая - на позиции 1. ---mss= ; установить MSS для клиента. может заставить сервер разбивать ответы, но существенно снижает скорость ---mss-pf=[~]port1[-port2] ; применять MSS только к портам назначения, подпадающим под фильтр. ~ означает инверсию ---tamper-start=[n] ; начинать дурение только с указанной байтовой позиции или номера блока исходяшего потока (считается позиция начала принятого блока) ---tamper-cutoff=[n] ; закончить дурение на указанной байтовой позиции или номере блока исходящего потока (считается позиция начала принятого блока) ---hostlist= ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются. - ; в файле должен быть хост на каждой строке. - ; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска. - ; при изменении времени модификации файла он перечитывается автоматически по необходимости - ; список может быть запакован в gzip. формат автоматически распознается и разжимается - ; списков может быть множество. пустой общий лист = его отсутствие - ; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello. ---hostlist-exclude= ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам. ---hostlist-auto= ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика) ---hostlist-auto-fail-threshold= ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3) ---hostlist-auto-fail-time= ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60) ---hostlist-auto-debug= ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты. ---new ; начало новой стратегии (новый профиль) ---filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии ---filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. поддерживается список через запятую. +--split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации +--split-any-protocol ; применять сегментацию к любым пакетам. по умолчанию - только к известным протоколам (http, TLS) +--disorder[=http|tls] ; путем манипуляций с сокетом вынуждает отправлять первым второй сегмент разделенного запроса +--oob[=http|tls] ; отправить байт out-of-band data (OOB) в конце первой части сплита +--oob-data=|0xHEX ; переопределить байт OOB. по умолчанию 0x00. +--hostcase ; менять регистр заголовка "Host:". по умолчанию на "host:". +--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase +--hostdot ; добавление точки после имени хоста : "Host: kinozal.tv." +--hosttab ; добавление табуляции после имени хоста : "Host: kinozal.tv\t" +--hostnospace ; убрать пробел после "Host:" +--hostpad= ; добавить паддинг-хедеров общей длиной перед Host: +--domcase ; домен после Host: сделать таким : TeSt.cOm +--methodspace ; добавить пробел после метода : "GET /" => "GET /" +--methodeol ; добавить перевод строки перед методом : "GET /" => "\r\nGET /" +--unixeol ; конвертировать 0D0A в 0A и использовать везде 0A +--tlsrec=N|-N|marker+N|marker-N ; разбивка TLS ClientHello на 2 TLS records на указанной позиции. Минимальное смещение - 6. +--mss= ; установить MSS для клиента. может заставить сервер разбивать ответы, но существенно снижает скорость +--mss-pf=[~]port1[-port2] ; применять MSS только к портам назначения, подпадающим под фильтр. ~ означает инверсию +--tamper-start=[n] ; начинать дурение только с указанной байтовой позиции или номера блока исходяшего потока (считается позиция начала принятого блока) +--tamper-cutoff=[n] ; закончить дурение на указанной байтовой позиции или номере блока исходящего потока (считается позиция начала принятого блока) +--hostlist= ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются. + ; в файле должен быть хост на каждой строке. + ; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска. + ; при изменении времени модификации файла он перечитывается автоматически по необходимости + ; список может быть запакован в gzip. формат автоматически распознается и разжимается + ; списков может быть множество. пустой общий лист = его отсутствие + ; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello. +--hostlist-exclude= ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам. +--hostlist-auto= ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика) +--hostlist-auto-fail-threshold= ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3) +--hostlist-auto-fail-time= ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60) +--hostlist-auto-debug= ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты. +--new ; начало новой стратегии (новый профиль) +--filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии +--filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. поддерживается список через запятую. --filter-l7=[http|tls|quic|wireguard|dht|unknown] ; фильтр протокола L6-L7. поддерживается несколько значений через запятую. ---ipset= ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая. ---ipset-exclude= ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая. +--ipset= ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая. +--ipset-exclude= ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая. ``` +### TCP СЕГМЕНТАЦИЯ В TPWS + +tpws, как и nfqws, поддерживает множественную сегментацию запросов. Сплит позиции задаются в `--split-pos`. +Указываются маркеры через запятую. Описание маркеров см в разделе [nfqws](#tcp-сегментация). + +На прикладном уровне в общем случае нет гарантированного средства заставить ядро выплюнуть +блок данных, порезанным в определенном месте. ОС держит буфер отсылки (SNDBUF) у каждого сокета. +Если у сокета включена опция TCP_NODELAY и буфер пуст, то каждый send приводит к отсылке +отдельного ip пакета или группы пакетов, если блок не вмещается в один ip пакет. +Однако, если в момент send уже имеется неотосланный буфер, то ОС присоединит данные к нему, +никакой отсылки отдельным пакетом не будет. Но в этом случае и так нет никакой гарантии, +что какой-то блок сообщения пойдет в начале пакета, на что собственно и заточены DPI. +Разбиение будет производится согласно MSS, который зависит от MTU исходящего интерфейса. +Таким образом DPI, смотрящие в начало поля данных TCP пакета, будут поломаны в любом случае. +Протокол http относится к запрос-ответным протоколам. Новое сообщение посылается только тогда, +когда сервер получил запрос и полностью вернул ответ. Значит запрос фактически был не только отослан, +но и принят другой стороной, а следовательно буфер отсылки пуст, и следующие 2 send приведут +к отсылке сегментов данных разными ip пакетами. + +Таким образом tpws обеспечивает сплит только за счет раздельных вызовов send, и это обычно работает надежно, +если разбивать не на слишком много частей и не на слишком мелкие подряд следующие части. +В последнем случае Linux все же может обьединить некоторые части, что приведет к несоответствию реальной сегментации +указанным сплит позициям. Другие ОС в этом вопросе ведут себя более предсказуемо. Спонтанного обьединения замечено не было. +Поэтому не стоит злоупотреблять сплитами и в особенности мелкими соседними пакетами. + +tpws работает на уровне сокетов, поэтому длинный запрос, не вмещающийся в 1 пакет (TLS с kyber), он получает целым блоком. +На каждую сплит часть он делает отдельный вызов `send()`. Но ОС не сможет отослать данные в одном пакете, если размер превысит MTU. +В случае слишком большого сегмента ОС дополнительно его порежет на более мелкие. Результат должен быть аналогичен nfqws. + +`--disorder` заставляет слать каждый 2-й пакет с TTL=1, начиная с первого. +К серверу приходят все четные пакеты сразу. На остальные ОС делает ретрансмиссию, и они приходят потом. +Это само по себе создает дополнительную задержку (200 мс в linux для первой ретрансмиссии). +Иным способом сделать disorder в сокет варианте не представляется возможным. +Итоговый порядок для 6 сегментов получается `2 4 6 1 3 5`. + +`--oob` высылает 1 байт out-of-band data после первого сплит сегмента. `oob` в каждом сегменте сплита показал себя ненадежным. +Сервер получает oob в сокет. + +Сочетание `oob` и `disorder` возможно только в Linux. Остальные ОС не умеют с таким справляться. Флаг URG теряется при ретрансмиссиях. +Сервер получает oob в сокет. Сочетание этих параметров в ос, кроме Linux, вызывает ошибку на этапе запуска. + +### TLSREC + +`--tlsrec` позволяют внутри одного tcp сегмента разрезать TLS ClientHello на 2 TLS records. Можно использовать стандартный +механизм маркеров для задания относительных позиций. + +`--tlsrec` ломает значительное количество сайтов. Криптобиблиотеки (openssl, ...) на оконечных http серверах +без проблем принимают разделенные tls сегменты, но мидлбоксы - не всегда. К мидлбоксам можно отнести CDN +или системы ddos-защиты. Поэтому применение `--tlsrec` без ограничителей вряд ли целесообразно. +В РФ `--tlsrec` обычно не работает с TLS 1.2, потому что цензор парсит сертификат сервера из ServerHello. +Работает только с TLS 1.3, поскольку там эта информация шифруется. +Впрочем, сейчас сайтов, не поддерживающих TLS 1.3, осталось немного. + +### MSS + +`--mss` устанавливает опцию сокета TCP_MAXSEG. Клиент выдает это значение в tcp опциях SYN пакета. +Сервер в ответ в SYN,ACK выдает свой MSS. На практике сервера обычно снижают размеры отсылаемых ими пакетов, но они +все равно не вписываются в низкий MSS, указанный клиентом. Обычно чем больше указал клиент, тем больше +шлет сервер. На TLS 1.2 если сервер разбил заброс так, чтобы домен из сертификата не попал в первый пакет, +это может обмануть DPI, секущий ответ сервера. +Схема может значительно снизить скорость и сработать не на всех сайтах. +С фильтром по hostlist совместимо только в режиме socks при включенном удаленном ресолвинге хостов. +(firefox network.proxy.socks_remote_dns). Это единственный вариант, когда tpws может узнать имя хоста +еще на этапе установления соединения. +Применяя данную опцию к сайтам TLS1.3, если броузер тоже поддерживает TLS1.3, то вы делаете только хуже. +Но нет способа автоматически узнать когда надо применять, когда нет, поскольку MSS идет только в +3-way handshake еще до обмена данными, а версию TLS можно узнать только по ответу сервера, который +может привести к реакции DPI. +Использовать только когда нет ничего лучше или для отдельных ресурсов. +Для http использовать смысла нет, поэтому заводите отдельный desync profile с фильтром по порту 443. +Работает только на Linux, не работает на BSD и MacOS. + +### ДРУГИЕ ПАРАМЕТРЫ ДУРЕНИЯ + +Параметр `--hostpad=` добавляет паддинг-хедеров перед `Host:` на указанное количество байтов. +Если размер `` слишком большой, то идет разбивка на разные хедеры по 2K. +Общий буфер приема http запроса - 64K, больший паддинг не поддерживается, да и http сервера +такое уже не принимают. +Полезно против DPI, выполняющих реассемблинг TCP с ограниченным буфером. +Если техника работает, то после некоторого количества bytes http запрос начнет проходить до сайта. +Если при этом критический размер padding около MTU, значит скорее всего DPI не выполняет реассемблинг пакетов, и лучше будет использовать обычные опции TCP сегментации. +Если все же реассемблинг выполняется, то критический размер будет около размера буфера DPI. Он может быть 4K или 8K, возможны и другие значения. + +### МНОЖЕСТВЕННЫЕ СТРАТЕГИИ + +Работают аналогично `nfqws`, кроме некоторых моментов. +Нет параметра `--filter-udp`, поскольку `tpws` udp не поддерживает. +Методы нулевой фазы (`--mss`) могут работать по хостлисту в одном единственном случае: +если используется режим socks и удаленный ресолвинг хостов через прокси. +То есть работоспособность вашей настройки в одном и том же режиме может зависеть от того, +применяет ли клиент удаленный ресолвинг. Это может быть неочевидно. +В одной программе работает, в другой - нет. +Если вы используете профиль с хостлистом , и вам нужен mss, укажите mss в профиле с хостлистом, +создайте еще один профиль без хостлиста, если его еще нет, и в нем еще раз укажите mss. +Тогда при любом раскладе будет выполняться mss. +Используйте `curl --socks5` и `curl --socks5-hostname` для проверки вашей стратегии. +Смотрите вывод `--debug`, чтобы убедиться в правильности настроек. + +### СЛУЖЕБНЫЕ ПАРАМЕТРЫ + `--debug` позволяет выводить подробный лог действий на консоль, в syslog или в файл. Может быть важен порядок следования опций. `--debug` лучше всего указывать в самом начале. Опции анализируются последовательно. Если ошибка будет при проверке опции, а до анализа `--debug` еще дело не дошло, @@ -850,28 +987,6 @@ tpws - это transparent proxy. Вместо удаления лучше использовать truncate. В шелле это можно сделать через команду ": >filename" -Параметры манипуляции могут сочетаться в любых комбинациях. - -В случае http запроса `split-http-req` имеет преимущество над split-pos. -split-pos по умолчанию работает только на http и TLS ClientHello. -Чтобы он работал на любых пакетах, укажите `--split-any-protocol`. - -На прикладном уровне в общем случае нет гарантированного средства заставить ядро выплюнуть -блок данных, порезанным в определенном месте. ОС держит буфер отсылки (SNDBUF) у каждого сокета. -Если у сокета включена опция TCP_NODELAY и буфер пуст, то каждый send приводит к отсылке -отдельного ip пакета или группы пакетов, если блок не вмещается в один ip пакет. -Однако, если в момент send уже имеется неотосланный буфер, то ОС присоединит данные к нему, -никакой отсылки отдельным пакетом не будет. Но в этом случае и так нет никакой гарантии, -что какой-то блок сообщения пойдет в начале пакета, на что собственно и заточены DPI. -Разбиение будет производится согласно MSS, который зависит от MTU исходящего интерфейса. -Таким образом DPI, смотрящие в начало поля данных TCP пакета, будут поломаны в любом случае. -Протокол http относится к запрос-ответным протоколам. Новое сообщение посылается только тогда, -когда сервер получил запрос и полностью вернул ответ. Значит запрос фактически был не только отослан, -но и принят другой стороной, а следовательно буфер отсылки пуст, и следующие 2 send приведут -к отсылке сегментов данных разными ip пакетами. -Резюме : tpws гарантирует сплит только за счет раздельных вызовов send, что на практике -вполне достаточно для протоколов http(s). - tpws может биндаться на множество интерфейсов и IP адресов (до 32 шт). Порт всегда только один. Параметры `--bind-iface*` и `--bind-addr` создают новый бинд. @@ -895,19 +1010,17 @@ tpws может биндаться на множество интерфейсо Параметры rcvbuf и sndbuf позволяют установить setsockopt SO_RCVBUF SO_SNDBUF для локального и удаленного соединения. -Если не указан ни один из параметров модификации содержимого, tpws работает в режиме `tcp proxy mode`. -Он отличается тем, что в оба конца применяется splice для переброски данных из одного сокета в другой -без копирования в память процесса. Практически - это то же самое, но может быть чуть побыстрее. -TCP проксирование может быть полезно для обхода блокировок, когда DPI спотыкается на экзотических -хедерах IP или TCP. Вы вряд ли сможете поправить хедеры, исходящие от айфончиков и гаджетиков, -но на linux сможете влиять на них в какой-то степени через `sysctl`. -Когда соединение проходит через tpws, фактически прокси-сервер сам устанавливает подключение к удаленному -узлу от своего имени, и на это распространяются настройки системы, на которой работает прокси. -tpws можно использовать на мобильном устройстве, раздающем интернет на тарифе сотового оператора, -где раздача запрещена, в socks режиме даже без рута. Соединения от tpws неотличимы от соединений -с самого раздающего устройства. Отличить можно только по содержанию (типа обновлений windows). -Заодно можно и обойти блокировки. 2 зайца одним выстрелом. -Более подробную информацию по вопросу обхода ограничений операторов гуглите на 4pda.ru. +`--skip-nodelay` может быть полезен, когда tpws используется без дурения, чтобы привести MTU к MTU системы, на которой работает tpws. +Это может быть полезно для скрытия факта использования VPN. Пониженный MTU - 1 из способов обнаружения +подозрительного подключения. С tcp proxy ваши соединения неотличимы от тех, что сделал бы сам шлюз. + +`--local-tcp-user-timeout` и `--remote-tcp-user-timeout` устанавливают значение таймаута в секундах +для соединений клиент-прокси и прокси-сервер. Этот таймаут соответствует опции сокета linux +TCP_USER_TIMEOUT. Под таймаутом подразумевается время, в течение которого буферизированные данные +не переданы или на переданные данные не получено подтверждение (ACK) от другой стороны. +Этот таймаут никак не касается времени отсутствия какой-либо передачи через сокет лишь потому, +что данных для передачи нет. Полезно для сокращения время закрытия подвисших соединений. +Поддерживается только на Linux и MacOS. Режим `--socks` не требует повышенных привилегий (кроме бинда на привилегированные порты 1..1023). Поддерживаются версии socks 4 и 5 без авторизации. Версия протокола распознается автоматически. @@ -921,82 +1034,6 @@ tpws поддерживает эту возможность асинхронно Если задан параметр `--no-resolve`, то подключения по именам хостов запрещаются, а пул ресолверов не создается. Тем самым экономятся ресурсы. -Параметр `--hostpad=` добавляет паддинг-хедеров перед Host: на указанное количество байтов. -Если размер `` слишком большой, то идет разбивка на разные хедеры по 2K. -Общий буфер приема http запроса - 64K, больший паддинг не поддерживается, да и http сервера -такое уже не принимают. -Полезно против DPI, выполняющих реассемблинг TCP с ограниченным буфером. -Если техника работает, то после некоторого количества bytes http запрос начнет проходить до сайта. -Если при этом критический размер padding около MTU, значит скорее всего DPI не выполняет реассемблинг пакетов, и лучше будет использовать обычные опции `--split-…` -Если все же реассемблинг выполняется, то критический размер будет около размера буфера DPI. Он может быть 4K или 8K, возможны и другие значения. - -`--disorder` - это попытка симулировать режим `disorder2 nfqws`, используя особенности ОС по реализации stream сокетов. -Однако, в отличие от nfqws, здесь не требуются повышенные привилегии. -Реализовано это следующим образом. У сокета есть возможность выставить TTL. Все пакеты будут отправляться с ним. -Перед отправкой первого сегмента ставим TTL=1. Пакет будет дропнут на первом же роутере, он не дойдет ни до DPI, ни до сервера. -Затем возвращаем TTL в значение по умолчанию. ОС отсылает второй сегмент, и он уже доходит до сервера. -Сервер возвращает SACK, потому что не получил первый кусок, и ОС его отправляет повторно, но здесь уже мы ничего не делаем. -Этот режим работает как ожидается на Linux и MacOS. Однако, на FreeBSD и OpenBSD он работает не так хорошо. -Ядро этих ОС отсылает ретрансмиссию в виде полного пакета. Потому выходит, что до сервера идет сначала второй кусок, -а потом полный запрос без сплита. На него может отреагировать DPI штатным образом. -`--disorder` является дополнительным флагом к любому сплиту. Сам по себе он не делает ничего. - -`--tlsrec` и `--tlsrec-pos` позволяют внутри одного tcp сегмента разрезать TLS ClientHello на 2 TLS records. -`--tlsrec=sni` режет между 1 и 2 символами hostname в SNI, делая невозможным бинарный поиск паттерна без анализа -структуры данных. В случае отсутствия SNI разбиение отменяется. -`--tlsrec-pos` режет на указанной позиции. Если длина блока данных TLS меньше указанной позиции, режем на позиции 1. -Параметр сочетается с `--split-pos`. В этом случае происходит сначала разделение на уровне TLS record layer, потом на уровне TCP. -Самая изощрённая атака `--tlsrec`, `--split-pos` и `--disorder` вместе. -`--tlsrec` ломает значительное количество сайтов. Криптобиблиотеки (openssl, ...) на оконечных http серверах -без проблем принимают разделенные tls сегменты, но мидлбоксы - не всегда. К мидлбоксам можно отнести CDN -или системы ddos-защиты. Поэтому применение `--tlsrec` без ограничителей вряд ли целесообразно. -В РФ `--tlsrec` обычно не работает с TLS 1.2, потому что цензор парсит сертификат сервера из ServerHello. -Работает только с TLS 1.3, поскольку там эта информация шифруется. -Впрочем, сейчас сайтов, не поддерживающих TLS 1.3, осталось немного. - -`--mss` устанавливает опцию сокета TCP_MAXSEG. Клиент выдает это значение в tcp опциях SYN пакета. -Сервер в ответ в SYN,ACK выдает свой MSS. На практике сервера обычно снижают размеры отсылаемых ими пакетов, но они -все равно не вписываются в низкий MSS, указанный клиентом. Обычно чем больше указал клиент, тем больше -шлет сервер. На TLS 1.2 если сервер разбил заброс так, чтобы домен из сертификата не попал в первый пакет, -это может обмануть DPI, секущий ответ сервера. -Схема может значительно снизить скорость и сработать не на всех сайтах. -С фильтром по hostlist совместимо только в режиме socks при включенном удаленном ресолвинге хостов. -(firefox network.proxy.socks_remote_dns). Это единственный вариант, когда tpws может узнать имя хоста -еще на этапе установления соединения. -Применяя данную опцию к сайтам TLS1.3, если броузер тоже поддерживает TLS1.3, то вы делаете только хуже. -Но нет способа автоматически узнать когда надо применять, когда нет, поскольку MSS идет только в -3-way handshake еще до обмена данными, а версию TLS можно узнать только по ответу сервера, который -может привести к реакции DPI. -Использовать только когда нет ничего лучше или для отдельных ресурсов. -Для http использовать смысла нет, поэтому заводите отдельный desync profile с фильтром по порту 443. -Работает только на linux, не работает на BSD и MacOS. - -`--skip-nodelay` может быть полезен, чтобы привести MTU к MTU системы, на которой работает tpws. -Это может быть полезно для скрытия факта использования VPN. Пониженный MTU - 1 из способов обнаружения -подозрительного подключения. С tcp proxy ваши соединения неотличимы от тех, что сделал бы сам шлюз. - -`--local-tcp-user-timeout` и `--remote-tcp-user-timeout` устанавливают значение таймаута в секундах -для соединений клиент-прокси и прокси-сервер. Этот таймаут соответствует опции сокета linux -TCP_USER_TIMEOUT. Под таймаутом подразумевается время, в течение которого буферизированные данные -не переданы или на переданные данные не получено подтверждение (ACK) от другой стороны. -Этот таймаут никак не касается времени отсутствия какой-либо передачи через сокет лишь потому, -что данных для передачи нет. Полезно для сокращения время закрытия подвисших соединений. -Поддерживается только на Linux и MacOS. - -### МНОЖЕСТВЕННЫЕ СТРАТЕГИИ - -Работают аналогично `nfqws`, кроме некоторых моментов. -Нет параметра `--filter-udp`, поскольку `tpws` udp не поддерживает. -Методы нулевой фазы (`--mss`) могут работать по хостлисту в одном единственном случае: -если используется режим socks и удаленный ресолвинг хостов через прокси. -То есть работоспособность вашей настройки в одном и том же режиме может зависеть от того, -применяет ли клиент удаленный ресолвинг. Это может быть неочевидно. -В одной программе работает, в другой - нет. -Если вы используете профиль с хостлистом , и вам нужен mss, укажите mss в профиле с хостлистом, -создайте еще один профиль без хостлиста, если его еще нет, и в нем еще раз укажите mss. -Тогда при любом раскладе будет выполняться mss. -Используйте `curl --socks5` и `curl --socks5-hostname` для проверки вашей стратегии. -Смотрите вывод `--debug`, чтобы убедиться в правильности настроек. ## Способы получения списка заблокированных IP @@ -1516,7 +1553,7 @@ nfqws начнет получать адреса пакетов из локал ``` TPWS_SOCKS_OPT=" --filter-tcp=80 --methodeol --new ---filter-tcp=443 --split-tls=sni --disorder " +--filter-tcp=443 --split-pos=1,midsld --disorder " ``` ***Включение стандартной опции tpws в прозрачном режиме***\ @@ -1529,7 +1566,7 @@ TPWS_SOCKS_OPT=" ``` TPWS_OPT=" --filter-tcp=80 --methodeol --new ---filter-tcp=443 --split-tls=sni --disorder " +--filter-tcp=443 --split-pos=1,midsld --disorder " ``` ***Включение стандартной опции nfqws***\ @@ -1566,9 +1603,9 @@ NFQWS_PORTS_UDP_KEEPALIVE= ***Параметры nfqws*** ``` NFQWS_OPT=" ---filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-fooling=md5sig --new ---filter-tcp=443 --dpi-desync=fake,disorder2 --dpi-desync-fooling=md5sig --new ---filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 " +--filter-tcp=80 --dpi-desync=fake,multisplit --dpi-desync-split-pos=method+2 --dpi-desync-fooling=md5sig --new +--filter-tcp=443 --dpi-desync=fake,multidisorder --dpi-desync-split-pos=1,midsld --dpi-desync-fooling=badseq,md5sig --new +--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 ``` ***Режим фильтрации хостов:*** @@ -1943,8 +1980,9 @@ zapret_custom_firewall_nft поднимает правила nftables. "не просто" до "почти невозможно". Если только вы не найдете готовое собранное ядро под ваш девайс. tpws будет работать в любом случае, он не требует чего-либо особенного. -В android нет /etc/passwd, потому опция `--user` не будет работать. Вместо нее можно -пользоваться числовыми user id и опцией `--uid`. + +Хотя linux варианты под Android работают, рекомендуется использовать специально собранные под bionic бинарники. +У них не будет проблем с DNS, с локальным временем и именами юзеров и групп. Рекомендую использовать gid 3003 (AID_INET). Иначе можете получить permission denied на создание сокета. Например: `--uid 1:3003`\ В iptables укажите: "! --uid-owner 1" вместо "! --uid-owner tpws".\ @@ -1956,10 +1994,6 @@ supersu: /system/su.d `nfqws` может иметь такой глюк. При запуске с uid по умолчанию (0x7FFFFFFF) при условии работы на сотовом интерфейсе и отключенном кабеле внешнего питания система может частично виснуть. Перестает работать тач и кнопки, но анимация на экране может продолжаться. Если экран был погашен, то включить его кнопкой power невозможно. -Это, видимо, связано с переводом в suspend процессов с определенным UID. UID соответствует приложению или -системному сервису. По UID android определяет политику power saving. -Так же возможно, что глюк связан с кривым драйвером сотового интерфейса от китайцев, поскольку при использовании -wifi такого не наблюдается. suspend обработчика nfqueue на обычном linux не вызывает подобных фатальных последствий. Изменение UID на низкий (--uid 1 подойдет) позволяет решить эту проблему. Глюк был замечен на android 8.1 на девайсе, основанном на платформе mediatek.