--dpi-desync-fwmark=<int|0xHEX> ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000
--dpi-desync-fwmark=<int|0xHEX> ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000
--dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов
--dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов
--dpi-desync-ttl6=<int> ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение ttl
--dpi-desync-ttl6=<int> ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение ttl
@ -274,10 +285,8 @@ dvtws, собираемый из тех же исходников (см. [док
--dpi-desync-fooling=<fooling> ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера. none md5sig badseq badsum datanoack hopbyhop hopbyhop2
--dpi-desync-fooling=<fooling> ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера. none md5sig badseq badsum datanoack hopbyhop hopbyhop2
--dpi-desync-repeats=<N> ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты)
--dpi-desync-repeats=<N> ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты)
--dpi-desync-skip-nosni=0|1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
--dpi-desync-skip-nosni=0|1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
--dpi-desync-split-pos=<1..1500> ; (только для split*, disorder*) разбивать пакет на указанной позиции
--dpi-desync-split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации в режимах split и disorder
--dpi-desync-split-http-req=method|host ; разбивка http request на указанном логическом месте
--dpi-desync-split-seqovl=N|-N|marker+N|marker-N ; единичный маркер, определяющий величину перекрытия sequence в режимах split и disorder. для split поддерживается только положительное число.
--dpi-desync-split-tls=sni|sniext ; разбивка tls client hello на указанном логическом месте
--dpi-desync-split-seqovl=<int> ; использовать sequence overlap перед первым отсылаемым оригинальным tcp сегментом
--dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; чем заполнять фейковую часть overlap
--dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; чем заполнять фейковую часть overlap
--dpi-desync-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000
--dpi-desync-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000
--dpi-desync-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000
--dpi-desync-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000
@ -315,12 +324,6 @@ dvtws, собираемый из тех же исходников (см. [док
--ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
--ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
```
```
Параметры манипуляции могут сочетаться в любых комбинациях.
> [!TIP]
> **ЗАМЕЧАНИЕ.** Параметр `--wsize` считается устаревшим и более не поддерживается в скриптах. Функции сплита выполняются в
> рамках атаки десинхронизации. Это быстрее и избавляет от целого ряда недостатков wsize.
`--debug` позволяет выводить подробный лог действий на консоль, в syslog или в файл. Может быть важен порядок следования
`--debug` позволяет выводить подробный лог действий на консоль, в syslog или в файл. Может быть важен порядок следования
опций. `--debug` лучше всего указывать в самом начале. Опции анализируются последовательно. Если ошибка будет при
опций. `--debug` лучше всего указывать в самом начале. Опции анализируются последовательно. Если ошибка будет при
проверке опции, а до анализа `--debug` еще дело не дошло, то сообщения не будут выведены в файл или syslog. При
проверке опции, а до анализа `--debug` еще дело не дошло, то сообщения не будут выведены в файл или syslog. При
@ -332,18 +335,24 @@ dvtws, собираемый из тех же исходников (см. [док
### АТАКА ДЕСИНХРОНИЗАЦИИ DPI
### АТАКА ДЕСИНХРОНИЗАЦИИ DPI
Суть ее в следующем. После выполнения tcp 3-way handshake идет первый пакет с данными от клиента. Там обычно `GET / ...`
Суть ее в следующем. Берется оригинальный запрос, модифицируется, добавляется поддельная информация (фейки)
или TLS ClientHello. Мы дропаем этот пакет, заменяя чем-то другим. Это может быть поддельная версия с безобидным, но
таким образом, чтобы ОС сервера передала серверному процессу оригинальный запрос в неизменном виде, а DPI увидел другое.
валидным запросом http или https (вариант `fake`), пакет сброса соединения (варианты `rst`, `rstack`), разбитый на части
То, что он блокировать не станет. Сервер видит одно, DPI - другое. DPI не понимает, что передается запрещенный запрос и не блокирует его.
оригинальный пакет с перепутанным порядком следования сегментов + обрамление первого сегмента фейками (`disorder`), то
же самое без перепутывания порядка сегментов (`split`). fakeknown отличается от fake тем, что применяется только к
Есть арсенал возможностей, чтобы достичь такого результата.
распознанному протоколу. В литературе такие атаки еще называют **TCB desynchronization** и **TCB teardown**. Надо, чтобы
Это может быть передача фейк пакетов, чтобы они дошли до DPI, но не дошли до сервера. Может использоваться фрагментация на уровне TCP (сегментация) или на уровне IP.
фейковые пакеты дошли до DPI, но не дошли до сервера. На вооружении есть следующие возможности : установить низкий TTL,
Есть атаки, основанные на игре с tcp sequence numbers или с перепутыванием порядка следования tcp сегментов.
посылать пакет с инвалидной чексуммой, добавлять tcp option **MD5 signature**, испортить sequence numbers. Все они не
Методы могут сочетаться в различных вариантах.
лишены недостатков.
### ФЕЙКИ
* `md5sig` работает не на всех серверах. Пакеты с md5 обычно отбрасывают только linux.
* `badsum` не сработает, если ваше устройство за NAT, который не пропускает пакеты с инвалидной суммой. Наиболее
Фейки - это отдельные сгенерированные nfqws пакеты, несущие ложную информацию для DPI.
Они либо не должны дойти до сервера, либо могут дойти, но должны быть им отброшены.
Иначе получается слом tcp соединения или нарушение целостности передаваемого потока, что гарантированно приводит к поломке ресурса.
Есть ряд методов для решения этой задачи.
* `md5sig` добавляет TCP опцию **MD5 signature**. Работает не на всех серверах. Пакеты с md5 обычно отбрасывают только linux.
* `badsum` портит контрольную сумму TCP. Не сработает, если ваше устройство за NAT, который не пропускает пакеты с инвалидной суммой. Наиболее
распространенная настройка NAT роутера в Linux их не пропускает. На Linux построено большинство домашних роутеров.
распространенная настройка NAT роутера в Linux их не пропускает. На Linux построено большинство домашних роутеров.
Непропускание обеспечивается так : настройка ядра sysctl по умолчанию
Непропускание обеспечивается так : настройка ядра sysctl по умолчанию
`net.netfilter.nf_conntrack_checksum=1` заставляет conntrack проверять tcp и udp чексуммы входящих пакетов и
`net.netfilter.nf_conntrack_checksum=1` заставляет conntrack проверять tcp и udp чексуммы входящих пакетов и
@ -359,7 +368,8 @@ dvtws, собираемый из тех же исходников (см. [док
себя ведут некоторые роутеры на базе mediatek. badsum пакеты уходят с клиентской ОС, но роутером не видятся в br-lan
себя ведут некоторые роутеры на базе mediatek. badsum пакеты уходят с клиентской ОС, но роутером не видятся в br-lan
через tcpdump. При этом если nfqws выполняется на самом роутере, обход может работать. badsum нормально уходят с
через tcpdump. При этом если nfqws выполняется на самом роутере, обход может работать. badsum нормально уходят с
внешнего интерфейса.
внешнего интерфейса.
* Пакеты с `badseq` будут наверняка отброшены принимающим узлом, но так же и DPI, если он ориентируется на sequence
* `badseq` увеличивает TCP sequence number на определенное значение, выводя его тем самым из TCP window.
Такие пакеты будут наверняка отброшены принимающим узлом, но так же и DPI, если он ориентируется на sequence
numbers. По умолчанию смещение seq выбирается -10000. Практика показала, что некоторые DPI не пропускают seq вне
numbers. По умолчанию смещение seq выбирается -10000. Практика показала, что некоторые DPI не пропускают seq вне
определенного окна. Однако, такое небольшое смещение может вызвать проблемы при существенной потоковой передаче и
определенного окна. Однако, такое небольшое смещение может вызвать проблемы при существенной потоковой передаче и
потере пакетов. Если вы используете `--dpi-desync-any-protocol`, может понадобится установить badseq increment
потере пакетов. Если вы используете `--dpi-desync-any-protocol`, может понадобится установить badseq increment
@ -383,7 +393,8 @@ dvtws, собираемый из тех же исходников (см. [док
может ломать NAT и не всегда работает с iptables, если используется masquerade, даже с локальной системы (почти всегда
может ломать NAT и не всегда работает с iptables, если используется masquerade, даже с локальной системы (почти всегда
на роутерах ipv4). На системах c iptables без masquerade и на nftables работает без ограничений. Экспериментально
на роутерах ipv4). На системах c iptables без masquerade и на nftables работает без ограничений. Экспериментально
выяснено, что многие провайдерские NAT не отбрасывают эти пакеты, потому работает даже с внутренним провайдерским IP.
выяснено, что многие провайдерские NAT не отбрасывают эти пакеты, потому работает даже с внутренним провайдерским IP.
Но linux NAT оно не пройдет, так что за домашним роутером эта техника не сработает, но может сработать с него.
Но linux NAT оно не пройдет, так что за домашним роутером эта техника скорее всего не сработает, но может сработать с него.
Может сработать и через роутер, если подключение по проводу, и на роутере включено аппаратное ускорение.
* `autottl`. Суть режима в автоматическом определении TTL, чтобы он почти наверняка прошел DPI и немного не дошел до
* `autottl`. Суть режима в автоматическом определении TTL, чтобы он почти наверняка прошел DPI и немного не дошел до
сервера. Берутся базовые значения TTL 64,128,255, смотрится входящий пакет
сервера. Берутся базовые значения TTL 64,128,255, смотрится входящий пакет
(да, требуется направить первый входящий пакет на nfqws !). Вычисляется длина пути, отнимается `delta` (1 по
(да, требуется направить первый входящий пакет на nfqws !). Вычисляется длина пути, отнимается `delta` (1 по
@ -396,44 +407,64 @@ dvtws, собираемый из тех же исходников (см. [док
Режимы дурения могут сочетаться в любых комбинациях. `--dpi-desync-fooling` берет множество значений через запятую.
Режимы дурения могут сочетаться в любых комбинациях. `--dpi-desync-fooling` берет множество значений через запятую.
Для режимов fake, rst, rstack после фейка отправляем оригинальный пакет.
### TCP СЕГМЕНТАЦИЯ
* `multisplit`. нарезаем запрос на указанных в `--dpi-desync-split-pos` позициях.
* `multidisorder`. нарезаем запрос на указанных в `--dpi-desync-split-pos` позициях и отправляем в обратном порядке.
* `fakedsplit`. нарезаем запрос на 2 части, обрамляя его фейками : фейк 1-й части, 1 часть, фейк 1-й части, 2 часть
* `fakeddisorder`. нарезаем запрос на 2 части, обрамляя его фейками : 2 часть, фейк 1-й части, 1 часть, фейк 1 части.
Для определения позиций нарезки используются маркеры.
* **Абсолютный положительный маркер** - числовое смещение внутри пакета или группы пакетов от начала.
* **Абсолютный отрицательный маркер** - числовое смещение внутри пакета или группы пакетов от следующего за концом байта. -1 указывает на последний байт.
* **Относительный маркер** - положительное или отрицательное смещение относительно логической позиции внутри пакета или группы пакетов.
Относительные позиции :
* **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, за ними идет поле данных.
Режим disorder делит оригинальный пакет на 2 части и отправляет следующую комбинацию в указанном порядке :
Пример списка маркеров : `100,midsld,sniext+1,endhost-2,-10`.
1. 2-я часть пакета
При разбиении пакета первым делом происходит ресолвинг маркеров - нахождение всех указанных относительных позиций и применение смещений.
2. поддельная 1-я часть пакета, поле данных заполнено нулями
Если относительная позиция отсутствует в текущем протоколе, такие позиции не применяются и отбрасываются.
3. 1-я часть пакета
Дальше происходит нормализация позиций относительно смещения текущего пакета в группе пакетов (многопакетные запросы TLS с kyber, например).
4. поддельная 1-я часть пакета, поле данных заполнено нулями. отсылка 2-й раз. Оригинальный пакет дропается всегда.
Выкидываются все позиции, выходящие за пределы текущего пакета. Оставшиеся сортируются в порядке возрастания и удаляются дубли.
В вариантах `multisplit` и `multidisorder` если не осталось ни одной позиции, разбиение не происходит.
Параметр `--dpi-desync-split-pos` позволяет указать байтовую позицию, на которой происходит разбивка. По умолчанию - 2.
Варианты `fakedsplit` и `fakeddisorder` применяют только одну позицию сплита. Ее поиск среди списка `--dpi-desync-split-pos` осуществляется особым образом.
Если позиция больше длины пакета, позиция выбирается 1. Этой последовательностью для DPI максимально усложняется задача
Сначала сверяются все относительные маркеры. Если среди них найден подходящий, применяется он. В противном случае сверяются все абсолютные маркеры.
реконструкции начального сообщения, по которому принимается решение о блокировке. Некоторым DPI хватит и tcp сегментов в
Если и среди них ничего не найдено, применяется позиция 1.
неправильном порядке, поддельные части сделаны для дополнительной надежности и более сложных алгоритмов реконструкции.
Режим `disorder2` отключает отправку поддельных частей.
Режим `split` очень похож на disorder, только нет изменения порядка следования сегментов :
Например, можно написать `--dpi-desync-split-pos=method+2,midsld,5`. Если протокол http, разбиение будет на позиции `method+2`.
Если протокол TLS - на позиции `midsld`. Если протокол неизвестен и включено `--dpi-desync-any-protocol`, разбиение будет на позиции 5.
Чтобы все было однозначнее, можно использовать разные профили для разных протоколов и указывать только одну позицию, которая точно есть в этом протоколе.
1. поддельная 1-я часть пакета, поле данных заполнено нулями
### ПЕРЕКРЫТИЕ SEQUENCE NUMBERS
2. 1-я часть пакета
3. поддельная 1-я часть пакета, поле данных заполнено нулями. отсылка 2-й раз.
4. 2-я часть пакета Режим split2 отключает отправку поддельных частей. Он может быть использован как более быстрая
альтернатива --wsize.
`disorder2` и `split2` не предполагают отсылку фейк пакетов, поэтому опции ttl и fooling неактуальны.
`seqovl` добавляет в начало одного из TCP сегментов `seqovl` байт со смещенным в минус sequence number на величину `seqovl`.
Для `split` - в начало первого сегмента, для `disorder` - в начало предпоследнего отсылаемого сегмента (второго в оригинальном порядке следования).
`seqovl` добавляет в начало первой отсылаемой части оригинального пакета (1 часть для split и 2 часть для disorder)
В случае `split` расчет идет на то, что предыдущий отсыл, если он был, уже попал в сокет серверного приложения, поэтому новая пришедшая часть лишь частично находится в
`seqovl` байт со смещенным в минус sequence number на величину seqovl. В случае `split2` расчет идет на то, что предыдущий
отсыл, если он был, уже попал в сокет серверного приложения, поэтому новая пришедшая часть лишь частично находится в
пределах текущего окна (in-window). Спереди фейковая часть отбрасывается, а оставшаяся часть содержит оригинал и
пределах текущего окна (in-window). Спереди фейковая часть отбрасывается, а оставшаяся часть содержит оригинал и
начинается с начала 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,
Для `disorder` overlap идет на предпоследнюю отсылаемую часть пакета.
поэтому серверная ОС принимает ее целиком, включая фейк. Но поскольку начальная часть данных из 1 пакета
Для простоты будем считать, что разбиение идет на 2 части, шлются они в порядке "2 1" при оригинальном порядке "1 2".
еще не принята, то фейк и реальные данные остаются в памяти ядра, не отправляясь в серверное приложение.
Обязательно, чтобы `seqovl` был меньше позиции первого сплита, иначе все отосланное будет передано в сокет сразу же, включая фейк, ломая протокол прикладного уровня.
Такая ситуация легко обнаруживается программой, и `seqovl` отменяется. Увеличение размера пакета невозможно в принципе.
При соблюдении условия 2-я часть пакета является полностью in-window, поэтому серверная ОС принимает ее целиком, включая фейк.
Но поскольку начальная часть данных из 1 пакета еще не принята, то фейк и реальные данные остаются в памяти ядра, не отправляясь в серверное приложение.
Как только приходит 1-я часть пакета, она переписывает фейковую часть в памяти ядра.
Как только приходит 1-я часть пакета, она переписывает фейковую часть в памяти ядра.
Ядро получает данные из 1 и 2 части, поэтому далее идет отправка в сокет приложения.
Ядро получает данные из 1 и 2 части, поэтому далее идет отправка в сокет приложения.
Таково поведение всех unix ОС, кроме solaris - оставлять последние принятые данные.
Таково поведение всех unix ОС, кроме solaris - оставлять последние принятые данные.
@ -441,7 +472,13 @@ Windows оставляет старые данные, поэтому disorder с
при работе с Windows серверами. Solaris практически мертв, windows серверов очень немного.
при работе с Windows серверами. Solaris практически мертв, windows серверов очень немного.
Можно использовать листы при необходимости.
Можно использовать листы при необходимости.
Метод позволяет обойтись без fooling и TTL. Фейки перемешаны с реальным данными.
Метод позволяет обойтись без fooling и TTL. Фейки перемешаны с реальным данными.
`split/disorder` вместо `split2/disorder2` по-прежнему добавляют дополнительные отдельные фейки.
`fakedsplit/fakeddisorder` по-прежнему добавляют дополнительные отдельные фейки.
`seqovl` в варианте `split` может быть только абсолютным положительным значением, поскольку применяется только в первому пакету.
В варианте `disorder` допустимо применение всех вариантов маркеров.
Они автоматически нормализуются к текущему пакету в серии. Можно сплитать на `midsld` и делать seqovl на `midsld-1`.
### СПЕЦИФИЧЕСКИЕ РЕЖИМЫ IPV6
Режимы десинхронизации `hopbyhop`, `destopt` и `ipfrag1` (не путать с fooling !) относятся только к `ipv6` и заключается
Режимы десинхронизации `hopbyhop`, `destopt` и `ipfrag1` (не путать с fooling !) относятся только к `ipv6` и заключается
в добавлении хедера `hop-by-hop options`, `destination options` или `fragment` во все пакеты, попадающие под десинхронизацию.
в добавлении хедера `hop-by-hop options`, `destination options` или `fragment` во все пакеты, попадающие под десинхронизацию.
@ -452,10 +489,22 @@ Windows оставляет старые данные, поэтому disorder с
extension хедерам в поисках транспортного хедера. Таким образом не поймет, что это tcp или udp, и пропустит пакет
extension хедерам в поисках транспортного хедера. Таким образом не поймет, что это tcp или udp, и пропустит пакет
без анализа. Возможно, какие-то DPI на это купятся.
без анализа. Возможно, какие-то DPI на это купятся.
Может сочетаться с любыми режимами 2-й фазы, кроме варианта `ipfrag1+ipfrag2`.
Может сочетаться с любыми режимами 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`.
При `hopbyhop,ipfrag2` последовательность хедеров будет : `ipv6,hop-by-hop`,`fragment`,`tcp/udp`.
Режим `ipfrag1` может срабатывать не всегда без специальной подготовки. См. раздел `IP фрагментация`.
Режим `ipfrag1` может срабатывать не всегда без специальной подготовки. См. раздел `IP фрагментация`.
### КОМБИНИРОВАНИЕ МЕТОДОВ ДЕСИНХРОНИЗАЦИИ
В параметре dpi-desync можно указать до 3 режимов через запятую.
* 0 фаза - предполагает работу на этапе установления соединения : `synack`, `syndata``--wsize`, `--wssize`.
* 1 фаза - отсылка чего-либо до оригинального пакета данных : `fake`, `rst`, `rstack`.
* 2 фаза - отсылка в модифицированном виде оригинального пакета данных (например, `fakedsplit` или `ipfrag2`).
Режимы требуют указания в порядке возрастания номеров фаз.
### РЕАКЦИЯ DPI НА ОТВЕТ СЕРВЕРА
Есть DPI, которые анализируют ответы от сервера, в частности сертификат из ServerHello, где прописаны домены.
Есть DPI, которые анализируют ответы от сервера, в частности сертификат из ServerHello, где прописаны домены.
Подтверждением доставки ClientHello является ACK пакет от сервера с номером ACK sequence, соответствующим длине ClientHello+1.
Подтверждением доставки ClientHello является ACK пакет от сервера с номером ACK sequence, соответствующим длине ClientHello+1.
В варианте disorder обычно приходит сперва частичное подтверждение (SACK), потом полный ACK.
В варианте disorder обычно приходит сперва частичное подтверждение (SACK), потом полный ACK.
@ -470,8 +519,7 @@ DPI может отстать от потока, если ClientHello его у
Лучшее решение - включить на сервере поддержку TLS 1.3. В нем сертификат сервера передается в зашифрованном виде.
Лучшее решение - включить на сервере поддержку TLS 1.3. В нем сертификат сервера передается в зашифрованном виде.
Это рекомендация ко всем админам блокируемых сайтов. Включайте TLS 1.3. Так вы дадите больше возможностей преодолеть DPI.
Это рекомендация ко всем админам блокируемых сайтов. Включайте TLS 1.3. Так вы дадите больше возможностей преодолеть DPI.
Хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
--bind-wait-ip=<sec> ; ждать до N секунд получения IP адреса (если задан --bind-wait-ifup - время идет после поднятия интерфейса)
--bind-wait-ip=<sec>; ждать до N секунд получения IP адреса (если задан --bind-wait-ifup - время идет после поднятия интерфейса)
--bind-wait-ip-linklocal=<sec>
--bind-wait-ip-linklocal=<sec>
; имеет смысл только при задании --bind-wait-ip
; имеет смысл только при задании --bind-wait-ip
; --bind-linklocal=unwanted : согласиться на LL после N секунд
; --bind-linklocal=unwanted : согласиться на LL после N секунд
; --bind-linklocal=prefer : согласиться на global address после N секунд
; --bind-linklocal=prefer : согласиться на global address после N секунд
--bind-wait-only ; подождать все бинды и выйти. результат 0 в случае успеха, иначе не 0.
--bind-wait-only ; подождать все бинды и выйти. результат 0 в случае успеха, иначе не 0.
--connect-bind-addr ; с какого адреса подключаться во внешнюю сеть. может быть ipv4 или ipv6 адрес
--connect-bind-addr ; с какого адреса подключаться во внешнюю сеть. может быть ipv4 или ipv6 адрес
; если указан ipv6 link local, то требуется указать с какого он интерфейса : fe80::1%br-lan
; если указан ipv6 link local, то требуется указать с какого он интерфейса : fe80::1%br-lan
; опция может повторяться для v4 и v6 адресов
; опция может повторяться для v4 и v6 адресов
; опция не отменяет правил маршрутизации ! выбор интерфейса определяется лишь правилами маршрутизации, кроме случая v6 link local.
; опция не отменяет правил маршрутизации ! выбор интерфейса определяется лишь правилами маршрутизации, кроме случая v6 link local.
--socks ; вместо прозрачного прокси реализовать socks4/5 proxy
--socks ; вместо прозрачного прокси реализовать socks4/5 proxy
--no-resolve ; запретить ресолвинг имен через socks5
--no-resolve ; запретить ресолвинг имен через socks5
--resolve-threads ; количество потоков ресолвера
--resolve-threads ; количество потоков ресолвера
--port=<port> ; на каком порту слушать
--port=<port> ; на каком порту слушать
--maxconn=<max_connections> ; максимальное количество соединений от клиентов к прокси
--maxconn=<max_connections> ; максимальное количество соединений от клиентов к прокси
--maxfiles=<max_open_files> ; макс количество файловых дескрипторов (setrlimit). мин требование (X*connections+16), где X=6 в tcp proxy mode, X=4 в режиме тамперинга.
--maxfiles=<max_open_files> ; макс количество файловых дескрипторов (setrlimit). мин требование (X*connections+16), где X=6 в tcp proxy mode, X=4 в режиме тамперинга.
; стоит сделать запас с коэффициентом как минимум 1.5. по умолчанию maxfiles (X*connections)*1.5+16
; стоит сделать запас с коэффициентом как минимум 1.5. по умолчанию maxfiles (X*connections)*1.5+16
--max-orphan-time=<sec> ; если вы запускаете через tpws торрент-клиент с множеством раздач, он пытается установить очень много исходящих соединений,
--max-orphan-time=<sec> ; если вы запускаете через tpws торрент-клиент с множеством раздач, он пытается установить очень много исходящих соединений,
; большая часть из которых отваливается по таймауту (юзера сидят за NAT, firewall, ...)
; большая часть из которых отваливается по таймауту (юзера сидят за NAT, firewall, ...)
; установление соединения в linux может длиться очень долго. локальный конец отвалился, перед этим послав блок данных,
; установление соединения в linux может длиться очень долго. локальный конец отвалился, перед этим послав блок данных,
; tpws ждет подключения удаленного конца, чтобы отослать ему этот блок, и зависает надолго.
; tpws ждет подключения удаленного конца, чтобы отослать ему этот блок, и зависает надолго.
; настройка позволяет сбрасывать такие подключения через N секунд, теряя блок данных. по умолчанию 5 сек. 0 означает отключить функцию
; настройка позволяет сбрасывать такие подключения через N секунд, теряя блок данных. по умолчанию 5 сек. 0 означает отключить функцию
; эта функция не действует на успешно подключенные ранее соединения
; эта функция не действует на успешно подключенные ранее соединения
--local-rcvbuf=<bytes> ; SO_RCVBUF для соединений client-proxy
--local-rcvbuf=<bytes> ; SO_RCVBUF для соединений client-proxy
--local-sndbuf=<bytes> ; SO_SNDBUF для соединений client-proxy
--local-sndbuf=<bytes> ; SO_SNDBUF для соединений client-proxy
--remote-rcvbuf=<bytes> ; SO_RCVBUF для соединений proxy-target
--remote-rcvbuf=<bytes> ; SO_RCVBUF для соединений proxy-target
--remote-sndbuf=<bytes> ; SO_SNDBUF для соединений proxy-target
--remote-sndbuf=<bytes> ; SO_SNDBUF для соединений proxy-target
--nosplice ; не использовать splice на linux системах
--nosplice ; не использовать splice на linux системах
--skip-nodelay ; не устанавливать в исходящих соединения TCP_NODELAY. несовместимо со split.
--skip-nodelay ; не устанавливать в исходящих соединения TCP_NODELAY. несовместимо со split.
--local-tcp-user-timeout=<seconds> ; таймаут соединений client-proxy (по умолчанию : 10 сек, 0 = оставить системное значение)
--local-tcp-user-timeout=<seconds> ; таймаут соединений client-proxy (по умолчанию : 10 сек, 0 = оставить системное значение)
--remote-tcp-user-timeout=<seconds> ; таймаут соединений proxy-target (по умолчанию : 20 сек, 0 = оставить системное значение)
--remote-tcp-user-timeout=<seconds> ; таймаут соединений proxy-target (по умолчанию : 20 сек, 0 = оставить системное значение)
--split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host
--split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации
--split-pos=<offset> ; делить все посылы на сегменты в указанной позиции. единственная опция, работающая на не-http. при указании split-http-req он имеет преимущество на http.
--split-any-protocol ; применять сегментацию к любым пакетам. по умолчанию - только к известным протоколам (http, TLS)
--split-any-protocol ; применять split-pos к любым пакетам. по умолчанию - только к http и TLS ClientHello
--disorder[=http|tls] ; путем манипуляций с сокетом вынуждает отправлять первым второй сегмент разделенного запроса
--disorder[=http|tls] ; путем манипуляций с сокетом вынуждает отправлять первым второй сегмент разделенного запроса
--oob[=http|tls] ; отправить байт out-of-band data (OOB) в конце первой части сплита
--oob[=http|tls] ; отправить байт out-of-band data (OOB) в конце первой части сплита
--oob-data=<char>|0xHEX ; переопределить байт OOB. по умолчанию 0x00.
--oob-data=<char>|0xHEX ; переопределить байт OOB. по умолчанию 0x00.
--hostcase ; менять регистр заголовка "Host:". по умолчанию на "host:".
--hostcase ; менять регистр заголовка "Host:". по умолчанию на "host:".
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
--hostdot ; добавление точки после имени хоста : "Host: kinozal.tv."
--hostdot ; добавление точки после имени хоста : "Host: kinozal.tv."
--hosttab ; добавление табуляции после имени хоста : "Host: kinozal.tv\t"
--hosttab ; добавление табуляции после имени хоста : "Host: kinozal.tv\t"
--hostnospace ; убрать пробел после "Host:"
--hostnospace ; убрать пробел после "Host:"
--hostpad=<bytes> ; добавить паддинг-хедеров общей длиной <bytes> перед Host:
--hostpad=<bytes> ; добавить паддинг-хедеров общей длиной <bytes> перед Host:
--domcase ; домен после Host: сделать таким : TeSt.cOm
--domcase ; домен после Host: сделать таким : TeSt.cOm
--methodspace ; добавить пробел после метода : "GET /" => "GET /"
--methodspace ; добавить пробел после метода : "GET /" => "GET /"
--methodeol ; добавить перевод строки перед методом : "GET /" => "\r\nGET /"
--methodeol ; добавить перевод строки перед методом : "GET /" => "\r\nGET /"
--unixeol ; конвертировать 0D0A в 0A и использовать везде 0A
--unixeol ; конвертировать 0D0A в 0A и использовать везде 0A
--tlsrec=N|-N|marker+N|marker-N ; разбивка TLS ClientHello на 2 TLS records на указанной позиции. Минимальное смещение - 6.
--tlsrec=sni|sniext ; разбивка TLS ClientHello на 2 TLS records. режем между 1 и 2 символами hostname в SNI или между байтами длины SNI extension. Если SNI нет - отмена.
--mss=<int> ; установить MSS для клиента. может заставить сервер разбивать ответы, но существенно снижает скорость
--tlsrec-pos=<pos> ; разбивка TLS ClientHello на 2 TLS records. режем на указанной позиции, если длина слишком мелкая - на позиции 1.
--mss-pf=[~]port1[-port2] ; применять MSS только к портам назначения, подпадающим под фильтр. ~ означает инверсию
--mss=<int> ; установить MSS для клиента. может заставить сервер разбивать ответы, но существенно снижает скорость
--tamper-start=[n]<pos> ; начинать дурение только с указанной байтовой позиции или номера блока исходяшего потока (считается позиция начала принятого блока)
--mss-pf=[~]port1[-port2] ; применять MSS только к портам назначения, подпадающим под фильтр. ~ означает инверсию
--tamper-cutoff=[n]<pos> ; закончить дурение на указанной байтовой позиции или номере блока исходящего потока (считается позиция начала принятого блока)
--tamper-start=[n]<pos> ; начинать дурение только с указанной байтовой позиции или номера блока исходяшего потока (считается позиция начала принятого блока)
--hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются.
--tamper-cutoff=[n]<pos> ; закончить дурение на указанной байтовой позиции или номере блока исходящего потока (считается позиция начала принятого блока)
; в файле должен быть хост на каждой строке.
--hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются.
; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
; в файле должен быть хост на каждой строке.
; при изменении времени модификации файла он перечитывается автоматически по необходимости
; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
; список может быть запакован в gzip. формат автоматически распознается и разжимается
; при изменении времени модификации файла он перечитывается автоматически по необходимости
; списков может быть множество. пустой общий лист = его отсутствие
; список может быть запакован в gzip. формат автоматически распознается и разжимается
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
; списков может быть множество. пустой общий лист = его отсутствие
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам.
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам.
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3)
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
--hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60)
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3)
--hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты.
--hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60)
--new ; начало новой стратегии (новый профиль)
--hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты.
--filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии
--new ; начало новой стратегии (новый профиль)
--filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. поддерживается список через запятую.
--filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии
--filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. поддерживается список через запятую.
--filter-l7=[http|tls|quic|wireguard|dht|unknown] ; фильтр протокола L6-L7. поддерживается несколько значений через запятую.
--filter-l7=[http|tls|quic|wireguard|dht|unknown] ; фильтр протокола L6-L7. поддерживается несколько значений через запятую.
--ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
--ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
--ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
--ipset-exclude=<filename>; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
```
```
`--debug` позволяет выводить подробный лог действий на консоль, в syslog или в файл.
### TCP СЕГМЕНТАЦИЯ В TPWS
Может быть важен порядок следования опций. `--debug` лучше всего указывать в самом начале.
Опции анализируются последовательно. Если ошибка будет при проверке опции, а до анализа `--debug` еще дело не дошло,
то сообщения не будут выведены в файл или syslog.
`--debug=0|1|2` позволяют сразу в одном параметре включить логирование на консоль и указать уровень.
Сохранено для совместимости с более старыми версиями. Для выбора уровня в режиме syslog или file используйте
отдельный параметр `--debug-level`. Если в этих режимах `--debug` не указывать уровень через `--debug-level`, то
автоматически назначается уровень 1.
При логировании в файл процесс не держит файл открытым. Ради каждой записи файл открывается и потом закрывается.
Так что файл можно удалить в любой момент, и он будет создан заново при первом же сообщении в лог.
Но имейте в виду, что если вы запускаете процесс под root, то будет сменен UID на не-root.
В начале на лог файл меняется owner, иначе запись будет невозможна. Если вы потом удалите файл,
и у процесса не будет прав на создание файла в его директории, лог больше не будет вестись.
Вместо удаления лучше использовать truncate.
В шелле это можно сделать через команду ": >filename"
Параметры манипуляции могут сочетаться в любых комбинациях.
В случае http запроса `split-http-req` имеет преимущество над split-pos.
tpws, как и nfqws, поддерживает множественную сегментацию запросов. Сплит позиции задаются в `--split-pos`.
split-pos по умолчанию работает только на http и TLS ClientHello.
Указываются маркеры через запятую. Описание маркеров см в разделе [nfqws](#tcp-сегментация).
Чтобы он работал на любых пакетах, укажите `--split-any-protocol`.
На прикладном уровне в общем случае нет гарантированного средства заставить ядро выплюнуть
На прикладном уровне в общем случае нет гарантированного средства заставить ядро выплюнуть
блок данных, порезанным в определенном месте. ОС держит буфер отсылки (SNDBUF) у каждого сокета.
блок данных, порезанным в определенном месте. ОС держит буфер отсылки (SNDBUF) у каждого сокета.
@ -869,84 +889,34 @@ split-pos по умолчанию работает только на http и TLS
когда сервер получил запрос и полностью вернул ответ. Значит запрос фактически был не только отослан,
когда сервер получил запрос и полностью вернул ответ. Значит запрос фактически был не только отослан,
но и принят другой стороной, а следовательно буфер отсылки пуст, и следующие 2 send приведут
но и принят другой стороной, а следовательно буфер отсылки пуст, и следующие 2 send приведут
к отсылке сегментов данных разными ip пакетами.
к отсылке сегментов данных разными ip пакетами.
Резюме : tpws гарантирует сплит только за счет раздельных вызовов send, что на практике
вполне достаточно для протоколов http(s).
tpws может биндаться на множество интерфейсов и IP адресов (до 32 шт).
Таким образом tpws обеспечивает сплит только за счет раздельных вызовов send, и это обычно работает надежно,
Порт всегда только один.
если разбивать не на слишком много частей и не на слишком мелкие подряд следующие части.
Параметры `--bind-iface*` и `--bind-addr` создают новый бинд.
В последнем случае Linux все же может обьединить некоторые части, что приведет к несоответствию реальной сегментации
Остальные параметры `--bind-*` относятся к последнему бинду.
указанным сплит позициям. Другие ОС в этом вопросе ведут себя более предсказуемо. Спонтанного обьединения замечено не было.
Для бинда на все ipv4 укажите `--bind-addr "0.0.0.0"`, на все ipv6 - `"::"`. `--bind-addr=""` - биндаемся на все ipv4 и ipv6.
Поэтому не стоит злоупотреблять сплитами и в особенности мелкими соседними пакетами.
Выбор режима использования link local ipv6 адресов (`fe80::/8`) :
```
--bind-iface6 --bind-linklocal=no : сначала приватный адрес fc00::/7, затем глобальный адрес
--bind-iface6 --bind-linklocal=unwanted : сначала приватный адрес fc00::/7, затем глобальный адрес, затем link local.
--bind-iface6 --bind-linklocal=prefer : сначала link local, затем приватный адрес fc00::/7, затем глобальный адрес.
--bind-iface6 --bind-linklocal=force : только link local
```
Если не указано ни одного бинда, то создается бинд по умолчанию на все адреса всех интерфейсов.
Для бинда на конкретный link-local address делаем так : `--bind-iface6=fe80::aaaa:bbbb:cccc:dddd%iface-name`
Параметры `--bind-wait*` могут помочь в ситуациях, когда нужно взять IP с интерфейса, но его еще нет, он не поднят
или не сконфигурирован.
В разных системах события ifup ловятся по-разному и не гарантируют, что интерфейс уже получил IP адрес определенного типа.
В общем случае не существует единого механизма повеситься на событие типа "на интерфейсе X появился link local address".
Для бинда на известный ip, когда еще интерфейс не сконфигурирован, нужно делать так: `--bind-addr=192.168.5.3 --bind-wait-ip=20`
В режиме transparent бинд возможен на любой несуществующий адрес, в режиме socks - только на существующий.
Параметры rcvbuf и sndbuf позволяют установить setsockopt SO_RCVBUF SO_SNDBUF для локального и удаленного соединения.
tpws работает на уровне сокетов, поэтому длинный запрос, не вмещающийся в 1 пакет (TLS с kyber), он получает целым блоком.
На каждую сплит часть он делает отдельный вызов `send()`. Но ОС не сможет отослать данные в одном пакете, если размер превысит MTU.
В случае слишком большого сегмента ОС дополнительно его порежет на более мелкие. Результат должен быть аналогичен nfqws.
Если не указан ни один из параметров модификации содержимого, tpws работает в режиме `tcp proxy mode`.
`--disorder` заставляет слать каждый 2-й пакет с TTL=1, начиная с первого.
Он отличается тем, что в оба конца применяется splice для переброски данных из одного сокета в другой
К серверу приходят все четные пакеты сразу. На остальные ОС делает ретрансмиссию, и они приходят потом.
без копирования в память процесса. Практически - это то же самое, но может быть чуть побыстрее.
Это само по себе создает дополнительную задержку (200 мс в linux для первой ретрансмиссии).
TCP проксирование может быть полезно для обхода блокировок, когда DPI спотыкается на экзотических
Иным способом сделать disorder в сокет варианте не представляется возможным.
хедерах IP или TCP. Вы вряд ли сможете поправить хедеры, исходящие от айфончиков и гаджетиков,
Итоговый порядок для 6 сегментов получается `2 4 6 1 3 5`.
но на linux сможете влиять на них в какой-то степени через `sysctl`.
Когда соединение проходит через tpws, фактически прокси-сервер сам устанавливает подключение к удаленному
узлу от своего имени, и на это распространяются настройки системы, на которой работает прокси.
tpws можно использовать на мобильном устройстве, раздающем интернет на тарифе сотового оператора,
где раздача запрещена, в socks режиме даже без рута. Соединения от tpws неотличимы от соединений
с самого раздающего устройства. Отличить можно только по содержанию (типа обновлений windows).
Заодно можно и обойти блокировки. 2 зайца одним выстрелом.
Более подробную информацию по вопросу обхода ограничений операторов гуглите на 4pda.ru.
Режим `--socks` не требует повышенных привилегий (кроме бинда на привилегированные порты 1..1023).
`--oob` высылает 1 байт out-of-band data после первого сплит сегмента. `oob` в каждом сегменте сплита показал себя ненадежным.
Поддерживаются версии socks 4 и 5 без авторизации. Версия протокола распознается автоматически.
Сервер получает oob в сокет.
Подключения к IP того же устройства, на котором работает tpws, включая localhost, запрещены.
tpws поддерживает эту возможность асинхронно, не блокируя процессинг других соединений, используя
многопоточный пул ресолверов. Количество потоков определяется автоматически в зависимости от `--maxconn`,
но можно задать и вручную через параметр `--resolver-threads`.
Запрос к socks выставляется на паузу, пока домен не будет преобразован в ip адрес в одном из потоков
ресолвера. Ожидание может быть более длинным, если все потоки заняты.
Если задан параметр `--no-resolve`, то подключения по именам хостов запрещаются, а пул ресолверов не создается.
Тем самым экономятся ресурсы.
Параметр `--hostpad=<bytes>` добавляет паддинг-хедеров перед Host: на указанное количество байтов.
Сочетание `oob` и `disorder` возможно только в Linux. Остальные ОС не умеют с таким справляться. Флаг URG теряется при ретрансмиссиях.
Если размер `<bytes>` слишком большой, то идет разбивка на разные хедеры по 2K.
Сервер получает oob в сокет. Сочетание этих параметров в ос, кроме Linux, вызывает ошибку на этапе запуска.
Общий буфер приема http запроса - 64K, больший паддинг не поддерживается, да и http сервера
такое уже не принимают.
### TLSREC
Полезно против DPI, выполняющих реассемблинг TCP с ограниченным буфером.
Если техника работает, то после некоторого количества bytes http запрос начнет проходить до сайта.
`--tlsrec` позволяют внутри одного tcp сегмента разрезать TLS ClientHello на 2 TLS records. Можно использовать стандартный
Если при этом критический размер 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 серверах
`--tlsrec` ломает значительное количество сайтов. Криптобиблиотеки (openssl, ...) на оконечных http серверах
без проблем принимают разделенные tls сегменты, но мидлбоксы - не всегда. К мидлбоксам можно отнести CDN
без проблем принимают разделенные tls сегменты, но мидлбоксы - не всегда. К мидлбоксам можно отнести CDN
или системы ddos-защиты. Поэтому применение `--tlsrec` без ограничителей вряд ли целесообразно.
или системы ddos-защиты. Поэтому применение `--tlsrec` без ограничителей вряд ли целесообразно.
@ -954,6 +924,8 @@ tpws поддерживает эту возможность асинхронно
Работает только с TLS 1.3, поскольку там эта информация шифруется.
Работает только с TLS 1.3, поскольку там эта информация шифруется.
Впрочем, сейчас сайтов, не поддерживающих TLS 1.3, осталось немного.
Впрочем, сейчас сайтов, не поддерживающих TLS 1.3, осталось немного.
### MSS
`--mss` устанавливает опцию сокета TCP_MAXSEG. Клиент выдает это значение в tcp опциях SYN пакета.
`--mss` устанавливает опцию сокета TCP_MAXSEG. Клиент выдает это значение в tcp опциях SYN пакета.
Сервер в ответ в SYN,ACK выдает свой MSS. На практике сервера обычно снижают размеры отсылаемых ими пакетов, но они
Сервер в ответ в SYN,ACK выдает свой MSS. На практике сервера обычно снижают размеры отсылаемых ими пакетов, но они
все равно не вписываются в низкий MSS, указанный клиентом. Обычно чем больше указал клиент, тем больше
все равно не вписываются в низкий MSS, указанный клиентом. Обычно чем больше указал клиент, тем больше
@ -969,19 +941,18 @@ tpws поддерживает эту возможность асинхронно
может привести к реакции DPI.
может привести к реакции DPI.
Использовать только когда нет ничего лучше или для отдельных ресурсов.
Использовать только когда нет ничего лучше или для отдельных ресурсов.
Для http использовать смысла нет, поэтому заводите отдельный desync profile с фильтром по порту 443.
Для http использовать смысла нет, поэтому заводите отдельный desync profile с фильтром по порту 443.
Работает только на linux, не работает на BSD и MacOS.
Работает только на Linux, не работает на BSD и MacOS.
`--skip-nodelay` может быть полезен, чтобы привести MTU к MTU системы, на которой работает tpws.
### ДРУГИЕ ПАРАМЕТРЫ ДУРЕНИЯ
Это может быть полезно для скрытия факта использования VPN. Пониженный MTU - 1 из способов обнаружения
подозрительного подключения. С tcp proxy ваши соединения неотличимы от тех, что сделал бы сам шлюз.
`--local-tcp-user-timeout` и `--remote-tcp-user-timeout` устанавливают значение таймаута в секундах
Параметр `--hostpad=<bytes>` добавляет паддинг-хедеров перед `Host:` на указанное количество байтов.
для соединений клиент-прокси и прокси-сервер. Этот таймаут соответствует опции сокета linux
Если размер `<bytes>` слишком большой, то идет разбивка на разные хедеры по 2K.
TCP_USER_TIMEOUT. Под таймаутом подразумевается время, в течение которого буферизированные данные
Общий буфер приема http запроса - 64K, больший паддинг не поддерживается, да и http сервера
не переданы или на переданные данные не получено подтверждение (ACK) от другой стороны.
такое уже не принимают.
Этот таймаут никак не касается времени отсутствия какой-либо передачи через сокет лишь потому,
Полезно против DPI, выполняющих реассемблинг TCP с ограниченным буфером.
что данных для передачи нет. Полезно для сокращения время закрытия подвисших соединений.
Если техника работает, то после некоторого количества bytes http запрос начнет проходить до сайта.
Поддерживается только на Linux и MacOS.
Если при этом критический размер padding около MTU, значит скорее всего DPI не выполняет реассемблинг пакетов, и лучше будет использовать обычные опции TCP сегментации.
Если все же реассемблинг выполняется, то критический размер будет около размера буфера DPI. Он может быть 4K или 8K, возможны и другие значения.
### МНОЖЕСТВЕННЫЕ СТРАТЕГИИ
### МНОЖЕСТВЕННЫЕ СТРАТЕГИИ
@ -998,6 +969,72 @@ TCP_USER_TIMEOUT. Под таймаутом подразумевается вр
Используйте `curl --socks5` и `curl --socks5-hostname` для проверки вашей стратегии.
Используйте `curl --socks5` и `curl --socks5-hostname` для проверки вашей стратегии.
Смотрите вывод `--debug`, чтобы убедиться в правильности настроек.
Смотрите вывод `--debug`, чтобы убедиться в правильности настроек.
### СЛУЖЕБНЫЕ ПАРАМЕТРЫ
`--debug` позволяет выводить подробный лог действий на консоль, в syslog или в файл.
Может быть важен порядок следования опций. `--debug` лучше всего указывать в самом начале.
Опции анализируются последовательно. Если ошибка будет при проверке опции, а до анализа `--debug` еще дело не дошло,
то сообщения не будут выведены в файл или syslog.
`--debug=0|1|2` позволяют сразу в одном параметре включить логирование на консоль и указать уровень.
Сохранено для совместимости с более старыми версиями. Для выбора уровня в режиме syslog или file используйте
отдельный параметр `--debug-level`. Если в этих режимах `--debug` не указывать уровень через `--debug-level`, то
автоматически назначается уровень 1.
При логировании в файл процесс не держит файл открытым. Ради каждой записи файл открывается и потом закрывается.
Так что файл можно удалить в любой момент, и он будет создан заново при первом же сообщении в лог.
Но имейте в виду, что если вы запускаете процесс под root, то будет сменен UID на не-root.
В начале на лог файл меняется owner, иначе запись будет невозможна. Если вы потом удалите файл,
и у процесса не будет прав на создание файла в его директории, лог больше не будет вестись.
Вместо удаления лучше использовать truncate.
В шелле это можно сделать через команду ": >filename"
tpws может биндаться на множество интерфейсов и IP адресов (до 32 шт).
Порт всегда только один.
Параметры `--bind-iface*` и `--bind-addr` создают новый бинд.
Остальные параметры `--bind-*` относятся к последнему бинду.
Для бинда на все ipv4 укажите `--bind-addr "0.0.0.0"`, на все ipv6 - `"::"`. `--bind-addr=""` - биндаемся на все ipv4 и ipv6.
Выбор режима использования link local ipv6 адресов (`fe80::/8`) :
```
--bind-iface6 --bind-linklocal=no : сначала приватный адрес fc00::/7, затем глобальный адрес
--bind-iface6 --bind-linklocal=unwanted : сначала приватный адрес fc00::/7, затем глобальный адрес, затем link local.
--bind-iface6 --bind-linklocal=prefer : сначала link local, затем приватный адрес fc00::/7, затем глобальный адрес.
--bind-iface6 --bind-linklocal=force : только link local
```
Если не указано ни одного бинда, то создается бинд по умолчанию на все адреса всех интерфейсов.
Для бинда на конкретный link-local address делаем так : `--bind-iface6=fe80::aaaa:bbbb:cccc:dddd%iface-name`
Параметры `--bind-wait*` могут помочь в ситуациях, когда нужно взять IP с интерфейса, но его еще нет, он не поднят
или не сконфигурирован.
В разных системах события ifup ловятся по-разному и не гарантируют, что интерфейс уже получил IP адрес определенного типа.
В общем случае не существует единого механизма повеситься на событие типа "на интерфейсе X появился link local address".
Для бинда на известный ip, когда еще интерфейс не сконфигурирован, нужно делать так: `--bind-addr=192.168.5.3 --bind-wait-ip=20`
В режиме transparent бинд возможен на любой несуществующий адрес, в режиме socks - только на существующий.
Параметры rcvbuf и sndbuf позволяют установить setsockopt SO_RCVBUF SO_SNDBUF для локального и удаленного соединения.
`--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 без авторизации. Версия протокола распознается автоматически.
Подключения к IP того же устройства, на котором работает tpws, включая localhost, запрещены.