Compare commits

..

9 Commits

Author SHA1 Message Date
bol-van
603265dac2 nfqws: do not realloc hostname in ipcache if it's the same 2025-05-08 13:45:28 +03:00
bol-van
ed0bb4c106 tpws: ipcache socks hostname 2025-05-08 13:42:24 +03:00
bol-van
6eae2b0e71 doc works 2025-05-08 12:23:51 +03:00
bol-van
c59771f744 doc works 2025-05-08 12:20:55 +03:00
bol-van
dd23d6f3f4 doc works 2025-05-08 12:08:38 +03:00
bol-van
92dc012f08 doc works 2025-05-08 12:01:04 +03:00
bol-van
9bcefde37a doc works 2025-05-08 11:45:50 +03:00
bol-van
d2f7a53927 nfqws: --ctrack-disable 2025-05-08 09:00:20 +03:00
bol-van
f1dd351854 nfqws: --ctrack-disable 2025-05-08 08:54:05 +03:00
9 changed files with 197 additions and 63 deletions

View File

@ -489,6 +489,7 @@ nfqws: --dpi-desync-fake-tls=! means default tls fake
nfqws: --dup*
nfqws: --orig*
nfqws: ipcache of hop count and host names
nfqws: --ctrack-disable
tpws: ipcache of host names
nfqws,tpws: set 1024 repeat limit to fakes and dups
init.d: remove --ipset parameter prohibition

View File

