mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-11 17:29:16 +05:00
1429 lines
128 KiB
Plaintext
1429 lines
128 KiB
Plaintext
zapret v.39
|
||
|
||
English
|
||
-------
|
||
|
||
For english version refer to docs/readme.eng.txt
|
||
|
||
Для чего это надо
|
||
-----------------
|
||
|
||
Автономное, без задействования сторонних серверов, средство противодействия DPI.
|
||
Может помочь обойти блокировки или замедление сайтов http(s), сигнатурный анализ tcp протоколов,
|
||
например с целью блокировки VPN.
|
||
|
||
Проект нацелен прежде всего на маломощные embedded устройства - роутеры, работающие под openwrt.
|
||
Поддерживаются традиционные Linux системы, FreeBSD, OpenBSD, частично MacOS.
|
||
В некоторых случаях возможна самостоятельная прикрутка решения к различным прошивкам.
|
||
|
||
|
||
Как это работает
|
||
----------------
|
||
|
||
В самом простейшем случае вы имеете дело с пассивным 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
|
||
|
||
Как это реализовать на практике в системе linux
|
||
-----------------------------------------------
|
||
|
||
Если кратко, то варианты можно классифицировать по следующей схеме :
|
||
|
||
1) Пассивный DPI, не отправляющий RST серверу. Помогут индивидуально настраиваемые под провайдера команды iptables.
|
||
На rutracker в разделе "обход блокировок - другие способы" по этому вопросу существует отдельная тема.
|
||
В данном проекте не рассматривается. Если вы не допустите срабатывание триггера запрета, то и не придется
|
||
бороться с его последствиями.
|
||
2) Модификация TCP соединения на уровне потока. Реализуется через proxy или transparent proxy.
|
||
3) Модификация TCP соединения на уровне пакетов. Реализуется через обработчик очереди NFQUEUE и raw сокеты.
|
||
|
||
Для вариантов 2 и 3 реализованы программы tpws и nfqws соответственно.
|
||
Чтобы они работали, необходимо их запустить с нужными параметрами и перенаправить на них определенный трафик
|
||
средствами iptables.
|
||
|
||
|
||
Для перенаправления 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:4 -m mark ! --mark 0x40000000/0x40000000 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass
|
||
|
||
Фильтр по mark нужен для отсечения от очереди пакетов, сгенерированных внутри nfqws.
|
||
Если применяется фильтр по connbytes 1:4, то обязательно добавлять в iptables и фильтр по mark. Иначе возможно
|
||
перепутывание порядка следования пакетов, что приведет к неработоспособности метода.
|
||
|
||
|
||
Если ваше устройство поддерживает аппаратное ускорение (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 работает без изменений.
|
||
|
||
|
||
Когда это работать не будет
|
||
---------------------------
|
||
|
||
* Если подменяется 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
|
||
--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 ; изменять server window size в исходящих пакетах по номеру меньше N
|
||
--ctrack-timeouts=S:E:F ; таймауты внутреннего conntrack в состояниях SYN, ESTABLISHED, FIN. по умолчанию 60:300: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 fake rst rstack disorder disorder2 split split2
|
||
--dpi-desync-fwmark=<int|0xHEX> ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000
|
||
--dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов
|
||
--dpi-desync-fooling=none|md5sig|ts|badseq|badsum ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера
|
||
--dpi-desync-retrans=0|1 ; (только для fake,rst,rstack) 0(default)=отправлять оригинал следом за фейком 1=дропать оригинал, заставляя ОС выполнять ретрансмиссию через 0.2 сек
|
||
--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-any-protocol=0|1 ; 0(default)=работать только по http request и tls clienthello 1=по всем непустым пакетам данных
|
||
--dpi-desync-fake-http=<filename> ; файл, содержащий фейковый http запрос для dpi-desync=fake, на замену стандартному w3.org
|
||
--dpi-desync-fake-tls=<filename> ; файл, содержащий фейковый tls clienthello для dpi-desync=fake, на замену стандартному w3.org
|
||
--dpi-desync-cutoff=N ; применять dpi desync только к исходящим пакетам по номеру меньше N
|
||
--hostlist=<filename> ; применять дурение только к хостам из листа
|
||
|
||
Параметры манипуляции могут сочетаться в любых комбинациях.
|
||
|
||
ЗАМЕЧАНИЕ. Параметр --wsize считается устаревшим и более не поддерживается в скриптах.
|
||
Функции сплита выполняются в рамках атаки десинхронизации. Это быстрее и избавляет от целого ряда недостатков wsize.
|
||
|
||
АТАКА ДЕСИНХРОНИЗАЦИИ DPI
|
||
Суть ее в следующем. После выполнения tcp 3-way handshake идет первый пакет с данными от клиента.
|
||
Там обычно "GET / ..." или TLS ClientHello. Мы дропаем этот пакет, заменяя чем-то другим.
|
||
Это может быть поддельная версия с безобидным, но валидным запросом http или https (вариант fake),
|
||
пакет сброса соединения (варианты rst, rstack), разбитый на части оригинальный пакет с перепутанным
|
||
порядком следования сегментов + обрамление первого сегмента фейками (disorder),
|
||
то же самое без перепутывания порядка сегментов (split).
|
||
В литературе такие атаки еще называют 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,
|
||
либо в FORWARD и OUTPUT. Совместное сочетание этих факторов приводит к непрохождению badsum через такой роутер,
|
||
а при наличии дропа INVALID в OUTPUT и к неработоспособности nfqws с badsum с самого роутера.
|
||
В openwrt из коробки net.netfilter.nf_conntrack_checksum=0, в других роутерах часто нет,
|
||
и не всегда это можно изменить. Чтобы nfqws мог работать, нужно выставить указанное значение sysctl в 0 на роутере.
|
||
Если роутер за другим NAT, например провайдерским, и он не пропускает invalid packets
|
||
вы ничего не сможете с этим сделать. Но обычно провайдеры все же пропускают badsum.
|
||
* пакеты с badseq будут наверняка отброшены принимающим узлом, но так же и DPI, если он ориентируется на sequence numbers
|
||
* TTL казалось бы - лучший вариант, но он требует индивидуальной настройки под каждого провайдера. Если DPI находится дальше локальных
|
||
сайтов провайдера, то вы можете отрезать себе доступ к ним. Необходим ip exclude list, заполняемый вручную.
|
||
Вместе с ttl можно применять md5sig. Это ничего не испортит, зато дает неплохой шанс работы сайтов, до которых "плохой" пакет дойдет по TTL.
|
||
Если не удается найти автоматическое решение, воспользуйтесь файлом zapret-hosts-user-exclude.txt.
|
||
КАКИМ СТОИТ ВЫБИРАТЬ TTL : найдите минимальное значение, при котором обход еще работает. Это и будет номер хопа вашего DPI.
|
||
|
||
Режимы дурения могут сочетаться в любых комбинациях. --dpi-desync-fooling берет множество значений через запятую.
|
||
|
||
Для режимов fake, rst, rstack после фейка отправляем оригинальный пакет. Можно его отправить сразу следом за фейком, а можно его просто дропнуть.
|
||
Если его дропнуть, ОС выполнит ретрансмиссию. Первая ретрансмиссия случается через 0.2 сек, потом задержка увеличивается экспоненциально.
|
||
Задержка может дать надежную гарантию, что пакеты пойдут именно в нужном порядке и будут именно в нем обработаны на DPI.
|
||
По умолчанию используется первый вариант, т.к. он быстрее.
|
||
При использовании dpi-desync-retrans=1 обязательно вставлять ограничитель connbytes в iptables, иначе получим зацикливание.
|
||
|
||
Режим disorder делит оригинальный пакет на 2 части и отправляет следующую комбинацию в указанном порядке :
|
||
1. 2-я часть пакета
|
||
2. поддельная 1-я часть пакета, поле данных заполнено нулями
|
||
3. 1-я часть пакета
|
||
4. поддельная 1-я часть пакета, поле данных заполнено нулями. отсылка 2-й раз.
|
||
Оригинальный пакет дропается всегда. Параметр --dpi-desync-split-pos позволяет указать байтовую позицию, на которой
|
||
происходит разбивка. По умолчанию - 3. Если позиция больше длины пакета, позиция выбирается 1.
|
||
Этой последовательностью для DPI максимально усложняется задача реконструкции начального сообщения,
|
||
по которому принимается решение о блокировке. Некоторым DPI хватит и tcp сегментов в неправильном порядке,
|
||
поддельные части сделаны для дополнительной надежности и более сложных алгоритмов реконструкции.
|
||
Режим disorder2 отключает отправку поддельных частей.
|
||
|
||
Режим split очень похож на disorder, только нет изменения порядка следования сегментов :
|
||
1. поддельная 1-я часть пакета, поле данных заполнено нулями
|
||
2. 1-я часть пакета
|
||
3. поддельная 1-я часть пакета, поле данных заполнено нулями. отсылка 2-й раз.
|
||
4. 2-я часть пакета
|
||
Режим split2 отключает отправку поддельных частей.
|
||
Он может быть использован как более быстрая альтернатива --wsize.
|
||
|
||
disorder2 и split2 не предполагают отсылку фейк пакетов, поэтому опции ttl и fooling неактуальны.
|
||
|
||
Есть 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:4 -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:4 -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:4 :
|
||
1 - для работы методов десинхронизации 0-й фазы и wssize
|
||
2 - иногда данные идут в 3-м пакете 3-way handshake
|
||
3 - стандартная ситуация
|
||
4 - для надежности. на случай, если выполнялась одна ретрансмиссия
|
||
|
||
КОМБИНИРОВАНИЕ МЕТОДОВ ДЕСИНХРОНИЗАЦИИ
|
||
В параметре dpi-desync можно указать до 3 режимов через запятую.
|
||
0 фаза предполагает работу на этапе установления соединения. Может быть synack.
|
||
На 0 фазу не действует фильтр по hostlist.
|
||
Последующие режимы отрабатывают на пакетах с данными.
|
||
Режим 1-й фазы может быть fake,rst,rstack. Режим 2-й фазы может быть disorder,disorder2,split,split2.
|
||
Может быть полезно, когда у провайдера стоит не один 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.
|
||
|
||
ВИРТУАЛЬНЫЕ МАШИНЫ
|
||
Изнутри VM от virtualbox и vmware в режиме NAT не работают многие техники пакетной магии nfqws.
|
||
Принудительно заменяется ttl, не проходят фейк пакеты. Необходимо настроить сеть в режиме bridge.
|
||
|
||
CONNTRACK
|
||
nfqws оснащен ограниченной реализацией слежения за состоянием tcp соединений (conntrack).
|
||
Он включается для реализации некоторых методов противодействия DPI.
|
||
На текущий момент это параметры --wssize и --dpi-desync-cutoff.
|
||
conntrack способен следить за фазой соединения : SYN,ESTABLISHED,FIN , количеством пакетов в каждую сторону, sequence numbers.
|
||
conntrack способен "кормиться" пакетами в обе или только в одну сторону.
|
||
Соединение попадает в таблицу при обнаружении пакетов с выставленными флагами SYN или SYN,ACK.
|
||
Поэтому если необходим conntrack, в правилах перенаправления iptables соединение должно идти на nfqws с самого первого пакета,
|
||
хотя затем может обрываться по фильтру connbytes.
|
||
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 прекращается (нумерация с 1 по аналогии connbytes).
|
||
Если проскочит пакет с 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 не влияет фильтр hostlist, поскольку он действует с самого начала соединения, когда еще нельзя
|
||
принять решение о попадании в лист.
|
||
--wssize может замедлять скорость и/или увеличивать время ответа сайтов, поэтому если есть другие работающие способы
|
||
обхода DPI, лучше применять их.
|
||
|
||
--dpi-desync-cutoff позволяет задать предел по номеру исходящего пакета, при достижении которого прекращается
|
||
применение dpi-desync. Полезно совместно с --dpi-desync-any-protocol=1.
|
||
На склонных к бездействию соединениях следует изменить таймауты conntrack.
|
||
Если соединение выпало из conntrack и задана опция --dpi-desync-cutoff, dpi desync применяться не будет.
|
||
|
||
|
||
tpws
|
||
-----
|
||
|
||
tpws - это transparent proxy.
|
||
--debug=0|1|2 ; Количество буковок в output : 0(default)=тихо, 1=подробно, 2=отладка
|
||
--daemon ; демонизировать прогу
|
||
--pidfile=<file> ; сохранить PID в файл
|
||
--user=<username> ; менять uid процесса
|
||
--uid=uid[:gid] ; менять uid процесса
|
||
--bind-addr ; на каком адресе слушать. может быть ipv4 или ipv6 адрес
|
||
; если указан 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.
|
||
--socks ; вместо прозрачного прокси реализовать socks4/5 proxy
|
||
--no-resolve ; запретить ресолвинг имен через socks5
|
||
--port=<port> ; на каком порту слушать
|
||
--maxconn=<max_connections> ; максимальное количество соединений от клиентов к прокси
|
||
--maxfiles=<max_open_files> ; макс количество файловых дескрипторов (setrlimit). мин требование (X*connections+16), где X=6 в tcp proxy mode, X=4 в режиме тамперинга.
|
||
; стоит сделать запас с коэффициентом как минимум 1.5. по умолчанию maxfiles (X*connections)*1.5+16
|
||
--max-orphan-time=<sec>; если вы запускаете через tpws торрент-клиент с множеством раздач, он пытается установить очень много исходящих соединений,
|
||
; большая часть из которых отваливается по таймату (юзера сидят за NAT, firewall, ...)
|
||
; установление соединения в linux может длиться очень долго. локальный конец отвалился, перед этим послав блок данных,
|
||
; tpws ждет подключения удаленного конца, чтобы отослать ему этот блок, и зависает надолго.
|
||
; настройка позволяет сбрасывать такие подключения через N секунд, теряя блок данных. по умолчанию 5 сек. 0 означает отключить функцию
|
||
; эта функция не действует на успешно подключенные ранее соединения
|
||
|
||
--local-rcvbuf=<bytes> ; SO_RCVBUF для соединений client-proxy
|
||
--local-sndbuf=<bytes> ; SO_SNDBUF для соединений client-proxy
|
||
--remote-rcvbuf=<bytes> ; SO_RCVBUF для соединений proxy-target
|
||
--remote-sndbuf=<bytes> ; SO_SNDBUF для соединений proxy-target
|
||
--skip-nodelay ; не устанавливать в исходящих соединения TCP_NODELAY. несовместимо со split.
|
||
|
||
--split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host
|
||
--split-pos=<offset> ; делить все посылы на сегменты в указанной позиции. единственная опция, работающая на не-http. при указании split-http-req он имеет преимущество на http.
|
||
--split-any-protocol ; применять split-pos к любым пакетам. по умолчанию - только к http и TLS ClientHello
|
||
--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
|
||
--hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются.
|
||
; в файле должен быть хост на каждой строке.
|
||
; список читается 1 раз при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
|
||
; для списка РКН может потребоваться система с 128 Mb памяти !
|
||
; расчитывайте требование RAM для процесса как 3-5 кратный размер файла списка.
|
||
; по сигналу HUP список будет перечитан при следующем принятом соединении
|
||
; список может быть запакован в gzip. формат автоматически распознается и разжимается
|
||
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
|
||
|
||
Параметры манипуляции могут сочетаться в любых комбинациях.
|
||
|
||
В случае 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 : сначала приватный адрес fd00::/8, затем глобальный адрес
|
||
--bind-iface6 --bind-linklocal=unwanted : сначала приватный адрес fd00::/8, затем глобальный адрес, затем link local.
|
||
--bind-iface6 --bind-linklocal=prefer : сначала link local, затем приватный адрес fd00::/8, затем глобальный адрес.
|
||
--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 поддерживает эту возможность, однако используется блокирующий ресолвинг. Пока система
|
||
ресолвит хост (это может занять секунды), вся активность останавливается.
|
||
tpws полностью работает на асинхронных сокетах, но ресолвинг может попортить эту модель.
|
||
С ним возможны атаки DoS на tpws. Если tpws обслуживает множество клиентов, то из-за частого
|
||
ресолвинга качество обслуживания может существенно ухудшиться.
|
||
Если удаленный ресолвинг создает проблемы, настройте клиенты на локальный ресолвинг, включите опцию
|
||
--no-resolve на стороне tpws.
|
||
|
||
Параметр --hostpad=<bytes> добавляет паддинг-хедеров перед Host: на указанное количество байтов.
|
||
Если размер <bytes> слишком большой, то идет разбивка на разные хедеры по 2K.
|
||
Общий буфер приема http запроса - 64K, больший паддинг не поддерживается, да и http сервера
|
||
такое уже не принимают.
|
||
Полезно против DPI, выполняющих реассемблинг TCP с ограниченным буфером.
|
||
Если техника работает, то после некоторого количества bytes http запрос начнет проходить до сайта.
|
||
Если при этом критический размер padding около MTU, значит скорее всего DPI не выполняет реассемблинг пакетов, и лучше будет использовать обычные опции --split-…
|
||
Если все же реассемблинг выполняется, то критический размер будет около размера буфера DPI. Он может быть 4K или 8K, возможны и другие значения.
|
||
|
||
--skip-nodelay может быть полезен, чтобы привести MTU к MTU системы, на которой работает tpws.
|
||
Это может быть полезно для скрытия факта использования VPN. Пониженный MTU - 1 из способов обнаружения
|
||
подозрительного подключения. С tcp proxy ваши соединения неотличимы от тех, что сделал бы сам шлюз.
|
||
|
||
|
||
Способы получения списка заблокированных IP
|
||
-------------------------------------------
|
||
|
||
1) Внесите заблокированные домены в ipset/zapret-hosts-user.txt и запустите ipset/get_user.sh
|
||
На выходе получите ipset/zapret-ip-user.txt с IP адресами.
|
||
|
||
Cкрипты с названием get_reestr_* оперируют дампом реестра заблокированных сайтов :
|
||
|
||
2) ipset/get_reestr_resolve.sh получает список доменов от rublacklist и дальше их ресолвит в ip адреса
|
||
в файл ipset/zapret-ip.txt.gz. В этом списке есть готовые IP адреса, но судя во всему они там в точности в том виде,
|
||
что вносит в реестр РосКомПозор. Адреса могут меняться, позор не успевает их обновлять, а провайдеры редко
|
||
банят по IP : вместо этого они банят http запросы с "нехорошим" заголовком "Host:" вне зависимости
|
||
от IP адреса. Поэтому скрипт ресолвит все сам, хотя это и занимает много времени.
|
||
Используется мультипоточный ресолвер mdig (собственная разработка).
|
||
Реестр РКН уже настолько огромен, что однопоточный ресолв займет вечность, а многопоточный хоть и тоже много времени,
|
||
но хотя бы оно конечно.
|
||
На роутерах с небольшим объемом RAM может сработать только с TMPDIR на внешнем носителе
|
||
|
||
3) ipset/get_reestr_ip.txt
|
||
взять все IP адреса из реестра и загнать в ipset zapret/zapret6
|
||
На роутерах с небольшим объемом RAM может сработать только с TMPDIR на внешнем носителе
|
||
|
||
4) ipset/get_reestr_combined.sh. для провайдеров, которые блокируют по IP https, а остальное по DPI.
|
||
IP https и IP без домена заносятся в ipset ipban, остальные в ipset zapret.
|
||
На роутерах с небольшим объемом RAM может сработать только с TMPDIR на внешнем носителе
|
||
|
||
Cкрипты с названием get_antifilter_* оперируют списками адресов и масок подсетей с сайтов antifilter.network и antifilter.download :
|
||
|
||
5) ipset/get_antifilter_ip.sh. получает лист https://antifilter.network/download/ip.lst.
|
||
|
||
7) ipset/get_antifilter_ipsmart.sh. получает лист https://antifilter.network/download/ipsmart.lst.
|
||
это умная суммаризация отдельных адресов из ip.lst по маскам от /32 до /22
|
||
количество префиксов измеряется всего лишь десятками тысяч, потому это лучшее решение для роутера с 64 Mb RAM
|
||
|
||
7) ipset/get_antifilter_ipsum.sh. получает лист https://antifilter.network/download/ipsum.lst.
|
||
это суммаризация отдельных адресов из ip.lst по маске /24
|
||
количество префиксов измеряется всего лишь десятками тысяч, потому можно использовать на роутерах с 64 Mb RAM
|
||
|
||
Все варианты рассмотренных скриптов автоматически создают и заполняют ipset.
|
||
Варианты 2-7 дополнительно вызывают вариант 1.
|
||
|
||
8) ipset/get_config.sh. этот скрипт вызывает то, что прописано в переменной GETLIST из файла config
|
||
Если переменная не определена, то ресолвятся лишь листы для ipset nozapret/nozapret6.
|
||
|
||
Листы РКН все время изменяются. Возникают новые тенденции. Требования к RAM могут меняться.
|
||
Поэтому необходима нечастая, но все же регулярная ревизия что же вообще у вас происходит на роутере.
|
||
Или вы можете узнать о проблеме лишь когда у вас начнет постоянно пропадать wifi, и вам придется
|
||
его перезагружать каждые 2 часа (метод кувалды).
|
||
|
||
Листы zapret-ip.txt и zapret-ipban.txt сохраняются в сжатом виде в файлы .gz.
|
||
Это позволяет снизить их размер во много раз и сэкономить место на роутере.
|
||
Отключить сжатие листов можно параметром конфига 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 со списком доменов.
|
||
Может быть только один hostlist.
|
||
|
||
Поддерживаются 2 варианта :
|
||
1) Внесите домены для дурения в ipset/zapret-hosts-users.txt. Удалите ipset/zapret-hosts.txt.gz.
|
||
Тогда init скрипт будет запускать tpws с листом zapret-hosts-users.txt.
|
||
|
||
2) Список доменов РКН может быть получен скриптом ipset/get_reestr_hostlist.sh - кладется в ipset/zapret-hosts.txt.gz.
|
||
Этот скрипт автоматически добавляет к списку РКН домены из zapret-hosts-user.txt.
|
||
init скрипт будет запускать tpws с листом zapret-hosts.txt.gz.
|
||
|
||
При фильтрации по именам доменов демон должен запускаться без фильтрации по ipset.
|
||
tpws и nfqws решают нужно ли применять дурение в зависимости от поля Host: в http запросе или SNI в TLS ClientHello.
|
||
При использовании больших списков, в том числе списка РКН, оцените объем RAM на роутере !
|
||
Если после запуска демона RAM под завязку или случаются oom, значит нужно отказаться от таких больших списков.
|
||
|
||
|
||
Проверка провайдера
|
||
-------------------
|
||
|
||
Перед настройкой нужно провести исследование какую бяку устроил вам ваш провайдер.
|
||
|
||
Нужно выяснить не подменяет ли он DNS и какой метод обхода DPI работает.
|
||
В этом вам поможет скрипт https://github.com/ValdikSS/blockcheck.
|
||
|
||
Если 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.
|
||
|
||
Если blockcheck не определил рабочие методы обхода, попробуйте атаку десинхронизации с различными параметрами.
|
||
|
||
Проанализируйте какие методы дурения DPI работают, в соответствии с ними настройте /opt/zapret/config.
|
||
|
||
|
||
Выбор параметров
|
||
----------------
|
||
|
||
Файл /opt/zapret/config используется различными компонентами системы и содержит основные настройки.
|
||
Его нужно просмотреть и при необходимости отредактировать.
|
||
|
||
|
||
Основной режим :
|
||
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
|
||
|
||
Режим фильтрации хостов :
|
||
none - применять дурение ко всем хостам
|
||
ipset - ограничить дурение ipset-ом zapret/zapret6
|
||
hostlist - ограничить дурение списком хостов из файла
|
||
|
||
MODE_FILTER=none
|
||
|
||
Опции tpws :
|
||
|
||
TPWS_OPT="--hostspell=HOST --split-http-req=method --split-pos=3"
|
||
|
||
Опции nfqws для атаки десинхронизации DPI :
|
||
|
||
DESYNC_MARK=0x40000000
|
||
NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
||
|
||
Задание раздельных опций nfqws для http и https :
|
||
|
||
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.
|
||
|
||
Настройка системы управления выборочным traffic offload (только openwrt)
|
||
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-ов
|
||
IPSET_OPT="hashsize 262144 maxelem 2097152"
|
||
ПРО РУГАНЬ в 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"
|
||
|
||
Включить или выключить сжатие больших листов в скриптах 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 :
|
||
|
||
Если ваша система работает как роутер, то нужно вписать названия внутреннего и внешнего интерфейсов :
|
||
IFACE_LAN=eth0
|
||
IFACE_WAN=eth1
|
||
ВАЖНО : настройка маршрутизации , маскарада и т.д. не входит в задачу zapret.
|
||
Включаются только режимы, обеспечивающие перехват транзитного трафика.
|
||
|
||
Параметр INIT_APPLY_FW=1 разрешает init скрипту самостоятельно применять правила iptables.
|
||
При иных значениях или если параметр закомментирован, правила применены не будут.
|
||
Это полезно, если у вас есть система управления фаерволом, в настройки которой и следует прикрутить правила.
|
||
|
||
Прикручивание к системе управления фаерволом или своей системе запуска
|
||
----------------------------------------------------------------------
|
||
|
||
Если вы используете какую-то систему управления фаерволом, то она может вступать в конфликт
|
||
с имеющимся скриптом запуска. При повторном применении правил она могла бы поломать настройки 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 start-daemons
|
||
/opt/zapret/init.d/sysv/zapret stop-daemons
|
||
|
||
Вариант custom
|
||
--------------
|
||
|
||
custom код вынесен в отдельный shell include
|
||
/opt/zapret/init.d/sysv/custom
|
||
или
|
||
/opt/zapret/init.d/openwrt/custom
|
||
|
||
Нужно свой код вписать в функции :
|
||
zapret_custom_daemons
|
||
zapret_custom_firewall
|
||
|
||
В файле custom пишите ваш код, пользуясь хелперами из "functions" или "zapret".
|
||
Смотрите как там сделано добавление iptables или запуск демонов.
|
||
Используя хелпер функции, вы избавитесь от необходимости учитывать все возможные случаи
|
||
типа наличия/отсутствия ipv6, является ли система роутером, имена интерфейсов, ...
|
||
Хелперы это учитывают , вам нужно сосредоточиться лишь на фильтрах iptables и
|
||
параметрах демонов.
|
||
|
||
Код для openwrt и sysv немного отличается. В sysv нужно обрабатывать и запуск, и остановку.
|
||
Запуск это или остановка передается в параметре $1 (0 или 1).
|
||
В openwrt за остановку демонов отвечает procd, а firewall вычищается при "fw3 restart",
|
||
потому нет необходимости реализовывать логику останова.
|
||
|
||
При апгрейде нужно сохранить лишь custom, другие файлы править не надо.
|
||
|
||
Готовый custom скрипт custom-tpws4http-nfqws4https позволяет применить дурение
|
||
tpws к http и nfqws к https. При этом поддерживаются установки из config.
|
||
Его можно использовать как стартовую точку для написания своих скриптов.
|
||
|
||
Пример ручной установки на debian-подобную систему
|
||
--------------------------------------------------
|
||
|
||
На debian основано большое количество дистрибутивов linux, включая ubuntu.
|
||
Здесь рассматриваются прежде всего Debian 8+ и Ubuntu 16+.
|
||
Но с большой вероятностью может сработать и на производных от них.
|
||
Главное условие - наличие systemd, apt и нескольких стандартных пакетов в репозитории.
|
||
|
||
Установить пакеты :
|
||
apt-get update
|
||
apt-get install ipset curl dnsutils git
|
||
|
||
Скопировать директорию zapret в /opt или скачать через git :
|
||
cd /opt
|
||
git clone --depth 1 https://github.com/bol-van/zapret
|
||
|
||
Запустить автоинсталятор бинариков. Он сам определит рабочую архитектуру и настроит все бинарики.
|
||
/opt/zapret/install_bin.sh
|
||
АЛЬТЕРНАТИВА : make -C /opt/zapret. Получите динамические бинарики под вашу ось.
|
||
Для сборки требуются dev пакеты : zlib1g-dev libcap-dev libnetfilter-queue-dev
|
||
|
||
Настроить параметры согласно разделу "Выбор параметров".
|
||
|
||
Создать ссылку на service unit в systemd :
|
||
ln -fs /opt/zapret/init.d/systemd/zapret.service /lib/systemd/system
|
||
|
||
Удалить старые листы, если они были созданы ранее :
|
||
/opt/zapret/ipset/clear_lists.sh
|
||
По желанию прописать в /opt/zapret/ipset/zapret-hosts-user.txt свои домены.
|
||
Выполнить скрипт обновления листа :
|
||
/opt/zapret/ipset/get_config.sh
|
||
Настроить таймер systemd для обновления листа :
|
||
ln -fs /opt/zapret/init.d/systemd/zapret-list-update.service /lib/systemd/system
|
||
ln -fs /opt/zapret/init.d/systemd/zapret-list-update.timer /lib/systemd/system
|
||
|
||
Принять изменения в systemd :
|
||
systemctl daemon-reload
|
||
|
||
Включить автозапуск службы :
|
||
systemctl enable zapret
|
||
|
||
Включить таймер обновления листа :
|
||
systemctl enable zapret-list-update.timer
|
||
|
||
Запустить службу :
|
||
systemctl start zapret
|
||
|
||
Шпаргалка по управлению службой и таймером :
|
||
|
||
enable auto start : systemctl enable zapret
|
||
disable auto start : systemctl disable zapret
|
||
start : systemctl start zapret
|
||
stop : systemctl stop zapret
|
||
status, output messages : systemctl status zapret
|
||
timer info : systemctl list-timer
|
||
delete service : systemctl disable zapret ; rm /lib/systemd/system/zapret.service
|
||
delete timer : systemctl disable zapret-list-update.timer ; rm /lib/systemd/system/zapret-list-update.*
|
||
|
||
Centos 7+, Fedora
|
||
-----------------
|
||
|
||
Centos с 7 версии и более-менее новые федоры построены на systemd.
|
||
В качестве пакетного менеджера используется yum.
|
||
|
||
Установить пакеты :
|
||
yum install -y curl ipset dnsutils git
|
||
|
||
Далее все аналогично debian.
|
||
|
||
OpenSUSE
|
||
--------
|
||
|
||
Новые OpenSUSE основаны на systemd и менеджере пакетов zypper.
|
||
|
||
Установить пакеты :
|
||
zypper --non-interactive install curl ipset
|
||
|
||
Далее все аналогично debian, кроме расположения systemd.
|
||
В opensuse он находится не в /lib/systemd, а в /usr/lib/systemd.
|
||
Правильные команды будут :
|
||
|
||
ln -fs /opt/zapret/init.d/systemd/zapret.service /usr/lib/systemd/system
|
||
ln -fs /opt/zapret/init.d/systemd/zapret-list-update.service /usr/lib/systemd/system
|
||
ln -fs /opt/zapret/init.d/systemd/zapret-list-update.timer /usr/lib/systemd/system
|
||
|
||
Arch linux
|
||
----------
|
||
|
||
Построен на базе systemd.
|
||
|
||
Установить пакеты :
|
||
pacman -Syy
|
||
pacman --noconfirm -S ipset curl
|
||
|
||
Далее все аналогично debian.
|
||
|
||
Gentoo
|
||
------
|
||
|
||
Эта система использует OpenRC - улучшенную версию sysvinit.
|
||
Установка пакетов производится командой : emerge <package_name>
|
||
Пакеты собираются из исходников.
|
||
|
||
Требуются все те же ipset, curl, git для скачивания с github.
|
||
git и curl по умолчанию могут присутствовать, ipset отсутствует.
|
||
|
||
emerge ipset
|
||
|
||
Настроить параметры согласно разделу "Выбор параметров".
|
||
|
||
Запустить автоинсталятор бинариков. Он сам определит рабочую архитектуру и настроит все бинарики.
|
||
/opt/zapret/install_bin.sh
|
||
АЛЬТЕРНАТИВА : make -C /opt/zapret. Получите динамические бинарики под вашу ось.
|
||
|
||
Удалить старые листы, если они были созданы ранее :
|
||
/opt/zapret/ipset/clear_lists.sh
|
||
По желанию прописать в /opt/zapret/ipset/zapret-hosts-user.txt свои домены.
|
||
Выполнить скрипт обновления листа :
|
||
/opt/zapret/ipset/get_config.sh
|
||
Зашедулить обновление листа :
|
||
crontab -e
|
||
Создать строчку "0 12 */2 * * /opt/zapret/ipset/get_config.sh"
|
||
|
||
Подключить init скрипт :
|
||
|
||
ln -fs /opt/zapret/init.d/sysv/zapret /etc/init.d
|
||
rc-update add zapret
|
||
|
||
Запустить службу :
|
||
|
||
rc-service zapret start
|
||
|
||
Шпаргалка по управлению службой :
|
||
|
||
enable auto start : rc-update add zapret
|
||
disable auto start : rc-update del zapret
|
||
start : rc-service zapret start
|
||
stop : rc-service zapret stop
|
||
|
||
|
||
Простая установка
|
||
-----------------
|
||
|
||
install_easy.sh автоматизирует описанные выше ручные варианты процедур установки.
|
||
Он поддерживает OpenWRT, linux системы на базе systemd и MacOS.
|
||
|
||
Для более гибкой настройки перед запуском инсталятора следует выполнить раздел "Выбор параметров".
|
||
|
||
Если система на базе systemd, но используется не поддерживаемый инсталятором менеджер пакетов
|
||
или названия пакетов не соответствуют прописанным в инсталятор, пакеты нужно установить вручную.
|
||
Требуется : ipset curl
|
||
|
||
В комплекте идут статические бинарики для большинства архитектур. Какой-то из них подойдет
|
||
с вероятностью 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/LEDE
|
||
--------------------------------
|
||
|
||
Установить дополнительные пакеты :
|
||
opkg update
|
||
opkg install iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt iptables-mod-conntrack-extra ipset curl
|
||
(ipv6) opkg install ip6tables-mod-nat
|
||
(опционально) opkg install gzip
|
||
(опционально) opkg install grep
|
||
(опционально) opkg install coreutils-sort
|
||
|
||
ЭКОНОМИЯ МЕСТА :
|
||
|
||
gzip от busybox в разы медленней полноценного варианта. gzip используется скриптами получения листов.
|
||
sort от busybox медленней полноценного варианта и жрет намного больше памяти. sort используется скриптами получения листов.
|
||
grep от busybox катастрофически медленный с опцией -f. она применяется в get_reestr_combined.sh. если вы не собираетесь
|
||
пользоваться этим скриптом, gnu grep можно не устанавливать
|
||
iptables-mod-nfqueue можно выкинуть, если не будем пользоваться nfqws
|
||
curl можно выкинуть, если для получения ip листа будет использоваться только get_user.sh
|
||
|
||
Самая главная трудность - скомпилировать программы на C. Это можно сделать на linux x64 при помощи SDK, который
|
||
можно скачать с официального сайта openwrt или LEDE. Но процесс кросс компиляции - это всегда сложности.
|
||
Недостаточно запустить make как на традиционной linux системе.
|
||
Поэтому в binaries имеются готовые статические бинарики для всех самых распространенных архитектур.
|
||
Статическая сборка означает, что бинарик не зависит от типа libc (glibc, uclibc или musl) и наличия установленных so.
|
||
Его можно использовать сразу. Лишь бы подходил тип CPU. У ARM и MIPS есть несколько версий.
|
||
Скорее всего найдется рабочий вариант. Если нет - вам придется собирать самостоятельно.
|
||
Для всех поддерживаемых архитектур бинарики запакованы upx. На текущий момент все, кроме mips64.
|
||
|
||
Скопировать директорию "zapret" в /opt на роутер.
|
||
|
||
Если места достаточно, самый простой способ :
|
||
opkg update
|
||
opkg install git-http
|
||
mkdir /opt
|
||
cd /opt
|
||
git clone --depth 1 https://github.com/bol-van/zapret
|
||
|
||
Если места немного :
|
||
opkg update
|
||
opkg install openssh-sftp-server unzip
|
||
ifconfig br-lan
|
||
Скачать на комп с github zip архив кнопкой "Clone or download"->Download ZIP
|
||
Скопировать средствами sftp zip архив на роутер в /tmp.
|
||
mkdir /opt
|
||
cd /opt
|
||
unzip /tmp/zapret-master.zip
|
||
mv zapret-master zapret
|
||
rm /tmp/zapret-master.zip
|
||
|
||
Если места совсем мало :
|
||
cd /tmp
|
||
nc -l -p 1111 >zapret.tar.gz
|
||
На linux системе скачать и распаковать zapret. Оставить необходимый минимум файлов.
|
||
Запаковать в архив zapret.tar.gz.
|
||
md5sum zapret.tar.gz
|
||
nc <router_ip> 1111 <zapret.tar.gz
|
||
На роутере
|
||
md5sum zapret.tar.gz
|
||
Проверить соответствие hash.
|
||
|
||
Не стоит работать с распакованной версией zapret на windows. Потеряются ссылки и chmod.
|
||
|
||
Запустить автоинсталятор бинариков. Он сам определит рабочую архитектуру и настроит все бинарики.
|
||
/opt/zapret/install_bin.sh
|
||
|
||
Создать ссылку на скрипт запуска :
|
||
ln -fs /opt/zapret/init.d/openwrt/zapret /etc/init.d
|
||
Создать ссылку на скрипт события поднятия интерфейса :
|
||
ln -fs /opt/zapret/init.d/openwrt/90-zapret /etc/hotplug.d/iface
|
||
|
||
Настроить параметры согласно разделу "Выбор параметров".
|
||
|
||
Удалить старые листы, если они были созданы ранее :
|
||
/opt/zapret/ipset/clear_lists.sh
|
||
По желанию прописать в /opt/zapret/ipset/zapret-hosts-user.txt свои домены.
|
||
Выполнить скрипт обновления листа :
|
||
/opt/zapret/ipset/get_config.sh
|
||
Зашедулить обновление листа :
|
||
crontab -e
|
||
Создать строчку "0 12 */2 * * /opt/zapret/ipset/get_config.sh"
|
||
|
||
Включить автозапуск службы и запустить ее :
|
||
/etc/init.d/zapret enable
|
||
/etc/init.d/zapret start
|
||
ПРИМЕЧАНИЕ : на этапе старта системы интерфейсы еще не подняты. в некоторых случаях невозможно правильно
|
||
сформировать параметры запуска демонов, не зная имя физического интерфейса LAN.
|
||
Cкрипт из /etc/hotplug.d/iface перезапустит демоны по событию поднятия LAN.
|
||
|
||
Создать ссылку на firewall include :
|
||
ln -fs /opt/zapret/init.d/openwrt/firewall.zapret /etc/firewall.zapret
|
||
Проверить была ли создана ранее запись о firewall include :
|
||
uci show firewall | grep firewall.zapret
|
||
Если firewall.zapret нет, значит добавить :
|
||
uci add firewall include
|
||
uci set firewall.@include[-1].path="/etc/firewall.zapret"
|
||
uci set firewall.@include[-1].reload="1"
|
||
uci commit firewall
|
||
Проверить не включен ли flow offload :
|
||
uci show firewall.@defaults[0]
|
||
Если flow_offloading=1 или flow_offloading_hw=1 ,
|
||
uci set firewall.@defaults[0].flow_offloading=0
|
||
uci set firewall.@defaults[0].flow_offloading_hw=0
|
||
uci commit firewall
|
||
Перезапустить фаервол :
|
||
fw3 restart
|
||
|
||
Посмотреть через iptables -nL, ip6tables -nL или через luci вкладку "firewall" появились ли нужные правила.
|
||
|
||
ЭКОНОМИЯ МЕСТА : если его мало, то можно оставить в директории zapret лишь подкаталог ipset, файл config и init.d/openwrt.
|
||
Далее нужно создать подкаталоги с реально используемыми бинариками (ip2net, mdig, tpws, nfq)
|
||
и скопировать туда из binaries рабочие executables.
|
||
Рекомендуется оставить ip2net и mdig. Из tpws и nfq оставить лишь тот, что был выбран в config.
|
||
|
||
ЕСЛИ ВСЕ ПЛОХО С МЕСТОМ : откажитесь от работы со списком РКН. используйте только get_user.sh
|
||
|
||
ЕСЛИ СОВСЕМ ВСЕ УЖАСНО С МЕСТОМ : берете tpws и делаете все своими руками. поднятие iptables, автостарт бинарика.
|
||
С некоторых версий скрипты запуска zapret без ipset не работают (он требуется для ip exclude)
|
||
|
||
СОВЕТ : Покупайте только роутеры с USB. В USB можно воткнуть флэшку и вынести на нее корневую файловую систему
|
||
или использовать ее в качестве оверлея. Не надо мучать себя, запихивая незапихиваемое в 8 мб встроенной флэшки.
|
||
Для комфортной работы с zapret нужен роутер с 16 Mb встроенной памяти или USB разъемом и 128+ Mb RAM.
|
||
На 64 Mb без swap будут проблемы с листами РКН. Если у вас только 64 Mb, и вы хотите листы РКН, подключите swap.
|
||
32 Mb для современных версий openwrt - конфигурация на грани живучести. Возможны хаотические падения процессов в oom.
|
||
Работа с листами РКН невозможна в принципе.
|
||
|
||
|
||
Простая установка на openwrt
|
||
----------------------------
|
||
|
||
Работает только если у вас на роутере достаточно места.
|
||
|
||
Копируем zapret на роутер в /tmp.
|
||
|
||
Запускаем установщик :
|
||
/tmp/zapret/install_easy.sh
|
||
Он скопирует в /opt/zapret только необходимый минимум файлов :
|
||
config
|
||
install_easy.sh
|
||
uninstall_easy.sh
|
||
install_bin.sh
|
||
init.d/openwrt/*
|
||
ipset/*
|
||
binaries/<ваша архитектура>/{tpws,nfqws,ip2net,mdig}
|
||
|
||
После успешной установки можно удалить zapret из tmp для освобождения RAM :
|
||
rm -r /tmp/zapret
|
||
|
||
Для более гибкой настройки перед запуском инсталятора следует выполнить раздел "Выбор параметров".
|
||
|
||
|
||
Android
|
||
-------
|
||
|
||
Без рута забудьте про nfqws и tpws в режиме transparent proxy. tpws будет работать только в режиме --socks.
|
||
|
||
Статистики наличия NFQUEUE в стоковых ядрах android у меня нет, но на первом попавшемся устройстве на базе MTK он есть.
|
||
Если 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
|
||
|
||
Я не проверял не прибивают ли новые андроиды iptables по своей прихоти в процессе работы
|
||
или при подключении/отключении wifi, mobile data, ...
|
||
|
||
Ответ на вопрос куда поместить 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
|
||
|
||
Мобильные модемы и роутеры 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 (WSL)
|
||
-------------
|
||
|
||
tpws в режиме socks можно запускать и под более-менее современными билдами windows 10 и windows server
|
||
с установленным WSL. Совсем не обязательно устанавливать дистрибутив убунту, как вам напишут почти в каждой
|
||
статье про WSL, которую вы найдете в сети. tpws - статический бинарик, ему дистрибутив не нужен.
|
||
|
||
Установить WSL : dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all
|
||
Скопировать на целевую систему binaries/x86_64/tpws_wsl.tgz.
|
||
Выполнить : wsl --import tpws "%USERPROFILE%\tpws" tpws_wsl.tgz
|
||
Запустить : wsl --exec /tpws --uid=1 --no-resolve --socks --bind-addr=127.0.0.1 --port=1080 <параметры_дурения>
|
||
Прописать socks 127.0.0.1:1080 в броузер или другую программу.
|
||
|
||
Удаление : wsl --unregister tpws
|
||
|
||
Проверено на windows 10 build 19041 (20.04).
|
||
|
||
ЗАМЕЧАНИЕ. Под Windows существует нативное решение GoodByeDPI, выполняющее дурение на пакетном уровне (по типу nfqws).
|
||
|
||
|
||
Другие прошивки
|
||
---------------
|
||
|
||
Для статических бинариков не имеет значения на чем они запущены : PC, android, приставка, роутер, любой другой девайс.
|
||
Подойдет любая прошивка, дистрибутив linux. Статические бинарики запустятся на всем.
|
||
Им нужно только ядро с необходимыми опциями сборки или модулями.
|
||
Но кроме бинариков в проекте используются еще и скрипты, в которых задействуются некоторые
|
||
стандартные программы.
|
||
|
||
ЗАМЕЧАНИЕ. Как показала практика, на некоторых ядрах бинарики с upx падают в segfault.
|
||
Если это ваш случай, скачайте upx и распакуйте бинарики. Распаковать можно на любой системе и любой архитектуре.
|
||
|
||
Основные причины почему нельзя просто так взять и установить эту систему на что угодно :
|
||
* отсутствие доступа к девайсу через shell
|
||
* отсутствие рута
|
||
* отсутствие раздела r/w для записи и энергонезависимого хранения файлов
|
||
* отсутствие возможности поставить что-то в автозапуск
|
||
* отсутствие cron
|
||
* недостаток модулей ядра или опций его сборки
|
||
* недостаток модулей 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.
|
||
С их помощью можно компенсировать недостаток ПО основной прошивки, за исключением ядра.
|
||
|
||
Подробное описание настроек для других прошивок выходит за рамки данного проекта.
|
||
|
||
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 и репозитория софта
|
||
* в репозитории есть все модули ядра, их можно доустановить через opkg. ядро пересобирать не нужно.
|
||
* в репозитории есть все модули iptables, их можно доустановить через opkg
|
||
* в репозитории есть огромное количество стандартных программ и дополнительного софта
|
||
* наличие SDK, позволяющего собрать недостающее
|
||
|
||
|
||
Обход блокировки через сторонний хост
|
||
-------------------------------------
|
||
|
||
Если не работает автономный обход, приходится перенаправлять трафик через сторонний хост.
|
||
Предлагается использовать прозрачный редирект через socks5 посредством iptables+redsocks, либо iptables+iproute+vpn.
|
||
Настройка варианта с redsocks на openwrt описана в https.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 не нужны совсем.
|
||
Это вариант наименее напряжный для чайников, хотя и не самый удобный в использовании.
|