mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-26 12:10:53 +03:00
1938 lines
197 KiB
Plaintext
1938 lines
197 KiB
Plaintext
|
zapret v.64
|
|||
|
|
|||
|
English
|
|||
|
-------
|
|||
|
|
|||
|
For english version refer to docs/readme.eng.txt
|
|||
|
|
|||
|
Для чего это надо
|
|||
|
-----------------
|
|||
|
|
|||
|
Автономное, без задействования сторонних серверов, средство противодействия DPI.
|
|||
|
Может помочь обойти блокировки или замедление сайтов http(s), сигнатурный анализ tcp и udp протоколов,
|
|||
|
например с целью блокировки VPN.
|
|||
|
|
|||
|
Проект нацелен прежде всего на маломощные embedded устройства - роутеры, работающие под openwrt.
|
|||
|
Поддерживаются традиционные Linux системы, FreeBSD, OpenBSD, частично MacOS.
|
|||
|
В некоторых случаях возможна самостоятельная прикрутка решения к различным прошивкам.
|
|||
|
|
|||
|
Большая часть функционала работает на windows.
|
|||
|
|
|||
|
Как побыстрее начать
|
|||
|
--------------------
|
|||
|
|
|||
|
Читайте docs/quick_start.txt для linux и openwrt, docs/quick_start_windows.txt для windows.
|
|||
|
|
|||
|
|
|||
|
Как это работает
|
|||
|
----------------
|
|||
|
|
|||
|
В самом простейшем случае вы имеете дело с пассивным DPI. Пассивный DPI может читать трафик
|
|||
|
из потока, может инжектить свои пакеты, но не может блокировать проходящие пакеты.
|
|||
|
Если запрос "плохой", пассивный DPI инжектит пакет RST, опционально дополняя его пакетом http redirect.
|
|||
|
Если фейк пакет инжектится только для клиента, в этом случае можно обойтись командами iptables
|
|||
|
для дропа RST и/или редиректа на заглушку по определенным условиям, которые нужно подбирать
|
|||
|
для каждого провайдера индивидуально. Так мы обходим последствия срабатывания триггера запрета.
|
|||
|
Если пассивный DPI направляет пакет RST в том числе и серверу, то вы ничего с этим не сможете сделать.
|
|||
|
Ваша задача - не допустить срабатывания триггера запрета. Одними iptables уже не обойдетесь.
|
|||
|
Этот проект нацелен именно на предотвращение срабатывания запрета, а не ликвидацию его последствий.
|
|||
|
|
|||
|
Активный DPI ставится в разрез провода и может дропать пакеты по любым критериям,
|
|||
|
в том числе распознавать TCP потоки и блокировать любые пакеты, принадлежащие потоку.
|
|||
|
|
|||
|
Как не допустить срабатывания триггера запрета ? Послать то, на что DPI не рассчитывает
|
|||
|
и что ломает ему алгоритм распознавания запросов и их блокировки.
|
|||
|
|
|||
|
Некоторые DPI не могут распознать http запрос, если он разделен на TCP сегменты.
|
|||
|
Например, запрос вида "GET / HTTP/1.1\r\nHost: kinozal.tv......"
|
|||
|
мы посылаем 2 частями : сначала идет "GET ", затем "/ HTTP/1.1\r\nHost: kinozal.tv.....".
|
|||
|
Другие DPI спотыкаются, когда заголовок "Host:" пишется в другом регистре : например, "host:".
|
|||
|
Кое-где работает добавление дополнительного пробела после метода : "GET /" => "GET /"
|
|||
|
или добавление точки в конце имени хоста : "Host: kinozal.tv."
|
|||
|
|
|||
|
Существует и более продвинутая магия, направленная на преодоление DPI на пакетном уровне.
|
|||
|
|
|||
|
Подробнее про DPI :
|
|||
|
https://habr.com/ru/post/335436
|
|||
|
https://geneva.cs.umd.edu/papers/geneva_ccs19.pdf
|
|||
|
|
|||
|
|
|||
|
Что сейчас происходит в России
|
|||
|
------------------------------
|
|||
|
|
|||
|
Раньше, до внедрения повсеместных систем ТСПУ, использовался зоопарк различных DPI
|
|||
|
у провайдеров. Какие-то были активными, какие-то пассивными.
|
|||
|
Сейчас время простых iptables окончательно ушло. Везде активный DPI ТСПУ, но кое-где
|
|||
|
могут оставаться невыключенными дополнительные старые DPI из зоопарка.
|
|||
|
В этом случае приходится обходить сразу несколько DPI.
|
|||
|
Все больше становится внереестровых блокировок, о которых вы узнаете только по факту
|
|||
|
недоступности чего-либо, в списках этого нет.
|
|||
|
Применяются блокировки некоторых диапазонов ip адресов (автономный обход невозможен)
|
|||
|
и протоколов (VPN).
|
|||
|
На некоторых диапазонах IP используется более строгий фильтр, распознающий попытки
|
|||
|
обмана через сегментацию. Должно быть это связано с некоторыми сервисами, которые
|
|||
|
пытаются таким образом обмануть DPI.
|
|||
|
|
|||
|
|
|||
|
Как это реализовать на практике в системе linux
|
|||
|
-----------------------------------------------
|
|||
|
|
|||
|
Если кратко, то варианты можно классифицировать по следующей схеме :
|
|||
|
|
|||
|
1) Пассивный DPI, не отправляющий RST серверу. Помогут индивидуально настраиваемые под провайдера команды iptables.
|
|||
|
На rutracker в разделе "обход блокировок - другие способы" по этому вопросу существует отдельная тема.
|
|||
|
В данном проекте не рассматривается. Если вы не допустите срабатывание триггера запрета, то и не придется
|
|||
|
бороться с его последствиями.
|
|||
|
2) Модификация TCP соединения на уровне потока. Реализуется через proxy или transparent proxy.
|
|||
|
3) Модификация TCP соединения на уровне пакетов. Реализуется через обработчик очереди NFQUEUE и raw сокеты.
|
|||
|
|
|||
|
Для вариантов 2 и 3 реализованы программы tpws и nfqws соответственно.
|
|||
|
Чтобы они работали, необходимо их запустить с нужными параметрами и перенаправить на них определенный трафик
|
|||
|
средствами iptables или nftables.
|
|||
|
|
|||
|
|
|||
|
Для перенаправления tcp соединения на transparent proxy используются команды следующего вида :
|
|||
|
|
|||
|
проходящий трафик :
|
|||
|
iptables -t nat -I PREROUTING -i <внутренний_интерфейс> -p tcp --dport 80 -j DNAT --to 127.0.0.127:988
|
|||
|
исходящий трафик :
|
|||
|
iptables -t nat -I OUTPUT -o <внешний_интерфейс> -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to 127.0.0.127:988
|
|||
|
|
|||
|
DNAT на localhost работает в цепочке OUTPUT, но не работает в цепочке PREROUTING без включения параметра route_localnet :
|
|||
|
|
|||
|
sysctl -w net.ipv4.conf.<внутренний_интерфейс>.route_localnet=1
|
|||
|
|
|||
|
Можно использовать "-j REDIRECT --to-port 988" вместо DNAT, однако в этом случае процесс transparent proxy
|
|||
|
должен слушать на ip адресе входящего интерфейса или на всех адресах. Слушать на всех - не есть хорошо
|
|||
|
с точки зрения безопасности. Слушать на одном (локальном) можно, но в случае автоматизированного
|
|||
|
скрипта придется его узнавать, потом динамически вписывать в команду. В любом случае требуются дополнительные усилия.
|
|||
|
Использование route_localnet тоже имеет потенциальные проблемы с безопасностью. Вы делаете доступным все, что висит
|
|||
|
на 127.0.0.0/8 для локальной подсети <внутренний_интерфейс>. Службы обычно привязываются к 127.0.0.1, поэтому можно
|
|||
|
средствами iptables запретить входящие на 127.0.0.1 не с интерфейса lo, либо повесить tpws на любой другой IP из
|
|||
|
из 127.0.0.0/8, например на 127.0.0.127, и разрешить входящие не с lo только на этот IP.
|
|||
|
|
|||
|
iptables -A INPUT ! -i lo -d 127.0.0.127 -j ACCEPT
|
|||
|
iptables -A INPUT ! -i lo -d 127.0.0.0/8 -j DROP
|
|||
|
|
|||
|
Фильтр по owner необходим для исключения рекурсивного перенаправления соединений от самого tpws.
|
|||
|
tpws запускается под пользователем "tpws", для него задается исключающее правило.
|
|||
|
|
|||
|
tpws может использоваться в режиме socks proxy. В этом случае iptables не нужны, а нужно прописать socks
|
|||
|
в настройки программы (например, броузера), с которой будем обходить блокировки.
|
|||
|
transparent proxy отличается от socks именно тем, что в варианте transparent настраивать клиентские программы не нужно.
|
|||
|
|
|||
|
|
|||
|
Для перенаправления на очередь NFQUEUE исходящего и проходящего в сторону внешнего интерфейса трафика используются
|
|||
|
команды следующего вида :
|
|||
|
|
|||
|
iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp --dport 80 -j NFQUEUE --queue-num 200 --queue-bypass
|
|||
|
|
|||
|
|
|||
|
Чтобы не трогать трафик на незаблокированные адреса, можно взять список заблокированных хостов, заресолвить его
|
|||
|
в IP адреса и загнать в ipset zapret, затем добавить фильтр в команду :
|
|||
|
|
|||
|
iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp --dport 80 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass
|
|||
|
|
|||
|
DPI может ловить только первый http запрос, игнорируя последующие запросы в keep-alive сессии.
|
|||
|
Тогда можем уменьшить нагрузку на проц, отказавшись от процессинга ненужных пакетов.
|
|||
|
|
|||
|
iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp --dport 80 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass
|
|||
|
|
|||
|
Фильтр по mark нужен для отсечения от очереди пакетов, сгенерированных внутри nfqws.
|
|||
|
Если применяется фильтр по connbytes 1:6, то обязательно добавлять в iptables и фильтр по mark. Иначе возможно
|
|||
|
перепутывание порядка следования пакетов, что приведет к неработоспособности метода.
|
|||
|
|
|||
|
Для некоторых атак на DPI требуется перенаправлять один или несколько входящих пакетов от соединения :
|
|||
|
|
|||
|
iptables -t mangle -I PREROUTING -i <внешний_интерфейс> -p tcp --sport 80 -m connbytes --connbytes-dir=reply --connbytes-mode=packets --connbytes 1:6 -m set --match-set zapret src -j NFQUEUE --queue-num 200 --queue-bypass
|
|||
|
|
|||
|
Получаемые пакеты будут фильтроваться по входящему интерфейсу, порту и IP источника, то есть наоборот прямому правилу.
|
|||
|
|
|||
|
Некоторые техники, ломающие NAT, не всегда можно реализовать через iptables. Требуются nftables.
|
|||
|
|
|||
|
|
|||
|
Если ваше устройство поддерживает аппаратное ускорение (flow offloading, hardware nat, hardware acceleration), то iptables могут не работать.
|
|||
|
При включенном offloading пакет не проходит по обычному пути netfilter.
|
|||
|
Необходимо или его отключить, или выборочно им управлять.
|
|||
|
|
|||
|
В новых ядрах (и в более старых, openwrt портировал изменение на 4.14) присутствует software flow offloading (SFO).
|
|||
|
Пакеты, проходящие через SFO, так же проходят мимо большей части механизмов iptables.
|
|||
|
При включенном SFO работает DNAT/REDIRECT (tpws). Эти соединения исключаются из offloading.
|
|||
|
Однако, остальные соединения идут через SFO, потому NFQUEUE будет срабатывать только до помещения
|
|||
|
соединения в flowtable. Практически это означает, что nfqws будет работать на window size changing,
|
|||
|
но не будут работать опции по модификации содержимого пакетов.
|
|||
|
Offload включается через специальный target в iptables "FLOWOFFLOAD". Не обязательно пропускать весь трафик через offload.
|
|||
|
Можно исключить из offload соединения, которые должны попасть на tpws или nfqws.
|
|||
|
openwrt не предусматривает выборочного управления offload.
|
|||
|
Поэтому скрипты zapret поддерживают свою систему выборочного управления offload в openwrt.
|
|||
|
|
|||
|
|
|||
|
Особенности применения ip6tables
|
|||
|
--------------------------------
|
|||
|
|
|||
|
ip6tables работают почти точно так же, как и ipv4, но есть ряд важных нюансов.
|
|||
|
В DNAT следует брать адрес --to в квадратные скобки. Например :
|
|||
|
|
|||
|
ip6tables -t nat -I OUTPUT -o <внешний_интерфейс> -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to [::1]:988
|
|||
|
|
|||
|
Параметра route_localnet не существует для ipv6.
|
|||
|
DNAT на localhost (::1) возможен только в цепочке OUTPUT.
|
|||
|
В цепочке PREROUTING DNAT возможен на любой global address или на link local address того же интерфейса,
|
|||
|
откуда пришел пакет.
|
|||
|
NFQUEUE работает без изменений.
|
|||
|
|
|||
|
|
|||
|
Особенности применения nftables
|
|||
|
-------------------------------
|
|||
|
|
|||
|
Более подробно преимущества и недостатки nftables применительно к данной системе описаны в docs/nftables_notes.txt
|
|||
|
Если коротко, то в nftables невозможно работать с большими ip листами на системах с малым количеством RAM.
|
|||
|
Остальные рассматриваемые здесь функции могут быть перенесены на nftables.
|
|||
|
|
|||
|
Рекомендуется версия nft 1.0.2 или выше. Но чем выше версия, тем лучше. В nft регулярно находят баги.
|
|||
|
|
|||
|
Относительно старые версии ядра и/или утилиты nft могут вызывать ошибки.
|
|||
|
В частности, на ubuntu 18.04 с ядром 4.15 будут проблемы. В 20.04 - работает.
|
|||
|
|
|||
|
Некоторые техники можно полноценно использовать только с nftables.
|
|||
|
Например, в iptables невозможно перенаправить пакеты на nfqws после NAT.
|
|||
|
Следовательно, при использовании NAT невозможно произвести атаку, не совместимую с NAT.
|
|||
|
В nftables этой проблемы не существует, потому что приоритеты хука выставляете вы сами, а не привязаны к фиксированным
|
|||
|
значениям, соответствующим разным таблицам iptables. В iptables нет таблицы, способной перехватить пакеты после MASQUERDADE.
|
|||
|
|
|||
|
|
|||
|
Когда это работать не будет
|
|||
|
---------------------------
|
|||
|
|
|||
|
* Если подменяется DNS. С этой проблемой легко справиться.
|
|||
|
* Если блокировка осуществляется по IP.
|
|||
|
* Если соединение проходит через фильтр, способный реконструировать TCP соединение, и который
|
|||
|
следует всем стандартам. Например, нас заворачивают на squid. Соединение идет через полноценный стек tcpip
|
|||
|
операционной системы, фрагментация отпадает сразу как средство обхода. Squid правильный, он все найдет
|
|||
|
как надо, обманывать его бесполезно.
|
|||
|
НО. Заворачивать на squid могут позволить себе лишь небольшие провайдеры, поскольку это очень ресурсоемко.
|
|||
|
Большие компании обычно используют DPI, который рассчитан на гораздо большую пропускную способность.
|
|||
|
Может применяться комбинированный подход, когда на DPI заворачивают только IP из "плохого" списка,
|
|||
|
и дальше уже DPI решает пропускать или нет. Так можно снизить нагрузку на DPI в десятки, если не сотни раз,
|
|||
|
а следовательно не покупать очень дорогие решения, обойдясь чем-то существенно более дешевым.
|
|||
|
Мелкие провайдеры могут покупать услугу фильтрации у вышестоящих, чтобы самим не морочиться, и
|
|||
|
они уже будут применять DPI.
|
|||
|
|
|||
|
|
|||
|
nfqws
|
|||
|
-----
|
|||
|
|
|||
|
Эта программа - модификатор пакетов и обработчик очереди NFQUEUE.
|
|||
|
Для BSD систем существует адаптированный вариант - dvtws, собираемый из тех же исходников (см. bsd.txt).
|
|||
|
|
|||
|
--debug=0|1 ; 1=выводить отладочные сообщения
|
|||
|
--daemon ; демонизировать прогу
|
|||
|
--pidfile=<file> ; сохранить PID в файл
|
|||
|
--user=<username> ; менять uid процесса
|
|||
|
--uid=uid[:gid] ; менять uid процесса
|
|||
|
--qnum=N ; номер очереди N
|
|||
|
--bind-fix4 ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv4 пакетов
|
|||
|
--bind-fix6 ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv6 пакетов
|
|||
|
--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
|
|||
|
--hostcase ; менять регистр заголовка "Host:" по умолчанию на "host:".
|
|||
|
--hostnospace ; убрать пробел после "Host:" и переместить его в конец значения "User-Agent:" для сохранения длины пакета
|
|||
|
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
|
|||
|
--domcase ; домен после Host: сделать таким : TeSt.cOm
|
|||
|
--dpi-desync=[<mode0>,]<mode>[,<mode2] ; атака по десинхронизации DPI. mode : synack syndata fake fakeknown rst rstack hopbyhop destopt ipfrag1 disorder disorder2 split split2 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-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
|
|||
|
--dpi-desync-repeats=<N> ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты)
|
|||
|
--dpi-desync-skip-nosni=0| 1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
|
|||
|
--dpi-desync-split-pos=<1..1500> ; (только для split*, disorder*) разбивать пакет на указанной позиции
|
|||
|
--dpi-desync-split-http-req=method|host ; разбивка http request на указанном логическом месте
|
|||
|
--dpi-desync-split-tls=sni|sniext ; разбивка tls client hello на указанном логическом месте
|
|||
|
--dpi-desync-split-seqovl=<int> ; использовать sequence overlap перед первым отсылаемым оригинальным tcp сегментом
|
|||
|
--dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; чем заполнять фейковую часть overlap
|
|||
|
--dpi-desync-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000
|
|||
|
--dpi-desync-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000
|
|||
|
--dpi-desync-any-protocol=0|1 ; 0(default)=работать только по http request и tls clienthello 1=по всем непустым пакетам данных
|
|||
|
--dpi-desync-fake-http=<filename>|0xHEX ; файл, содержащий фейковый http запрос для dpi-desync=fake, на замену стандартному www.iana.org
|
|||
|
--dpi-desync-fake-tls=<filename>|0xHEX ; файл, содержащий фейковый tls clienthello для dpi-desync=fake, на замену стандартному
|
|||
|
--dpi-desync-fake-unknown=<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного протокола для dpi-desync=fake, на замену стандартным нулям 256 байт
|
|||
|
--dpi-desync-fake-syndata=<filename>|0xHEX ; файл, содержащий фейковый пейлоад пакета SYN для режима десинхронизации syndata
|
|||
|
--dpi-desync-fake-quic=<filename>|0xHEX ; файл, содержащий фейковый QUIC Initial
|
|||
|
--dpi-desync-fake-dht=<filename>|0xHEX ; файл, содержащий фейковый пейлоад DHT протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
|
|||
|
--dpi-desync-fake-unknown-udp=<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного udp протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
|
|||
|
--dpi-desync-udplen-increment=<int> ; насколько увеличивать длину udp пейлоада в режиме udplen
|
|||
|
--dpi-desync-udplen-pattern=<filename>|0xHEX ; чем добивать udp пакет в режиме udplen. по умолчанию - нули
|
|||
|
--dpi-desync-start=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N
|
|||
|
--dpi-desync-cutoff=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
|
|||
|
--hostlist=<filename> ; применять дурение только к хостам из листа. может быть множество листов, они объединяются. пустой обший лист = его отсутствие
|
|||
|
--hostlist-exclude=<filename> ; не применять дурение к хостам из листа. может быть множество листов, они объединяются
|
|||
|
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
|
|||
|
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3)
|
|||
|
--hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60)
|
|||
|
--hostlist-auto-retrans-threshold=<int> ; сколько ретрансмиссий запроса считать блокировкой (по умолчанию: 3)
|
|||
|
--hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты.
|
|||
|
--new ; начало новой стратегии
|
|||
|
--filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии
|
|||
|
--filter-tcp=[~]port1[-port2] ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. установка фильтра tcp и неустановка фильтра udp запрещает udp.
|
|||
|
--filter-udp=[~]port1[-port2] ; фильтр портов udp для текущей стратегии. ~ означает инверсию. установка фильтра udp и неустановка фильтра tcp запрещает udp.
|
|||
|
|
|||
|
Параметры манипуляции могут сочетаться в любых комбинациях.
|
|||
|
|
|||
|
ЗАМЕЧАНИЕ. Параметр --wsize считается устаревшим и более не поддерживается в скриптах.
|
|||
|
Функции сплита выполняются в рамках атаки десинхронизации. Это быстрее и избавляет от целого ряда недостатков wsize.
|
|||
|
|
|||
|
--debug позволяет выводить подробный лог действий на консоль, в syslog или в файл.
|
|||
|
Может быть важен порядок следования опций. --debug лучше всего указывать в самом начале.
|
|||
|
Опции анализируются последовательно. Если ошибка будет при проверке опции, а до анализа --debug еще дело не дошло,
|
|||
|
то сообщения не будут выведены в файл или syslog.
|
|||
|
При логировании в файл процесс не держит файл открытым. Ради каждой записи файл открывается и потом закрывается.
|
|||
|
Так что файл можно удалить в любой момент, и он будет создан заново при первом же сообщении в лог.
|
|||
|
Но имейте в виду, что если вы запускаете процесс под root, то будет сменен UID на не-root.
|
|||
|
В начале на лог файл меняется owner, иначе запись будет невозможна. Если вы потом удалите файл,
|
|||
|
и у процесса не будет прав на создание файла в его директории, лог больше не будет вестись.
|
|||
|
Вместо удаления лучше использовать truncate.
|
|||
|
В шелле это можно сделать через команду ": >filename"
|
|||
|
|
|||
|
АТАКА ДЕСИНХРОНИЗАЦИИ DPI
|
|||
|
Суть ее в следующем. После выполнения tcp 3-way handshake идет первый пакет с данными от клиента.
|
|||
|
Там обычно "GET / ..." или TLS ClientHello. Мы дропаем этот пакет, заменяя чем-то другим.
|
|||
|
Это может быть поддельная версия с безобидным, но валидным запросом http или https (вариант fake),
|
|||
|
пакет сброса соединения (варианты rst, rstack), разбитый на части оригинальный пакет с перепутанным
|
|||
|
порядком следования сегментов + обрамление первого сегмента фейками (disorder),
|
|||
|
то же самое без перепутывания порядка сегментов (split).
|
|||
|
fakeknown отличается от fake тем, что применяется только к распознанному протоколу.
|
|||
|
В литературе такие атаки еще называют TCB desynchronization и TCB teardown.
|
|||
|
Надо, чтобы фейковые пакеты дошли до DPI, но не дошли до сервера.
|
|||
|
На вооружении есть следующие возможности : установить низкий TTL, посылать пакет с инвалидной чексуммой,
|
|||
|
добавлять tcp option "MD5 signature", испортить sequence numbers. Все они не лишены недостатков.
|
|||
|
|
|||
|
* md5sig работает не на всех серверах. Пакеты с md5 обычно отбрасывают только linux.
|
|||
|
* badsum не сработает, если ваше устройство за NAT, который не пропускает пакеты с инвалидной суммой.
|
|||
|
Наиболее распространенная настройка NAT роутера в Linux их не пропускает. На Linux построено большинство
|
|||
|
домашних роутеров. Непропускание обеспечивается так : настройка ядра sysctl по умолчанию
|
|||
|
net.netfilter.nf_conntrack_checksum=1 заставляет conntrack проверять tcp и udp чексуммы входящих пакетов
|
|||
|
и выставлять state INVALID для пакетов с инвалидной суммой.
|
|||
|
Обычно в правилах iptables вставляется правило для дропа пакетов с состоянием INVALID в цепочке FORWARD.
|
|||
|
Совместное сочетание этих факторов приводит к непрохождению badsum через такой роутер.
|
|||
|
В openwrt из коробки net.netfilter.nf_conntrack_checksum=0, в других роутерах часто нет,
|
|||
|
и не всегда это можно изменить. Чтобы nfqws мог работать через роутер, нужно на нем выставить указанное
|
|||
|
значение sysctl в 0. nfqws на самом роутере будет работать и без этой настройки, потому что
|
|||
|
чексумма локально созданных пакетов не проверяется никогда.
|
|||
|
Если роутер за другим NAT, например провайдерским, и он не пропускает invalid packets
|
|||
|
вы ничего не сможете с этим сделать. Но обычно провайдеры все же пропускают badsum.
|
|||
|
На некоторых адаптерах/свитчах/драйверах принудительно включен rx-checksum offload, badsum пакеты отсекаются
|
|||
|
еще до получения в ОС. В этом случае если что-то и можно сделать, то только модифицировать драйвер,
|
|||
|
что представляется задачей крайне нетривиальной. Установлено, что так себя ведут некоторые роутеры на базе mediatek.
|
|||
|
badsum пакеты уходят с клиентской ОС, но роутером не видятся в br-lan через tcpdump.
|
|||
|
При этом если nfqws выполняется на самом роутере, обход может работать. badsum нормально уходят с внешнего интерфейса.
|
|||
|
* Пакеты с badseq будут наверняка отброшены принимающим узлом, но так же и DPI, если он ориентируется
|
|||
|
на sequence numbers. По умолчанию смещение seq выбирается -10000. Практика показала, что некоторые DPI
|
|||
|
не пропускают seq вне определенного окна. Однако, такое небольшое смещение может вызвать проблемы
|
|||
|
при существенной потоковой передаче и потере пакетов. Если вы используете --dpi-desync-any-protocol,
|
|||
|
может понадобится установить badseq increment 0x80000000. Это обеспечит надежную гарантию,
|
|||
|
что поддельный пакет не вклинится в tcp window на сервере. Так же было замечено, что badseq ломает логику
|
|||
|
некоторых DPI при анализе http, вызывая зависание соединения. Причем на тех же DPI TLS с badseq работает нормально.
|
|||
|
* TTL казалось бы - лучший вариант, но он требует индивидуальной настройки под каждого провайдера.
|
|||
|
Если DPI находится дальше локальных сайтов провайдера, то вы можете отрезать себе доступ к ним.
|
|||
|
Ситуация усугубляется наличием ТСПУ на магистралах, что вынуждает делать TTL достаточно высоким, увеличивая
|
|||
|
риск пробоя фейка до сервера.
|
|||
|
Необходим ip exclude list, заполняемый вручную. Вместе с ttl можно применять md5sig. Это ничего не испортит,
|
|||
|
зато дает неплохой шанс работы сайтов, до которых "плохой" пакет дойдет по TTL.
|
|||
|
Если не удается найти автоматическое решение, воспользуйтесь файлом zapret-hosts-user-exclude.txt.
|
|||
|
Некоторые стоковые прошивки роутеров фиксируют исходящий TTL, без отключения этой опции через них работать не будет.
|
|||
|
КАКИМ СТОИТ ВЫБИРАТЬ TTL : найдите минимальное значение, при котором обход еще работает.
|
|||
|
Это и будет номер хопа вашего DPI.
|
|||
|
* hopbyhop относится только к ipv6. Добавляется ipv6 extenstion header "hop-by-hop options".
|
|||
|
В варианте hopbyhop2 добавляются 2 хедера, что является нарушением стандарта и гарантированно отбрасывается
|
|||
|
стеком протоколов во всех ОС. Один хедер hop-by-hop принимается всеми ОС, однако на некоторых каналах/провайдерах
|
|||
|
такие пакеты могут фильтроваться и не доходить. Расчет идет на то, что DPI проанализирует пакет с hop-by-hop,
|
|||
|
но он либо не дойдет до адресата всилу фильтров провайдера, либо будет отброшен сервером, потому что хедера два.
|
|||
|
* datanoack высылает фейки со снятым tcp флагом ACK. Сервера такое не принимают, а DPI может принять.
|
|||
|
Эта техника может ломать NAT и не всегда работает с iptables, если используется masquerade, даже с локальной
|
|||
|
системы (почти всегда на роутерах ipv4). На системах c iptables без masquerade и на nftables работает без
|
|||
|
ограничений. Экспериментально выяснено, что многие провайдерские NAT не отбрасывают эти пакеты, потому
|
|||
|
работает даже с внутренним провайдерским IP. Но linux NAT оно не пройдет, так что за домашним роутером эта
|
|||
|
техника не сработает, но может сработать с него.
|
|||
|
* autottl. Суть режима в автоматическом определении TTL, чтобы он почти наверняка прошел DPI и немного не дошел до
|
|||
|
сервера. Берутся базовые значения TTL 64,128,255, смотрится входящий пакет
|
|||
|
(да, требуется направить первый входящий пакет на nfqws !).
|
|||
|
Вычисляется длина пути, отнимается delta (1 по умолчанию). Если TTL вне диапазона (min,max - 3,20 по умолчанию),
|
|||
|
то берутся значения min,max, чтобы вписаться в диапазон. Если при этом полученный TTL больше длины пути,
|
|||
|
то автоматизм не сработал и берутся фиксированные значения TTL для атаки.
|
|||
|
Техника позволяет решить вопрос, когда вся сеть перегорожена шлагбаумами (DPI, ТСПУ) везде где только можно,
|
|||
|
включая магистралов. Но потенциально может давать сбои.
|
|||
|
Например, при асимметрии входящего и исходящего канала до конкретного сервера.
|
|||
|
На каких-то провайдерах эта техника будет работать неплохо, на других доставит больше проблем, чем пользы.
|
|||
|
Где-то может потребоваться тюнинг параметров. Лучше использовать с дополнительным ограничителем.
|
|||
|
|
|||
|
Режимы дурения могут сочетаться в любых комбинациях. --dpi-desync-fooling берет множество значений через запятую.
|
|||
|
|
|||
|
Для режимов fake, rst, rstack после фейка отправляем оригинальный пакет.
|
|||
|
|
|||
|
Режим disorder делит оригинальный пакет на 2 части и отправляет следующую комбинацию в указанном порядке :
|
|||
|
1. 2-я часть пакета
|
|||
|
2. поддельная 1-я часть пакета, поле данных заполнено нулями
|
|||
|
3. 1-я часть пакета
|
|||
|
4. поддельная 1-я часть пакета, поле данных заполнено нулями. отсылка 2-й раз.
|
|||
|
Оригинальный пакет дропается всегда. Параметр --dpi-desync-split-pos позволяет указать байтовую позицию, на которой
|
|||
|
происходит разбивка. По умолчанию - 2. Если позиция больше длины пакета, позиция выбирается 1.
|
|||
|
Этой последовательностью для DPI максимально усложняется задача реконструкции начального сообщения,
|
|||
|
по которому принимается решение о блокировке. Некоторым DPI хватит и tcp сегментов в неправильном порядке,
|
|||
|
поддельные части сделаны для дополнительной надежности и более сложных алгоритмов реконструкции.
|
|||
|
Режим disorder2 отключает отправку поддельных частей.
|
|||
|
|
|||
|
Режим split очень похож на disorder, только нет изменения порядка следования сегментов :
|
|||
|
1. поддельная 1-я часть пакета, поле данных заполнено нулями
|
|||
|
2. 1-я часть пакета
|
|||
|
3. поддельная 1-я часть пакета, поле данных заполнено нулями. отсылка 2-й раз.
|
|||
|
4. 2-я часть пакета
|
|||
|
Режим split2 отключает отправку поддельных частей.
|
|||
|
Он может быть использован как более быстрая альтернатива --wsize.
|
|||
|
|
|||
|
disorder2 и split2 не предполагают отсылку фейк пакетов, поэтому опции ttl и fooling неактуальны.
|
|||
|
|
|||
|
seqovl добавляет в начало первой отсылаемой части оригинального пакета (1 часть для split и 2 часть для disorder)
|
|||
|
seqovl байт со смещенным в минус sequence number на величину seqovl.
|
|||
|
В случае split2 расчет идет на то, что предыдущий отсыл, если он был, уже попал в сокет серверного приложения,
|
|||
|
поэтому новая пришедшая часть лишь частично находится в пределах текущего окна (in-window).
|
|||
|
Спереди фейковая часть отбрасывается, а оставшаяся часть содержит оригинал и начинается с начала window,
|
|||
|
поэтому попадает в сокет.
|
|||
|
Серверное приложение получает все, что реально отсылает клиент, отбрасывая фейковую out-of-window часть.
|
|||
|
Но DPI не может этого понять, поэтому у него происходит sequence десинхронизация.
|
|||
|
|
|||
|
Для disorder2 overlap идет на 2-ю часть пакета. Обязательно, чтобы seqovl был меньше split_pos, иначе
|
|||
|
все отосланное будет передано в сокет сразу же, включая фейк, ломая протокол прикладного уровня.
|
|||
|
При соблюдении этого условия 2-я часть пакета является полностью in-window,
|
|||
|
поэтому серверная ОС принимает ее целиком, включая фейк. Но поскольку начальная часть данных из 1 пакета
|
|||
|
еще не принята, то фейк и реальные данные остаются в памяти ядра, не отправляясь в серверное приложение.
|
|||
|
Как только приходит 1-я часть пакета, она переписывает фейковую часть в памяти ядра.
|
|||
|
Ядро получает данные из 1 и 2 части, поэтому далее идет отправка в сокет приложения.
|
|||
|
Таково поведение всех unix ОС, кроме solaris - оставлять последние принятые данные.
|
|||
|
Windows оставляет старые данные, поэтому disorder с seqovl будет приводить к зависаниям соединения
|
|||
|
при работе с Windows серверами. Solaris практически мертв, windows серверов очень немного.
|
|||
|
Можно использовать листы при необходимости.
|
|||
|
Метод позволяет обойтись без fooling и TTL. Фейки перемешаны с реальным данными.
|
|||
|
split/disorder вместо split2/disorder2 по-прежнему добавляют дополнительные отдельные фейки.
|
|||
|
|
|||
|
Режимы десинхронизации hopbyhop, destopt и ipfrag1 (не путать с fooling !) относятся только к ipv6 и заключается
|
|||
|
в добавлении хедера "hop-by-hop options", "destination options" или "fragment" во все пакеты, попадающие под десинхронизацию.
|
|||
|
Здесь надо обязательно понимать, что добавление хедера увеличивает размер пакета, потому не может быть применено
|
|||
|
к пакетам максимального размера. Это имеет место при передаче больших сообщений.
|
|||
|
В случае невозможности отослать пакет дурение будет отменено, пакет будет выслан в оригинале.
|
|||
|
Расчет идет на то, что DPI увидит 0 в поле next header основного заголовка ipv6 и не будет скакать по
|
|||
|
extension хедерам в поисках транспортного хедера. Таким образом не поймет, что это tcp или udp, и пропустит пакет
|
|||
|
без анализа. Возможно, какие-то DPI на это купятся.
|
|||
|
Может сочетаться с любыми режимами 2-й фазы, кроме варианта "ipfrag1+ipfrag2".
|
|||
|
Например, "hopbyhop,split2" означает разбить tcp пакет на 2 сегмента, в каждый из них добавить hop-by-hop.
|
|||
|
При "hopbyhop,ipfrag2" последовательность хедеров будет : ipv6,hop-by-hop,fragment,tcp/udp.
|
|||
|
Режим "ipfrag1" может срабатывать не всегда без специальной подготовки. См. раздел "IP фрагментация".
|
|||
|
|
|||
|
Есть DPI, которые анализируют ответы от сервера, в частности сертификат из ServerHello, где прописаны домены.
|
|||
|
Подтверждением доставки ClientHello является ACK пакет от сервера с номером ACK sequence, соответствующим длине ClientHello+1.
|
|||
|
В варианте disorder обычно приходит сперва частичное подтверждение (SACK), потом полный ACK.
|
|||
|
Если вместо ACK или SACK идет RST пакет с минимальной задержкой, то DPI вас отсекает еще на этапе вашего запроса.
|
|||
|
Если RST идет после полного ACK спустя задержку, равную примерно пингу до сервера,
|
|||
|
тогда вероятно DPI реагирует на ответ сервера.
|
|||
|
DPI может отстать от потока, если ClientHello его удовлетворил и не проверять ServerHello.
|
|||
|
Тогда вам повезло. Вариант fake может сработать.
|
|||
|
Если же он не отстает и упорно проверяет ServerHello, то можно попробовать заставить сервер высылать ServerHello частями
|
|||
|
через параметр --wssize (см. conntrack).
|
|||
|
Если и это не помогает, то сделать с этим что-либо вряд ли возможно без помощи со стороны сервера.
|
|||
|
Лучшее решение - включить на сервере поддержку TLS 1.3. В нем сертификат сервера передается в зашифрованном виде.
|
|||
|
Это рекомендация ко всем админам блокируемых сайтов. Включайте TLS 1.3. Так вы дадите больше возможностей преодолеть DPI.
|
|||
|
|
|||
|
Хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
|
|||
|
Субдомены учитываются автоматически. Поддерживаются листы gzip.
|
|||
|
|
|||
|
iptables для задействования атаки на первый пакет данных :
|
|||
|
|
|||
|
iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp -m multiport --dports 80,443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
|||
|
|
|||
|
Этот вариант применяем, когда DPI не следит за всеми запросами http внутри keep-alive сессии.
|
|||
|
Если следит, направляем только первый пакет от https и все пакеты от http :
|
|||
|
|
|||
|
iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
|||
|
iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp --dport 80 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
|||
|
|
|||
|
mark нужен, чтобы сгенерированный поддельный пакет не попал опять к нам на обработку. nfqws выставляет fwmark при его отсылке.
|
|||
|
хотя nfqws способен самостоятельно различать помеченные пакеты, фильтр в iptables по mark нужен при использовании connbytes,
|
|||
|
чтобы не допустить изменения порядка следования пакетов. Процессинг очереди - процесс отложенный.
|
|||
|
Если ядро имеет пакеты на отсылку вне очереди - оно их отправляет незамедлительно.
|
|||
|
Изменение правильного порядка следования пакетов при десинхронизации ломает всю идею.
|
|||
|
При отсутствии ограничения на connbytes, атака будет работать и без фильтра по mark.
|
|||
|
Но лучше его все же оставить для увеличения скорости.
|
|||
|
|
|||
|
Почему --connbytes 1:6 :
|
|||
|
1 - для работы методов десинхронизации 0-й фазы и wssize
|
|||
|
2 - иногда данные идут в 3-м пакете 3-way handshake
|
|||
|
3 - стандартная ситуация приема одного пакета запроса
|
|||
|
4-6 - на случай ретрансмиссии или запроса длиной в несколько пакетов (TLSClientHello с kyber, например)
|
|||
|
|
|||
|
КОМБИНИРОВАНИЕ МЕТОДОВ ДЕСИНХРОНИЗАЦИИ
|
|||
|
В параметре dpi-desync можно указать до 3 режимов через запятую.
|
|||
|
0 фаза предполагает работу на этапе установления соединения. Может быть synack или syndata.
|
|||
|
На 0 фазу не действует фильтр по hostlist.
|
|||
|
Последующие режимы отрабатывают на пакетах с данными.
|
|||
|
Режим 1-й фазы может быть fake,rst,rstack. Режим 2-й фазы может быть disorder,disorder2,split,split2,ipfrag2.
|
|||
|
Может быть полезно, когда у провайдера стоит не один DPI.
|
|||
|
|
|||
|
РЕЖИМ SYNACK
|
|||
|
В документации по geneva это называется "TCB turnaround". Попытка ввести DPI в заблуждение относительно
|
|||
|
ролей клиента и сервера.
|
|||
|
!!! Поскольку режим нарушает работу NAT, техника может сработать только если между атакующим устройством
|
|||
|
и DPI нет NAT. Атака не сработает через NAT роутер, но может сработать с него.
|
|||
|
Для реализации атаки в linux обязательно требуется отключить стандартное правило firewall,
|
|||
|
дропающее инвалидные пакеты в цепочке OUTPUT. Например : -A OUTPUT -m state --state INVALID -j DROP
|
|||
|
В openwrt можно отключить drop INVALID в OUTPUT и FORWARD через опцию в /etc/config/firewall :
|
|||
|
|
|||
|
config zone
|
|||
|
option name 'wan'
|
|||
|
.........
|
|||
|
option masq_allow_invalid '1'
|
|||
|
|
|||
|
К сожалению, отключить только в OUTPUT таким образом нельзя. Но можно сделать иначе. Вписать в /etc/firewall.user :
|
|||
|
|
|||
|
iptables -D zone_wan_output -m comment --comment '!fw3' -j zone_wan_dest_ACCEPT
|
|||
|
ip6tables -D zone_wan_output -m comment --comment '!fw3' -j zone_wan_dest_ACCEPT
|
|||
|
|
|||
|
Лучше делать так, потому что отсутствие дропа INVALID в FORWARD может привести к нежелательным утечкам пакетов из LAN.
|
|||
|
Если не принять эти меры, отсылка SYN,ACK сегмента вызовет ошибку и операция будет прервана.
|
|||
|
Остальные режимы тоже не сработают. Если поймете, что вам synack не нужен, обязательно верните правило дропа INVALID.
|
|||
|
|
|||
|
РЕЖИМ SYNDATA
|
|||
|
Тут все просто. Добавляются данные в пакет SYN. Все ОС их игнорируют, если не используется TCP fast open (TFO),
|
|||
|
а DPI может воспринять, не разобравшись есть там TFO или нет.
|
|||
|
Оригинальные соединения с TFO не трогаются, поскольку это их точно сломает.
|
|||
|
Без уточняющего параметра добавляются 16 нулевых байтов.
|
|||
|
|
|||
|
ВИРТУАЛЬНЫЕ МАШИНЫ
|
|||
|
Изнутри VM от virtualbox и vmware в режиме NAT не работают многие техники пакетной магии nfqws.
|
|||
|
Принудительно заменяется ttl, не проходят фейк пакеты. Необходимо настроить сеть в режиме bridge.
|
|||
|
|
|||
|
CONNTRACK
|
|||
|
nfqws оснащен ограниченной реализацией слежения за состоянием tcp соединений (conntrack).
|
|||
|
Он включается для реализации некоторых методов противодействия DPI.
|
|||
|
conntrack способен следить за фазой соединения : SYN,ESTABLISHED,FIN, количеством пакетов в каждую сторону,
|
|||
|
sequence numbers. conntrack способен "кормиться" пакетами в обе или только в одну сторону.
|
|||
|
Соединение попадает в таблицу при обнаружении пакетов с выставленными флагами SYN или SYN,ACK.
|
|||
|
Поэтому если необходим conntrack, в правилах перенаправления iptables соединение должно идти на nfqws с самого первого
|
|||
|
пакета, хотя затем может обрываться по фильтру connbytes.
|
|||
|
Для UDP инициатором попадания в таблицу является первый UDP пакет. Он же и определяет направление потока.
|
|||
|
Считается, что первый UDP пакет исходит от клиента к серверу. Далее все пакеты с совпадающими
|
|||
|
src_ip,src_port,dst_ip,dst_port считаются принадлежащими этому потоку до истечения времени неактивности.
|
|||
|
conntrack - простенький, он не писался с учетом всевозможных атак на соединение, он не проверяет
|
|||
|
пакеты на валидность sequence numbers или чексумму. Его задача - лишь обслуживание нужд nfqws, он обычно
|
|||
|
кормится только исходящим трафиком, потому нечувствителен к подменам со стороны внешней сети.
|
|||
|
Соединение удаляется из таблицы, как только отпадает нужда в слежении за ним или по таймауту неактивности.
|
|||
|
Существуют отдельные таймауты на каждую фазу соединения. Они могут быть изменены параметром --ctrack-timeouts.
|
|||
|
|
|||
|
--wssize позволяет изменить с клиента размер tcp window для сервера, чтобы он послал следующие ответы разбитыми на части.
|
|||
|
Чтобы это подействовало на все серверные ОС, необходимо менять window size в каждом исходящем с клиента пакете до отсылки сообщения,
|
|||
|
ответ на который должен быть разбит (например, TLS ClientHello). Именно поэтому и необходим conntrack, чтобы
|
|||
|
знать когда надо остановиться. Если не остановиться и все время устанавливать низкий wssize, скорость упадет катастрофически.
|
|||
|
В linux это может быть купировано через connbytes, но в BSD системах такой возможности нет.
|
|||
|
В случае http(s) останавливаемся сразу после отсылки первого http запроса или TLS ClientHello.
|
|||
|
Если вы имеете дело с не http(s), то вам потребуется параметр --wssize-cutoff. Он устанавливает предел, с которого действие
|
|||
|
wssize прекращается. Префикс d перед номером означает учитывать только пакеты с data payload, префикс s - relative sequence number,
|
|||
|
проще говоря количество переданных клиентом байтов + 1.
|
|||
|
Если проскочит пакет с http request или TLS ClientHello, действие wssize прекращается сразу же, не дожидаясь wssize-cutoff.
|
|||
|
Если ваш протокол склонен к долгому бездействию, следует увеличить таймаут фазы ESTABLISHED через параметр --ctrack-timeouts.
|
|||
|
Таймаут по умолчанию низкий - всего 5 минут.
|
|||
|
Не забывайте, что nfqws кормится приходящими на него пакетами. Если вы ограничили поступление пакетов через connbytes,
|
|||
|
то в таблице могут остаться повисшие соединения в фазе ESTABLISHED, которые отвалятся только по таймауту.
|
|||
|
Для диагностики состояния conntrack пошлите сигнал SIGUSR1 процессу nfqws : killall -SIGUSR1 nfqws.
|
|||
|
Текущая таблица будет выведена nfqws в stdout.
|
|||
|
|
|||
|
Обычно в SYN пакете клиент отсылает кроме window size еще и TCP extension "scaling factor".
|
|||
|
scaling factor представляет из себя степень двойки, на которую умножается window size : 0=>1, 1=>2, 2=>4, ..., 8=>256, ...
|
|||
|
В параметре wssize scaling factor указывается через двоеточие.
|
|||
|
Scaling factor может только снижаться, увеличение заблокировано, чтобы не допустить превышение размера окна со стороны сервера.
|
|||
|
Для принуждения сервера к фрагментации ServerHello, чтобы избежать просекание имени сервера из сертификата сервера на DPI,
|
|||
|
лучше всего использовать --wssize=1:6 . Основное правило - делать scale_factor как можно больше, чтобы после восстановления
|
|||
|
window size итоговый размер окна стал максимально возможным. Если вы сделаете 64:0, будет очень медленно.
|
|||
|
С другой стороны нельзя допустить, чтобы ответ сервера стал достаточно большим, чтобы DPI нашел там искомое.
|
|||
|
|
|||
|
--wssize не работает в профилях с хостлистами, поскольку он действует с самого начала соединения, когда еще нельзя
|
|||
|
принять решение о попадании в лист. Однако, профиль с auto hostlist может содержать --wssize.
|
|||
|
--wssize может замедлять скорость и/или увеличивать время ответа сайтов, поэтому если есть другие работающие способы
|
|||
|
обхода DPI, лучше применять их.
|
|||
|
|
|||
|
--dpi-desync-cutoff позволяет задать предел, при достижении которого прекращается применение dpi-desync.
|
|||
|
Доступны префиксы n,d,s по аналогии с --wssize-cutoff.
|
|||
|
Полезно совместно с --dpi-desync-any-protocol=1.
|
|||
|
На склонных к бездействию соединениях следует изменить таймауты conntrack.
|
|||
|
Если соединение выпало из conntrack и задана опция --dpi-desync-cutoff, dpi desync применяться не будет.
|
|||
|
|
|||
|
РЕАССЕМБЛИНГ
|
|||
|
nfqws поддерживает реассемблинг некоторых видов запросов.
|
|||
|
На текущий момент это TLS и QUIC ClientHello. Они бывает длинными, если в chrome включить пост-квантовую
|
|||
|
криптографию tls-kyber, и занимают как правило 2 или 3 пакета. kyber включен по умолчанию, начиная с chromium 124.
|
|||
|
chrome рандомизирует фингерпринт TLS. SNI может оказаться как в начале, так и в конце, то есть
|
|||
|
попасть любой пакет. stateful DPI обычно реассемблирует запрос целиком, и только потом
|
|||
|
принимает решение о блокировке.
|
|||
|
В случае получения TLS или QUIC пакета с частичным ClientHello начинается процесс сборки, а пакеты
|
|||
|
задерживаются и не отсылаются до ее окончания. По окончании сборки пакеты проходит через десинхронизацию
|
|||
|
на основании полностью собранного ClientHello.
|
|||
|
При любой ошибке в процессе сборки задержанные пакеты немедленно отсылаются в сеть, а десинхронизация отменяется.
|
|||
|
|
|||
|
Есть специальная поддержка всех вариантов tcp сплита для многосегментного TLS.
|
|||
|
Если указать позицию сплита больше длины первого пакета или использовать --dpi-desync-split-tls,
|
|||
|
то разбивка происходит не обязательно первого пакета, а того, на который пришлась итоговая позиция.
|
|||
|
Если, допустим, клиент послал TLS ClientHello длиной 2000, а SNI начинается с 1700,
|
|||
|
и заданы опции fake,split2, то перед первым пакетом идет fake, затем первый пакет в оригинале,
|
|||
|
а последний пакет разбивается на 2 сегмента. В итоге имеем фейк в начале и 3 реальных сегмента.
|
|||
|
|
|||
|
ПОДДЕРЖКА UDP
|
|||
|
Атаки на udp более ограничены в возможностях. udp нельзя фрагментировать иначе, чем на уровне ip.
|
|||
|
Для UDP действуют только режимы десинхронизации fake,hopbyhop,destopt,ipfrag1,ipfrag2,udplen,tamper.
|
|||
|
Возможно сочетание fake,hopbyhop,destopt с ipfrag2, fake,fakeknown с udplen и tamper.
|
|||
|
udplen увеличивает размер udp пакета на указанное в --dpi-desync-udplen-increment количество байтов.
|
|||
|
Паддинг заполняется нулями по умолчанию, но можно задать свой паттерн.
|
|||
|
Предназначено для обмана DPI, ориентирующегося на размеры пакетов.
|
|||
|
Может сработать, если пользовательский протокол не привязан жестко к размеру udp пейлоада.
|
|||
|
Режим tamper означает модификацию пакетов известных протоколов особенным для протокола образом.
|
|||
|
На текущий момент работает только с DHT.
|
|||
|
Поддерживается определение пакетов QUIC Initial с расшифровкой содержимого и имени хоста, то есть параметр
|
|||
|
--hostlist будет работать.
|
|||
|
Определяются пакеты wireguard handshake initiation и DHT (начинается с 'd1', кончается 'e').
|
|||
|
Для десинхронизации других протоколов обязательно указывать --dpi-desync-any-protocol.
|
|||
|
Реализован conntrack для udp. Можно пользоваться --dpi-desync-cutoff. Таймаут conntrack для udp
|
|||
|
можно изменить 4-м параметром в --ctrack-timeouts.
|
|||
|
Атака fake полезна только для stateful DPI, она бесполезна для анализа на уровне отдельных пакетов.
|
|||
|
По умолчанию fake наполнение - 64 нуля. Можно указать файл в --dpi-desync-fake-unknown-udp.
|
|||
|
|
|||
|
IP ФРАГМЕНТАЦИЯ
|
|||
|
Современная сеть практически не пропускает фрагментированные tcp на уровне ip.
|
|||
|
На udp с этим дело получше, поскольку некоторые udp протоколы могут опираться на этот механизм (IKE старых версий).
|
|||
|
Однако, кое-где бывает, что режут и фрагментированный udp.
|
|||
|
Роутеры на базе linux могут самопроизвольно собирать или перефрагментировать пакеты.
|
|||
|
Позиция фрагментации задается отдельно для tcp и udp. По умолчанию 24 и 8 соответственно, должна быть кратна 8.
|
|||
|
Смещение считается с транспортного заголовка.
|
|||
|
|
|||
|
Существует ряд моментов вокруг работы с фрагментами на Linux, без понимания которых может ничего не получиться.
|
|||
|
|
|||
|
ipv4 : Linux дает отсылать ipv4 фрагменты, но стандартные настройки iptables в цепочке OUTPUT могут вызывать ошибки отправки.
|
|||
|
|
|||
|
ipv6 : Нет способа для приложения гарантированно отослать фрагменты без дефрагментации в conntrack.
|
|||
|
На разных системах получается по-разному. Где-то нормально уходят, где-то пакеты дефрагментируются.
|
|||
|
Для ядер <4.16 похоже, что нет иного способа решить эту проблему, кроме как выгрузить модуль nf_conntrack,
|
|||
|
который подтягивает зависимость nf_defrag_ipv6. Он то как раз и выполняет дефрагментацию.
|
|||
|
Для ядер 4.16+ ситуация чуть лучше. Из дефрагментации исключаются пакеты в состоянии NOTRACK.
|
|||
|
Чтобы не загромождать описание, смотрите пример решения этой проблемы в blockcheck.sh.
|
|||
|
|
|||
|
Иногда требуется подгружать модуль ip6table_raw с параметром raw_before_defrag=1.
|
|||
|
В openwrt параметры модулей указываются через пробел после их названий в файлах /etc/modules.d.
|
|||
|
В традиционных системах посмотрите используется ли iptables-legacy или iptables-nft. Если legacy, то нужно создать файл
|
|||
|
/etc/modprobe.d/ip6table_raw.conf с содержимым :
|
|||
|
options ip6table_raw raw_before_defrag=1
|
|||
|
В некоторых традиционных дистрибутивах можно изменить текущий ip6tables через : update-alternatives --config ip6tables
|
|||
|
Если вы хотите оставаться на iptables-nft, вам придется пересобрать патченную версию. Патч совсем небольшой.
|
|||
|
В nft.c найдите фрагмент :
|
|||
|
{
|
|||
|
.name = "PREROUTING",
|
|||
|
.type = "filter",
|
|||
|
.prio = -300, /* NF_IP_PRI_RAW */
|
|||
|
.hook = NF_INET_PRE_ROUTING,
|
|||
|
},
|
|||
|
{
|
|||
|
.name = "OUTPUT",
|
|||
|
.type = "filter",
|
|||
|
.prio = -300, /* NF_IP_PRI_RAW */
|
|||
|
.hook = NF_INET_LOCAL_OUT,
|
|||
|
},
|
|||
|
и замените везде -300 на -450.
|
|||
|
|
|||
|
Это нужно сделать вручную, никакой автоматики в blockcheck.sh нет.
|
|||
|
|
|||
|
Либо можно раз и навсегда избавиться от этой проблемы, используя nftables. Там можно создать netfilter hook
|
|||
|
с любым приоритетом. Используйте приоритет -401 и ниже.
|
|||
|
|
|||
|
При использовании iptables и NAT, похоже, что нет способа прицепить обработчик очереди после NAT.
|
|||
|
Пакет попадает в nfqws с source адресом внутренней сети, затем фрагментируется и уже не обрабатывается NAT.
|
|||
|
Так и уходит во внешюю сеть с src ip 192.168.x.x. Следовательно, метод не срабатывает.
|
|||
|
Видимо единственный рабочий метод - отказаться от iptables и использовать nftables.
|
|||
|
Хук должен быть с приоритетом 101 или выше.
|
|||
|
|
|||
|
МНОЖЕСТВЕННЫЕ СТРАТЕГИИ
|
|||
|
nfqws способен по-разному реагировать на различные запросы и применять разные стратегии дурения.
|
|||
|
Это реализовано посредством поддержки множества профилей дурения.
|
|||
|
Профили разделяются в командной строке параметром --new. Первый профиль создается автоматически.
|
|||
|
Для него не нужно --new. Каждый профиль имеет фильтр. По умолчанию он пуст, то есть профиль удовлетворяет
|
|||
|
любым условиям.
|
|||
|
Фильтр может содержать жесткие параметры : версия ip протокола или порты tcp/udp.
|
|||
|
Они всегда однозначно идентифицируются даже на нулевой фазе десинхронизации, когда еще хост неизвестен.
|
|||
|
В качестве фильтра могут выступать и хост-листы. Они могут сочетаться с жесткими параметрами.
|
|||
|
При поступлении запроса идет проверка профилей в порядке от первого до последнего до
|
|||
|
достижения первого совпадения с фильтром.
|
|||
|
Жесткие параметры фильтра сверяются первыми. При несовпадении идет сразу же переход к следующему профилю.
|
|||
|
Если какой-то профиль удовлетворяет жесткому фильтру и содержит авто-хостлист, он выбирается сразу.
|
|||
|
Если профиль удовлетворяет жесткому фильтру, для него задан хостлист, и у нас еще нет имени хоста,
|
|||
|
идет переход к следующему профилю. В противном случае идет проверка по хостлистам этого профиля.
|
|||
|
Если имя хоста удовлетворяет листам, выбирается этот профиль. Иначе идет переход к следующему.
|
|||
|
Может так случиться, что до получения имени хоста соединение идет по одному профилю, а при получении
|
|||
|
хоста профиль меняется на лету. Поэтому если у вас есть параметры дурения нулевой фазы, тщательно
|
|||
|
продумывайте что может произойти при переключении стратегии. Смотрите debug log, чтобы лучше
|
|||
|
понять что делает nfqws.
|
|||
|
Нумерация профилей идет с 1 до N. Последним в цепочке создается пустой профиль с номером 0.
|
|||
|
Он используется, когда никакие условия фильтров не совпали.
|
|||
|
|
|||
|
ВАЖНО : множественные стратегии создавались только для случаев, когда невозможно обьединить
|
|||
|
имеющиеся стратегии для разных ресурсов. Копирование стратегий из blockcheck для разных сайтов
|
|||
|
во множество профилей без понимания как они работают приведет к нагромождению параметров, которые все равно
|
|||
|
не покроют все возможные заблокированные ресурсы. Вы только увязните в этой каше.
|
|||
|
|
|||
|
|
|||
|
tpws
|
|||
|
-----
|
|||
|
|
|||
|
tpws - это transparent proxy.
|
|||
|
--debug=0|1|2|syslog|@<filename> ; 0,1,2 = логирование на косоль : 0=тихо, 1(default)=подробно, 2=отладка.
|
|||
|
--debug-level=0|1|2 ; указать уровень логирования для syslog и @<filename>
|
|||
|
--daemon ; демонизировать прогу
|
|||
|
--pidfile=<file> ; сохранить PID в файл
|
|||
|
--user=<username> ; менять uid процесса
|
|||
|
--uid=uid[:gid] ; менять uid процесса
|
|||
|
--bind-addr ; на каком адресе слушать. может быть ipv4 или ipv6 адрес
|
|||
|
; если указан ipv6 link local, то требуется указать с какого он интерфейса : fe80::1%br-lan
|
|||
|
--bind-linklocal=no|unwanted|prefer|force
|
|||
|
; no : биндаться только на global ipv6
|
|||
|
; unwanted (default) : предпочтительно global, если нет - LL
|
|||
|
; prefer : предпочтительно LL, если нет - global
|
|||
|
; force : биндаться только на LL
|
|||
|
--bind-iface4=<iface> ; слушать на первом ipv4 интерфейса iface
|
|||
|
--bind-iface6=<iface> ; слушать на первом ipv6 интерфейса iface
|
|||
|
--bind-wait-ifup=<sec> ; ждать до N секунд появления и поднятия интерфейса
|
|||
|
--bind-wait-ip=<sec> ; ждать до N секунд получения IP адреса (если задан --bind-wait-ifup - время идет после поднятия интерфейса)
|
|||
|
--bind-wait-ip-linklocal=<sec>
|
|||
|
; имеет смысл только при задании --bind-wait-ip
|
|||
|
; --bind-linklocal=unwanted : согласиться на LL после N секунд
|
|||
|
; --bind-linklocal=prefer : согласиться на global address после N секунд
|
|||
|
--bind-wait-only ; подождать все бинды и выйти. результат 0 в случае успеха, иначе не 0.
|
|||
|
--connect-bind-addr ; с какого адреса подключаться во внешнюю сеть. может быть ipv4 или ipv6 адрес
|
|||
|
; если указан ipv6 link local, то требуется указать с какого он интерфейса : fe80::1%br-lan
|
|||
|
; опция может повторяться для v4 и v6 адресов
|
|||
|
; опция не отменяет правил маршрутизации ! выбор интерфейса определяется лишь правилами маршрутизации, кроме случая v6 link local.
|
|||
|
--socks ; вместо прозрачного прокси реализовать socks4/5 proxy
|
|||
|
--no-resolve ; запретить ресолвинг имен через socks5
|
|||
|
--resolve-threads ; количество потоков ресолвера
|
|||
|
--port=<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
|
|||
|
--nosplice ; не использовать splice на linux системах
|
|||
|
--skip-nodelay ; не устанавливать в исходящих соединения TCP_NODELAY. несовместимо со split.
|
|||
|
--local-tcp-user-timeout=<seconds> ; таймаут соединений client-proxy (по умолчанию : 10 сек, 0 = оставить системное значение)
|
|||
|
--remote-tcp-user-timeout=<seconds> ; таймаут соединений proxy-target (по умолчанию : 20 сек, 0 = оставить системное значение)
|
|||
|
|
|||
|
--split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host
|
|||
|
--split-pos=<offset> ; делить все посылы на сегменты в указанной позиции. единственная опция, работающая на не-http. при указании split-http-req он имеет преимущество на http.
|
|||
|
--split-any-protocol ; применять split-pos к любым пакетам. по умолчанию - только к http и TLS ClientHello
|
|||
|
--disorder[=http|tls] ; путем манипуляций с сокетом вынуждает отправлять первым второй сегмент разделенного запроса
|
|||
|
--oob[=http|tls] ; отправить байт out-of-band data (OOB) в конце первой части сплита
|
|||
|
--oob-data=<char>|0xHEX ; переопределить байт OOB. по умолчанию 0x00.
|
|||
|
--hostcase ; менять регистр заголовка "Host:". по умолчанию на "host:".
|
|||
|
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
|
|||
|
--hostdot ; добавление точки после имени хоста : "Host: kinozal.tv."
|
|||
|
--hosttab ; добавление табуляции после имени хоста : "Host: kinozal.tv\t"
|
|||
|
--hostnospace ; убрать пробел после "Host:"
|
|||
|
--hostpad=<bytes> ; добавить паддинг-хедеров общей длиной <bytes> перед Host:
|
|||
|
--domcase ; домен после Host: сделать таким : TeSt.cOm
|
|||
|
--methodspace ; добавить пробел после метода : "GET /" => "GET /"
|
|||
|
--methodeol ; добавить перевод строки перед методом : "GET /" => "\r\nGET /"
|
|||
|
--unixeol ; конвертировать 0D0A в 0A и использовать везде 0A
|
|||
|
--tlsrec=sni|sniext ; разбивка TLS ClientHello на 2 TLS records. режем между 1 и 2 символами hostname в SNI или между байтами длины SNI extension. Если SNI нет - отмена.
|
|||
|
--tlsrec-pos=<pos> ; разбивка TLS ClientHello на 2 TLS records. режем на указанной позиции, если длина слишком мелкая - на позиции 1.
|
|||
|
--mss=<int> ; установить MSS для клиента. может заставить сервер разбивать ответы, но существенно снижает скорость
|
|||
|
--mss-pf=[~]port1[-port2] ; применять MSS только к портам назначения, подпадающим под фильтр. ~ означает инверсию
|
|||
|
--tamper-start=[n]<pos> ; начинать дурение только с указанной байтовой позиции или номера блока исходяшего потока (считается позиция начала принятого блока)
|
|||
|
--tamper-cutoff=[n]<pos> ; закончить дурение на указанной байтовой позиции или номере блока исходящего потока (считается позиция начала принятого блока)
|
|||
|
--hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются.
|
|||
|
; в файле должен быть хост на каждой строке.
|
|||
|
; список читается 1 раз при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
|
|||
|
; по сигналу HUP список будет перечитан при следующем принятом соединении
|
|||
|
; список может быть запакован в gzip. формат автоматически распознается и разжимается
|
|||
|
; списков может быть множество, они объединяются. пустой общий лист = его отсутствие
|
|||
|
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
|
|||
|
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов, они объединяются
|
|||
|
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
|
|||
|
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3)
|
|||
|
--hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60)
|
|||
|
--hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты.
|
|||
|
--new ; начало новой стратегии
|
|||
|
--filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии
|
|||
|
--filter-tcp=[~]port1[-port2] ; фильтр портов tcp для текущей стратегии. ~ означает инверсию.
|
|||
|
|
|||
|
|
|||
|
--debug позволяет выводить подробный лог действий на консоль, в syslog или в файл.
|
|||
|
Может быть важен порядок следования опций. --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.
|
|||
|
split-pos по умолчанию работает только на http и TLS ClientHello.
|
|||
|
Чтобы он работал на любых пакетах, укажите --split-any-protocol.
|
|||
|
|
|||
|
На прикладном уровне в общем случае нет гарантированного средства заставить ядро выплюнуть
|
|||
|
блок данных, порезанным в определенном месте. ОС держит буфер отсылки (SNDBUF) у каждого сокета.
|
|||
|
Если у сокета включена опция TCP_NODELAY и буфер пуст, то каждый send приводит к отсылке
|
|||
|
отдельного ip пакета или группы пакетов, если блок не вмещается в один ip пакет.
|
|||
|
Однако, если в момент send уже имеется неотосланный буфер, то ОС присоединит данные к нему,
|
|||
|
никакой отсылки отдельным пакетом не будет. Но в этом случае и так нет никакой гарантии,
|
|||
|
что какой-то блок сообщения пойдет в начале пакета, на что собственно и заточены DPI.
|
|||
|
Разбиение будет производится согласно MSS, который зависит от MTU исходящего интерфейса.
|
|||
|
Таким образом DPI, смотрящие в начало поля данных TCP пакета, будут поломаны в любом случае.
|
|||
|
Протокол http относится к запрос-ответным протоколам. Новое сообщение посылается только тогда,
|
|||
|
когда сервер получил запрос и полностью вернул ответ. Значит запрос фактически был не только отослан,
|
|||
|
но и принят другой стороной, а следовательно буфер отсылки пуст, и следующие 2 send приведут
|
|||
|
к отсылке сегментов данных разными ip пакетами.
|
|||
|
Резюме : tpws гарантирует сплит только за счет раздельных вызовов send, что на практике
|
|||
|
вполне достаточно для протоколов http(s).
|
|||
|
|
|||
|
tpws может биндаться на множество интерфейсов и IP адресов (до 32 шт).
|
|||
|
Порт всегда только один.
|
|||
|
Параметры --bind-iface* и --bind-addr создают новый бинд.
|
|||
|
Остальные параметры --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 работает в режиме "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, запрещены.
|
|||
|
socks5 позволяет удаленно ресолвить хосты (curl : --socks5-hostname firefox : socks_remote_dns=true).
|
|||
|
tpws поддерживает эту возможность асинхронно, не блокируя процессинг других соединений, используя
|
|||
|
многопоточный пул ресолверов. Количество потоков определяется автоматически в зависимости от "--maxconn",
|
|||
|
но можно задать и вручную через параметр "--resolver-threads".
|
|||
|
Запрос к socks выставляется на паузу, пока домен не будет преобразован в ip адрес в одном из потоков
|
|||
|
ресолвера. Ожидание может быть более длинным, если все потоки заняты.
|
|||
|
Если задан параметр "--no-resolve", то подключения по именам хостов запрещаются, а пул ресолверов не создается.
|
|||
|
Тем самым экономятся ресурсы.
|
|||
|
|
|||
|
Параметр --hostpad=<bytes> добавляет паддинг-хедеров перед Host: на указанное количество байтов.
|
|||
|
Если размер <bytes> слишком большой, то идет разбивка на разные хедеры по 2K.
|
|||
|
Общий буфер приема http запроса - 64K, больший паддинг не поддерживается, да и http сервера
|
|||
|
такое уже не принимают.
|
|||
|
Полезно против DPI, выполняющих реассемблинг TCP с ограниченным буфером.
|
|||
|
Если техника работает, то после некоторого количества bytes http запрос начнет проходить до сайта.
|
|||
|
Если при этом критический размер padding около MTU, значит скорее всего DPI не выполняет реассемблинг пакетов, и лучше будет использовать обычные опции --split-…
|
|||
|
Если все же реассемблинг выполняется, то критический размер будет около размера буфера DPI. Он может быть 4K или 8K, возможны и другие значения.
|
|||
|
|
|||
|
--disorder - это попытка симулировать режим disorder2 nfqws, используя особенности ОС по реализации stream сокетов.
|
|||
|
Однако, в отличие от nfqws, здесь не требуются повышенные привилегии.
|
|||
|
Реализовано это следующим образом. У сокета есть возможность выставить TTL. Все пакеты будут отправляться с ним.
|
|||
|
Перед отправкой первого сегмента ставим TTL=1. Пакет будет дропнут на первом же роутере, он не дойдет ни до DPI, ни до сервера.
|
|||
|
Затем возвращаем TTL в значение по умолчанию. ОС отсылает второй сегмент, и он уже доходит до сервера.
|
|||
|
Сервер возвращает SACK, потому что не получил первый кусок, и ОС его отправляет повторно, но здесь уже мы ничего не делаем.
|
|||
|
Этот режим работает как ожидается на Linux и MacOS. Однако, на FreeBSD и OpenBSD он работает не так хорошо.
|
|||
|
Ядро этих ОС отсылает ретрансмиссию в виде полного пакета. Потому выходит, что до сервера идет сначала второй кусок,
|
|||
|
а потом полный запрос без сплита. На него может отреагировать DPI штатным образом.
|
|||
|
--disorder является дополнительным флагом к любому сплиту. Сам по себе он не делает ничего.
|
|||
|
|
|||
|
--tlsrec и --tlsrec-pos позволяют внутри одного tcp сегмента разрезать TLS ClientHello на 2 TLS records.
|
|||
|
--tlsrec=sni режет между 1 и 2 символами hostname в SNI, делая невозможным бинарный поиск паттерна без анализа
|
|||
|
структуры данных. В случае отсутствия SNI разбиение отменяется.
|
|||
|
--tlsrec-pos режет на указанной позиции. Если длина блока данных TLS меньше указанной позиции, режем на позиции 1.
|
|||
|
Параметр сочетается с --split-pos. В этом случае происходит сначала разделение на уровне TLS record layer, потом на уровне TCP.
|
|||
|
Самая изощрённая атака --tlsrec, --split-pos и --disorder вместе.
|
|||
|
--tlsrec ломает значительное количество сайтов. Криптобиблиотеки (openssl, ...) на оконечных http серверах
|
|||
|
без проблем принимают разделенные tls сегменты, но мидлбоксы - не всегда. К мидлбоксам можно отнести CDN
|
|||
|
или системы ddos-защиты. Поэтому применение --tlsrec без ограничителей вряд ли целесообразно.
|
|||
|
В РФ --tlsrec обычно не работает с TLS 1.2, потому что цензор парсит сертификат сервера из ServerHello.
|
|||
|
Работает только с TLS 1.3, поскольку там эта информация шифруется.
|
|||
|
Впрочем, сейчас сайтов, не поддерживающих TLS 1.3, осталось немного.
|
|||
|
|
|||
|
--mss устанавливает опцию сокета TCP_MAXSEG. Клиент выдает это значение в tcp опциях SYN пакета.
|
|||
|
Сервер в ответ в SYN,ACK выдает свой MSS. На практике сервера обычно снижают размеры отсылаемых ими пакетов, но они
|
|||
|
все равно не вписываются в низкий MSS, указанный клиентом. Обычно чем больше указал клиент, тем больше
|
|||
|
шлет сервер. На TLS 1.2 если сервер разбил заброс так, чтобы домен из сертификата не попал в первый пакет,
|
|||
|
это может обмануть DPI, секущий ответ сервера.
|
|||
|
Схема может значительно снизить скорость и сработать не на всех сайтах.
|
|||
|
С фильтром по hostlist совместимо только в режиме socks при включенном удаленном ресолвинге хостов.
|
|||
|
(firefox network.proxy.socks_remote_dns). Это единственный вариант, когда tpws может узнать имя хоста
|
|||
|
еще на этапе установления соединения.
|
|||
|
Применяя данную опцию к сайтам TLS1.3, если броузер тоже поддерживает TLS1.3, то вы делаете только хуже.
|
|||
|
Но нет способа автоматически узнать когда надо применять, когда нет, поскольку MSS идет только в
|
|||
|
3-way handshake еще до обмена данными, а версию TLS можно узнать только по ответу сервера, который
|
|||
|
может привести к реакции DPI.
|
|||
|
Использовать только когда нет ничего лучше или для отдельных ресурсов.
|
|||
|
Для http использовать смысла нет, поэтому заводите отдельный desync profile с фильтром по порту 443.
|
|||
|
Работает только на linux, не работает на BSD и MacOS.
|
|||
|
|
|||
|
--skip-nodelay может быть полезен, чтобы привести MTU к MTU системы, на которой работает tpws.
|
|||
|
Это может быть полезно для скрытия факта использования VPN. Пониженный MTU - 1 из способов обнаружения
|
|||
|
подозрительного подключения. С tcp proxy ваши соединения неотличимы от тех, что сделал бы сам шлюз.
|
|||
|
|
|||
|
--local-tcp-user-timeout и --remote-tcp-user-timeout устанавливают значение таймаута в секундах
|
|||
|
для соединений клиент-прокси и прокси-сервер. Этот таймаут соответствует опции сокета linux
|
|||
|
TCP_USER_TIMEOUT. Под таймаутом подразумевается время, в течение которого буферизированные данные
|
|||
|
не переданы или на переданные данные не получено подтверждение (ACK) от другой стороны.
|
|||
|
Этот таймаут никак не касается времени отсутствия какой-либо передачи через сокет лишь потому,
|
|||
|
что данных для передачи нет. Полезно для сокращения время закрытия подвисших соединений.
|
|||
|
Поддерживается только на Linux и MacOS.
|
|||
|
|
|||
|
МНОЖЕСТВЕННЫЕ СТРАТЕГИИ
|
|||
|
Работают аналогично nfqws, кроме некоторых моментов.
|
|||
|
Нет параметра --filter-udp, поскольку tpws udp не поддерживает.
|
|||
|
Методы нулевой фазы (--mss) могут работать по хостлисту в одном единственном случае :
|
|||
|
если используется режим socks и удаленный ресолвинг хостов через прокси.
|
|||
|
То есть работоспособность вашей настройки в одном и том же режиме может зависеть от того,
|
|||
|
применяет ли клиент удаленный ресолвинг. Это может быть неочевидно.
|
|||
|
В одной программе работает, в другой - нет.
|
|||
|
Если вы используете профиль с хостлистом , и вам нужен mss, укажите mss в профиле с хостлистом,
|
|||
|
создайте еще один профиль без хостлиста, если его еще нет, и в нем еще раз укажите mss.
|
|||
|
Тогда при любом раскладе будет выполняться mss.
|
|||
|
Используйте `curl --socks5` и `curl --socks5-hostname` для проверки вашей стратегии.
|
|||
|
Смотрите вывод --debug, чтобы убедиться в правильности настроек.
|
|||
|
|
|||
|
Способы получения списка заблокированных IP
|
|||
|
-------------------------------------------
|
|||
|
|
|||
|
!!! nftables не могут работать с ipset-ами. Собственный аналогичный механизм требует огромного количество RAM
|
|||
|
!!! для загрузки больших листов. Например, для загона 100K записей в nfset не хватает даже 256 Mb.
|
|||
|
!!! Если вам нужны большие листы на домашних роутерах, откатывайтесь на iptables+ipset.
|
|||
|
|
|||
|
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_preresolved.sh. то же самое, что и 2), только берется уже заресолвленый список
|
|||
|
со стороннего ресурса.
|
|||
|
|
|||
|
4) ipset/get_reestr_preresolved_smart.sh. то же самое, что и 3), с добавлением всего диапазона некоторых
|
|||
|
автономных систем (прыгающие IP адреса из cloudflare, facebook, ...) и некоторых поддоменов блокируемых сайтов
|
|||
|
|
|||
|
Cкрипты с названием get_antifilter_* оперируют списками адресов и масок подсетей с сайтов antifilter.network и antifilter.download :
|
|||
|
|
|||
|
5) ipset/get_antifilter_ip.sh. получает лист https://antifilter.download/list/ip.lst.
|
|||
|
|
|||
|
6) ipset/get_antifilter_ipsmart.sh. получает лист https://antifilter.network/download/ipsmart.lst.
|
|||
|
умная суммаризация отдельных адресов из ip.lst по маскам от /32 до /22
|
|||
|
|
|||
|
7) ipset/get_antifilter_ipsum.sh. получает лист https://antifilter.download/list/ipsum.lst.
|
|||
|
суммаризация отдельных адресов из ip.lst по маске /24
|
|||
|
|
|||
|
8) ipset/get_antifilter_ipresolve.sh. получает лист https://antifilter.download/list/ipresolve.lst.
|
|||
|
пре-ресолвленный список, аналогичный получаемый при помощи get_reestr_resolve. только ipv4.
|
|||
|
|
|||
|
9) ipset/get_antifilter_allyouneed.sh. получает лист https://antifilter.download/list/allyouneed.lst.
|
|||
|
Суммарный список префиксов, созданный из ipsum.lst и subnet.lst.
|
|||
|
|
|||
|
Все варианты рассмотренных скриптов автоматически создают и заполняют ipset.
|
|||
|
Варианты 2-9 дополнительно вызывают вариант 1.
|
|||
|
|
|||
|
10) ipset/get_config.sh. этот скрипт вызывает то, что прописано в переменной GETLIST из файла config
|
|||
|
Если переменная не определена, то ресолвятся лишь листы для ipset nozapret/nozapret6.
|
|||
|
|
|||
|
Листы РКН все время изменяются. Возникают новые тенденции. Требования к RAM могут меняться.
|
|||
|
Поэтому необходима нечастая, но все же регулярная ревизия что же вообще у вас происходит на роутере.
|
|||
|
Или вы можете узнать о проблеме лишь когда у вас начнет постоянно пропадать wifi, и вам придется
|
|||
|
его перезагружать каждые 2 часа (метод кувалды).
|
|||
|
|
|||
|
Самые щадящие варианты по RAM - get_antifilter_allyouneed.sh, get_antifilter_ipsum.sh.
|
|||
|
|
|||
|
Листы zapret-ip.txt и zapret-ipban.txt сохраняются в сжатом виде в файлы .gz.
|
|||
|
Это позволяет снизить их размер во много раз и сэкономить место на роутере.
|
|||
|
Отключить сжатие листов можно параметром конфига GZIP_LISTS=0.
|
|||
|
|
|||
|
На роутерах не рекомендуется вызывать эти скрипты чаще раза за 2 суток, поскольку сохранение идет
|
|||
|
либо во внутреннюю флэш память роутера, либо в случае extroot - на флэшку.
|
|||
|
В обоих случаях слишком частая запись может убить флэшку, но если это произойдет с внутренней
|
|||
|
флэш памятью, то вы просто убьете роутер.
|
|||
|
|
|||
|
Принудительное обновление ipset выполняет скрипт ipset/create_ipset.sh.
|
|||
|
Если передан параметр "no-update", скрипт не обновляет ipset, а только создает его при его отсутствии и заполняет.
|
|||
|
Это полезно, когда могут случиться несколько последовательных вызовов скрипта. Нет смысла несколько раз перезаполнять
|
|||
|
ipset, это длительная операция на больших листах. Листы можно обновлять раз в несколько суток, и только тогда
|
|||
|
вызывать create_ipset без параметра "no-update". Во всех остальных случаях стоит применять "no-update".
|
|||
|
|
|||
|
Список РКН уже достиг внушительных размеров в сотни тысяч IP адресов. Поэтому для оптимизации ipset
|
|||
|
применяется утилита ip2net. Она берет список отдельных IP адресов и пытается интеллектуально создать из него подсети для сокращения
|
|||
|
количества адресов. ip2net отсекает неправильные записи в листах, гарантируя отсутствие ошибок при их загрузке.
|
|||
|
ip2net написан на языке C, поскольку операция ресурсоемкая. Иные способы роутер может не потянуть.
|
|||
|
|
|||
|
Можно внести список доменов в 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 адреса или подсети.
|
|||
|
|
|||
|
FreeBSD. Скрипты ipset/*.sh работают так же на FreeBSD. Вместо ipset они создают lookup таблицы ipfw с аналогичными именами.
|
|||
|
ipfw таблицы в отличие от ipset могут содержать как ipv4, так и ipv6 адреса и подсети в одной таблице, поэтому разделения нет.
|
|||
|
|
|||
|
Параметр конфига LISTS_RELOAD задает произвольную команду для перезагрузки листов.
|
|||
|
Это особенно полезно на BSD системах с PF.
|
|||
|
LISTS_RELOAD=- отключает перезагрузку листов.
|
|||
|
|
|||
|
|
|||
|
ip2net
|
|||
|
------
|
|||
|
|
|||
|
Утилита ip2net предназначена для преобразования ipv4 или ipv6 списка ip в список подсетей
|
|||
|
с целью сокращения размера списка. Входные данные берутся из stdin, выходные выдаются в stdout.
|
|||
|
|
|||
|
-4 ; лист - ipv4 (по умолчанию)
|
|||
|
-6 ; лист - ipv6
|
|||
|
--prefix-length=min[-max] ; диапазон рассматриваемых длин префиксов. например : 22-30 (ipv4), 56-64 (ipv6)
|
|||
|
--v4-threshold=mul/div ; ipv4 : включать подсети, в которых заполнено по крайней мере mul/div адресов. например : 3/4
|
|||
|
--v6-threshold=N ; ipv6 : минимальное количество ip для создания подсети
|
|||
|
|
|||
|
В списке могут присутствовать записи вида ip/prefix и ip1-ip2. Такие записи выкидываются в stdout без изменений.
|
|||
|
Они принимаются командой ipset. ipset умеет для листов hash:net из ip1-ip2 делать оптимальное покрытие ip/prefix.
|
|||
|
ipfw из FreeBSD понимает ip/prefix, но не понимает ip1-ip2.
|
|||
|
ip2net фильтрует входные данные, выкидывая неправильные IP адреса.
|
|||
|
|
|||
|
Выбирается подсеть, в которой присутствует указанный минимум адресов.
|
|||
|
Для ipv4 минимум задается как процент от размера подсети (mul/div. например, 3/4), для ipv6 минимум задается напрямую.
|
|||
|
|
|||
|
Размер подсети выбирается следующим алгоритмом :
|
|||
|
Сначала в указанном диапазоне длин префиксов ищутся подсети, в которых количество адресов - максимально.
|
|||
|
Если таких сетей найдено несколько, берется наименьшая сеть (префикс больше).
|
|||
|
Например, заданы параметры v6_threshold=2 prefix_length=32-64, имеются следующие ipv6 :
|
|||
|
1234:5678:aaaa::5
|
|||
|
1234:5678:aaaa::6
|
|||
|
1234:5678:aaac::5
|
|||
|
Результат будет :
|
|||
|
1234:5678:aaa8::/45
|
|||
|
Эти адреса так же входят в подсеть /32. Однако, нет смысла проходиться ковровой бомбардировкой,
|
|||
|
когда те же самые адреса вполне влезают в /45 и их ровно столько же.
|
|||
|
Если изменить v6_threshold=4, то результат будет :
|
|||
|
1234:5678:aaaa::5
|
|||
|
1234:5678:aaaa::6
|
|||
|
1234:5678:aaac::5
|
|||
|
То есть ip не объединятся в подсеть, потому что их слишком мало.
|
|||
|
Если изменить prefix_length=56-64, результат будет :
|
|||
|
1234:5678:aaaa::/64
|
|||
|
1234:5678:aaac::5
|
|||
|
|
|||
|
Требуемое процессорное время для вычислений сильно зависит от ширины диапазона длин префиксов, размера искомых подсетей и длины листа.
|
|||
|
Если ip2net думает слишком долго, не используйте слишком большие подсети и уменьшите диапазон длин префиксов.
|
|||
|
Учтите, что арифметика mul/div - целочисленная. При превышении разрядной сетки 32 bit результат непредсказуем.
|
|||
|
Не надо делать такое : 5000000/10000000. 1/2 - гораздо лучше.
|
|||
|
|
|||
|
|
|||
|
Фильтрация по именам доменов
|
|||
|
----------------------------
|
|||
|
|
|||
|
Альтернативой ipset является использование tpws или nfqws со списком доменов.
|
|||
|
Оба демона принимают неограниченное количество листов include (--hostlist) и exclude (--hostlist-exclude).
|
|||
|
Все листы одного типа объединяются, и таким образом остаются только 2 листа.
|
|||
|
Прежде всего проверяется exclude list. При вхождении в него происходит отказ от дурения.
|
|||
|
Далее при наличии include list проверяется домен на вхождение в него. При невхождении в список отказ от дурения.
|
|||
|
Пустой список приравнивается к его отсутствию.
|
|||
|
В иных случаях происходит дурение.
|
|||
|
Нет ни одного списка - дурение всегда.
|
|||
|
Есть только exclude список - дурение всех, кроме.
|
|||
|
Есть только include список - дурение только их.
|
|||
|
Есть оба - дурение только include, кроме exclude.
|
|||
|
|
|||
|
В системе запуска это обыграно следующим образом.
|
|||
|
Присутствуют 2 include списка :
|
|||
|
ipset/zapret-hosts-users.txt.gz или ipset/zapret-hosts-users.txt
|
|||
|
ipset/zapret-hosts.txt.gz или ipset/zapret-hosts.txt
|
|||
|
и 1 exclude список
|
|||
|
ipset/zapret-hosts-users-exclude.txt.gz или ipset/zapret-hosts-users-exclude.txt
|
|||
|
|
|||
|
При режиме фильтрации MODE_FILTER=hostlist система запуска передает nfqws или tpws все листы, файлы которых присутствуют.
|
|||
|
Если вдруг листы include присутствуют, но все они пустые, то работа аналогична отсутствию include листа.
|
|||
|
Файл есть, но не смотря на это дурится все, кроме exclude.
|
|||
|
Если вам нужен именно такой режим - не обязательно удалять zapret-hosts-users.txt. Достаточно сделать его пустым.
|
|||
|
|
|||
|
Поддомены учитываются автоматически. Например, строчка "ru" вносит в список "*.ru". Строчка "*.ru" в списке не сработает.
|
|||
|
|
|||
|
Список доменов РКН может быть получен скриптами ipset/get_reestr_hostlist.sh или ipset/get_antizapret_domains.sh
|
|||
|
- кладется в ipset/zapret-hosts.txt.gz.
|
|||
|
|
|||
|
Чтобы обновить списки, перезапускать nfqws или tpws не нужно. Обновляете файлы, затем даете сигнал HUP.
|
|||
|
По HUP листы будут перечитаны. Если вдруг какого-то листа не окажется, процесс завершится с ошибкой.
|
|||
|
Скрипты получения листов из ipset сами выдают HUP в конце.
|
|||
|
|
|||
|
При фильтрации по именам доменов демон должен запускаться без фильтрации по ipset.
|
|||
|
tpws и nfqws решают нужно ли применять дурение в зависимости от хоста, полученного из протокола прикладного уровня (http, tls, quic).
|
|||
|
При использовании больших списков, в том числе списка РКН, оцените объем RAM на роутере !
|
|||
|
Если после запуска демона RAM под завязку или случаются oom, значит нужно отказаться от таких больших списков.
|
|||
|
|
|||
|
|
|||
|
Режим фильтрации autohostlist
|
|||
|
-----------------------------
|
|||
|
|
|||
|
Этот режим позволяет проанализировать как запросы со стороны клиента, так и ответы от сервера.
|
|||
|
Если хост еще не находится ни в каких листах и обнаруживается ситуация, похожая на блокировку,
|
|||
|
происходит автоматическое добавление хоста в список autohostlist как в памяти, так и в файле.
|
|||
|
nfqws или tpws сами ведут этот файл.
|
|||
|
Чтобы какой-то хост не смог попась в autohostlist используйте hostlist-exclude.
|
|||
|
Если он все-же туда попал - удалите запись из файла вручную. Процессы автоматически перечитают файл.
|
|||
|
tpws/nfqws сами назначают владельцем файла юзера, под которым они работают после сброса привилегий,
|
|||
|
чтобы иметь возможность обновлять лист.
|
|||
|
|
|||
|
В случае nfqws данный режим требует перенаправления в том числе и входящего трафика.
|
|||
|
Крайне рекомендовано использовать ограничитель connbytes, чтобы nfqws не обрабатывал гигабайты.
|
|||
|
По этой же причине не рекомендуется использование режима на BSD системах. Там нет фильтра connbytes.
|
|||
|
|
|||
|
На linux системах при использовании nfqws и фильтра connbytes может понадобится :
|
|||
|
sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1
|
|||
|
Было замечено, что некоторые DPI в России возвращают RST с неверным ACK. Это принимается tcp/ip стеком
|
|||
|
linux, но через раз приобретает статус INVALID в conntrack. Поэтому правила с connbytes срабатывают
|
|||
|
через раз, не пересылая RST пакет nfqws.
|
|||
|
|
|||
|
Как вообще могут вести себя DPI, получив "плохой запрос" и приняв решение о блокировке :
|
|||
|
|
|||
|
1) Зависание : просто отмораживается, блокируя прохождение пакетов по TCP каналу.
|
|||
|
2) RST : отправляет RST клиенту и/или серверу
|
|||
|
3) Редирект : (только для http) отправляет редирект на сайт-заглушку
|
|||
|
4) Подмена сертификата : (только для https) полный перехват TLS сеанса с попыткой всунуть что-то
|
|||
|
свое клиенту. Применяется нечасто, поскольку броузеры на такое ругаются.
|
|||
|
|
|||
|
nfqws и tpws могут сечь варианты 1-3, 4 они не распознают.
|
|||
|
Всилу специфики работы с отдельными пакетами или с TCP каналом tpws и nfqws распознают эти ситуации
|
|||
|
по-разному.
|
|||
|
Что считается ситуацией, похожей на блокировку :
|
|||
|
1) [nfqws] Несколько ретрансмиссий первого запроса в TCP сеансе, в котором имеется host.
|
|||
|
2) [nfqws,tpws] RST, пришедший в ответ на первый запрос с хостом.
|
|||
|
3) [nfqws,tpws] HTTP редирект, пришедший в ответ на первый запрос с хостом, на глобальный адрес
|
|||
|
с доменом 2 уровня, не совпадающим с доменом 2 уровня оригинального запроса.
|
|||
|
4) [tpws] закрытие соединения клиентом после отправки первого запроса с хостом, если не было на него
|
|||
|
ответа со стороны сервера. Это обычно случается по таймауту, когда нет ответа (случай "зависание").
|
|||
|
|
|||
|
Чтобы снизить вероятность ложных срабатываний, имеется счетчик ситуаций, похожих на блокировку.
|
|||
|
Если за определенное время произойдет более определенного их количества, хост считается заблокированным
|
|||
|
и заносится в autohostlist. По нему сразу же начинает работать стратегия по обходу блокировки.
|
|||
|
Если в процессе счета вебсайт отвечает без признаков блокировки, счетчик сбрасывается.
|
|||
|
Вероятно, это был временный сбой сайта.
|
|||
|
|
|||
|
На практике работа с данным режимом выглядит так.
|
|||
|
Первый раз пользователь заходит на сайт и получает заглушку, сброс соединения или броузер подвисает,
|
|||
|
вываливаясь по таймауту с сообщением о невозможности загрузить страницу.
|
|||
|
Надо долбить F5, принуждая броузер повторять попытки. После некоторой попытки сайт
|
|||
|
начинает работать, и дальше он будет работать всегда.
|
|||
|
|
|||
|
С этим режимом можно использовать техники обхода, ломающие значительное количество сайтов.
|
|||
|
Если сайт не ведет себя как заблокированный, значит обход применен не будет.
|
|||
|
В противном случае терять все равно нечего.
|
|||
|
Однако, могут быть временные сбои сервера, приводящие к ситуации, аналогичной блокировке.
|
|||
|
Могут происходит ложные срабатывания. Если такое произошло, стратегия может начать ломать
|
|||
|
незаблокированный сайт. Эту ситуацию, увы, придется вам контролировать вручную.
|
|||
|
Заносите такие домены в ipset/zapret-hosts-user-exclude.txt, чтобы избежать повторения.
|
|||
|
Чтобы впоследствии разобраться почему домен был занесен в лист, можно включить autohostlist debug log.
|
|||
|
Он полезен тем, что работает без постоянного просмотра вывода nfqws в режиме debug.
|
|||
|
В лог заносятся только основные события, ведущие к занесению хоста в лист.
|
|||
|
По логу можно понять как избежать ложных срабатываний и подходит ли вообще вам этот режим.
|
|||
|
|
|||
|
Можно использовать один autohostlist с множеством процессов. Все процессы проверяют время модификации файла.
|
|||
|
Если файл был изменен в другом процессе, то происходит перечитывание всех include листов, включая autohostlist.
|
|||
|
Все процессы должны работать под одним uid, чтобы были права доступа на файл.
|
|||
|
|
|||
|
Скрипты zapret ведут autohostlist в ipset/zapret-hosts-auto.txt.
|
|||
|
install_easy.sh при апгрейде zapret сохраняет этот файл.
|
|||
|
Режим autohostlist включает в себя режим hostlist.
|
|||
|
Можно вести ipset/zapret-hosts-user.txt, ipset/zapret-hosts-user-exclude.txt.
|
|||
|
|
|||
|
|
|||
|
Проверка провайдера
|
|||
|
-------------------
|
|||
|
|
|||
|
Перед настройкой нужно провести исследование какую бяку устроил вам ваш провайдер.
|
|||
|
|
|||
|
Нужно выяснить не подменяет ли он DNS и какой метод обхода DPI работает.
|
|||
|
В этом вам поможет скрипт blockcheck.sh.
|
|||
|
|
|||
|
Если DNS подменяется, но провайдер не перехватывает обращения к сторонним DNS, поменяйте DNS на публичный.
|
|||
|
Например : 8.8.8.8, 8.8.4.4, 1.1.1.1, 1.0.0.1, 9.9.9.9
|
|||
|
Если DNS подменяется и провайдер перехватывает обращения к сторонним DNS, настройте dnscrypt.
|
|||
|
Еще один эффективный вариант - использовать ресолвер от yandex 77.88.8.88 на нестандартном порту 1253.
|
|||
|
Многие провайдеры не анализируют обращения к DNS на нестандартных портах.
|
|||
|
|
|||
|
Следует прогнать blockcheck по нескольким заблокированным сайтам и выявить общий характер блокировок.
|
|||
|
Разные сайты могут быть заблокированы по-разному, нужно искать такую технику, которая работает на большинстве.
|
|||
|
Чтобы записать вывод blockcheck.sh в файл, выполните : ./blockcheck.sh | tee /tmp/blockcheck.txt
|
|||
|
|
|||
|
Проанализируйте какие методы дурения DPI работают, в соответствии с ними настройте /opt/zapret/config.
|
|||
|
|
|||
|
Имейте в виду, что у провайдеров может быть несколько DPI или запросы могут идти через разные каналы
|
|||
|
по методу балансировки нагрузки. Балансировка может означать, что на разных ветках разные DPI или
|
|||
|
они находятся на разных хопах. Такая ситуация может выражаться в нестабильности работы обхода.
|
|||
|
Дернули несколько раз curl. То работает, то connection reset или редирект. blockcheck.sh выдает
|
|||
|
странноватые результаты. То split работает на 2-м. хопе, то на 4-м. Достоверность результата вызывает сомнения.
|
|||
|
В этом случае задайте несколько повторов одного и того же теста. Тест будет считаться успешным только,
|
|||
|
если все попытки пройдут успешно.
|
|||
|
|
|||
|
При использовании autottl следует протестировать как можно больше разных доменов. Эта техника
|
|||
|
может на одних провайдерах работать стабильно, на других потребуется выяснить при каких параметрах
|
|||
|
она стабильна, на третьих полный хаос, и проще отказаться.
|
|||
|
|
|||
|
Blockcheck имеет 3 уровня сканирования.
|
|||
|
Цель режима quick - максимально быстро найти хоть что-то работающее.
|
|||
|
standard дает возможность провести исследование как и на что реагирует DPI в плане методов обхода.
|
|||
|
force дает максимум проверок даже в случаях, когда ресурс работает без обхода или с более простыми стратегиями.
|
|||
|
|
|||
|
СКАН ПОРТОВ
|
|||
|
Если в системе присутствует совместимый netcat (ncat от nmap или openbsd ncat. в openwrt по умолчанию нет.),
|
|||
|
то выполняется сканирование портов http или https всех IP адресов домена.
|
|||
|
Если ни один IP не отвечает, то результат очевиден. Можно останавливать сканирование.
|
|||
|
Автоматически оно не остановится, потому что netcat-ы недостаточно подробно информируют о причинах ошибки.
|
|||
|
Если доступна только часть IP, то можно ожидать хаотичных сбоев, т.к. подключение идет к случайному адресу
|
|||
|
из списка.
|
|||
|
|
|||
|
ПРОВЕРКА НА ЧАСТИЧНЫЙ IP block
|
|||
|
Под частичным блоком подразумевается ситуация, когда коннект на порты есть, но по определенному транспортному
|
|||
|
или прикладному протоколу всегда идет реакция DPI вне зависимости от запрашиваемого домена.
|
|||
|
Эта проверка так же не выдаст автоматического вердикта/решения, потому что может быть очень много вариаций.
|
|||
|
Вместо этого анализ происходящего возложен на самого пользователя или тех, кто будет читать лог.
|
|||
|
Суть этой проверки в попытке дернуть неблокированный IP с блокированным доменом и наоборот, анализируя
|
|||
|
при этом реакцию DPI. Реакция DPI обычно проявляется в виде таймаута (зависание запроса), connection reset
|
|||
|
или http redirect на заглушку. Любой другой вариант скорее всего говорит об отсутствии реакции DPI.
|
|||
|
В частности, любые http коды, кроме редиректа, ведущего именно на заглушку, а не куда-то еще.
|
|||
|
На TLS - ошибки handshake без задержек.
|
|||
|
Ошибка сертификата может говорить как о реакции DPI с MiTM атакой (подмена сертификата), так и
|
|||
|
о том, что принимающий сервер неблокированного домена все равно принимает ваш TLS handshake с чужим доменом,
|
|||
|
пытаясь при этом выдать сертификат без запрошенного домена. Требуется дополнительный анализ.
|
|||
|
Если на заблокированный домен есть реакция на всех IP адресах, значит есть блокировка по домену.
|
|||
|
Если на неблокированный домен есть реакция на IP адресах блокированного домена, значит имеет место блок по IP.
|
|||
|
Соответственно, если есть и то, и другое, значит есть и блок по IP, и блок по домену.
|
|||
|
Неблокированный домен первым делом проверяется на доступность на оригинальном адресе.
|
|||
|
При недоступности тест отменяется, поскольку он будет неинформативен.
|
|||
|
|
|||
|
Если выяснено, что есть частичный блок по IP на DPI, то скорее всего все остальные тесты будут провалены
|
|||
|
вне зависимости от стратегий обхода. Но бывают и некоторые исключения. Например, пробитие через ipv6
|
|||
|
option headers. Или сделать так, чтобы он не мог распознать протокол прикладного уровня.
|
|||
|
Дальнейшие тесты могут быть не лишены смысла.
|
|||
|
|
|||
|
ПРИМЕРЫ БЛОКИРОВКИ ТОЛЬКО ПО ДОМЕНУ БЕЗ БЛОКА ПО IP
|
|||
|
|
|||
|
> testing iana.org on it's original ip
|
|||
|
!!!!! AVAILABLE !!!!!
|
|||
|
> testing rutracker.org on 192.0.43.8 (iana.org)
|
|||
|
curl: (28) Operation timed out after 1002 milliseconds with 0 bytes received
|
|||
|
> testing iana.org on 172.67.182.196 (rutracker.org)
|
|||
|
HTTP/1.1 409 Conflict
|
|||
|
> testing iana.org on 104.21.32.39 (rutracker.org)
|
|||
|
HTTP/1.1 409 Conflict
|
|||
|
|
|||
|
> testing iana.org on it's original ip
|
|||
|
!!!!! AVAILABLE !!!!!
|
|||
|
> testing rutracker.org on 192.0.43.8 (iana.org)
|
|||
|
curl: (28) Connection timed out after 1001 milliseconds
|
|||
|
> testing iana.org on 172.67.182.196 (rutracker.org)
|
|||
|
curl: (35) OpenSSL/3.2.1: error:0A000410:SSL routines::ssl/tls alert handshake failure
|
|||
|
> testing iana.org on 104.21.32.39 (rutracker.org)
|
|||
|
curl: (35) OpenSSL/3.2.1: error:0A000410:SSL routines::ssl/tls alert handshake failure
|
|||
|
|
|||
|
> testing iana.org on it's original ip
|
|||
|
!!!!! AVAILABLE !!!!!
|
|||
|
> testing rutracker.org on 192.0.43.8 (iana.org)
|
|||
|
HTTP/1.1 307 Temporary Redirect
|
|||
|
Location: https://www.gblnet.net/blocked.php
|
|||
|
> testing iana.org on 172.67.182.196 (rutracker.org)
|
|||
|
HTTP/1.1 409 Conflict
|
|||
|
> testing iana.org on 104.21.32.39 (rutracker.org)
|
|||
|
HTTP/1.1 409 Conflict
|
|||
|
|
|||
|
> testing iana.org on it's original ip
|
|||
|
!!!!! AVAILABLE !!!!!
|
|||
|
> testing rutracker.org on 192.0.43.8 (iana.org)
|
|||
|
curl: (35) Recv failure: Connection reset by peer
|
|||
|
> testing iana.org on 172.67.182.196 (rutracker.org)
|
|||
|
curl: (35) OpenSSL/3.2.1: error:0A000410:SSL routines::ssl/tls alert handshake failure
|
|||
|
> testing iana.org on 104.21.32.39 (rutracker.org)
|
|||
|
curl: (35) OpenSSL/3.2.1: error:0A000410:SSL routines::ssl/tls alert handshake failure
|
|||
|
|
|||
|
|
|||
|
ПРИМЕР ПОЛНОГО IP БЛОКА ИЛИ БЛОКА TCP ПОРТА ПРИ ОТСУТСТВИИ БЛОКА ПО ДОМЕНУ
|
|||
|
|
|||
|
* port block tests ipv4 startmail.com:80
|
|||
|
ncat -z -w 1 145.131.90.136 80
|
|||
|
145.131.90.136 does not connect. netcat code 1
|
|||
|
ncat -z -w 1 145.131.90.152 80
|
|||
|
145.131.90.152 does not connect. netcat code 1
|
|||
|
|
|||
|
* curl_test_http ipv4 startmail.com
|
|||
|
- checking without DPI bypass
|
|||
|
curl: (28) Connection timed out after 2002 milliseconds
|
|||
|
UNAVAILABLE code=28
|
|||
|
|
|||
|
- IP block tests (requires manual interpretation)
|
|||
|
> testing iana.org on it's original ip
|
|||
|
!!!!! AVAILABLE !!!!!
|
|||
|
> testing startmail.com on 192.0.43.8 (iana.org)
|
|||
|
HTTP/1.1 302 Found
|
|||
|
Location: https://www.iana.org/
|
|||
|
> testing iana.org on 145.131.90.136 (startmail.com)
|
|||
|
curl: (28) Connection timed out after 2002 milliseconds
|
|||
|
> testing iana.org on 145.131.90.152 (startmail.com)
|
|||
|
curl: (28) Connection timed out after 2002 milliseconds
|
|||
|
|
|||
|
|
|||
|
Выбор параметров
|
|||
|
----------------
|
|||
|
|
|||
|
Файл /opt/zapret/config используется различными компонентами системы и содержит основные настройки.
|
|||
|
Его нужно просмотреть и при необходимости отредактировать.
|
|||
|
|
|||
|
На linux системах можно выбрать использовать iptables или nftables.
|
|||
|
По умолчанию на традиционных linux выбирается nftables, если установлен nft.
|
|||
|
На openwrt по умолчанию выбирается nftables на новых версиях с firewall4.
|
|||
|
|
|||
|
FWTYPE=iptables
|
|||
|
|
|||
|
Основной режим :
|
|||
|
tpws - tpws в режиме transparent
|
|||
|
tpws-socks - tpws в режиме socks
|
|||
|
вешается на localhost и LAN интерфейс (если задан IFACE_LAN или если система - OpenWRT). порт 988
|
|||
|
nfqws - nfqws
|
|||
|
filter - только заполнить ipset или загрузить hostlist
|
|||
|
custom - нужно самому запрограммировать запуск демонов в init скрипте и правила iptables
|
|||
|
|
|||
|
MODE=tpws
|
|||
|
|
|||
|
Применять ли дурение к HTTP :
|
|||
|
|
|||
|
MODE_HTTP=1
|
|||
|
|
|||
|
Применять ли дурение к последовательным http запросам в одном tcp соединении (http keeaplive).
|
|||
|
Относится только к nfqws. Выключение данной функции способно сэкономить загрузку процессора.
|
|||
|
tpws всегда работает с http keepalive
|
|||
|
|
|||
|
MODE_HTTP_KEEPALIVE=0
|
|||
|
|
|||
|
Применять ли дурение к HTTPS :
|
|||
|
|
|||
|
MODE_HTTPS=1
|
|||
|
|
|||
|
Применять ли дурение к QUIC :
|
|||
|
|
|||
|
MODE_QUIC=0
|
|||
|
|
|||
|
Режим фильтрации хостов :
|
|||
|
none - применять дурение ко всем хостам
|
|||
|
ipset - ограничить дурение ipset-ом zapret/zapret6
|
|||
|
hostlist - ограничить дурение списком хостов из файла
|
|||
|
autohostlist - режим hostlist + распознавание блокировок и ведения автоматического листа
|
|||
|
|
|||
|
MODE_FILTER=none
|
|||
|
|
|||
|
Опции tpws :
|
|||
|
|
|||
|
TPWS_OPT="--hostspell=HOST --split-http-req=method --split-pos=3"
|
|||
|
|
|||
|
Дополнительный низкоприоритетный профиль десинхронизации для режимов с MODE_FILTER=hostlist.
|
|||
|
После реализации поддержки множественных профилей режимы нулевой фазы десинхронизации больше не применяются с хостлистом !
|
|||
|
Для их применения требуется дополнительный профиль без хостлист фильтра.
|
|||
|
|
|||
|
#TPWS_OPT_SUFFIX="--mss 88"
|
|||
|
|
|||
|
Опции nfqws для атаки десинхронизации DPI :
|
|||
|
|
|||
|
DESYNC_MARK=0x40000000
|
|||
|
DESYNC_MARK_POSTNAT=0x20000000
|
|||
|
NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
|||
|
|
|||
|
Задание раздельных опций nfqws для http и https и для версий ip протоколов 4,6 :
|
|||
|
|
|||
|
NFQWS_OPT_DESYNC_HTTP="--dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
|||
|
NFQWS_OPT_DESYNC_HTTPS="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
|||
|
NFQWS_OPT_DESYNC_HTTP6="--dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none"
|
|||
|
NFQWS_OPT_DESYNC_HTTPS6="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none"
|
|||
|
|
|||
|
Если какая-то из переменных NFQWS_OPT_DESYNC_HTTP/NFQWS_OPT_DESYNC_HTTPS не определена,
|
|||
|
берется значение NFQWS_OPT_DESYNC.
|
|||
|
Если какая-то из переменных NFQWS_OPT_DESYNC_HTTP6/NFQWS_OPT_DESYNC_HTTPS6 не определена,
|
|||
|
берется значение NFQWS_OPT_DESYNC_HTTP/NFQWS_OPT_DESYNC_HTTPS.
|
|||
|
|
|||
|
Дополнительный низкоприоритетный профиль десинхронизации для режимов с MODE_FILTER=hostlist.
|
|||
|
После реализации поддержки множественных профилей режимы нулевой фазы десинхронизации больше не применяются с хостлистом !
|
|||
|
Для их применения требуется дополнительный профиль без хостлист фильтра.
|
|||
|
#NFQWS_OPT_DESYNC_SUFFIX="--dpi-desync=syndata"
|
|||
|
#NFQWS_OPT_DESYNC_HTTP_SUFFIX="--dpi-desync=syndata"
|
|||
|
#NFQWS_OPT_DESYNC_HTTPS_SUFFIX="--wssize 1:6"
|
|||
|
#NFQWS_OPT_DESYNC_HTTP6_SUFFIX="--dpi-desync=syndata"
|
|||
|
#NFQWS_OPT_DESYNC_HTTPS6_SUFFIX="--wssize 1:6"
|
|||
|
|
|||
|
Значения по умолчанию заполняются аналогично NFQWS_OPT_*.
|
|||
|
|
|||
|
Опции дурения для QUIC :
|
|||
|
NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake"
|
|||
|
NFQWS_OPT_DESYNC_QUIC6="--dpi-desync=hopbyhop"
|
|||
|
Если NFQWS_OPT_DESYNC_QUIC6 не задано, то берется NFQWS_OPT_DESYNC_QUIC.
|
|||
|
|
|||
|
Настройка системы управления выборочным traffic offload (только если поддерживается)
|
|||
|
donttouch : выборочное управление отключено, используется системная настройка, простой инсталлятор выключает системную настройку, если она не совместима с выбранным режимом
|
|||
|
none : выборочное управление отключено, простой инсталлятор выключает системную настройку
|
|||
|
software : выборочное управление включено в режиме software, простой инсталлятор выключает системную настройку
|
|||
|
hardware : выборочное управление включено в режиме hardware, простой инсталлятор выключает системную настройку
|
|||
|
|
|||
|
FLOWOFFLOAD=donttouch
|
|||
|
|
|||
|
Параметр GETLIST указывает инсталлятору install_easy.sh какой скрипт дергать
|
|||
|
для обновления списка заблокированных ip или хостов.
|
|||
|
Он же вызывается через get_config.sh из запланированных заданий (crontab или systemd timer).
|
|||
|
Поместите сюда название скрипта, который будете использовать для обновления листов.
|
|||
|
Если не нужно, то параметр следует закомментировать.
|
|||
|
|
|||
|
Можно индивидуально отключить ipv4 или ipv6. Если параметр закомментирован или не равен "1",
|
|||
|
использование протокола разрешено.
|
|||
|
#DISABLE_IPV4=1
|
|||
|
DISABLE_IPV6=1
|
|||
|
|
|||
|
Количество потоков для многопоточного DNS ресолвера mdig (1..100).
|
|||
|
Чем их больше, тем быстрее, но не обидится ли на долбежку ваш DNS сервер ?
|
|||
|
MDIG_THREADS=30
|
|||
|
|
|||
|
Место для хранения временных файлов. При скачивании огромных реестров в /tmp места может не хватить.
|
|||
|
Если файловая система на нормальном носителе (не встроенная память роутера), то можно
|
|||
|
указать место на флэшке или диске.
|
|||
|
TMPDIR=/opt/zapret/tmp
|
|||
|
|
|||
|
Опции для создания ipset-ов и nfset-ов
|
|||
|
|
|||
|
SET_MAXELEM=262144
|
|||
|
IPSET_OPT="hashsize 262144 maxelem 2097152"
|
|||
|
|
|||
|
Хук, позволяющий внести ip адреса динамически. $1 = имя таблицы
|
|||
|
Адреса выводятся в stdout. В случае nfset автоматически решается проблема возможного пересечения интервалов.
|
|||
|
IPSET_HOOK="/etc/zapret.ipset.hook"
|
|||
|
|
|||
|
ПРО РУГАНЬ в dmesg по поводу нехватки памяти.
|
|||
|
Может так случиться, что памяти в системе достаточно, но при попытке заполнить огромный ipset
|
|||
|
ядро начинает громко ругаться, ipset заполняется не полностью.
|
|||
|
Вероятная причина в том, что превышается hashsize, заданный при создании ipset (create_ipset.sh).
|
|||
|
Происходит переаллокация списка, не находится непрерывных фрагментов памяти нужной длины.
|
|||
|
Это лечится увеличением hashsize. Но чем больше hashsize, тем больше занимает ipset в памяти.
|
|||
|
Задавать слишком большой hashsize для недостаточно больших списков нецелесообразно.
|
|||
|
|
|||
|
Опции для вызова ip2net. Отдельно для листов ipv4 и ipv6.
|
|||
|
IP2NET_OPT4="--prefix-length=22-30 --v4-threshold=3/4"
|
|||
|
IP2NET_OPT6="--prefix-length=56-64 --v6-threshold=5"
|
|||
|
|
|||
|
Настройка режима autohostlist.
|
|||
|
AUTOHOSTLIST_RETRANS_THRESHOLD=3
|
|||
|
AUTOHOSTLIST_FAIL_THRESHOLD=2
|
|||
|
AUTOHOSTLIST_FAIL_TIME=60
|
|||
|
AUTOHOSTLIST_DEBUG=0
|
|||
|
|
|||
|
Включить или выключить сжатие больших листов в скриптах ipset/*.sh. По умолчанию включено.
|
|||
|
GZIP_LISTS=1
|
|||
|
|
|||
|
Команда для перезагрузки ip таблиц фаервола.
|
|||
|
Если не указано или пустое, выбирается автоматически ipset или ipfw при их наличии.
|
|||
|
На BSD системах с PF нет автоматической загрузки. Там нужно указать команду явно : pfctl -f /etc/pf.conf
|
|||
|
На более новых pfctl (есть в новых FreeBSD, нет в OpenBSD 6.8) можно дать команду загрузки только таблиц : pfctl -Tl -f /etc/pf.conf
|
|||
|
"-" означает отключение загрузки листов даже при наличии поддерживаемого backend.
|
|||
|
#LISTS_RELOAD="pfctl -f /etc/pf.conf"
|
|||
|
#LISTS_RELOAD=-
|
|||
|
|
|||
|
В openwrt существует сеть по умолчанию 'lan'. Только трафик с этой сети будет перенаправлен на tpws.
|
|||
|
Но возможно задать другие сети или список сетей :
|
|||
|
OPENWRT_LAN="lan lan2 lan3"
|
|||
|
|
|||
|
В openwrt в качестве wan берутся интерфейсы, имеющие default route. Отдельно для ipv4 и ipv6.
|
|||
|
Это можно переопределить :
|
|||
|
OPENWRT_WAN4="wan4 vpn"
|
|||
|
OPENWRT_WAN6="wan6 vpn6"
|
|||
|
|
|||
|
Параметр INIT_APPLY_FW=1 разрешает init скрипту самостоятельно применять правила iptables.
|
|||
|
При иных значениях или если параметр закомментирован, правила применены не будут.
|
|||
|
Это полезно, если у вас есть система управления фаерволом, в настройки которой и следует прикрутить правила.
|
|||
|
На openwrt неприменимо при использовании firewall3+iptables.
|
|||
|
|
|||
|
Следующие настройки не актуальны для openwrt :
|
|||
|
|
|||
|
Если ваша система работает как роутер, то нужно вписать названия внутренних и внешних интерфейсов :
|
|||
|
IFACE_LAN=eth0
|
|||
|
IFACE_WAN=eth1
|
|||
|
IFACE_WAN6="henet ipsec0"
|
|||
|
Несколько интерфейсов могут быть вписаны через пробел.
|
|||
|
Если IFACE_WAN6 не задан, то берется значение IFACE_WAN.
|
|||
|
|
|||
|
ВАЖНО : настройка маршрутизации, маскарада и т.д. не входит в задачу zapret.
|
|||
|
Включаются только режимы, обеспечивающие перехват транзитного трафика.
|
|||
|
Возможно определить несколько интерфейсов следующим образом : IFACE_LAN="eth0 eth1 eth2"
|
|||
|
|
|||
|
Прикручивание к системе управления фаерволом или своей системе запуска
|
|||
|
----------------------------------------------------------------------
|
|||
|
|
|||
|
Если вы используете какую-то систему управления фаерволом, то она может вступать в конфликт
|
|||
|
с имеющимся скриптом запуска. При повторном применении правил она могла бы поломать настройки iptables от zapret.
|
|||
|
В этом случае правила для iptables должны быть прикручены к вашему фаерволу отдельно от запуска tpws или nfqws.
|
|||
|
|
|||
|
Следующие вызовы позволяют применить или убрать правила iptables отдельно :
|
|||
|
|
|||
|
/opt/zapret/init.d/sysv/zapret start_fw
|
|||
|
/opt/zapret/init.d/sysv/zapret stop_fw
|
|||
|
/opt/zapret/init.d/sysv/zapret restart_fw
|
|||
|
|
|||
|
А так можно запустить или остановить демоны отдельно от фаервола :
|
|||
|
|
|||
|
/opt/zapret/init.d/sysv/zapret start_daemons
|
|||
|
/opt/zapret/init.d/sysv/zapret stop_daemons
|
|||
|
/opt/zapret/init.d/sysv/zapret restart_daemons
|
|||
|
|
|||
|
nftables сводят практически на нет конфликты между разными системами управления, поскольку позволяют
|
|||
|
использовать независимые таблицы и хуки. Используется отдельная nf-таблица "zapret".
|
|||
|
Если ваша система ее не будет трогать, скорее всего все будет нормально.
|
|||
|
|
|||
|
Для nftables предусмотрено несколько дополнительных вызовов :
|
|||
|
|
|||
|
Посмотреть set-ы интерфейсов, относящихся к lan, wan и wan6. По ним идет завертывание трафика.
|
|||
|
А так же таблицу flow table с именами интерфейсов ingress hook.
|
|||
|
/opt/zapret/init.d/sysv/zapret list_ifsets
|
|||
|
|
|||
|
Обновить set-ы интерфейсов, относящихся к lan, wan и wan6.
|
|||
|
Для традиционных linux список интерфейсов берется из переменных конфига IFACE_LAN, IFACE_WAN.
|
|||
|
Для openwrt определяется автоматически. Множество lanif может быть расширено параметром OPENWRT_LAN.
|
|||
|
Все интерфейсы lan и wan так же добавляются в ingress hook от flow table.
|
|||
|
/opt/zapret/init.d/sysv/zapret reload_ifsets
|
|||
|
|
|||
|
Просмотр таблицы без содержимого set-ов. Вызывает nft -t list table inet zapret
|
|||
|
/opt/zapret/init.d/sysv/zapret list_table
|
|||
|
|
|||
|
Так же возможно прицепиться своим скриптом к любой стадии применения и снятия фаервола со стороны zapret скриптов :
|
|||
|
|
|||
|
INIT_FW_PRE_UP_HOOK="/etc/firewall.zapret.hook.pre_up"
|
|||
|
INIT_FW_POST_UP_HOOK="/etc/firewall.zapret.hook.post_up"
|
|||
|
INIT_FW_PRE_DOWN_HOOK="/etc/firewall.zapret.hook.pre_down"
|
|||
|
INIT_FW_POST_DOWN_HOOK="/etc/firewall.zapret.hook.post_down"
|
|||
|
|
|||
|
Эти настройки доступны в config.
|
|||
|
Может быть полезно, если вам нужно использовать nftables set-ы, например ipban/ipban6.
|
|||
|
nfset-ы принадлежат только одной таблице, следовательно вам придется писать правила для таблицы zapret,
|
|||
|
а значит нужно синхронизироваться с применением/снятием правил со стороны zapret скриптов.
|
|||
|
|
|||
|
|
|||
|
Вариант custom
|
|||
|
--------------
|
|||
|
|
|||
|
custom код вынесен в отдельные shell includes.
|
|||
|
Поддерживается старый вариант в
|
|||
|
/opt/zapret/init.d/sysv/custom
|
|||
|
/opt/zapret/init.d/openwrt/custom
|
|||
|
/opt/zapret/init.d/macos/custom
|
|||
|
Он считается устаревшим. Актуальный вариант - помещать отдельные скрипты там же, но в директорию "custom.d".
|
|||
|
Она будет просканирована стандартным образом, т.е. в алфавитном порядке, и каждый скрипт будет применен.
|
|||
|
Рядом имеется "custom.d.examples". Это готовые скрипты, который можно копировать в "custom.d".
|
|||
|
Особо стоит отметить "10-inherit-*". Они наследуют стандартные режимы nfqws/tpws/tpws-socks.
|
|||
|
Полезно, чтобы не писать код заново. Достаточно лишь скопировать соответствующий файл.
|
|||
|
|
|||
|
Для linux пишется код в функции
|
|||
|
zapret_custom_daemons
|
|||
|
zapret_custom_firewall
|
|||
|
zapret_custom_firewall_nft
|
|||
|
|
|||
|
Для macos
|
|||
|
zapret_custom_daemons
|
|||
|
zapret_custom_firewall_v4
|
|||
|
zapret_custom_firewall_v6
|
|||
|
|
|||
|
zapret_custom_daemons поднимает демоны nfqws/tpws в нужном вам количестве и с нужными вам параметрами.
|
|||
|
Особо обратите внимание на номер демона в функциях "run_daemon" и "do_daemon".
|
|||
|
Они должны быть уникальными во всех скриптах. При накладке будет ошибка.
|
|||
|
Так же следует избегать пересечения номеров портов tpws и очередей nfqws.
|
|||
|
При пересечении какой-то из демонов не запустится.
|
|||
|
Чтобы как-то нивелировать эту проблему, в examples используется переменная DNUM.
|
|||
|
На ее базе считается диапазон номеров очередей (5 шт), которые использует этот скрипт.
|
|||
|
При таком подходе достаточно, чтобы DNUM был везде уникален.
|
|||
|
Поскольку номера очереди и портов имеют нумерацию до 65536, можно использовать DNUM до 13106.
|
|||
|
Однако, следует оставить номера очереди 200-299 для стандартных режимов и не использовать их.
|
|||
|
|
|||
|
custom скрипты могут использовать переменные из config. Можно помещать в config свои переменные
|
|||
|
и использовать их в скриптах.
|
|||
|
Можно использовать функции-хелперы. Они являются частью общего пространства функций shell.
|
|||
|
Полезные функции можно взять из примеров скриптов. Так же смотрите "common/*.sh".
|
|||
|
Используя хелпер функции, вы избавитесь от необходимости учитывать все возможные случаи
|
|||
|
типа наличия/отсутствия ipv6, является ли система роутером, имена интерфейсов, ...
|
|||
|
Хелперы это учитывают, вам нужно сосредоточиться лишь на фильтрах {ip,nf}tables и
|
|||
|
параметрах демонов.
|
|||
|
|
|||
|
Код для openwrt и sysv немного отличается. В sysv нужно обрабатывать и запуск, и остановку демонов.
|
|||
|
Запуск это или остановка передается в параметре $1 (0 или 1).
|
|||
|
В openwrt за остановку отвечает procd.
|
|||
|
|
|||
|
Для фаервола в linux кастом пишется отдельно для iptables и nftables. Все очень похоже, но отличается
|
|||
|
написание фильтров и названия процедур хелперов. Если вам не нужны iptables или nftables -
|
|||
|
можете не писать соответствующую функцию.
|
|||
|
|
|||
|
В macos firewall-функции ничего сами никуда не заносят. Их задача - лишь выдать текст в stdout,
|
|||
|
содержащий правила для pf-якоря. Остальное сделает обертка.
|
|||
|
|
|||
|
|
|||
|
Простая установка
|
|||
|
-----------------
|
|||
|
|
|||
|
install_easy.sh автоматизирует ручные варианты процедур установки (см manual_setup.txt).
|
|||
|
Он поддерживает OpenWRT, linux системы на базе systemd или openrc и MacOS.
|
|||
|
|
|||
|
Для более гибкой настройки перед запуском инсталлятора следует выполнить раздел "Выбор параметров".
|
|||
|
|
|||
|
Если система запуска поддерживается, но используется не поддерживаемый инсталлятором менеджер пакетов
|
|||
|
или названия пакетов не соответствуют прописанным в инсталлятор, пакеты нужно установить вручную.
|
|||
|
Всегда требуется curl. ipset - только для режима iptables, для nftables - не нужен.
|
|||
|
|
|||
|
Для совсем обрезанных дистрибутивов (alpine) требуется отдельно установить iptables и ip6tables, либо nftables.
|
|||
|
|
|||
|
В комплекте идут статические бинарники для большинства архитектур. Какой-то из них подойдет
|
|||
|
с вероятностью 99%. Но если у вас экзотическая система, инсталлятор попробует собрать бинарники сам
|
|||
|
через make. Для этого нужны gcc, make и необходимые -dev пакеты. Можно форсировать режим
|
|||
|
компиляции следующим вызовом :
|
|||
|
|
|||
|
install_easy.sh make
|
|||
|
|
|||
|
Под openwrt все уже сразу готово для использования системы в качестве роутера.
|
|||
|
Имена интерфейсов WAN и LAN известны из настроек системы.
|
|||
|
Под другими системами роутер вы настраиваете самостоятельно. инсталлятор в это не вмешивается.
|
|||
|
инсталлятор в зависимости от выбранного режима может спросить LAN и WAN интерфейсы.
|
|||
|
Нужно понимать, что заворот проходящего трафика на tpws в прозрачном режиме происходит до выполнения маршрутизации,
|
|||
|
следовательно возможна фильтрация по LAN и невозможна по WAN.
|
|||
|
Решение о завороте на tpws локального исходящего трафика принимается после выполнения маршрутизации,
|
|||
|
следовательно ситуация обратная : LAN не имеет смысла, фильтрация по WAN возможна.
|
|||
|
Заворот на nfqws происходит всегда после маршрутизации, поэтому к нему применима только фильтрация по WAN.
|
|||
|
Возможность прохождения трафика в том или ином направлении настраивается вами в процессе конфигурации роутера.
|
|||
|
|
|||
|
Деинсталляция выполняется через uninstall_easy.sh
|
|||
|
|
|||
|
|
|||
|
Простая установка на openwrt
|
|||
|
----------------------------
|
|||
|
|
|||
|
Работает только если у вас на роутере достаточно места.
|
|||
|
|
|||
|
Копируем zapret на роутер в /tmp.
|
|||
|
|
|||
|
Запускаем установщик :
|
|||
|
sh /tmp/zapret/install_easy.sh
|
|||
|
Он скопирует в /opt/zapret только необходимый минимум файлов.
|
|||
|
|
|||
|
После успешной установки можно удалить zapret из tmp для освобождения RAM :
|
|||
|
rm -r /tmp/zapret
|
|||
|
|
|||
|
Для более гибкой настройки перед запуском инсталлятора следует выполнить раздел "Выбор параметров".
|
|||
|
|
|||
|
Система простой инсталяции заточена на любое умышленное или неумышленное изменение прав доступа на файлы.
|
|||
|
Устойчива к репаку под windows. После копирования в /opt права будут принудительно восстановлены.
|
|||
|
|
|||
|
Android
|
|||
|
-------
|
|||
|
|
|||
|
Без рута забудьте про nfqws и tpws в режиме transparent proxy. tpws будет работать только в режиме --socks.
|
|||
|
|
|||
|
Ядра Android имеют поддержку NFQUEUE. nfqws работает.
|
|||
|
|
|||
|
В стоковых ядрах нет поддержки ipset. В общем случае сложность задачи по поднятию ipset варьируется от
|
|||
|
"не просто" до "почти невозможно". Если только вы не найдете готовое собранное ядро под ваш девайс.
|
|||
|
|
|||
|
tpws будет работать в любом случае, он не требует чего-либо особенного.
|
|||
|
В android нет /etc/passwd, потому опция --user не будет работать. Вместо нее можно
|
|||
|
пользоваться числовыми user id и опцией --uid.
|
|||
|
Рекомендую использовать gid 3003 (AID_INET). Иначе можете получить permission denied на создание сокета.
|
|||
|
Например : --uid 1:3003
|
|||
|
В iptables укажите : "! --uid-owner 1" вместо "! --uid-owner tpws".
|
|||
|
Напишите шелл скрипт с iptables и tpws, запускайте его средствами вашего рут менеджера.
|
|||
|
Скрипты автозапуска лежат тут :
|
|||
|
magisk : /data/adb/service.d
|
|||
|
supersu : /system/su.d
|
|||
|
|
|||
|
nfqws может иметь такой глюк. При запуске с uid по умолчанию (0x7FFFFFFF) при условии работы на сотовом интерфейсе
|
|||
|
и отключенном кабеле внешнего питания система может частично виснуть. Перестает работать тач и кнопки,
|
|||
|
но анимация на экране может продолжаться. Если экран был погашен, то включить его кнопкой power невозможно.
|
|||
|
Это, видимо, связано с переводом в suspend процессов с определенным UID. UID соответствует приложению или
|
|||
|
системному сервису. По UID android определяет политику power saving.
|
|||
|
Так же возможно, что глюк связан с кривым драйвером сотового интерфейса от китайцев, поскольку при использовании
|
|||
|
wifi такого не наблюдается. suspend обработчика nfqueue на обычном linux не вызывает подобных фатальных последствий.
|
|||
|
Изменение UID на низкий (--uid 1 подойдет) позволяет решить эту проблему.
|
|||
|
Глюк был замечен на android 8.1 на девайсе, основанном на платформе mediatek.
|
|||
|
|
|||
|
Ответ на вопрос куда поместить tpws на android без рута, чтобы потом его запускать из приложений.
|
|||
|
Файл заливаем через adb shell в /data/local/tmp/, лучше всего в субфолдер.
|
|||
|
mkdir /data/local/tmp/zapret
|
|||
|
adb push tpws /data/local/tmp/zapret
|
|||
|
chmod 755 /data/local/tmp/zapret /data/local/tmp/zapret/tpws
|
|||
|
chcon u:object_r:system_file:s0 /data/local/tmp/zapret/tpws
|
|||
|
|
|||
|
Как найти стратегию обхода сотового оператора : проще всего раздать инет на комп с linux.
|
|||
|
Можно записать live image linux на флэшку и загрузиться с нее или запустить виртуалку с linux
|
|||
|
и пробросить в нее usb устройство от режима модема с телефона.
|
|||
|
На компе с linux прогнать стандартную процедуру blockcheck. При переносе правил на телефон уменьшить TTL на 1,
|
|||
|
если правила с TTL присутствуют в стратегии.
|
|||
|
Можно развернуть rootfs какого-нибудь дистрибутива linux прямо на телефоне, имея рута.
|
|||
|
Это лучше всего делать с компа через adb shell.
|
|||
|
Если компа нет, то это единственный вариант, хотя и неудобный.
|
|||
|
Подойдет что-то легковесное, например, alpine или даже openwrt.
|
|||
|
Если это не эмулятор android, то универсальная архитектура - arm (любой вариант).
|
|||
|
Если вы точно знаете, что ОС у вас 64-разрядная, то лучше вместо arm - aarch64.
|
|||
|
|
|||
|
mount --bind /dev /data/linux/dev
|
|||
|
mount --bind /proc /data/linux/proc
|
|||
|
mount --bind /sys /data/linux/sys
|
|||
|
chroot /data/linux
|
|||
|
|
|||
|
Первым делом вам нужно будет один раз настроить DNS. Сам он не заведется.
|
|||
|
|
|||
|
echo nameserver 1.1.1.1 >/etc/resolv.conf
|
|||
|
|
|||
|
Далее нужно средствами пакетного менеджера установить iptables-legacy. Обязательно НЕ iptables-nft,
|
|||
|
который как правило присутствует по умолчанию. В ядре android нет nftables.
|
|||
|
ls -la $(which iptables)
|
|||
|
Линк должен указывать на legacy вариант.
|
|||
|
Если нет, значит устанавливайте нужные пакеты вашего дистрибутива, и убеждайтесь в правильности ссылок.
|
|||
|
iptables -S
|
|||
|
Так можно проверить, что ваш iptables увидел то, что туда насовал android. iptables-nft выдаст ошибку.
|
|||
|
Далее качаем zapret в /opt/zapret. Обычные действия с install_prereq.sh, install_bin.sh, blockcheck.sh.
|
|||
|
|
|||
|
Учтите, что стратегии обхода сотового оператора и домашнего wifi вероятно будут разные.
|
|||
|
Выделить сотового оператора легко через параметр iptables -o <имя интерфейса>. Имя может быть, например, ccmni0.
|
|||
|
Его легко увидеть через ifconfig.
|
|||
|
Wifi сеть - обычно wlan0.
|
|||
|
|
|||
|
Переключать blockcheck между оператором и wifi можно вместе со всем инетом - включив или выключив wifi.
|
|||
|
Если найдете стратегию для wifi и впишите ее в автостарт, то при подключении к другому wifi
|
|||
|
она может не сработать или вовсе что-то поломать, потому подумайте стоит ли.
|
|||
|
Может быть лучше сделать скрипты типа "запустить обход домашнего wifi", "снять обход домашнего wifi",
|
|||
|
и пользоваться ими по необходимости из терминала.
|
|||
|
Но домашний wifi лучше все-же обходить на роутере.
|
|||
|
|
|||
|
|
|||
|
Мобильные модемы и роутеры huawei
|
|||
|
---------------------------------
|
|||
|
|
|||
|
Устройства типа E3372, E8372, E5770 разделяют общую идеологию построения системы.
|
|||
|
Имеются 2 вычислительных ядра. Одно ядро выполняет vxworks, другое - linux.
|
|||
|
На 4pda имеются модифицированные прошивки с telnet и adb. Их и нужно использовать.
|
|||
|
|
|||
|
Дальнейшие утверждения проверены на E8372. На других может быть аналогично или похоже.
|
|||
|
Присутствуют дополнительные аппаратные блоки для offload-а сетевых функций.
|
|||
|
Не весь трафик идет через linux. Исходящий трафик с самого модема проходит
|
|||
|
цепочку OUTPUT нормально, на FORWARD =>wan часть пакетов выпадает из tcpdump.
|
|||
|
|
|||
|
tpws работает обычным образом.
|
|||
|
|
|||
|
nfqueue поломан. можно собрать фиксящий модуль https://github.com/im-0/unfuck-nfqueue-on-e3372h,
|
|||
|
используя исходники с huawei open source. Исходники содержат тулчейн и полусобирающееся,
|
|||
|
неактуальное ядро. Конфиг можно взять с рабочего модема из /proc/config.gz.
|
|||
|
С помощью этих исходников умельцы могут собрать модуль unfuck_nfqueue.ko.
|
|||
|
После его применения NFQUEUE и nfqws для arm работают нормально.
|
|||
|
|
|||
|
Чтобы избежать проблемы с offload-ом при использовании nfqws, следует комбинировать tpws в режиме tcp proxy и nfqws.
|
|||
|
Правила NFQUEUE пишутся для цепочки OUTPUT.
|
|||
|
connbytes придется опускать, поскольку модуля в ядре нет. Но это не смертельно.
|
|||
|
|
|||
|
Скрипт автозапуска - /system/etc/autorun.sh. Создайте свой скрипт настройки zapret,
|
|||
|
запускайте из конца autorun.sh через "&". Скрипт должен в начале делать sleep 5, чтобы дождаться
|
|||
|
поднятия сети и iptables от huawei.
|
|||
|
|
|||
|
ПРЕДУПРЕЖДЕНИЕ.
|
|||
|
На этом модеме происходят хаотические сбросы соединений tcp по непонятным причинам.
|
|||
|
Выглядит это так, если запускать curl с самого модема :
|
|||
|
curl www.ru
|
|||
|
curl: (7) Failed to connect to www.ru port 80: Host is unreachable
|
|||
|
Возникает ошибка сокета EHOSTUNREACH (errno -113). То же самое видно в tpws.
|
|||
|
В броузере не подгружаются части веб страниц, картинки, стили.
|
|||
|
В tcpdump на внешнем интерфейсе eth_x виден только единственный и безответный SYN пакет, без сообщений ICMP.
|
|||
|
ОС каким-то образом узнает о невозможности установить TCP соединение и выдает ошибку.
|
|||
|
Если выполнять подключение с клиента, то SYN пропадают, соединение не устанавливается.
|
|||
|
ОС клиента проводит ретрансмиссию, и с какого-то раза подключение удается.
|
|||
|
Поэтому без tcp проксирования в этой ситуации сайты тупят, но загружаются, а с проксированием
|
|||
|
подключение выполняется, но вскоре сбрасывается без каких-либо данных, и броузеры не пытаются установить
|
|||
|
его заново. Поэтому качество броузинга с tpws может быть хуже, но дело не в tpws.
|
|||
|
Частота сбросов заметно возрастает, если запущен торент клиент, имеется много tcp соединений.
|
|||
|
Однако, причина не в переполнении таблицы conntrack. Увеличение лимитов и очистка conntrack не помогают.
|
|||
|
Предположительно эта особенность связана с обработкой пакетов сброса соединения в hardware offload.
|
|||
|
Точного ответа на вопрос у меня нет. Если вы знаете - поделитесь, пожалуйста.
|
|||
|
Чтобы не ухудшать качество броузинга, можно фильтровать заворот на tpws по ip фильтру.
|
|||
|
Поддержка ipset отсутствует. Значит, все, что можно сделать - создать индивидуальные правила
|
|||
|
на небольшое количество хостов.
|
|||
|
|
|||
|
Некоторые наброски скриптов присутствуют в files/huawei. Не готовое решение ! Смотрите, изучайте, приспосабливайте.
|
|||
|
Здесь можно скачать готовые полезные статические бинарники для arm, включая curl : https://github.com/bol-van/bins
|
|||
|
|
|||
|
|
|||
|
FreeBSD, OpenBSD, MacOS
|
|||
|
-----------------------
|
|||
|
|
|||
|
Описано в docs/bsd.txt
|
|||
|
|
|||
|
|
|||
|
Windows
|
|||
|
-------
|
|||
|
|
|||
|
Описано в docs/windows.txt
|
|||
|
|
|||
|
|
|||
|
Другие прошивки
|
|||
|
---------------
|
|||
|
|
|||
|
Для статических бинариков не имеет значения на чем они запущены : PC, android, приставка, роутер, любой другой девайс.
|
|||
|
Подойдет любая прошивка, дистрибутив linux. Статические бинарники запустятся на всем.
|
|||
|
Им нужно только ядро с необходимыми опциями сборки или модулями.
|
|||
|
Но кроме бинариков в проекте используются еще и скрипты, в которых задействуются некоторые
|
|||
|
стандартные программы.
|
|||
|
|
|||
|
Основные причины почему нельзя просто так взять и установить эту систему на что угодно :
|
|||
|
* отсутствие доступа к девайсу через shell
|
|||
|
* отсутствие рута
|
|||
|
* отсутствие раздела r/w для записи и энергонезависимого хранения файлов
|
|||
|
* отсутствие возможности поставить что-то в автозапуск
|
|||
|
* отсутствие cron
|
|||
|
* неотключаемый flow offload или другая проприетарщина в netfilter
|
|||
|
* недостаток модулей ядра или опций его сборки
|
|||
|
* недостаток модулей iptables (/usr/lib/iptables/lib*.so)
|
|||
|
* недостаток стандартных программ (типа ipset, curl) или их кастрированность (облегченная замена)
|
|||
|
* кастрированный или нестандартный шелл sh
|
|||
|
|
|||
|
Если в вашей прошивке есть все необходимое, то вы можете адаптировать zapret под ваш девайс в той или иной степени.
|
|||
|
Может быть у вас не получится поднять все части системы, однако вы можете хотя бы попытаться
|
|||
|
поднять tpws и завернуть на него через -j REDIRECT весь трафик на порт 80.
|
|||
|
Если вам есть куда записать tpws, есть возможность выполнять команды при старте, то как минимум
|
|||
|
это вы сделать сможете. Скорее всего поддержка REDIRECT в ядре есть. Она точно есть на любом роутере,
|
|||
|
на других устройствах под вопросом. NFQUEUE, ipset на большинстве прошивок отсутствуют из-за ненужности.
|
|||
|
|
|||
|
Пересобрать ядро или модули для него будет скорее всего достаточно трудно.
|
|||
|
Для этого вам необходимо будет по крайней мере получить исходники вашей прошивки.
|
|||
|
User mode компоненты могут быть привнесены относительно безболезненно, если есть место куда их записать.
|
|||
|
Специально для девайсов, имеющих область r/w, существует проект entware.
|
|||
|
Некоторые прошивки даже имеют возможность его облегченной установки через веб интерфейс.
|
|||
|
entware содержит репозиторий user-mode компонент, которые устанавливаются в /opt.
|
|||
|
С их помощью можно компенсировать недостаток ПО основной прошивки, за исключением ядра.
|
|||
|
|
|||
|
Можно попытаться использовать sysv init script таким образом, как это описано в разделе
|
|||
|
"Прикручивание к системе управления фаерволом или своей системе запуска".
|
|||
|
В случае ругани на отсутствие каких-то базовых программ, их следует восполнить посредством entware.
|
|||
|
Перед запуском скрипта путь к дополнительным программам должен быть помещен в PATH.
|
|||
|
|
|||
|
Подробное описание настроек для других прошивок выходит за рамки данного проекта.
|
|||
|
|
|||
|
Openwrt является одной из немногих относительно полноценных linux систем для embedded devices.
|
|||
|
Она характеризуется следующими вещами, которые и послужили основой выбора именно этой прошивки :
|
|||
|
* полный root доступ к девайсу через shell. на заводских прошивках чаще всего отсутствует, на многих альтернативных есть
|
|||
|
* корень r/w. это практически уникальная особенность openwrt. заводские и большинство альтернативных прошивок
|
|||
|
построены на базе squashfs root (r/o), а конфигурация хранится в специально отформатированной области
|
|||
|
встроенной памяти, называемой nvram. не имеющие r/w корня системы сильно кастрированы. они не имеют
|
|||
|
возможности доустановки ПО из репозитория без специальных вывертов и заточены в основном
|
|||
|
на чуть более продвинутого, чем обычно, пользователя и управление имеющимся функционалом через веб интерфейс,
|
|||
|
но функционал фиксированно ограничен. альтернативные прошивки как правило могут монтировать r/w раздел
|
|||
|
в какую-то область файловой системы, заводские обычно могут монтировать лишь флэшки, подключенные к USB,
|
|||
|
и не факт, что есть поддержка unix файловых системы. может быть поддержка только fat и ntfs.
|
|||
|
* возможность выноса корневой файловой системы на внешний носитель (extroot) или создания на нем оверлея (overlay)
|
|||
|
* наличие менеджера пакетов opkg и репозитория софта
|
|||
|
* flow offload предсказуемо, стандартно и выборочно управляем, а так же отключаем
|
|||
|
* в репозитории есть все модули ядра, их можно доустановить через opkg. ядро пересобирать не нужно.
|
|||
|
* в репозитории есть все модули iptables, их можно доустановить через opkg
|
|||
|
* в репозитории есть огромное количество стандартных программ и дополнительного софта
|
|||
|
* наличие SDK, позволяющего собрать недостающее
|
|||
|
|
|||
|
|
|||
|
Обход блокировки через сторонний хост
|
|||
|
-------------------------------------
|
|||
|
|
|||
|
Если не работает автономный обход, приходится перенаправлять трафик через сторонний хост.
|
|||
|
Предлагается использовать прозрачный редирект через socks5 посредством iptables+redsocks, либо iptables+iproute+vpn.
|
|||
|
Настройка варианта с redsocks на openwrt описана в redsocks.txt.
|
|||
|
Настройка варианта с iproute+wireguard - в wireguard_iproute_openwrt.txt.
|
|||
|
|
|||
|
|
|||
|
Почему стоит вложиться в покупку VPS
|
|||
|
------------------------------------
|
|||
|
|
|||
|
VPS - это виртуальный сервер. Существует огромное множество датацентров, предлагающих данную услугу.
|
|||
|
На VPS могут выполняться какие угодно задачи. От простого веб сайта до навороченной системы собственной разработки.
|
|||
|
Можно использовать VPS и для поднятия собственного vpn или прокси.
|
|||
|
Сама широта возможных способов применения, распространенность услуги сводят к минимуму возможности
|
|||
|
регуляторов по бану сервисов такого типа. Да, если введут белые списки, то решение загнется, но это будет уже другая
|
|||
|
реальность, в которой придется изобретать иные решения.
|
|||
|
Пока этого не сделали, никто не будет банить хостинги просто потому, что они предоставляют хостинг услуги.
|
|||
|
Вы как индивидуум скорее всего никому не нужны. Подумайте чем вы отличаетесь от известного VPN провайдера.
|
|||
|
VPN провайдер предоставляет _простую_ и _доступную_ услугу по обходу блокировок для масс.
|
|||
|
Этот факт делает его первоочередной целью блокировки. РКН направит уведомление, после отказа сотрудничать
|
|||
|
заблокирует VPN. Предоплаченная сумма пропадет.
|
|||
|
У регуляторов нет и никогда не будет ресурсов для тотальной проверки каждого сервера в сети.
|
|||
|
Возможен китайский расклад, при котором DPI выявляет vpn протоколы и динамически банит IP серверов,
|
|||
|
предоставляющих нелицензированный VPN. Но имея знания, голову, вы всегда можете обфусцировать
|
|||
|
vpn трафик или применить другие типы VPN, более устойчивые к анализу на DPI или просто менее широкоизвестные,
|
|||
|
а следовательно с меньшей вероятностью обнаруживаемые регулятором.
|
|||
|
У вас есть свобода делать на вашем VPS все что вы захотите, адаптируясь к новым условиям.
|
|||
|
Да, это потребует знаний. Вам выбирать учиться и держать ситуацию под контролем, когда вам ничего запретить
|
|||
|
не могут, или покориться системе.
|
|||
|
|
|||
|
VPS можно прибрести в множестве мест. Существуют специализированные на поиске предложений VPS порталы.
|
|||
|
Например, вот этот : https://vps.today/
|
|||
|
Для персонального VPN сервера обычно достаточно самой минимальной конфигурации, но с безлимитным трафиком или
|
|||
|
с большим лимитом по трафику (терабайты). Важен и тип VPS. Openvz подойдет для openvpn, но
|
|||
|
вы не поднимете на нем wireguard, ipsec, то есть все, что требует kernel mode.
|
|||
|
Для kernel mode требуется тип виртуализации, предполагающий запуск полноценного экземпляра ОС linux
|
|||
|
вместе с ядром. Подойдут kvm, xen, hyper-v, vmware.
|
|||
|
|
|||
|
По цене можно найти предложения, которые будут дешевле готовой VPN услуги, но при этом вы сам хозяин в своей лавке
|
|||
|
и не рискуете попасть под бан регулятора, разве что "заодно" под ковровую бомбардировку с баном миллионов IP.
|
|||
|
Кроме того, если вам совсем все кажется сложным, прочитанное вызывает ступор, и вы точно знаете, что ничего
|
|||
|
из описанного сделать не сможете, то вы сможете хотя бы использовать динамическое перенаправление портов ssh
|
|||
|
для получения шифрованного socks proxy и прописать его в броузер. Знания linux не нужны совсем.
|
|||
|
Это вариант наименее напряжный для чайников, хотя и не самый удобный в использовании.
|