--dpi-desync-fwmark=<int|0xHEX> ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000
--dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов
--dpi-desync-fooling=none|md5sig|badsum ; дополнительные методики как сделать, чтобы десинхронизирующий пакет не дошел до сервера
--dpi-desync-retrans=0|1 ; (только для fake,rst,rstack) 0(default)=отправлять оригинал следом за фейком 1=дропать оригинал, заставляя ОС выполнять ретрансмиссию через 0.2 сек
--dpi-desync-skip-nosni=0|1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
--dpi-desync-split-pos=<1..1500> ; (только для disorder) разбивать пакет на указанной позиции
connbytes направит в очередь только первый пакет с данными. mark нужен, чтобы сгенерированный поддельный пакет не попал опять к нам на обработку.
nfqws выставляет fwmark при его отсылке.
tpws
-----
tpws - это transparent proxy.
--debug=0|1|2 ; Количество буковок в output : 0(default)=тихо, 1=подробно, 2=отладка
--daemon ; демонизировать прогу
--pidfile=<file> ; сохранить PID в файл
--user=<username> ; менять uid процесса
--uid=uid[:gid] ; менять uid процесса
--bind-addr ; на каком адресе слушать. может быть ipv4 или ipv6 адрес. если не указано, то слушает на всех адресах ipv4 и ipv6
; если указан ipv6 link local, то требуется указать с какого он интерфейса через --bind-iface6
--bind-linklocal=prefer|force ; если prefer, то найти link local от iface6. если не найдено - использовать первый адрес любого типа.
; если force и link local не найден - выход по ошибке.
--bind-iface4=<iface> ; слушать на первом ipv4 интерфейса iface
--bind-iface6=<iface> ; слушать на первом ipv6 интерфейса iface. при bind-linklocal определяет интерфейс, откуда брать ipv6 link local
--bind-wait-ifup=<sec> ; ждать до N секунд появления и поднятия интерфейса
--bind-wait-ip=<sec> ; ждать до N секунд получения IP адреса (если задан --bind-wait-ifup - время идет после поднятия интерфейса)
--bind-wait-ip-linklocal=<sec> ; (только если заданы --bind-wait-ip и --bind-linklocal=prefer) согласиться на global address после N секунд
--socks ; вместо прозрачного прокси реализовать socks4/5 proxy
--no-resolve ; запретить ресолвинг имен через socks5
--port=<port> ; на каком порту слушать
--maxconn=<max_connections> ; максимальное количество соединений от клиентов к прокси
--maxfiles=<max_open_files> ; макс количество файловых дескрипторов (setrlimit). мин требование (X*connections+16), где X=6 в tcp proxy mode, X=4 в режиме тамперинга.
; стоит сделать запас с коэффициентом как минимум 1.5. по умолчанию maxfiles (X*connections)*1.5+16
--max-orphan-time=<sec>; если вы запускате через tpws торрент-клиент с множеством раздач, он пытается установить очень много исходящих соединений,
; большая часть из которых отваливается по таймату (юзера сидят за NAT, firewall, ...)
; установление соединения в linux может длиться очень долго. локальный конец отвалился, перед этим послав блок данных,
; tpws ждет подключения удаленного конца, чтобы отослать ему этот блок, и зависает надолго.
; настройка позволяет сбрасывать такие подключения через N секунд, теряя блок данных. по умолчанию 5 сек. 0 означает отключить функцию
; эта функция не действует на успешно подключенные ранее соединения
--local-rcvbuf=<bytes> ; SO_RCVBUF для соединений client-proxy
--local-sndbuf=<bytes> ; SO_SNDBUF для соединений client-proxy
--remote-rcvbuf=<bytes> ; SO_RCVBUF для соединений proxy-target
--remote-sndbuf=<bytes> ; SO_SNDBUF для соединений proxy-target
--skip-nodelay ; не устанавливать в исходящих соединения TCP_NODELAY. несовместимо со split.
--split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host
--split-pos=<offset> ; делить все посылы на сегменты в указанной позиции. Если отсыл длинее 8Kb (размер буфера приема), то будет разделен каждый блок по 8Kb.
--hostcase ; менять регистр заголовка "Host:". по умолчанию на "host:".
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
--hostdot ; добавление точки после имени хоста : "Host: kinozal.tv."
--hosttab ; добавление табуляции после имени хоста : "Host: kinozal.tv\t"
--hostnospace ; убрать пробел после "Host:"
--hostpad=<bytes> ; добавить паддинг-хедеров общей длиной <bytes> перед Host:
--methodspace ; добавить пробел после метода : "GET /" => "GET /"
--methodeol ; добавить перевод строки перед методом : "GET /" => "\r\nGET /"
--unixeol ; конвертировать 0D0A в 0A и использовать везде 0A
--hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются. в файле должен быть хост на каждой строке.
; список читается 1 раз при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
; для списка РКН может потребоваться система с 128 Mb памяти ! расчитывайте требование RAM для процесса как 3-5 кратный размер файла списка.
; по сигналу HUP список будет перечитан при следующем принятом соединении
; список может быть запакован в gzip. формат автоматически распознается и разжимается
Параметры манипуляции могут сочетаться в любых комбинациях.
Есть исключения : split-pos заменяет split-http-req. hostdot и hosttab взаимоисключающи.
На прикладном уровне в общем случае нет гарантированного средства заставить ядро выплюнуть
блок данных, порезанным в определенном месте. ОС держит буфер отсылки (SNDBUF) у каждого сокета.
Если у сокета включена опция TCP_NODELAY и буфер пуст, то каждый send приводит к отсылке
отдельного ip пакета или группы пакетов, если блок не вмещается в один ip пакет.
Однако, если в момент send уже имеется неотосланный буфер, то ОС присоединит данные к нему,
никакой отсылки отдельным пакетом не будет. Но в этом случае и так нет никакой гарантии,
что какой-то блок сообщения пойдет в начале пакета, на что собственно и заточены DPI.
Разбиение будет производится согласно MSS, который зависит от MTU исходящего интерфейса.
Таким образом DPI, смотрящие в начало поля данных TCP пакета, будут поломаны в любом случае.
Протокол http относится к запрос-ответным протоколам. Новое сообщение посылается только тогда,
когда сервер получил запрос и полностью вернул ответ. Значит запрос фактически был не только отослан,
но и принят другой стороной, а следовательно буфер отсылки пуст, и следующие 2 send приведут
к отсылке сегментов данных разными ip пакетами.
Резюме : tpws гарантирует сплит только за счет раздельных вызовов send, что на практике
вполне достаточно для протоколов http(s).
tpws может биндаться только к одному ip или ко всем сразу.
Для бинда на все ipv4 укажите "0.0.0.0", на все ipv6 - "::". Без параметров биндаемся на все ipv4 и ipv6.
Параметры --bind-wait* могут помочь в ситуациях, когда нужно взять IP с интерфейса, но его еще нет, он не поднят
или не сконфигурирован.
В разных системах события ifup ловятся по-разному и не гарантируют, что интерфейс уже получил IP адрес определенного типа.
В общем случае не существует единого механизма повеситься на событие типа "на интерфейсе X появился link local address".
Параметры 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.
Режим "--socks" не требует повышенных привилегий (кроме бинда на привилегированные порты 1..1023).
Поддерживаются версии socks 4 и 5 без авторизации. Версия протокола распознается автоматически.
Подключения к IP того же устройства, на котором работает tpws, включая localhost, запрещены.
tpws поддерживает эту возможность, однако используется блокирующий ресолвинг. Пока система
ресолвит хост (это может занять секунды), вся активность останавливается.
tpws полностью работает на асинхронных сокетах, но ресолвинг может попортить эту модель.
С ним возможны атаки DoS на tpws. Если tpws обслуживает множество клиентов, то из-за частого
ресолвинга качество обслуживания может существенно ухудшиться.
Если удаленный ресолвинг создает проблемы, настройте клиенты на локальный ресолвинг, включите опцию
--no-resolve на стороне tpws.
Параметр --hostpad=<bytes> добавляет паддинг-хедеров перед Host: на указанное количество байтов.
Если размер <bytes> слишком большой, то идет разбивка на разные хедеры по 2K.
Общий буфер приема http запроса - 64K, больший паддинг не поддерживается, да и http сервера
такое уже не принимают.
Полезно против DPI, выполняющих реассемблинг TCP с ограниченным буфером.
Если техника работает, то после некоторого количества bytes http запрос начнет проходить до сайта.
Если при этом критический размер padding около MTU, значит скорее всего DPI не выполняет реассемблинг пакетов, и лучше будет использовать обычные опции --split-…
Если все же реассемблинг выполняется, то критический размер будет около размера буфера DPI. Он может быть 4K или 8K, возможны и другие значения.
--skip-nodelay может быть полезен, чтобы привести MTU к MTU системы, на которой работает tpws.
Это может быть полезно для скрытия факта использования VPN. Пониженный MTU - 1 из способов обнаружения
подозрительного подключения. С tcp proxy ваши соединения неотличимы от тех, что сделал бы сам шлюз.
Способы получения списка заблокированных IP
-------------------------------------------
1) Внесите заблокирванные домены в ipset/zapret-hosts-user.txt и запустите ipset/get_user.sh
На выходе получите ipset/zapret-ip-user.txt с IP адресами.
Cкрипты с названием get_reestr_* оперируют дампом реестра заблокированных сайтов :
2) ipset/get_reestr_resolve.sh получает список доменов от rublacklist и дальше их ресолвит в ip адреса
в файл ipset/zapret-ip.txt.gz. В этом списке есть готовые IP адреса, но судя во всему они там в точности в том виде,
что вносит в реестр РосКомПозор. Адреса могут меняться, позор не успевает их обновлять, а провайдеры редко
банят по IP : вместо этого они банят http запросы с "нехорошим" заголовком "Host:" вне зависимости
от IP адреса. Поэтому скрипт ресолвит все сам, хотя это и занимает много времени.
Используется мультипоточный ресолвер mdig (собственная разработка).
Реестр РКН уже настолько огромен, что однопоточный ресолв займет вечность, а многопоточный хоть и тоже много времени,
но хотя бы оно конечно.
3) ipset/get_reestr_ip.txt
взять все IP адреса из реестра и загнать в ipset zapret/zapret6
на роутерах с <128 Mb RAM может сработать только с TMPDIR на внешнем носителе
4) ipset/get_reestr_combined.sh. для провайдеров, которые блокируют по IP https, а остальное по DPI.
IP https и IP без домена заносятся в ipset ipban, остальные в ipset zapret.
на роутерах с <128 Mb RAM может сработать только с TMPDIR на внешнем носителе
Скрипты 3 и 4 убирают из списка мусор. На данный момент мусором считается миллион+ забаненых telegram proxy IP.
Это сокращает размер списка кардинально. Большой объем памяти требуется только для временного хранения скачанного
реестра в /tmp. Потом из списка уберется мусор, он станет значительно легче, поместится в ipset даже на 64 Mb RAM.
Поэтому поможет задание TMPDIR на флэшку.
Cкрипты с названием get_antifilter_* оперируют списками адресов и масок подсетей с сайтов antifilter.network и antifilter.download :
5) ipset/get_antifilter_ip.sh. получает лист https://antifilter.network/download/ip.lst.
лист содержит огромное количество ip (> миллиона).
на роутерах с <128 Mb RAM даже не пытайтесь
7) ipset/get_antifilter_ipsmart.sh. получает лист https://antifilter.network/download/ipsmart.lst.
это умная суммаризация отдельных адресов из ip.lst по маскам от /32 до /22
количество префиксов измеряется всего лишь десятками тысяч, потому это лучшее решение для роутера с 64 Mb RAM
7) ipset/get_antifilter_ipsum.sh. получает лист https://antifilter.network/download/ipsum.lst.
это суммаризация отдельных адресов из ip.lst по маске /24
количество префиксов измеряется всего лишь десятками тысяч, потому можно использовать на роутерах с 64 Mb RAM
Все варианты рассмотренных скриптов автоматически создают и заполняют ipset.
Варианты 2-7 дополнительно вызывают вариант 1.
8) ipset/get_config.sh. этот скрипт вызывает то, что прописано в переменной GETLIST из файла config
Если переменная не определена, то ресолвятся лишь листы для ipset nozapret/nozapret6.
Листы РКН все время изменяются. Возникают новые тенденции. Требования к RAM могут меняться.
Поэтому необходима нечастая, но все же регулярная ревизия что же вообще у вас происходит на роутере.
Или вы можете узнать о проблеме лишь когда у вас начнет постоянно пропадать wifi, и вам придется
его перезагружать каждые 2 часа (метод кувалды).
Листы zapret-ip.txt и zapret-ipban.txt сохраняются в сжатом виде в файлы .gz.
Это позволяет снизить их размер во много раз и сэкономить место на роутере.
На роутерах не рекомендуется вызывать эти скрипты чаще раза за 2 суток, поскольку сохранение идет
либо во внутреннюю флэш память роутера, либо в случае extroot - на флэшку.
В обоих случаях слишком частая запись может убить флэшку, но если это произойдет с внутренней
флэш памятью, то вы просто убьете роутер.
Принудительное обновление ipset выполняет скрипт ipset/create_ipset.sh.
Если передан параметр "no-update", скрипт не обновляет ipset, а только создает его при его отсутствии и заполняет.
Это полезно, когда могут случиться несколько последовательных вызовов скрипта. Нет смысла несколько раз перезаполнять
ipset, это длительная операция на больших листах. Листы можно обновлять раз в несколько суток, и только тогда
вызывать create_ipset без параметра "no-update". Во всех остальных случаях стоит применять "no-update".
Список РКН уже достиг внушительных размеров в сотни тысяч IP адресов. Поэтому для оптимизации ipset
применяется утилита ip2net. Она берет список отдельных IP адресов и пытается интеллектуально создать из него подсети для сокращения
количества адресов. ip2net написан на языке C, поскольку операция ресурсоемкая. Иные способы роутер может не потянуть.
Если ip2net скомпилирован или в каталог ip2net скопирован бинарик, то скрипт create_ipset.sh использует ipset типа hash:net, прогоняя список через ip2net.
В противном случае используется ipset типа hash:ip, список загружается как есть.
Соответственно, если вам не нравится ip2net, просто уберите из каталога ip2net бинарик.
Можно внести список доменов в ipset/zapret-hosts-user-ipban.txt. Их ip адреса будут помещены
в отдельный ipset "ipban". Он может использоваться для принудительного завертывания всех
соединений на прозрачный proxy "redsocks" или на VPN.
IPV6 : если включен ipv6, то дополнительно создаются листы с таким же именем, но с "6" на конце перед расширением.
zapret-ip.txt => zapret-ip6.txt
Создаются ipset-ы zapret6 и ipban6.
Листы с antifilter не содержат список ipv6 адресов.
СИСТЕМА ИСКЛЮЧЕНИЯ IP. Все скрипты ресолвят файл zapret-hosts-user-exclude.txt, создавая zapret-ip-exclude.txt и zapret-ip-exclude6.txt.
Они загоняются в ipset-ы nozapret и nozapret6. Все правила, создаваемые init скриптами, создаются с учетом этих ipset.
Помещенные в них IP не участвуют в процессе.
zapret-hosts-user-exclude.txt может содержать домены, ipv4 и ipv6 адреса или подсети.
ip2net
------
Утилита ip2net предназначена для преобразования ipv4 или ipv6 списка ip в список подсетей
с целью сокращения размера списка. Входные данные берутся из stdin, выходные выдаются в stdout.