mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-27 12:40:53 +03:00
1893 lines
192 KiB
Plaintext
1893 lines
192 KiB
Plaintext
zapret v.62
|
||
|
||
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. позволяет разобраться почему там появляются хосты.
|
||
|
||
|
||
--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 может узнать имя хоста
|
||
еще на этапе установления соединения.
|
||
Невозможен фильтр по версии TLS.
|
||
Взамен имеется фильтр по портам --mss-pf. --mss-pf=443 применяет дурение только к https.
|
||
Применяя данную опцию к сайтам TLS1.3, если броузер тоже поддерживает TLS1.3, то вы делаете только хуже.
|
||
Но нет способа автоматически узнать когда надо применять, когда нет, поскольку MSS идет только в
|
||
3-way handshake еще до обмена данными, а версию TLS можно узнать только по ответу сервера, который
|
||
может привести к реакции DPI.
|
||
Использовать только когда нет ничего лучше или для отдельных ресурсов.
|
||
Работает только на 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.
|
||
|
||
Способы получения списка заблокированных 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"
|
||
|
||
Опции 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 include
|
||
/opt/zapret/init.d/sysv/custom
|
||
или
|
||
/opt/zapret/init.d/openwrt/custom
|
||
|
||
Нужно свой код вписать в функции :
|
||
zapret_custom_daemons
|
||
zapret_custom_firewall
|
||
zapret_custom_firewall_nft
|
||
|
||
В файле custom пишите ваш код, пользуясь хелперами из "functions" или "zapret".
|
||
Смотрите как там сделано добавление iptables или запуск демонов.
|
||
Используя хелпер функции, вы избавитесь от необходимости учитывать все возможные случаи
|
||
типа наличия/отсутствия ipv6, является ли система роутером, имена интерфейсов, ...
|
||
Хелперы это учитывают, вам нужно сосредоточиться лишь на фильтрах {ip,nf}tables и
|
||
параметрах демонов.
|
||
|
||
Код для openwrt и sysv немного отличается. В sysv нужно обрабатывать и запуск, и остановку демонов.
|
||
Запуск это или остановка передается в параметре $1 (0 или 1).
|
||
В openwrt за остановку отвечает procd.
|
||
|
||
Для фаервола кастом пишется отдельно для iptables и nftables. Все очень похоже, но отличается
|
||
написание фильтров и названия процедур хелперов. Если вам не нужны iptables или nftables -
|
||
можете не писать соответствующую функцию.
|
||
|
||
Готовый custom скрипт custom-tpws4http-nfqws4https позволяет применить дурение
|
||
tpws к http и nfqws к https. При этом поддерживаются установки из config.
|
||
Его можно использовать как стартовую точку для написания своих скриптов.
|
||
|
||
|
||
Простая установка
|
||
-----------------
|
||
|
||
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 не нужны совсем.
|
||
Это вариант наименее напряжный для чайников, хотя и не самый удобный в использовании.
|