tpws: hostdot

This commit is contained in:
bolvan 2016-02-25 16:43:48 +03:00
parent 0697347673
commit 5c8f4c2d66
4 changed files with 364 additions and 338 deletions

View File

@ -10,27 +10,31 @@ ISP support : tested on mns.ru and beeline (corbina)
init scripts : rewritten init scripts for simple choise of ISP init scripts : rewritten init scripts for simple choise of ISP
create_ipset : now using 'ipset restore', it works much faster create_ipset : now using 'ipset restore', it works much faster
readme : updated. now using UTF-8 charset. readme : updated. now using UTF-8 charset.
v3 v3
tpws : added transparent proxy (supports TPROXY and DNAT). tpws : added transparent proxy (supports TPROXY and DNAT).
can help when ISP tracks whole HTTP session, not only the beginning can help when ISP tracks whole HTTP session, not only the beginning
ipset : added zapret-hosts-user.txt which contain user defined host names to be resolved ipset : added zapret-hosts-user.txt which contain user defined host names to be resolved
and added to zapret ip list and added to zapret ip list
ISP support : dom.ru support via TPROXY/DNAT ISP support : dom.ru support via TPROXY/DNAT
ISP support : successfully tested sknt.ru on 'domru' configuration ISP support : successfully tested sknt.ru on 'domru' configuration
other configs will probably also work, but cannot test other configs will probably also work, but cannot test
compile : openwrt compile howto compile : openwrt compile howto
v4 v4
tpws : added ability to insert extra space after http method : "GET /" => "GET /" tpws : added ability to insert extra space after http method : "GET /" => "GET /"
ISP support : TKT support ISP support : TKT support
v5 v5
nfqws : ipv6 support in nfqws nfqws : ipv6 support in nfqws
v6 v6
ipset : added "get_antizapret.sh" ipset : added "get_antizapret.sh"
v7
tpws : added ability to insert "." after Host: name

View File

@ -1,33 +1,33 @@
For window size changing : For window size changing :
iptables -t raw -I PREROUTING -p tcp --sport 80 --tcp-flags SYN,ACK SYN,ACK -j NFQUEUE --queue-num 200 --queue-bypass iptables -t raw -I PREROUTING -p tcp --sport 80 --tcp-flags SYN,ACK SYN,ACK -j NFQUEUE --queue-num 200 --queue-bypass
iptables -t raw -I PREROUTING -p tcp --sport 80 --tcp-flags SYN,ACK SYN,ACK -m set --match-set zapret src -j NFQUEUE --queue-num 200 --queue-bypass iptables -t raw -I PREROUTING -p tcp --sport 80 --tcp-flags SYN,ACK SYN,ACK -m set --match-set zapret src -j NFQUEUE --queue-num 200 --queue-bypass
For outgoing data manipulation ("Host:" case changing) : For outgoing data manipulation ("Host:" case changing) :
iptables -t mangle -I POSTROUTING -p tcp --dport 80 -j NFQUEUE --queue-num 200 --queue-bypass iptables -t mangle -I POSTROUTING -p tcp --dport 80 -j NFQUEUE --queue-num 200 --queue-bypass
iptables -t mangle -I POSTROUTING -p tcp --dport 80 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass iptables -t mangle -I POSTROUTING -p tcp --dport 80 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass
iptables -t mangle -I POSTROUTING -p tcp --dport 80 -m set --match-set zapret dst -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:5 -j NFQUEUE --queue-num 200 --queue-bypass iptables -t mangle -I POSTROUTING -p tcp --dport 80 -m set --match-set zapret dst -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:5 -j NFQUEUE --queue-num 200 --queue-bypass
For TPROXY : For TPROXY :
sysctl -w net.ipv4.ip_forward=1 sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
ip -f inet rule add fwmark 1 lookup 100 ip -f inet rule add fwmark 1 lookup 100
ip -f inet route add local default dev lo table 100 ip -f inet route add local default dev lo table 100
# prevent loop # prevent loop
iptables -t filter -I INPUT -p tcp --dport 1188 -j REJECT iptables -t filter -I INPUT -p tcp --dport 1188 -j REJECT
iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 80 -j MARK --set-mark 1 iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 80 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 1188 iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 1188
iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 80 -m set --match-set zapret dst -j MARK --set-mark 1 iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 80 -m set --match-set zapret dst -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 80 -m mark --mark 0x1/0x1 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 1188 iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 80 -m mark --mark 0x1/0x1 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 1188
For DNAT : For DNAT :
# run tpws as user "tpws". its required to avoid loops. # run tpws as user "tpws". its required to avoid loops.
sysctl -w net.ipv4.conf.eth1.route_localnet=1 sysctl -w net.ipv4.conf.eth1.route_localnet=1
iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to 127.0.0.1:1188 iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to 127.0.0.1:1188
iptables -t nat -I OUTPUT -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to 127.0.0.1:1188 iptables -t nat -I OUTPUT -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to 127.0.0.1:1188

View File