@ -1,4 +1,4 @@
# zapret v70.7
# zapret v71
# ВНИМАНИЕ, остерегайтесь мошенников
@ -25,7 +25,10 @@ zapret является свободным и open source.
- [TCP СЕГМЕНТАЦИЯ](#tcp-сегментация)
- [ПЕРЕКРЫТИЕ SEQUENCE NUMBERS](#перекрытие-sequence-numbers)
- [СПЕЦИФИЧЕСКИЕ РЕЖИМЫ IPV6](#специфические-режимы-ipv6)
- [МОДИФИКАЦИЯ ОРИГИНАЛА](#модификация-оригинала)
- [ДУБЛИКАТЫ](#дубликаты)
- [КОМБИНИРОВАНИЕ МЕТОДОВ ДЕСИНХРОНИЗАЦИИ](#комбинирование-методов-десинхронизации)
- [КЭШ IP](#кэш-ip)
- [РЕАКЦИЯ DPI НА ОТВЕТ СЕРВЕРА](#реакция-dpi-на-ответ-сервера)
- [РЕЖИМ SYNACK](#режим-synack)
- [РЕЖИМ SYNDATA](#режим-syndata)
@ -169,10 +172,30 @@ dvtws, собираемый из тех же исходников (см. [док
--qnum=N ; номер очереди N
--bind-fix4 ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv4 пакетов
--bind-fix6 ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv6 пакетов
--ctrack-timeouts=S:E:F[:U] ; таймауты внутреннего conntrack в состояниях SYN, ESTABLISHED, FIN, таймаут udp. по умолчанию 60:300:60:60
--ctrack-disable=[0|1] ; 1 или остутствие аргумента отключает conntrack
--ipcache-lifetime=<int> ; время жизни записей кэша IP в секундах. 0 - без ограничений.
--ipcache-hostname=[0|1] ; 1 или отсутствие аргумента включают кэширование имен хостов для применения в стратегиях нулевой фазы
--wsize=<winsize>[:<scale_factor>] ; менять tcp window size на указанный размер в SYN,ACK. если не задан scale_factor, то он не меняется (устарело !)
--wssize=<winsize>[:<scale_factor>] ; менять tcp window size на указанный размер в исходящих пакетах. scale_factor по умолчанию 0. (см. conntrack !)
--wssize-cutoff=[n|d|s]N ; изменять server window size в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
--ctrack-timeouts=S:E:F[:U] ; таймауты внутреннего conntrack в состояниях SYN, ESTABLISHED, FIN, таймаут udp. по умолчанию 60:300:60:60
--orig-ttl=<int> ; модифицировать TTL оригинального пакета
--orig-ttl6=<int> ; модифицировать ipv6 hop limit оригинальных пакетов. если не указано, используется значение --orig-ttl
--orig-autottl=[<delta>[:<min>[-<max>]]] ; режим auto ttl для ipv4 и ipv6. по умолчанию: +5:3-64. delta=0 отключает функцию
--orig-autottl6=[<delta>[:<min>[-<max>]]] ; переопределение предыдущего параметра для ipv6
--orig-mod-start=[n|d|s]N ; применять orig-mod только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N
--orig-mod-cutoff=[n|d|s]N ; применять orig-mod только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
--dup=<int> ; высылать N дубликатов до оригинала
--dup-replace=[0|1] ; 1 или отсутствие аргумента блокирует отправку оригинала. отправляются только дубликаты.
--dup-ttl=<int> ; модифицировать TTL дубликатов
--dup-ttl6=<int> ; модифицировать ipv6 hop limit дубликатов. если не указано, используется значение --dup-ttl
--dup-autottl=[<delta>[:<min>[-<max>]]] ; режим auto ttl для ipv4 и ipv6. по умолчанию: +1:3-64. delta=0 отключает функцию
--dup-autottl6=[<delta>[:<min>[-<max>]]] ; переопределение предыдущего параметра для ipv6
--dup-fooling=<fooling> ; дополнительные методики как сделать, чтобы дубликат не дошел до сервера. none md5sig badseq badsum datanoack hopbyhop hopbyhop2
--dup-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000
--dup-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000
--dup-start=[n|d|s]N ; применять dup только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N
--dup-cutoff=[n|d|s]N ; применять dup только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
--hostcase ; менять регистр заголовка "Host:" по умолчанию на "host:".
--hostnospace ; убрать пробел после "Host:" и переместить его в конец значения "User-Agent:" для сохранения длины пакета
--methodeol ; добавить перевод строки в unix стиле ('\n') перед методом и убрать пробел из Host: : "GET / ... Host: domain.com" => "\nGET / ... Host:domain.com"
@ -181,7 +204,7 @@ dvtws, собираемый из тех же исходников (см. [док
--dpi-desync=[<mode0>,]<mode>[,<mode2] ; атака по десинхронизации DPI. mode : synack syndata fake fakeknown rst rstack hopbyhop destopt ipfrag1 multisplit multidisorder fakedsplit fakeddisorder ipfrag2 udplen tamper
--dpi-desync-fwmark=<int|0xHEX> ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000
--dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов
--dpi-desync-ttl6=<int> ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение ttl
--dpi-desync-ttl6=<int> ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение --dpi-desync-ttl
--dpi-desync-autottl=[<delta>[:<min>[-<max>]]] ; режим auto ttl для ipv4 и ipv6. по умолчанию: 1:3-20. delta=0 отключает функцию.
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]] ; переопределение предыдущего параметра для ipv6
--dpi-desync-fooling=<fooling> ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера. none md5sig badseq badsum datanoack hopbyhop hopbyhop2
@ -310,14 +333,19 @@ dvtws, собираемый из тех же исходников (см. [док
выяснено, что многие провайдерские NAT не отбрасывают эти пакеты, потому работает даже с внутренним провайдерским IP.
Но linux NAT оно не пройдет, так что за домашним роутером эта техника скорее всего не сработает, но может сработать с него.
Может сработать и через роутер, если подключение по проводу, и на роутере включено аппаратное ускорение.
* `autottl`. Суть режима в автоматическом определении TTL, чтобы он почти наверняка прошел DPI и немного не дошел до
сервера. Берутся базовые значения TTL 64,128,255, смотрится входящий пакет
(да, требуется направить первый входящий пакет на nfqws !). Вычисляется длина пути, отнимается `delta` (1 по
умолчанию). Если TTL вне диапазона (min,max - 3,20 по умолчанию), то берутся значения min,max, чтобы вписаться в
диапазон. Если при этом полученный TTL больше длины пути, то автоматизм не сработал и берутся фиксированные значения
TTL для атаки. Техника позволяет решить вопрос, когда вся сеть перегорожена шлагбаумами (DPI, ТСПУ) везде где только
* `autottl`. Суть режима в автоматическом определении TTL, чтобы пакет почти наверняка прошел DPI и немного не дошел до
сервера (`--dpi-desync-autottl`). Или наоборот - TTL едва хватило, чтобы он все-таки дошел до сервера (см `--dup-autottl`, `--orig-autottl`).
Берутся базовые значения TTL 64,128,255, смотрится входящий пакет (да, требуется направить первый входящий пакет на nfqws !).
Вычисляется длина пути, прибавляется `delta`. delta может быть положительной или отрицательной.
Чтобы задать положительную дельту, нужно указать унарный знак **+** перед числом.
В случае его отсутствия или при наличии унарного знака **-** дельта считается отрицательной.
Если TTL вне диапазона min,max, то берутся значения min,max, чтобы вписаться в
диапазон. Если при этом дельта отрицательная и полученный TTL больше длины пути или дельта положительная и полученный TTL меньше длины пути,
то автоматизм не сработал и берутся фиксированные значения : `--dpi-desync-ttl`, `--orig-ttl`, `--dup-ttl`.
Техника позволяет решить вопрос, когда вся сеть перегорожена шлагбаумами (DPI, ТСПУ) везде где только
можно, включая магистралов. Но потенциально может давать сбои. Например, при асимметрии входящего и исходящего канала
до конкретного сервера. На каких-то провайдерах эта техника будет работать неплохо, на других доставит больше проблем,
до конкретного сервера. Некоторые сервера выдают нестандартный TTL (google), потому на них получается полная ерунда.
Если не учитывать подобные исключения, то на каких-то провайдерах эта техника будет работать неплохо, на других доставит больше проблем,
чем пользы. Где-то может потребоваться тюнинг параметров. Лучше использовать с дополнительным ограничителем.
Режимы дурения могут сочетаться в любых комбинациях. `--dpi-desync-fooling` берет множество значений через запятую.
@ -450,16 +478,69 @@ extension хедерам в поисках транспортного хедер
При `hopbyhop,ipfrag2` последовательность хедеров будет : `ipv6,hop-by-hop`,`fragment`,`tcp/udp`.
Режим `ipfrag1` может срабатывать не всегда без специальной подготовки. См. раздел `IP фрагментация`.
### МОДИФИКАЦИЯ ОРИГИНАЛА
Параметры `--orig-ttl` и `--orig-ttl6` позволяют изменить TTL оригинальных пакетов.
Если дальнейшие манипуляции связаны с оригиналом, например, идет TCP сегментация, то исходными
данными являются измененные оригинальные пакеты. То есть в данном примере TCP сегменты пойдут с измененным TTL.
Вариант `--orig-autottl` и `--orig-autottl6` работает аналогично `dpi-desync-autottl`, но по оригинальным пакетам.
Дельту стоит указывать положительную с унарным знаком `+`, иначе оригинал не дойдет до сервера, и вы вообще ничего не получите.
Пример : `--orig-autottl=+5:3-64`.
`--orig-mod-start` и `--orig-mod-cutoff` задают ограничитель по началу и концу модификации оригинала.
Схема аналогична `--dpi-desync-start` и `--dpi-desync-cutoff`.
Функция может быть полезна, когда DPI охотится за фейками и блокирует соединение при наличии подозрительных признаков,
в частности, измененный TTL у фейка относительно оригинала.
### ДУБЛИКАТЫ
Дубликаты - это копии оригинальных пакетов, высылаемые перед ними. Включаются параметром `--dup=N`, где N - количество дублей,
не включающее оригинал. `--dup-replace` отключает отсылку оригинала.
Отсылка дублей имеет место только в тех случаях, когда высылается и оригинал без реконструкции.
Например, если случилась TCP сегментация, то оригинал фактически дропается и заменяется искусственно сконструированными сегментами.
Дубли высланы не будут. Это же касается изменения состава хедеров ipv6, режима tamper для DHT и других.
Возможно применение всех вариантов дурения, как и для desync : `--dup-ttl`. `--dup-ttl6`, `--dup-fooling`. Нужно ли, чтобы эти пакеты доходили до сервера и в каком виде, решаете вы согласно задуманной стратегии.
Вариант `--dup-autottl` и `--dup-autottl6` работает аналогично `dpi-desync-autottl`, но по дублям.
Дельту можно указывать положительную с унарным знаком `+`, а можно и отрицательную. Зависит от вашей задумки.
Пример : `--dup-autottl=-2:3-64`.
`--dup-start` и `--dup-cutoff` задают ограничитель по началу и концу применения стратегии дубликатов.
Схема аналогична `--dpi-desync-start` и `--dpi-desync-cutoff`.
Функция может помочь, когда DPI сечет разницу в характеристиках фейков и оригинала.
Дубликатами можно попытаться заставить DPI принять , что весь сеанс идет аномальным.
Например, у нас имеется TCP сеанс с MD5 сразу с первого SYN пакета. Значит последующие MD5 будут восприниматься нормально.
### КОМБИНИРОВАНИЕ МЕТОДОВ ДЕСИНХРОНИЗАЦИИ
В параметре dpi-desync можно указать до 3 режимов через запятую.
* 0 фаза - предполагает работу на этапе установления соединения : `synack`, `syndata`, `--wsize`, `--wssize`. На эту фазу не действуют фильтры по [hostlist](#множественные-стратегии).
* 0 фаза - предполагает работу на этапе установления соединения : `synack`, `syndata`, `--wsize`, `--wssize`. На эту фазу не действуют фильтры по [hostlist](#множественные-стратегии), кроме случая, описанного [далее](#кэш-ip).
* 1 фаза - отсылка чего-либо до оригинального пакета данных : `fake`, `rst`, `rstack`.
* 2 фаза - отсылка в модифицированном виде оригинального пакета данных (например, `fakedsplit` или `ipfrag2`).
Режимы требуют указания в порядке возрастания номеров фаз.
### КЭШ IP
ipcache представляет собой структуру в памяти процесса, позволяющую по ключу IP адреса и имени интерфейса запоминать некоторую информацию,
которую впоследствии можно извлечь и использовать как недостающие данные. На текущий момент это применяются в следующих ситуациях :
1. IP,interface => hop count . Кэшируется количество хопов до сервера для последующего применения в autottl прямо с первого пакета, когда еще ответа не было. Пока записи в кэше нет, autottl не будет применен сразу. При повторном запросе до истечения времени жизни записи autottl будет применение сразу.
2. IP => hostname . Кэшируется имя хоста, вне привязки к интерфейсу, для последующего применения в стратегиях нулевой фазы. Режим отключен по умолчанию и включается через параметры `ipcache-hostname`.
Данная техника является экспериментальной. Ее проблема в том, что как такового нет однозначного соответствия между доменом и IP. Множество доменов могут ссылаться на тот же IP адрес.
При коллизии происходит замещение имени хоста на последний вариант.
Домен может скакать по разным IP на CDN. Сейчас один адрес, через час - другой. Эта проблема решается через время жизни записей кэша : `--ipcache-lifetime`. По умолчанию 2 часа.
Однако, может случиться и так, что в вашем случае применение техники несет больше пользы, чем проблем. Будьте готовы к непонятному на первый взгляд поведению, которое может быть исследовано только через `--debug` лог.
При подаче сигнала SIGUSR2 процесс выводит содержимое ipcache на консоль.
### РЕАКЦИЯ DPI НА ОТВЕТ СЕРВЕРА
Есть DPI, которые анализируют ответы от сервера, в частности сертификат из ServerHello, где прописаны домены.
@ -861,6 +942,8 @@ tpws - это transparent proxy.
--local-tcp-user-timeout=<seconds> ; таймаут соединений client-proxy (по умолчанию : 10 сек, 0 = оставить системное значение)
--remote-tcp-user-timeout=<seconds> ; таймаут соединений proxy-target (по умолчанию : 20 сек, 0 = оставить системное значение)
--fix-seg=<int> ; исправлять неудачи tcp сегментации ценой задержек для всех клиентов и замедления. ждать до N мс. по умолчанию 30 мс.
--ipcache-lifetime=<int> ; время жизни записей кэша IP в секундах. 0 - без ограничений.
--ipcache-hostname=[0|1] ; 1 или отсутствие аргумента включают кэширование имен хостов для применения в стратегиях нулевой фазы
--split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации
--split-any-protocol ; применять сегментацию к любым пакетам. по умолчанию - только к известным протоколам (http, TLS)
@ -982,9 +1065,9 @@ tpws работает на уровне сокетов, поэтому длин
шлет сервер. На TLS 1.2 если сервер разбил заброс так, чтобы домен из сертификата не попал в первый пакет,
это может обмануть DPI, секущий ответ сервера.
Схема может значительно снизить скорость и сработать не на всех сайтах.
С фильтром по hostlist совместимо только в режиме socks при включенном удаленном ресолвинге хостов.
(firefox network.proxy.socks_remote_dns). Это единственный вариант, когда tpws может узнать имя хоста
еще на этапе установления соединения.
С фильтром по hostlist совместимо только в [некоторых случаях](#множественные-стратегии-1), когда возможно узнать имя хоста на момент применения дурения.
Применяя данную опцию к сайтам TLS1.3, если броузер тоже поддерживает TLS1.3, то вы делаете только хуже.
Но нет способа автоматически узнать когда надо применять, когда нет, поскольку MSS идет только в
3-way handshake еще до обмена данными, а версию TLS можно узнать только по ответу сервера, который
@ -1008,14 +1091,17 @@ tpws работает на уровне сокетов, поэтому длин
Работают аналогично **nfqws**, кроме некоторых моментов.
Нет параметра `--filter-udp`, поскольку **tpws** udp не поддерживает.
Методы нулевой фазы (`--mss`) могут работать по хостлисту в одном единственном случае:
если используется режим socks и удаленный ресолвинг хостов через прокси.
То есть работоспособность вашей настройки в одном и том же режиме может зависеть от того,
применяет ли клиент удаленный ресолвинг. Это может быть неочевидно.
В одной программе работает, в другой - нет.
Если вы используете профиль с хостлистом , и вам нужен mss, укажите mss в профиле с хостлистом,
Методы нулевой фазы (`--mss`) могут работать по хостлисту только в двух случаях:
если используется режим socks и удаленный ресолвинг хостов через прокси, либо используется система [кэша IP](#кэш-ip) для запоминания соответствия IP->hostname.
Работоспособность вашей настройки в одном и том же режиме может зависеть от того,
применяет ли клиент удаленный ресолвинг. Это может быть неочевидно. В одной программе работает, в другой - нет.
Если вы используете профиль с хостлистом , и вам нужен mss всегда, укажите mss в профиле с хостлистом,
создайте еще один профиль без хостлиста, если его еще нет, и в нем еще раз укажите mss.
Тогда при любом раскладе будет выполняться mss.
Если вам нужен mss по хостлисту, указывайте `--mss` только в профиле с хостлистом и убедитесь в наличии любого из необходимых условий работы в таком режиме.
Используйте `curl --socks5` и `curl --socks5-hostname` для проверки вашей стратегии.
Смотрите вывод `--debug`, чтобы убедиться в правильности настроек.
@ -1660,13 +1746,16 @@ nfqws начнет получать адреса пакетов из локал
Каждая опция предполагает запуск одного инстанса соответствующего демона. Все различия методов дурения
для `http`, `https`, `quic` и т.д. должны быть отражены через схему мультистратегий.
В этом смысле настройка похожа на вариант `winws` на Windows, а перенос конфигов не должен представлять больших сложностей.
Основное правило настройки перехвата - перехватывайте только необходимый минимум.
Любой перехват лишнего - это бессмысленная нагрузка на вашу систему.
Опции демонов `--ipset` использовать запрещено. Это сделано намеренно и искусственно, чтобы не поощрять простой и
работающий, но неэффективный метод на *nix системах. Используйте `ipset`-ы режима ядра.
При необходимости пишите и задействуйте `custom scripts`.
Опции демонов `--ipset` использовать нужно с умом. Не стоит перехватывать весь трафик, чтобы потом по параметру --ipset
выделить лишь горстку IP. Это будет работать, но очень неэффективно с точки зрения нагрузки на систему.
Используйте `ipset`-ы режима ядра. При необходимости пишите и задействуйте `custom scripts`.
Но если у вас и так идет работа по всем IP, и нужно написать небольшую специализацию по IP, то --ipset вполне уместен.
Настройки демонов можно для удобства писать на нескольких строках, используя двойные или одинарные кавычки.
Чтобы задействовать стандартные обновляемые хост-листы из `ipset`, используйте маркер <HOSTLIST>.
Чтобы задействовать стандартные обновляемые хост-листы из каталога `ipset`, используйте маркер <HOSTLIST>.
Он будет заменен на параметры, соответствующие режиму MODE_FILTER, и будут подставлены реально существующие файлы.
Если MODE_FILTER не предполагает стандартного хостлиста, <HOSTLIST> будет заменен на пустую строку.
Стандартные хостлисты следует вставлять в финальных стратегиях (стратегиях по умолчанию), закрывающих цепочки по
@ -1760,7 +1849,7 @@ hardware: выборочное управление включено в режи
```
`FLOWOFFLOAD=donttouch`
Параметр GETLIST указывает инсталлятору `install_easy.sh` какой скрипт дергать
Параметр `GETLIST` указывает инсталлятору `install_easy.sh` какой скрипт дергать
для обновления списка заблокированных ip или хостов.
Он же вызывается через `get_config.sh` из запланированных заданий (crontab или systemd timer).
Поместите сюда название скрипта, который будете использовать для обновления листов.
@ -1847,11 +1936,18 @@ OPENWRT_WAN4="wan4 vpn"
OPENWRT_WAN6="wan6 vpn6"
```
Параметр INIT_APPLY_FW=1 разрешает init скрипту самостоятельно применять правила iptables.\
Параметр `INIT_APPLY_FW=1` разрешает init скрипту самостоятельно применять правила iptables.\
При иных значениях или если параметр закомментирован, правила применены не будут.\
Это полезно, если у вас есть система управления фаерволом, в настройки которой и следует прикрутить правила.\
На OpenWrt неприменимо при использовании firewall3+iptables.
`FILTER_TTL_EXPIRED_ICMP=1` включает механизмы блокировки пакетов icmp time exceeded, высылаемые роутерами по пути следования пакета в ответ на исчерпание TTL/HL.
В linux соединение обрывается системой, если в ответ на первый пакет (для tcp - SYN) пришел такой icmp. Аналогичная схема имеется и в datagram сокетах.
Блокировка icmp идет исключительно за счет средств iptables/nftables.
Чтобы не трогать весь трафик, в режиме PRENAT используется connmark для пометки сеансов, над которыми поработал nfqws. В режиме POSTNAT так сделать нельзя,
поэтому помечаются все сеансы, заворачиваемые на nfqws.
Настройку лучше отключить, если вы не ожидаете проблем от icmp, тк в этом случае будет меньше ненужных вмешательств в трафик.
***Следующие настройки не актуальны для openwrt:***
Если ваша система работает как роутер, то нужно вписать названия внутренних и внешних интерфейсов:
@ -2334,32 +2430,38 @@ OpenWrt является одной из немногих относительн
VPS — это виртуальный сервер. Существует огромное множество датацентров, предлагающих данную услугу.
На VPS могут выполняться какие угодно задачи. От простого веб-сайта до навороченной системы собственной разработки.
Можно использовать VPS и для поднятия собственного VPN или прокси.
Сама широта возможных способов применения и распространенность услуги ограничивают возможности регуляторов
по бану сервисов такого типа. Да, если введут белые списки, то решение загнется, но это будет уже другая
Сама широта возможных способов применения и распространенность услуги сводят к минимуму возможности
регуляторов по бану сервисов такого типа. Да, если введут белые списки, то решение загнется, но это будет уже другая
реальность, в которой придется изобретать иные решения.
Пока этого не сделали. Однако, уже наблюдаются попытки гасить некоторые протоколы на диапазонах VPS провайдеров.
Вплоть до TLS. Как следствие не работают ни средства обхода типа VLESS, ни обычные сайты.
Пока это делается еще точечно, не на всех провайдерах. Не стоит сразу оплачивать VPS надолго. Сначала проверьте
все ли работает из того, что вам нужно. Или может быть стоит найти другой VPS.
VPS имеет преимущество над VPN провайдером.
Пока этого не сделали, никто не будет банить хостинги просто потому, что они предоставляют хостинг услуги.
Вы, как индивидуум, скорее всего, никому не нужны. Подумайте чем вы отличаетесь от известного VPN провайдера.
VPN-провайдер предоставляет _простую_ и оступную_ услугу по обходу блокировок для масс.
Все, что просто и доступно, первым делом идет под блок.
Этот факт делает его первоочередной целью блокировки. РКН направит уведомление, после отказа сотрудничать
заблокирует VPN. Предоплаченная сумма пропадет.
У регуляторов нет и никогда не будет ресурсов для тотальной проверки каждого сервера в сети.
Возможен китайский расклад, при котором DPI выявляет VPN-протоколы и динамически банит IP серверов,
предоставляющих нелицензированный VPN. Но имея знания, голову, вы всегда можете обфусцировать
VPN трафик или применить другие типы VPN, более устойчивые к анализу на DPI, или просто менее широкоизвестные,
а следовательно с меньшей вероятностью обнаруживаемые регулятором.
У вас есть свобода делать на вашем VPS все что вы захотите, адаптируясь к новым условиям.
Да, это потребует знаний. Вам выбирать учиться и держать ситуацию под контролем, когда вам ничего запретить
не могут, или покориться системе. Порог необходимых знаний и возможностей для самостоятельного входа в обход блокировок будет только возрастать.
не могут, или покориться системе.
VPS можно приобрести в множестве мест. Существуют специализированные на поиске предложений VPS порталы.\
Например, [вот этот](https://vps.today). Для персонального VPN сервера обычно достаточно самой минимальной конфигурации, но с безлимитным трафиком или
Например, [вот этот](https://vps.today).
Для персонального VPN сервера обычно достаточно самой минимальной конфигурации, но с безлимитным трафиком или
с большим лимитом по трафику (терабайты). Важен и тип VPS. OpenVZ подойдёт для OpenVPN, но
вы не поднимете на нем WireGuard, IPsec, то есть все, что требует kernel mode.
Для kernel mode требуется тип виртуализации, предполагающий запуск полноценного экземпляра ОС linux
вместе с ядром. Подойдут KVM, Xen, Hyper-V, VMware.
По цене можно найти предложения, которые будут дешевле готовой VPN услуги, но при этом вы сам хозяин в своей лавке
и не рискуете попасть под бан регулятора, разве что «заодно» — под ковровую бомбардировку с баном миллионов IP.
Кроме того, если вам совсем все кажется сложным, прочитанное вызывает ступор и вы точно знаете, что ничего
из описанного сделать не сможете, то вы сможете хотя бы использовать динамическое перенаправление портов SSH
для получения шифрованного SOCKS-прокси и прописать его в браузер. Знания linux не нужны совсем.
Это вариант наименее напряжный для чайников, хотя и не самый удобный в использовании.
## Поддержать разработчика
USDT `0x3d52Ce15B7Be734c53fc9526ECbAB8267b63d66E`

View File

@ -562,7 +562,8 @@ static uint8_t ct_new_postnat_fix(const t_ctrack *ctrack, struct ip *ip, struct
// so we need to workaround this.
// we can't use low ttl because TCP/IP stack listens to ttl expired ICMPs and notify socket
// we also can't use fooling because DPI would accept fooled packets
if (ctrack && ctrack->pcounter_orig==1)
// SYN and SYN,ACK checks are for conntrack-less mode
if (ctrack && ctrack->pcounter_orig==1 || tcp && (tcp_syn_segment(tcp) || tcp_synack_segment(tcp)))
{
DLOG("applying linux postnat conntrack workaround\n");
if (proto==IPPROTO_UDP && udp && len_pkt)
@ -809,6 +810,8 @@ static bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr
DLOG_ERR("ipcache_put_hostname: out of memory\n");
return false;
}
if (!ipc->hostname || strcmp(ipc->hostname,hostname))
{
free(ipc->hostname);
if (!(ipc->hostname = strdup(hostname)))
{
@ -816,6 +819,7 @@ static bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr
return false;
}
DLOG("hostname cached: %s\n", hostname);
}
return true;
}
static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr *a6, char *hostname, size_t hostname_buf_len)
@ -1161,12 +1165,15 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
{
// in real mode ctrack may be NULL or not NULL, conntrack_replay is equal to ctrack
if (!params.ctrack_disable)
{
ConntrackPoolPurge(&params.conntrack);
if (ConntrackPoolFeed(&params.conntrack, dis->ip, dis->ip6, dis->tcp, NULL, dis->len_payload, &ctrack, &bReverse))
{
dp = ctrack->dp;
ctrack_replay = ctrack;
}
}
if (dp)
DLOG("using cached desync profile %d\n",dp->n);
else if (!ctrack || !ctrack->dp_search_complete)
@ -2370,12 +2377,15 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
{
// in real mode ctrack may be NULL or not NULL, conntrack_replay is equal to ctrack
if (!params.ctrack_disable)
{
ConntrackPoolPurge(&params.conntrack);
if (ConntrackPoolFeed(&params.conntrack, dis->ip, dis->ip6, NULL, dis->udp, dis->len_payload, &ctrack, &bReverse))
{
dp = ctrack->dp;
ctrack_replay = ctrack;
}
}
if (dp)
DLOG("using cached desync profile %d\n",dp->n);
else if (!ctrack || !ctrack->dp_search_complete)

View File

@ -1417,6 +1417,7 @@ static void exithelp(void)
" --bind-fix6\t\t\t\t\t; apply outgoing interface selection fix for generated ipv6 packets\n"
#endif
" --ctrack-timeouts=S:E:F[:U]\t\t\t; internal conntrack timeouts for TCP SYN, ESTABLISHED, FIN stages, UDP timeout. default %u:%u:%u:%u\n"
" --ctrack-disable=[0|1]\t\t\t\t; 1 or no argument disables conntrack\n"
" --ipcache-lifetime=<int>\t\t\t; time in seconds to keep cached hop count and domain name (default %u). 0 = no expiration\n"
" --ipcache-hostname=[0|1]\t\t\t; 1 or no argument enables ip->hostname caching\n"
#ifdef __CYGWIN__
@ -1620,6 +1621,7 @@ enum opt_indices {
IDX_WSSIZE,
IDX_WSSIZE_CUTOFF,
IDX_CTRACK_TIMEOUTS,
IDX_CTRACK_DISABLE,
IDX_IPCACHE_LIFETIME,
IDX_IPCACHE_HOSTNAME,
IDX_HOSTCASE,
@ -1739,6 +1741,7 @@ static const struct option long_options[] = {
[IDX_WSSIZE] = {"wssize", required_argument, 0, 0},
[IDX_WSSIZE_CUTOFF] = {"wssize-cutoff", required_argument, 0, 0},
[IDX_CTRACK_TIMEOUTS] = {"ctrack-timeouts", required_argument, 0, 0},
[IDX_CTRACK_DISABLE] = {"ctrack-disable", optional_argument, 0, 0},
[IDX_IPCACHE_LIFETIME] = {"ipcache-lifetime", required_argument, 0, 0},
[IDX_IPCACHE_HOSTNAME] = {"ipcache-hostname", optional_argument, 0, 0},
[IDX_HOSTCASE] = {"hostcase", no_argument, 0, 0},
@ -2048,6 +2051,9 @@ int main(int argc, char **argv)
exit_clean(1);
}
break;
case IDX_CTRACK_DISABLE:
params.ctrack_disable = !optarg || atoi(optarg);
break;
case IDX_IPCACHE_LIFETIME:
if (sscanf(optarg, "%u", &params.ipcache_lifetime)!=1)
{
@ -2056,7 +2062,7 @@ int main(int argc, char **argv)
}
break;
case IDX_IPCACHE_HOSTNAME:
params.cache_hostname = !optarg || !!atoi(optarg);
params.cache_hostname = !optarg || atoi(optarg);
break;
case IDX_HOSTCASE:
dp->hostcase = true;
@ -2180,7 +2186,7 @@ int main(int argc, char **argv)
params.autottl_present=true;
break;
case IDX_DUP_REPLACE:
dp->dup_replace = optarg ? !!atoi(optarg) : true;
dp->dup_replace = !optarg || atoi(optarg);
break;
case IDX_DUP_FOOLING:
if (!parse_fooling(optarg,&dp->dup_fooling_mode))
@ -2966,9 +2972,14 @@ int main(int argc, char **argv)
goto exiterr;
}
if (params.ctrack_disable)
DLOG_CONDUP("conntrack disabled ! some functions will not work. make sure it's what you want.\n");
else
{
DLOG("initializing conntrack with timeouts tcp=%u:%u:%u udp=%u\n", params.ctrack_t_syn, params.ctrack_t_est, params.ctrack_t_fin, params.ctrack_t_udp);
if (params.autottl_present || params.cache_hostname) DLOG("ipcache lifetime %us\n", params.ipcache_lifetime);
ConntrackPoolInit(&params.conntrack, 10, params.ctrack_t_syn, params.ctrack_t_est, params.ctrack_t_fin, params.ctrack_t_udp);
}
if (params.autottl_present || params.cache_hostname) DLOG("ipcache lifetime %us\n", params.ipcache_lifetime);
#ifdef __linux__
result = nfq_main();

View File

@ -197,9 +197,10 @@ struct params_s
unsigned int ctrack_t_syn, ctrack_t_est, ctrack_t_fin, ctrack_t_udp;
t_conntrack conntrack;
bool ctrack_disable;
unsigned int ipcache_lifetime;
bool autottl_present,cache_hostname;
unsigned int ipcache_lifetime;
ip_cache ipcache;
};

View File

@ -12,6 +12,7 @@
// this saves memory. sockaddr_storage is larger than required. it can be 128 bytes. sockaddr_in6 is 28 bytes.
typedef union
{
sa_family_t sa_family;
struct sockaddr_in sa4; // size 16
struct sockaddr_in6 sa6; // size 28
} sockaddr_in46;

View File

@ -91,7 +91,7 @@ static void TLSDebug(const uint8_t *tls,size_t sz)
TLSDebugHandshake(tls+5,sz-5);
}
static bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname)
bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname)
{
if (!params.cache_hostname) return true;
@ -101,6 +101,8 @@ static bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr
DLOG_ERR("ipcache_put_hostname: out of memory\n");
return false;
}
if (!ipc->hostname || strcmp(ipc->hostname,hostname))
{
free(ipc->hostname);
if (!(ipc->hostname = strdup(hostname)))
{
@ -108,6 +110,7 @@ static bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr
return false;
}
VPRINT("hostname cached: %s\n", hostname);
}
return true;
}
static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr *a6, char *hostname, size_t hostname_buf_len)

View File

@ -21,6 +21,7 @@ typedef struct
} t_ctrack;
void apply_desync_profile(t_ctrack *ctrack, const struct sockaddr *dest);
bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname);
void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment,size_t segment_buffer_size,size_t *size, size_t *multisplit_pos, int *multisplit_count, uint8_t *split_flags);
void tamper_in(t_ctrack *ctrack, const struct sockaddr *client, uint8_t *segment,size_t segment_buffer_size,size_t *size);

View File

@ -494,6 +494,9 @@ static bool connect_remote_conn(tproxy_conn_t *conn)
{
int mss=0;
if (conn->track.hostname)
if (!ipcache_put_hostname(conn->dest.sa_family==AF_INET ? &((struct sockaddr_in*)&conn->dest)->sin_addr : NULL, conn->dest.sa_family==AF_INET6 ? &((struct sockaddr_in6*)&conn->dest)->sin6_addr : NULL , conn->track.hostname))
DLOG_ERR("ipcache_put_hostname: out of memory");
apply_desync_profile(&conn->track, (struct sockaddr *)&conn->dest);
if (conn->track.dp && conn->track.dp->mss)
@ -1087,7 +1090,8 @@ static bool resolve_complete(struct resolve_item *ri, struct tailhead *conn_list
if (!conn->track.hostname)
{
DBGPRINT("resolve_complete put hostname : %s\n", ri->dom);
conn->track.hostname = strdup(ri->dom);
if (!(conn->track.hostname = strdup(ri->dom)))
DLOG_ERR("dup hostname: out of memory\n");
}
sa46copy(&conn->dest, (struct sockaddr *)&ri->ss);
return proxy_mode_connect_remote(conn,conn_list);