@ -1,255 +1,259 @@
zapret v.6 zapret v.7
Для чего это надо Для чего это надо
----------------- -----------------
Обойти блокировки веб сайтов http. Обойти блокировки веб сайтов http.
Как это работает Как это работает
---------------- ----------------
У провайдеров в DPI бывают бреши. Они случаются от того, что правила DPI пишут для У провайдеров в DPI бывают бреши. Они случаются от того, что правила DPI пишут для
обычных пользовательских программ, опуская все возможные случаи, допустимые по стандартам. обычных пользовательских программ, опуская все возможные случаи, допустимые по стандартам.
Это делается для простоты и скорости. Нет смысла ловить хакеров, которых 0.01%, Это делается для простоты и скорости. Нет смысла ловить хакеров, которых 0.01%,
ведь все равно эти блокировки обходятся довольно просто даже обычными пользователями. ведь все равно эти блокировки обходятся довольно просто даже обычными пользователями.
Некоторые DPI не могут распознать http запрос, если он разделен на TCP сегменты. Некоторые DPI не могут распознать http запрос, если он разделен на TCP сегменты.
Например, запрос вида "GET / HTTP/1.1\r\nHost: kinozal.tv......" Например, запрос вида "GET / HTTP/1.1\r\nHost: kinozal.tv......"
мы посылаем 2 частями : сначала идет "GET ", затем "/ HTTP/1.1\r\nHost: kinozal.tv.....". мы посылаем 2 частями : сначала идет "GET ", затем "/ HTTP/1.1\r\nHost: kinozal.tv.....".
Другие DPI спотыкаются, когда заголовок "Host:" пишется в другом регистре : например, "host:". Другие DPI спотыкаются, когда заголовок "Host:" пишется в другом регистре : например, "host:".
Кое-где работает добавление дополнительного пробела после метода : "GET /" => "GET /". Кое-где работает добавление дополнительного пробела после метода : "GET /" => "GET /"
или добавление точки в конце имени хоста : "Host: kinozal.tv."
Как это реализовать на практике в системе linux
----------------------------------------------- Как это реализовать на практике в системе linux
-----------------------------------------------
Как заставить систему разбивать запрос на части ? Можно прогнать всю TCP сессию
через transparent proxy, а можно подменить поле tcp window size на первом входящем TCP пакете с SYN,ACK. Как заставить систему разбивать запрос на части ? Можно прогнать всю TCP сессию
Тогда клиент подумает, что сервер установил для него маленький window size и первый сегмент с данными через transparent proxy, а можно подменить поле tcp window size на первом входящем TCP пакете с SYN,ACK.
отошлет не более указанной длины. В последующих пакетах мы не будем менять ничего. Тогда клиент подумает, что сервер установил для него маленький window size и первый сегмент с данными
Дальнейшее поведение системы по выбору размера отсылаемых пакетов зависит от реализованного отошлет не более указанной длины. В последующих пакетах мы не будем менять ничего.
в ней алгоритма. Опыт показывает, что linux первый пакет всегда отсылает не более указанной Дальнейшее поведение системы по выбору размера отсылаемых пакетов зависит от реализованного
в window size длины, остальные пакеты до некоторых пор шлет не более max(36,указанный_размер). в ней алгоритма. Опыт показывает, что linux первый пакет всегда отсылает не более указанной
После некоторого количества пакетов срабатывает механизм window scaling и начинает в window size длины, остальные пакеты до некоторых пор шлет не более max(36,указанный_размер).
учитываться фактор скалинга, размер пакетов становится не более max(36,указанный_рамер << scale_factor). После некоторого количества пакетов срабатывает механизм window scaling и начинает
Не слишком изящное поведение, но поскольку на размеры входящик пакетов мы не влияем, учитываться фактор скалинга, размер пакетов становится не более max(36,указанный_рамер << scale_factor).
а объем принимаемых по http данных обычно гораздо выше объема отсылаемых, то визуально Не слишком изящное поведение, но поскольку на размеры входящик пакетов мы не влияем,
появятся лишь небольшие задержки. а объем принимаемых по http данных обычно гораздо выше объема отсылаемых, то визуально
Windows ведет себя в аналогичном случае гораздо более предсказуемо. Первый сегмент появятся лишь небольшие задержки.
уходит указанной длины, дальше window size меняется в зависимости от значения, Windows ведет себя в аналогичном случае гораздо более предсказуемо. Первый сегмент
присылаемого в новых tcp пакетах. То есть скорость почти сразу же восстанавливается уходит указанной длины, дальше window size меняется в зависимости от значения,
до возможного максимума. присылаемого в новых tcp пакетах. То есть скорость почти сразу же восстанавливается
до возможного максимума.
Перехватить пакет с SYN,ACK не представляет никакой сложности средствами iptables.
Однако, возможности редактирования пакетов в iptables сильно ограничены. Перехватить пакет с SYN,ACK не представляет никакой сложности средствами iptables.
Просто так поменять window size стандартными модулями нельзя. Однако, возможности редактирования пакетов в iptables сильно ограничены.
Для этого мы воспользуемся средством NFQUEUE. Это средство позволяет Просто так поменять window size стандартными модулями нельзя.
передавать пакеты на обработку процессам, работающим в user mode. Для этого мы воспользуемся средством NFQUEUE. Это средство позволяет
Процесс, приняв пакет, может его изменить, что нам и нужно. передавать пакеты на обработку процессам, работающим в user mode.
Процесс, приняв пакет, может его изменить, что нам и нужно.
iptables -t raw -I PREROUTING -p tcp --sport 80 --tcp-flags SYN,ACK SYN,ACK -j NFQUEUE --queue-num 200 --queue-bypass
iptables -t raw -I PREROUTING -p tcp --sport 80 --tcp-flags SYN,ACK SYN,ACK -j NFQUEUE --queue-num 200 --queue-bypass
Будет отдавать нужные нам пакеты процессу, слушающему на очереди с номером 200.
Он подменит window size. PREROUTING поймает как пакеты, адресованные самому хосту, Будет отдавать нужные нам пакеты процессу, слушающему на очереди с номером 200.
так и маршрутизируемые пакеты. То есть решение одинаково работает как на клиенте, Он подменит window size. PREROUTING поймает как пакеты, адресованные самому хосту,
так и на роутере. На роутере на базе PC или на базе OpenWRT. так и маршрутизируемые пакеты. То есть решение одинаково работает как на клиенте,
В принципе этого достаточно. так и на роутере. На роутере на базе PC или на базе OpenWRT.
Однако, при таком воздействии на TCP будет небольшая задержка. В принципе этого достаточно.
Чтобы не трогать хосты, которые не блокируются провайдером, можно сделать такой ход. Однако, при таком воздействии на TCP будет небольшая задержка.
Создать список заблоченых доменов или скачать его с rublacklist. Чтобы не трогать хосты, которые не блокируются провайдером, можно сделать такой ход.
Заресолвить все домены в ipv4 адреса. Загнать их в ipset с именем "zapret". Создать список заблоченых доменов или скачать его с rublacklist.
Добавить в правило : Заресолвить все домены в ipv4 адреса. Загнать их в ipset с именем "zapret".
Добавить в правило :
iptables -t raw -I PREROUTING -p tcp --sport 80 --tcp-flags SYN,ACK SYN,ACK -m set --match-set zapret src -j NFQUEUE --queue-num 200 --queue-bypass
iptables -t raw -I PREROUTING -p tcp --sport 80 --tcp-flags SYN,ACK SYN,ACK -m set --match-set zapret src -j NFQUEUE --queue-num 200 --queue-bypass
Такии образом воздействие будет производиться только на ip адреса, относящиеся к заблокированным сайтам.
Список можно обновлять через cron раз в несколько дней. Такии образом воздействие будет производиться только на ip адреса, относящиеся к заблокированным сайтам.
Если обновлять через rublacklist, то это займет довольно долго. Более часа. Но ресурсов Список можно обновлять через cron раз в несколько дней.
этот процесс не отнимает, так что никаких проблем это не вызовет, особенно, если система Если обновлять через rublacklist, то это займет довольно долго. Более часа. Но ресурсов
работает постоянно. этот процесс не отнимает, так что никаких проблем это не вызовет, особенно, если система
работает постоянно.
Если DPI не обходится через разделение запроса на сегменты, то иногда срабатывает изменение
"Host:" на "host:". В этом случае нам может не понадобится замена window size, поэтому цепочка Если DPI не обходится через разделение запроса на сегменты, то иногда срабатывает изменение
PREROUTING нам не нужна. Вместо нее вешаемся на исходящие пакеты в цепочке POSTROUTING : "Host:" на "host:". В этом случае нам может не понадобится замена window size, поэтому цепочка
PREROUTING нам не нужна. Вместо нее вешаемся на исходящие пакеты в цепочке POSTROUTING :
iptables -t mangle -I POSTROUTING -p tcp --dport 80 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass
iptables -t mangle -I POSTROUTING -p tcp --dport 80 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass
В этом случае так же возможны дополнительные моменты. DPI может ловить только первый http запрос, игнорируя
последующие запросы в keep-alive сессии. Тогда можем уменьшить нагрузку на проц, отказавшись от процессинга ненужных пакетов. В этом случае так же возможны дополнительные моменты. DPI может ловить только первый http запрос, игнорируя
последующие запросы в keep-alive сессии. Тогда можем уменьшить нагрузку на проц, отказавшись от процессинга ненужных пакетов.
iptables -t mangle -I POSTROUTING -p tcp --dport 80 -m set --match-set zapret dst -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:5 -j NFQUEUE --queue-num 200 --queue-bypass
iptables -t mangle -I POSTROUTING -p tcp --dport 80 -m set --match-set zapret dst -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:5 -j NFQUEUE --queue-num 200 --queue-bypass
Случается так, что провайдер мониторит всю HTTP сессию с keep-alive запросами. В этом случае
недостаточно ограничивать TCP window при установлении соединения. Необходимо посылать отдельными Случается так, что провайдер мониторит всю HTTP сессию с keep-alive запросами. В этом случае
TCP сегментами каждый новый запрос. Эта задача решается через полное проксирование трафика через недостаточно ограничивать TCP window при установлении соединения. Необходимо посылать отдельными
transparent proxy (TPROXY или DNAT). TPROXY не работает с соединениями, исходящими с локальной системы, TCP сегментами каждый новый запрос. Эта задача решается через полное проксирование трафика через
так что это решение применимо только на роутере. DNAT работает и с локальными соединениеми, transparent proxy (TPROXY или DNAT). TPROXY не работает с соединениями, исходящими с локальной системы,
но имеется опасность входа в бесконечную рекурсию, поэтому демон запускается под отдельным пользователем, так что это решение применимо только на роутере. DNAT работает и с локальными соединениеми,
и для этого пользователя отключается DNAT через "-m owner". Полное проксирование требует больше ресурсов но имеется опасность входа в бесконечную рекурсию, поэтому демон запускается под отдельным пользователем,
процессора, чем манипуляция с исходящими пакетами без реконструкции TCP соединения. и для этого пользователя отключается DNAT через "-m owner". Полное проксирование требует больше ресурсов
процессора, чем манипуляция с исходящими пакетами без реконструкции TCP соединения.
iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to 127.0.0.1:1188
iptables -t nat -I OUTPUT -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to 127.0.0.1:1188 iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to 127.0.0.1:1188
iptables -t nat -I OUTPUT -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to 127.0.0.1:1188
nfqws
----- nfqws
-----
Эта программа - модификатор пакетов и обработчик очереди NFQUEUE.
Она берет следующие параметры : Эта программа - модификатор пакетов и обработчик очереди NFQUEUE.
--qnum=200 ; номер очереди Она берет следующие параметры :
--wsize=4 ; менять tcp window size на указанный размер --daemon ; демонизировать прогу
--hostcase ; менять регистр заголовка "Host:" --qnum=200 ; номер очереди
--daemon ; демонизировать прогу --wsize=4 ; менять tcp window size на указанный размер
--hostcase ; менять регистр заголовка "Host:"
tpws Параметры манипуляции могут сочетаться в любых комбинациях.
-----
tpws
tpws - это transparent proxy. -----
--bind-addr ; на каком адресе слушать. может быть ipv4 или ipv6 адрес. если не указано, то слушает на всех адресах ipv4 и ipv6
--port=<port> ; на каком порту слушать tpws - это transparent proxy.
--split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host --bind-addr ; на каком адресе слушать. может быть ipv4 или ipv6 адрес. если не указано, то слушает на всех адресах ipv4 и ipv6
--hostcase ; замена "Host:" => "host:" --port=<port> ; на каком порту слушать
--methodspace ; добавить пробел после метода : "GET /" => "GET /" --daemon ; демонизировать прогу
--daemon ; демонизировать прогу --user=<username> ; менять uid процесса
--user=<username> ; менять uid процесса --split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host
--hostcase ; замена "Host:" => "host:"
Провайдеры --hostdot ; добавление точки после имени хоста : "Host: kinozal.tv."
---------- --methodspace ; добавить пробел после метода : "GET /" => "GET /"
Параметры манипуляции могут сочетаться в любых комбинациях.
mns.ru : нужна замена window size на 4
beeline (corbina) : нужна замена регистра "Host:" на протяжении всей http сессии Провайдеры
dom.ru : нужно проксирование HTTP сессий через tpws с заменой регистра "Host:" и разделение TCP сегментов на хедере "Host:". ----------
Ахтунг ! Домру блокирует все поддомены заблоченого домена. IP адреса всевозможных поддоменов узнать невозможно из реестра
блокировок, поэтому если вдруг на каком-то сайте вылезает блокировочный баннер, то идите в консоль firefox, вкладка network. mns.ru : нужна замена window size на 4
Загружайте сайт и смотрите куда идет редирект. Потом вносите домен в zapret-hosts-user.txt. Например, на kinozal.tv имеются beeline (corbina) : нужна замена регистра "Host:" на протяжении всей http сессии
2 запрашиваемых поддомена : s.kinozal.tv и st.kinozal.tv с разными IP адресами. dom.ru : нужно проксирование HTTP сессий через tpws с заменой регистра "Host:" и разделение TCP сегментов на хедере "Host:".
sknt.ru : проверена работа с tpws с параметром "--split-http-req=method". возможно, будет работать nfqueue, пока возможности Ахтунг ! Домру блокирует все поддомены заблоченого домена. IP адреса всевозможных поддоменов узнать невозможно из реестра
проверить нет блокировок, поэтому если вдруг на каком-то сайте вылезает блокировочный баннер, то идите в консоль firefox, вкладка network.
tkt : помогает разделение http запроса на сегменты, настройки mns.ru подходят Загружайте сайт и смотрите куда идет редирект. Потом вносите домен в zapret-hosts-user.txt. Например, на kinozal.tv имеются
ТКТ был куплен ростелекомом, используется фильтрация ростелекома. 2 запрашиваемых поддомена : s.kinozal.tv и st.kinozal.tv с разными IP адресами.
Поскольку DPI не отбрасывает входящую сессию, а только всовывает свой пакет, который приходит раньше ответа от настоящего сервера, sknt.ru : проверена работа с tpws с параметром "--split-http-req=method". возможно, будет работать nfqueue, пока возможности
блокировки так же обходятся без применения "тяжелой артиллерии" следующим правилом : проверить нет
iptables -t raw -I PREROUTING -p tcp --sport 80 -m string --hex-string "|0D0A|Location: http://95.167.13.50" --algo bm -j DROP --from 40 --to 200 tkt : помогает разделение http запроса на сегменты, настройки mns.ru подходят
Ростелеком : см tkt ТКТ был куплен ростелекомом, используется фильтрация ростелекома.
Поскольку DPI не отбрасывает входящую сессию, а только всовывает свой пакет, который приходит раньше ответа от настоящего сервера,
Способы получения списка заблокированных IP блокировки так же обходятся без применения "тяжелой артиллерии" следующим правилом :
------------------------------------------- iptables -t raw -I PREROUTING -p tcp --sport 80 -m string --hex-string "|0D0A|Location: http://95.167.13.50" --algo bm -j DROP --from 40 --to 200
Ростелеком : см tkt
1) Внесите заблокирванные домены в ipset/zapret-hosts-user.txt и запустите ipset/get_user.sh
На выходе получите ipset/zapret-ip-user.txt с IP адресами. Способы получения списка заблокированных IP
-------------------------------------------
2) ipset/get_reestr.sh получает список доменов от rublacklist и дальше их ресолвит в ip адреса
в файл ipset/zapret-ip.txt. В этом списке есть готовые IP адреса, но судя во всему они там в точности в том виде, 1) Внесите заблокирванные домены в ipset/zapret-hosts-user.txt и запустите ipset/get_user.sh
что вносит в реестр РосКомПозор. Адреса могут меняться, позор не успевает их обновлять, а провайдеры редко На выходе получите ipset/zapret-ip-user.txt с IP адресами.
банят по IP : вместо этого они банят http запросы с "нехорошим" заголовком "Host:" вне зависимости
от IP адреса. Поэтому скрипт ресолвит все сам, хотя это и занимает много времени. 2) ipset/get_reestr.sh получает список доменов от rublacklist и дальше их ресолвит в ip адреса
Дополнительное требование - объем памяти в /tmp для сохранения туда скачанного файла, размер которого в файл ipset/zapret-ip.txt. В этом списке есть готовые IP адреса, но судя во всему они там в точности в том виде,
несколько Мб и продолжает расти. На роутерах openwrt /tmp представляет собой tmpfs , то есть ramdisk. что вносит в реестр РосКомПозор. Адреса могут меняться, позор не успевает их обновлять, а провайдеры редко
В случае роутера с 32 мб памяти ее может не хватить, и будут проблемы. В этом случае используйте банят по IP : вместо этого они банят http запросы с "нехорошим" заголовком "Host:" вне зависимости
следующий скрипт. от IP адреса. Поэтому скрипт ресолвит все сам, хотя это и занимает много времени.
Скрипт автоматически вызывает ipset/get_user.sh и обновляет ipset Дополнительное требование - объем памяти в /tmp для сохранения туда скачанного файла, размер которого
несколько Мб и продолжает расти. На роутерах openwrt /tmp представляет собой tmpfs , то есть ramdisk.
3) ipset/get_anizapret.sh. быстро и без нагрузки на роутер получает лист с http://antizapret.prostovpn.org. В случае роутера с 32 мб памяти ее может не хватить, и будут проблемы. В этом случае используйте
Скрипт автоматически вызывает ipset/get_user.sh и обновляет ipset следующий скрипт.
Скрипт автоматически вызывает ipset/get_user.sh и обновляет ipset
На роутерах не рекомендуется вызывать эти скрипты чаще раза за 2 суток, поскольку сохранение идет
либо во внутреннюю флэш память роутера, либо в случае extroot - на флэшку. 3) ipset/get_anizapret.sh. быстро и без нагрузки на роутер получает лист с http://antizapret.prostovpn.org.
В обоих случаях слишком частая запись может убить флэшку, но если это произойдет с внутренней Скрипт автоматически вызывает ipset/get_user.sh и обновляет ipset
флэш памятью, то вы просто убьете роутер.
На роутерах не рекомендуется вызывать эти скрипты чаще раза за 2 суток, поскольку сохранение идет
Обновление ipset выполняет скрипт ipset/create_ipset.sh либо во внутреннюю флэш память роутера, либо в случае extroot - на флэшку.
В обоих случаях слишком частая запись может убить флэшку, но если это произойдет с внутренней
Пример установки на debian 7 флэш памятью, то вы просто убьете роутер.
----------------------------
Debian 7 изначально содержит ядро 3.2. Оно не умеет делать DNAT на localhost. Обновление ipset выполняет скрипт ipset/create_ipset.sh
Конечно, можно не привязывать tpws к 127.0.0.1 и заменить в правилах iptables "DNAT 127.0.0.1" на "REDIRECT",
но лучше установить более свежее ядро. Оно есть в стабильном репозитории : Пример установки на debian 7
apt-get update ----------------------------
apt-get install linux-image-3.16 Debian 7 изначально содержит ядро 3.2. Оно не умеет делать DNAT на localhost.
Установить пакеты : Конечно, можно не привязывать tpws к 127.0.0.1 и заменить в правилах iptables "DNAT 127.0.0.1" на "REDIRECT",
apt-get update но лучше установить более свежее ядро. Оно есть в стабильном репозитории :
apt-get install libnetfilter-queue-dev ipset curl apt-get update
Скопировать директорию "zapret" в /opt. apt-get install linux-image-3.16
Собрать nfqws : Установить пакеты :
cd /opt/zapret/nfq apt-get update
make apt-get install libnetfilter-queue-dev ipset curl
Собрать tpws : Скопировать директорию "zapret" в /opt.
cd /opt/zapret/tpws Собрать nfqws :
make cd /opt/zapret/nfq
Скопировать /opt/zapret/init.d/debian7/zapret в /etc/init.d. make
В /etc/init.d/zapret выбрать пераметр "ISP". В зависимости от него будут применены нужные правила. Собрать tpws :
Там же выбрать параметр SLAVE_ETH, соответствующий названию внутреннего сетевого интерфейса. cd /opt/zapret/tpws
Включить автостарт : chkconfig zapret on make
(опционально) Вручную первый раз получить новый список ip адресов : /opt/zapret/ipset/get_antizapret.sh Скопировать /opt/zapret/init.d/debian7/zapret в /etc/init.d.
Зашедулить задание обновления листа : В /etc/init.d/zapret выбрать пераметр "ISP". В зависимости от него будут применены нужные правила.
crontab -e Там же выбрать параметр SLAVE_ETH, соответствующий названию внутреннего сетевого интерфейса.
Создать строчку "0 12 * * */2 /opt/zapret/ipset/get_antizapret.sh". Это значит в 12:00 каждые 2 дня обновлять список. Включить автостарт : chkconfig zapret on
Запустить службу : service zapret start (опционально) Вручную первый раз получить новый список ip адресов : /opt/zapret/ipset/get_antizapret.sh
Попробовать зайти куда-нибудь : http://ej.ru, http://kinozal.tv, http://grani.ru. Зашедулить задание обновления листа :
Если не работает, то остановить службу zapret, добавить правило в iptables вручную, crontab -e
запустить nfqws в терминале под рутом с нужными параметрами. Создать строчку "0 12 * * */2 /opt/zapret/ipset/get_antizapret.sh". Это значит в 12:00 каждые 2 дня обновлять список.
Пытаться подключаться к заблоченым сайтам, смотреть вывод программы. Запустить службу : service zapret start
Если нет никакой реакции, значит скорее всего указан неверный номер очереди или ip назначения нет в ipset. Попробовать зайти куда-нибудь : http://ej.ru, http://kinozal.tv, http://grani.ru.
Если реакция есть, но блокировка не обходится, значит параметры обхода подобраные неверно, или это средство Если не работает, то остановить службу zapret, добавить правило в iptables вручную,
не работает в вашем случае на вашем провайдере. запустить nfqws в терминале под рутом с нужными параметрами.
Никто и не говорил, что это будет работать везде. Пытаться подключаться к заблоченым сайтам, смотреть вывод программы.
Попробуйте снять дамп в wireshark или "tcpdump -vvv -X host <ip>", посмотрите действительно ли первый Если нет никакой реакции, значит скорее всего указан неверный номер очереди или ip назначения нет в ipset.
сегмент TCP уходит коротким и меняется ли регистр "Host:". Если реакция есть, но блокировка не обходится, значит параметры обхода подобраные неверно, или это средство
не работает в вашем случае на вашем провайдере.
ubuntu 12,14 Никто и не говорил, что это будет работать везде.
------------ Попробуйте снять дамп в wireshark или "tcpdump -vvv -X host <ip>", посмотрите действительно ли первый
сегмент TCP уходит коротким и меняется ли регистр "Host:".
Имеется готовый конфиг для upstart : zapret.conf. Его нужно скопировать в /etc/init и настроить по аналогии с debian.
Запуск службы : "start zapret" ubuntu 12,14
Останов службы : "stop zapret" ------------
Другие linux системы Имеется готовый конфиг для upstart : zapret.conf. Его нужно скопировать в /etc/init и настроить по аналогии с debian.
-------------------- Запуск службы : "start zapret"
Останов службы : "stop zapret"
Существует несколько основных систем запуска служб : sysvinit, upstart, systemd.
Настройка зависит от системы, используемой в вашем дистрибутиве. Другие linux системы
Типичная стратегия - найти скрипт или конфигурацию запуска других служб и написать свой по аналогии, --------------------
при необходимости почитывая документацию по системе запуска.
Нужные команды можно взять из предложенных скриптов. Существует несколько основных систем запуска служб : sysvinit, upstart, systemd.
Настройка зависит от системы, используемой в вашем дистрибутиве.
Фаерволлы Типичная стратегия - найти скрипт или конфигурацию запуска других служб и написать свой по аналогии,
--------- при необходимости почитывая документацию по системе запуска.
Нужные команды можно взять из предложенных скриптов.
Если вы используете какую-то систему управления фаерволом, то она может вступать в конфликт
с имеющимся скриптом запуска. В этом случае правила для iptables должны быть прикручены Фаерволлы
к вашему фаерволу отдельно от скрипта запуска tpws или nfqws. ---------
Именно так решается вопрос в случае с openwrt, поскольку там своя система управления фаерволом.
При повторном применении правил она могла бы поломать настройки iptables, сделанные скриптом из init.d. Если вы используете какую-то систему управления фаерволом, то она может вступать в конфликт
с имеющимся скриптом запуска. В этом случае правила для iptables должны быть прикручены
Что делать с openwrt к вашему фаерволу отдельно от скрипта запуска tpws или nfqws.
-------------------- Именно так решается вопрос в случае с openwrt, поскольку там своя система управления фаерволом.
При повторном применении правил она могла бы поломать настройки iptables, сделанные скриптом из init.d.
Установить дополнительные пакеты :
opkg update Что делать с openwrt
opkg install iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt ipset curl bind-tools --------------------
Самая главная трудность - скомпилировать программы на C. Установить дополнительные пакеты :
Это можно сделать средствами кросс-компиляции на любой традиционной linux системе. opkg update
Читайте compile/build_howto_openwrt.txt. opkg install iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt ipset curl bind-tools
Ваша задача - получить ipk файлы для tpws и nfqws.
Скопировать директорию "zapret" в /opt на роутер. Самая главная трудность - скомпилировать программы на C.
Установить ipk. Для этого сначала копируем на роутер ipk в /tmp, потом opkg install /tmp/*.ipk. Это можно сделать средствами кросс-компиляции на любой традиционной linux системе.
Смотрим, что появились исполняемые файлы /opt/zapret/tpws/tpws, /opt/zapret/nfq/nfqws. Читайте compile/build_howto_openwrt.txt.
Скопировать /opt/zapret/init.d/zapret в /etc/init.d. Ваша задача - получить ipk файлы для tpws и nfqws.
В /etc/init.d/zapret выбрать пераметр "ISP". В зависимости от него будут применены нужные правила. Скопировать директорию "zapret" в /opt на роутер.
/etc/init.d/zapret enable Установить ipk. Для этого сначала копируем на роутер ipk в /tmp, потом opkg install /tmp/*.ipk.
/etc/init.d/zapret start Смотрим, что появились исполняемые файлы /opt/zapret/tpws/tpws, /opt/zapret/nfq/nfqws.
В зависимости от вашего провайдера либо внести нужные записи в /etc/firewall.user, либо Скопировать /opt/zapret/init.d/zapret в /etc/init.d.
скопировать 99-zapret в /etc/hotplug.d/firewall (сначала нужно mkdir /etc/hotplug.d/firewall). В /etc/init.d/zapret выбрать пераметр "ISP". В зависимости от него будут применены нужные правила.
В /etc/hotplug.d/firewall/99-zapret выбрать нужного провайдера. /etc/init.d/zapret enable
/etc/init.d/firewall restart /etc/init.d/zapret start
Посмотреть через iptables -L или через luci вкладку "firewall" появились ли нужные правила. В зависимости от вашего провайдера либо внести нужные записи в /etc/firewall.user, либо
Зашедулить задание обновления листа : скопировать 99-zapret в /etc/hotplug.d/firewall (сначала нужно mkdir /etc/hotplug.d/firewall).
crontab -e В /etc/hotplug.d/firewall/99-zapret выбрать нужного провайдера.
Создать строчку "0 12 * * */2 /opt/zapret/ipset/get_antizapret.sh". Это значит в 12:00 каждые 2 дня обновлять список. /etc/init.d/firewall restart
Посмотреть через iptables -L или через luci вкладку "firewall" появились ли нужные правила.
Если у вас linux x64, то вместо компиляции toolchain можно использовать пре-компилированный SDK от разработчиков openwrt. Зашедулить задание обновления листа :
https://downloads.openwrt.org/ crontab -e
Найдите вашу версию openwrt, найдите вашу архитектуру, скачайте файл "OpenWrt-SDK-*". Создать строчку "0 12 * * */2 /opt/zapret/ipset/get_antizapret.sh". Это значит в 12:00 каждые 2 дня обновлять список.
Фактически это тот же buildroot, только в нем уже подготовлен toolchain для нужной версии openwrt,
нужной target архитектуры и хост-системы linux x64. Если у вас linux x64, то вместо компиляции toolchain можно использовать пре-компилированный SDK от разработчиков openwrt.
https://downloads.openwrt.org/
Найдите вашу версию openwrt, найдите вашу архитектуру, скачайте файл "OpenWrt-SDK-*".
Фактически это тот же buildroot, только в нем уже подготовлен toolchain для нужной версии openwrt,
нужной target архитектуры и хост-системы linux x64.

View File

@ -33,7 +33,7 @@ struct params_s
gid_t gid; gid_t gid;
uint16_t port; uint16_t port;
bool daemon; bool daemon;
bool hostcase,methodcase,methodspace; bool hostcase,hostdot,methodspace;
enum splithttpreq split_http_req; enum splithttpreq split_http_req;
int maxconn; int maxconn;
}; };
@ -106,8 +106,8 @@ bool handle_epollin(tproxy_conn_t *conn,int *data_transferred){
{ {
if (bOutgoing) if (bOutgoing)
{ {
char buf[RD_BLOCK_SIZE+1],*p; char buf[RD_BLOCK_SIZE+2],*p,*phost=NULL;
ssize_t l,split_pos=0,pos; ssize_t l,split_pos=0,method_split_pos=0,host_split_pos=0,pos;
const char **split_array,**split_item,**item; const char **split_array,**split_item,**item;
rd = recv(fd_in,buf,RD_BLOCK_SIZE,MSG_DONTWAIT); rd = recv(fd_in,buf,RD_BLOCK_SIZE,MSG_DONTWAIT);
@ -128,19 +128,48 @@ bool handle_epollin(tproxy_conn_t *conn,int *data_transferred){
memmove(p+1,p,bs-pos); memmove(p+1,p,bs-pos);
*p = ' '; // insert extra space *p = ' '; // insert extra space
bs++; // block will grow by 1 byte bs++; // block will grow by 1 byte
split_pos = pos; // remember split positing and use it if required method_split_pos = pos; // remember split position and use it if required
break; break;
} }
} }
} }
if (params.hostdot)
{
if (phost=find_bin(buf,bs,"\r\nHost: ",8))
{
host_split_pos = phost-buf+7;
p = phost+8;
while(p<(buf+bs) && *p!='\r' && *p!='\n') p++;
if (p<(buf+bs))
{
pos = p-buf;
printf("Adding dot to host name at pos %d\n",pos);
memmove(p+1,p,bs-pos);
*p = '.'; // insert dot
bs++; // block will grow by 1 byte
}
}
}
switch (params.split_http_req) switch (params.split_http_req)
{ {
case split_method: case split_method:
// do we have already split position ? if so use it without another search // do we have already split position ? if so use it without another search
split_array = split_pos ? NULL : http_split_methods; if (method_split_pos)
{
split_array = NULL;
split_pos = method_split_pos;
}
else
split_array = http_split_methods;
break; break;
case split_host: case split_host:
split_array = http_split_host; if (host_split_pos)
{
split_array = NULL;
split_pos = host_split_pos;
}
else
split_array = http_split_host;
break; break;
default: default:
split_array = NULL; split_array = NULL;
@ -148,6 +177,7 @@ bool handle_epollin(tproxy_conn_t *conn,int *data_transferred){
} }
if (split_array) if (split_array)
{ {
// we havent found split post yet. need to search.
for(split_item=split_array;*split_item;split_item++) for(split_item=split_array;*split_item;split_item++)
{ {
l = strlen(*split_item); l = strlen(*split_item);
@ -162,27 +192,15 @@ bool handle_epollin(tproxy_conn_t *conn,int *data_transferred){
} }
if (params.hostcase) if (params.hostcase)
{ {
if (p=find_bin(buf,bs,"\r\nHost: ",8)) if (phost || (phost=find_bin(buf,bs,"\r\nHost: ",8)))
{ {
printf("Changing 'Host:' => 'host:' at pos %d\n",p-buf); printf("Changing 'Host:' => 'host:' at pos %d\n",phost-buf);
p[2]='h'; phost[2]='h';
}
}
if (params.methodcase)
{
for(split_item=http_split_methods;*split_item;split_item++)
{
l = strlen(*split_item);
if (p=find_bin(buf,bs,*split_item,l))
{
printf("Changing '%s' case\n",*split_item);
*p += 'a'-'A';
break;
}
} }
} }
if (split_pos) if (split_pos)
{ {
printf("Splitting at pos %d\n",split_pos);
wr=send_with_flush(fd_out,buf,split_pos,0); wr=send_with_flush(fd_out,buf,split_pos,0);
if (wr>=0) if (wr>=0)
wr=send(fd_out,buf+split_pos,bs-split_pos,0); wr=send(fd_out,buf+split_pos,bs-split_pos,0);
@ -366,7 +384,7 @@ int8_t block_sigpipe(){
void exithelp() void exithelp()
{ {
printf(" --bind-addr=<ipv4_addr>|<ipv6_addr>\n --port=<port>\n --maxconn=<max_connections>\n --split-http-req=method|host\n --hostcase\t\t; change Host: => host:\n --methodcase\t\t; change GET => gET, POST=>pOST, ...\n --methodspace\t\t; add extra space after method\n --daemon\t\t; daemonize\n --user=<username>\t; drop root privs\n"); printf(" --bind-addr=<ipv4_addr>|<ipv6_addr>\n --port=<port>\n --maxconn=<max_connections>\n --split-http-req=method|host\n --hostcase\t\t; change Host: => host:\n --hostdot\t\t; add \".\" after Host: name\n --methodspace\t\t; add extra space after method\n --daemon\t\t; daemonize\n --user=<username>\t; drop root privs\n");
exit(1); exit(1);
} }
@ -387,7 +405,7 @@ void parse_params(int argc, char *argv[])
{"user",required_argument,0,0},// optidx=5 {"user",required_argument,0,0},// optidx=5
{"maxconn",required_argument,0,0},// optidx=6 {"maxconn",required_argument,0,0},// optidx=6
{"hostcase",no_argument,0,0},// optidx=7 {"hostcase",no_argument,0,0},// optidx=7
{"methodcase",no_argument,0,0},// optidx=8 {"hostdot",no_argument,0,0},// optidx=8
{"split-http-req",required_argument,0,0},// optidx=9 {"split-http-req",required_argument,0,0},// optidx=9
{"methodspace",no_argument,0,0},// optidx=10 {"methodspace",no_argument,0,0},// optidx=10
{NULL,0,NULL,0} {NULL,0,NULL,0}
@ -440,8 +458,8 @@ void parse_params(int argc, char *argv[])
case 7: /* hostcase */ case 7: /* hostcase */
params.hostcase = true; params.hostcase = true;
break; break;
case 8: /* methodcase */ case 8: /* hostdot */
params.methodcase = true; params.hostdot = true;
break; break;
case 9: /* split-http-req */ case 9: /* split-http-req */
if (!strcmp(optarg,"method")) if (!strcmp(optarg,"method"))