mirror of
https://github.com/bol-van/zapret.git
synced 2025-05-24 22:32:58 +03:00
separate config from init script
This commit is contained in:
120
docs/changes.txt
Normal file
120
docs/changes.txt
Normal file
@@ -0,0 +1,120 @@
|
||||
v1
|
||||
|
||||
Initial release
|
||||
|
||||
v2
|
||||
|
||||
nfqws : command line options change. now using standard getopt.
|
||||
nfqws : added options for window size changing and "Host:" case change
|
||||
ISP support : tested on mns.ru and beeline (corbina)
|
||||
init scripts : rewritten init scripts for simple choise of ISP
|
||||
create_ipset : now using 'ipset restore', it works much faster
|
||||
readme : updated. now using UTF-8 charset.
|
||||
|
||||
v3
|
||||
|
||||
tpws : added transparent proxy (supports TPROXY and DNAT).
|
||||
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
|
||||
and added to zapret ip list
|
||||
ISP support : dom.ru support via TPROXY/DNAT
|
||||
ISP support : successfully tested sknt.ru on 'domru' configuration
|
||||
other configs will probably also work, but cannot test
|
||||
compile : openwrt compile howto
|
||||
|
||||
v4
|
||||
|
||||
tpws : added ability to insert extra space after http method : "GET /" => "GET /"
|
||||
ISP support : TKT support
|
||||
|
||||
v5
|
||||
|
||||
nfqws : ipv6 support in nfqws
|
||||
|
||||
v6
|
||||
|
||||
ipset : added "get_antizapret.sh"
|
||||
|
||||
v7
|
||||
|
||||
tpws : added ability to insert "." after Host: name
|
||||
|
||||
v8
|
||||
|
||||
openwrt init : removed hotplug.d/firewall because of race conditions. now only use /etc/firewall.user
|
||||
|
||||
v9
|
||||
|
||||
ipban : added ipban ipset. place domains banned by ip to zapret-hosts-user-ipban.txt
|
||||
these IPs must be soxified for both http and https
|
||||
ISP support : tiera support
|
||||
ISP support : added DNS filtering to ubuntu and debian scripts
|
||||
|
||||
v10
|
||||
|
||||
tpws : added split-pos option. split every message at specified position
|
||||
|
||||
v11
|
||||
|
||||
ipset : scripts optimizations
|
||||
|
||||
v12
|
||||
|
||||
nfqws : fix wrong tcp checksum calculation if packet length is odd and platform is big-endian
|
||||
|
||||
v13
|
||||
|
||||
added binaries
|
||||
|
||||
v14
|
||||
|
||||
change get_antizapret script to work with https://github.com/zapret-info/z-i/raw/master/dump.csv
|
||||
filter out 192.168.*, 127.*, 10.* from blocked ips
|
||||
|
||||
v15
|
||||
|
||||
added --hostspell option to nfqws and tpws
|
||||
ISP support : beeline now catches "host" but other spellings still work
|
||||
openwrt/LEDE : changed init script to work with procd
|
||||
tpws, nfqws : minor cosmetic fixes
|
||||
|
||||
v16
|
||||
|
||||
tpws: split-http-req=method : split inside method name, not after
|
||||
ISP support : mns.ru changed split pos to 3 (got redirect page with HEAD req : curl -I ej.ru)
|
||||
|
||||
v17
|
||||
|
||||
ISP support : athome moved from nfqws to tpws because of instability and http request hangs
|
||||
tpws : added options unixeol,methodeol,hosttab
|
||||
|
||||
v18
|
||||
|
||||
tpws,nfqws : added hostnospace option
|
||||
|
||||
v19
|
||||
|
||||
tpws : added hostlist option
|
||||
|
||||
v20
|
||||
|
||||
added ip2net. ip2net groups ips from iplist into subnets and reduces ipset size twice
|
||||
|
||||
v21
|
||||
|
||||
added mdig. get_reestr.sh is *real* again
|
||||
|
||||
v22
|
||||
|
||||
total review of init script logic
|
||||
dropped support of older debian 7 and ubuntu 12/14 systems
|
||||
install_bin.sh : auto binaries preparation
|
||||
docs: readme review. some new topics added, others deleted
|
||||
docs: VPN setup with policy based routing using wireguard
|
||||
docs: wireguard modding guide
|
||||
|
||||
v23
|
||||
|
||||
major init system rewrite
|
||||
openwrt : separate firewall include /etc/firewall.zapret
|
||||
install_easy.sh : easy setup on openwrt, debian, ubuntu, centos, fedora, opensuse
|
154
docs/https.txt
Normal file
154
docs/https.txt
Normal file
@@ -0,0 +1,154 @@
|
||||
Расскажу как я решал вопрос с блокировкой https на роутере.
|
||||
На тех провайдерах, что мне доступны, все, кроме одного либо банили https по IP (вообще нет конекта), либо захватывали TLS сессию и она намертво зависала - пакеты больше не приходили. На домру удалось выяснить, что DPI цепляется к SNI (Server Name Indication) в TLS, но сплит TLS запроса не помог. Я пришел к выводу, что https самым разумным будет прозрачно заворачивать в socks.
|
||||
Tor поддерживает "из коробки" режим transparent proxy. Это можно использовать в теории, но практически - только на роутерах с 128 мб памяти и выше. Таких роутеров не так много. В основном объем памяти 32 или 64 мб. И тор еще и тормозной.
|
||||
Другой вариант напрашивается, если у вас есть доступ к какой-нибудь unix системе с SSH, где сайты не блокируются. Например, у вас есть VPS вне России. Именно так и поступил.
|
||||
Понятийно требуются следующие шаги :
|
||||
1) Выделять IP, на которые надо проксировать трафик. У нас уже имеется ipset "zapret", технология создания которого отработана.
|
||||
2) Сделать так, чтобы все время при загрузке системы на некотором порту возникал socks.
|
||||
3) Установить transparent соксификатор. Redsocks прекрасно подошел на эту роль.
|
||||
4) Завернуть через iptables трафик с порта назначения 443 и на ip адреса из ipset 'zapret' на соксификатор
|
||||
Буду рассматривать систему на базе openwrt dedicated driver, где уже установлена система обхода dpi "zapret".
|
||||
По крайней мере нужно иметь заполненный ipset 'zapret', устанавливать tpws или nfqws не обязательно.
|
||||
Более того, если они на вашей системе не срабатывают, то можно соксифицировать не только https, но и http.
|
||||
|
||||
* Сделать так, чтобы все время при загрузке системы на некотором порту возникал socks
|
||||
|
||||
Т.к. дефолтный dropbear клиент не поддерживает создание socks, то для начала придется заменить dropbear ssh client на openssh : пакеты openssh-client и openssh-client-utils.
|
||||
Устанавливать их нужно с опцией opkg --force-overwrite, поскольку они перепишут ssh клиент от dropbear.
|
||||
После установки пакетов расслабим неоправданно жестокие права : chmod 755 /etc/ssh.
|
||||
Следует создать пользователя, под которым будем крутить ssh client. Допустим, это будет 'proxy'.
|
||||
Сначала установить пакет shadow-useradd.
|
||||
Код:
|
||||
useradd -d /home/proxy proxy
|
||||
mkdir -p /home/proxy
|
||||
chown proxy:proxy /home/proxy
|
||||
Openssh ловит разные глюки, если у него нет доступа к /dev/tty.
|
||||
Добавим в /etc/rc.local строчку : "chmod 666 /dev/tty"
|
||||
Сгенерируем для него ключ RSA для доступа к ssh серверу.
|
||||
Код:
|
||||
su proxy
|
||||
cd
|
||||
mkdir -m 700 .ssh
|
||||
cd .ssh
|
||||
ssh-keygen
|
||||
ls
|
||||
exit
|
||||
Должны получиться файлы id_rsa и id_rsa.pub.
|
||||
Строчку из id_rsa.pub следует добавить на ssh сервер в файл $HOME/.ssh/authorized_keys.
|
||||
Более подробно о доступе к ssh через авторизацию по ключам : https://beget.com/ru/articles/ssh_by_key
|
||||
Предположим, ваш ssh сервер - vps.mydomain.com, пользователь называется 'proxy'.
|
||||
Проверить подключение можно так : ssh -N -D 1098 -l proxy vps.mydomain.com.
|
||||
Сделайте это под пользователем "proxy", поскольку при первом подключении ssh спросит о правильности hostkey.
|
||||
Соединение может отвалиться в любой момент, поэтому нужно зациклить запуск ssh.
|
||||
Для этого лучший вариант - использовать procd - упрощенная замена systemd на openwrt версий BB и выше.
|
||||
/etc/init.d/socks_vps :
|
||||
Код:
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2006-2011 OpenWrt.org
|
||||
START=50
|
||||
STOP=50
|
||||
USE_PROCD=1
|
||||
USERNAME=proxy
|
||||
COMMAND="ssh -N -D 1098 -l proxy vps.mydomain.com"
|
||||
start_service() {
|
||||
procd_open_instance
|
||||
procd_set_param user $USERNAME
|
||||
procd_set_param respawn 10 10 0
|
||||
procd_set_param command $COMMAND
|
||||
procd_close_instance
|
||||
}
|
||||
Этому файлу нужно дать права : chmod +x /etc/init.d/socks_vps
|
||||
Запуск : /etc/init.d/socks_vps start
|
||||
Останов : /etc/init.d/socks_vps stop
|
||||
Включить автозагрузку : /etc/init.d/socks_vps enable
|
||||
Проверка : curl --socks5 127.0.0.1:1098 https://btc-e.com
|
||||
|
||||
* Организовать прозрачную соксификацию
|
||||
|
||||
Установить пакет redsocks. Redsocks есть готовый для CC 15.05.1 и DD, для более старых версий openwrt его можно взять c http://downloads.openwrt.org, либо воспользоваться прекомпилированным статическим бинариком из комплекта "zapret".
|
||||
Если вы берете ipk с downloads.openwrt.org, то имейте в виду переход с uclibc в CC на musl в DD. Динамические бинарики между ними несовместимы.
|
||||
/etc/redsocks.conf :
|
||||
скрытый текст
|
||||
После чего перезапускаем : /etc/init.d/redsocks restart
|
||||
Смотрим появился ли листенер : netstat -tnlp | grep 1099
|
||||
Автостарт redsocks при таком конфиге не работает, потому что на момент запуска сеть не инициализирована, и у нас даже нет 127.0.0.1.
|
||||
Вместо штатного автостарта будем вешаться на события поднятия интерфейса. Разберем это позже.
|
||||
Пока что отключим автостарт : /etc/init.d/redsocks disable
|
||||
|
||||
* Завертывание соединений через iptables
|
||||
|
||||
/etc/firewall.user
|
||||
Код:
|
||||
SOXIFIER_PORT=1099
|
||||
. /lib/functions/network.sh
|
||||
network_find_wan wan_iface
|
||||
for ext_iface in $wan_iface; do
|
||||
network_get_device ext_device $ext_iface
|
||||
iptables -t nat -C OUTPUT -p tcp --dport 443 -o $ext_device -m set --match-set zapret dst -j REDIRECT --to-port $SOXIFIER_PORT ||
|
||||
iptables -t nat -I OUTPUT -p tcp --dport 443 -o $ext_device -m set --match-set zapret dst -j REDIRECT --to-port $SOXIFIER_PORT
|
||||
done
|
||||
sysctl -w net.ipv4.conf.br-lan.route_localnet=1
|
||||
iptables -t nat -C prerouting_lan_rule -p tcp --dport 443 -m set --match-set zapret dst -j DNAT --to 127.0.0.1:$SOXIFIER_PORT ||
|
||||
iptables -t nat -I prerouting_lan_rule -p tcp --dport 443 -m set --match-set zapret dst -j DNAT --to 127.0.0.1:$SOXIFIER_PORT
|
||||
Внести параметр "reload" а /etc/config/firewall в указанное место :
|
||||
Код:
|
||||
config include
|
||||
option path '/etc/firewall.user'
|
||||
option reload '1'
|
||||
Перезапуск : /etc/init.d/firewall restart
|
||||
Все, теперь можно проверять :
|
||||
/etc/init.d/redsocks stop
|
||||
curl https://btc-e.com
|
||||
# должно обломаться с надписью "Connection refused". если не обламывается - значит ip адрес btc-e.com не в ipset,
|
||||
# либо не сработали правила фаервола. например, из-за не установленных модулей ipt
|
||||
/etc/init.d/redsocks start
|
||||
curl https://btc-e.com
|
||||
# должно выдать страницу
|
||||
|
||||
* Автозапуск redsocks
|
||||
|
||||
Я сделал для себя небольшой скриптик, вешающийся на события поднятия и опускания интерфейсов.
|
||||
/etc/hotplug.d/iface/99-exec-on-updown
|
||||
Код:
|
||||
#!/bin/sh
|
||||
if [ "$ACTION" = ifup ]; then
|
||||
cmd=$(uci get network.$INTERFACE.exec_on_up)
|
||||
[ -n "$cmd" ] && $cmd
|
||||
fi
|
||||
if [ "$ACTION" = ifdown ]; then
|
||||
cmd=$(uci get network.$INTERFACE.exec_on_down)
|
||||
[ -n "$cmd" ] && $cmd
|
||||
fi
|
||||
Теперь можно в описания интерфейсов в /etc/config/nework внести в соответствующий раздел :
|
||||
Код:
|
||||
config interface 'wan'
|
||||
........
|
||||
option exec_on_up '/etc/init.d/redsocks start'
|
||||
Теперь reboot. Заходим снова, смотрим, что есть redsocks, есть ssh, опять проверяем curl https://btc-e.com.
|
||||
Пробуем зайти на https://btc-e.com с компа внутри локалки.
|
||||
|
||||
* Если у вас нет своего сервера
|
||||
|
||||
Если у вас нет своего сервера, да и просто для упрощения настройки, можно использовать proxy от antizapret.prostovpn.org.
|
||||
Посмотрите на http://antizapret.prostovpn.org/proxy.pac. Вы увидите список доменов, по которому броузер выносит решение : идти напрямую или использовать proxy. Proxy указано как "proxy.antizapret.prostovpn.org:3128".
|
||||
Этот прокси работает только на IP назначения из списка https://github.com/zapret-info/z-i/raw/master/dump.csv, на остальные возвращает ошибку, чтобы его не использовали для других целей. Поддерживается метод CONNECT, а значит можно его использовать для проксирования https.
|
||||
В последней версии "zapret" я добавил скрипт "ipset/get_antizapret.sh". Он парсит список ip от "antizapret" и заносит в ipset "zapret". Это гарантирует, что вызов прокси будет по тем адресам, которые разрешены для проксирования.
|
||||
|
||||
* Как изменится вышеописанная процедура
|
||||
|
||||
Убираем все, что связано с ssh. Это нам не потребуется.
|
||||
В /etc/redsocks.conf меняем :
|
||||
Код:
|
||||
ip = 127.0.0.1;
|
||||
port = 1098;
|
||||
type = socks5;
|
||||
на :
|
||||
Код:
|
||||
ip = proxy.antizapret.prostovpn.org;
|
||||
port = 3128;
|
||||
type = http-connect;
|
||||
В отличие от SSH, TLS хэндшейк теперь пойдет в открытую, то есть DPI его могут высечь из proxy протокола и проверить поле SNI (Server Name Indication).
|
||||
Так же могут поступить чуть проще : анализировать IP назначения в методе "CONNECT".
|
||||
Однако, практически это вряд ли будут делать. Если и будут, то немногие.
|
||||
Но если вы вдруг захотите таким способом проксировать http, то здесь вероятность перехвата и облома очень высока. Многие DPI прекрасно ловят proxy запросы.
|
||||
Сначала проверьте работает ли у вас antizapret в предложенном ими варианте : http://antizapret.prostovpn.org
|
58
docs/iptables.txt
Normal file
58
docs/iptables.txt
Normal file
@@ -0,0 +1,58 @@
|
||||
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 -m set --match-set zapret src -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
|
||||
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 -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
|
||||
|
||||
|
||||
For TPROXY :
|
||||
|
||||
sysctl -w net.ipv4.ip_forward=1
|
||||
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
||||
|
||||
ip -f inet rule add fwmark 1 lookup 100
|
||||
ip -f inet route add local default dev lo table 100
|
||||
# prevent loop
|
||||
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 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 mark --mark 0x1/0x1 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 1188
|
||||
|
||||
For DNAT :
|
||||
|
||||
# run tpws as user "tpws". its required to avoid loops.
|
||||
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 OUTPUT -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to 127.0.0.1:1188
|
||||
|
||||
|
||||
Reset all iptable rules :
|
||||
|
||||
iptables -F
|
||||
iptables -X
|
||||
iptables -t nat -F
|
||||
iptables -t nat -X
|
||||
iptables -t mangle -F
|
||||
iptables -t mangle -X
|
||||
iptables -t raw -F
|
||||
iptables -t raw -X
|
||||
|
||||
Reset iptable policies :
|
||||
|
||||
iptables -P INPUT ACCEPT
|
||||
iptables -P FORWARD ACCEPT
|
||||
iptables -P OUTPUT ACCEPT
|
||||
iptables -t mangle -P POSTROUTING ACCEPT
|
||||
iptables -t mangle -P PREROUTING ACCEPT
|
||||
iptables -t mangle -P INPUT ACCEPT
|
||||
iptables -t mangle -P FORWARD ACCEPT
|
||||
iptables -t mangle -P OUTPUT ACCEPT
|
||||
iptables -t raw -P PREROUTING ACCEPT
|
||||
iptables -t raw -P OUTPUT ACCEPT
|
652
docs/readme.txt
Normal file
652
docs/readme.txt
Normal file
@@ -0,0 +1,652 @@
|
||||
zapret v.23
|
||||
|
||||
Для чего это надо
|
||||
-----------------
|
||||
|
||||
Обойти блокировки веб сайтов http.
|
||||
|
||||
Как это работает
|
||||
----------------
|
||||
|
||||
У провайдеров в DPI бывают бреши. Они случаются от того, что правила DPI пишут для
|
||||
обычных пользовательских программ, опуская все возможные случаи, допустимые по стандартам.
|
||||
Это делается для простоты и скорости. Нет смысла ловить хакеров, которых 0.01%,
|
||||
ведь все равно эти блокировки обходятся довольно просто даже обычными пользователями.
|
||||
|
||||
Некоторые 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."
|
||||
|
||||
Как это реализовать на практике в системе linux
|
||||
-----------------------------------------------
|
||||
|
||||
Как заставить систему разбивать запрос на части ? Можно прогнать всю TCP сессию
|
||||
через transparent proxy, а можно подменить поле tcp window size на первом входящем TCP пакете с SYN,ACK.
|
||||
Тогда клиент подумает, что сервер установил для него маленький window size и первый сегмент с данными
|
||||
отошлет не более указанной длины. В последующих пакетах мы не будем менять ничего.
|
||||
Дальнейшее поведение системы по выбору размера отсылаемых пакетов зависит от реализованного
|
||||
в ней алгоритма. Опыт показывает, что linux первый пакет всегда отсылает не более указанной
|
||||
в window size длины, остальные пакеты до некоторых пор шлет не более max(36,указанный_размер).
|
||||
После некоторого количества пакетов срабатывает механизм window scaling и начинает
|
||||
учитываться фактор скалинга, размер пакетов становится не более max(36,указанный_рамер << scale_factor).
|
||||
Не слишком изящное поведение, но поскольку на размеры входящик пакетов мы не влияем,
|
||||
а объем принимаемых по http данных обычно гораздо выше объема отсылаемых, то визуально
|
||||
появятся лишь небольшие задержки.
|
||||
Windows ведет себя в аналогичном случае гораздо более предсказуемо. Первый сегмент
|
||||
уходит указанной длины, дальше window size меняется в зависимости от значения,
|
||||
присылаемого в новых tcp пакетах. То есть скорость почти сразу же восстанавливается
|
||||
до возможного максимума.
|
||||
|
||||
Перехватить пакет с SYN,ACK не представляет никакой сложности средствами iptables.
|
||||
Однако, возможности редактирования пакетов в iptables сильно ограничены.
|
||||
Просто так поменять window size стандартными модулями нельзя.
|
||||
Для этого мы воспользуемся средством 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
|
||||
|
||||
Будет отдавать нужные нам пакеты процессу, слушающему на очереди с номером 200.
|
||||
Он подменит window size. PREROUTING поймает как пакеты, адресованные самому хосту,
|
||||
так и маршрутизируемые пакеты. То есть решение одинаково работает как на клиенте,
|
||||
так и на роутере. На роутере на базе PC или на базе OpenWRT.
|
||||
В принципе этого достаточно.
|
||||
Однако, при таком воздействии на TCP будет небольшая задержка.
|
||||
Чтобы не трогать хосты, которые не блокируются провайдером, можно сделать такой ход.
|
||||
Создать список заблоченых доменов или скачать его с 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
|
||||
|
||||
Таким образом воздействие будет производиться только на ip адреса, относящиеся к заблокированным сайтам.
|
||||
Список можно обновлять через cron раз в несколько дней.
|
||||
Если обновлять через rublacklist, то это займет довольно долго. Более часа. Но ресурсов
|
||||
этот процесс не отнимает, так что никаких проблем это не вызовет, особенно, если система
|
||||
работает постоянно.
|
||||
|
||||
Если DPI не обходится через разделение запроса на сегменты, то иногда срабатывает изменение
|
||||
"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
|
||||
|
||||
В этом случае так же возможны дополнительные моменты. DPI может ловить только первый http запрос, игнорируя
|
||||
последующие запросы в keep-alive сессии. Тогда можем уменьшить нагрузку на проц, отказавшись от процессинга ненужных пакетов.
|
||||
|
||||
iptables -t mangle -I POSTROUTING -p tcp --dport 80 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:5 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
|
||||
Случается так, что провайдер мониторит всю HTTP сессию с keep-alive запросами. В этом случае
|
||||
недостаточно ограничивать TCP window при установлении соединения. Необходимо посылать отдельными
|
||||
TCP сегментами каждый новый запрос. Эта задача решается через полное проксирование трафика через
|
||||
transparent proxy (TPROXY или DNAT). TPROXY не работает с соединениями, исходящими с локальной системы,
|
||||
так что это решение применимо только на роутере. DNAT работает и с локальными соединениеми,
|
||||
но имеется опасность входа в бесконечную рекурсию, поэтому демон запускается под отдельным пользователем,
|
||||
и для этого пользователя отключается 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
|
||||
|
||||
nfqws
|
||||
-----
|
||||
|
||||
Эта программа - модификатор пакетов и обработчик очереди NFQUEUE.
|
||||
Она берет следующие параметры :
|
||||
--daemon ; демонизировать прогу
|
||||
--qnum=200 ; номер очереди
|
||||
--wsize=4 ; менять tcp window size на указанный размер
|
||||
--hostcase ; менять регистр заголовка "Host:" по умолчанию на "host:".
|
||||
--hostnospace ; убрать пробел после "Host:" и переместить его в конец значения "User-Agent:" для сохранения длины пакета
|
||||
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
|
||||
Параметры манипуляции могут сочетаться в любых комбинациях.
|
||||
|
||||
tpws
|
||||
-----
|
||||
|
||||
tpws - это transparent proxy.
|
||||
--bind-addr ; на каком адресе слушать. может быть ipv4 или ipv6 адрес. если не указано, то слушает на всех адресах ipv4 и ipv6
|
||||
--port=<port> ; на каком порту слушать
|
||||
--daemon ; демонизировать прогу
|
||||
--user=<username> ; менять uid процесса
|
||||
--split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host
|
||||
--split-pos=<offset> ; делить все посылы на сегменты в указанной позиции. Если отсыл длинее 8Kb (размер буфера приема), то будет разделен каждый блок по 8Kb.
|
||||
--hostcase ; менять регистр заголовка "Host:". по умолчанию на "host:".
|
||||
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
|
||||
--hostdot ; добавление точки после имени хоста : "Host: kinozal.tv."
|
||||
--hosttab ; добавление табуляции после имени хоста : "Host: kinozal.tv\t"
|
||||
--hostnospace ; убрать пробел после "Host:"
|
||||
--methodspace ; добавить пробел после метода : "GET /" => "GET /"
|
||||
--methodeol ; добавить перевод строки перед методом : "GET /" => "\r\nGET /"
|
||||
--unixeol ; конвертировать 0D0A в 0A и использовать везде 0A
|
||||
--hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются. в файле должен быть хост на каждой строке.
|
||||
; список читается 1 раз при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
|
||||
; для списка РКН может потребоваться система с 128 Mb памяти ! расчитывайте требование RAM для процесса как 3-5 кратный размер файла списка.
|
||||
; по сигналу HUP список будет перечитан при следующем принятом соединении
|
||||
Параметры манипуляции могут сочетаться в любых комбинациях.
|
||||
Есть исключения : split-pos заменяет split-http-req. hostdot и hosttab взаимоисключающи.
|
||||
|
||||
Способы получения списка заблокированных IP
|
||||
-------------------------------------------
|
||||
|
||||
1) Внесите заблокирванные домены в ipset/zapret-hosts-user.txt и запустите ipset/get_user.sh
|
||||
На выходе получите ipset/zapret-ip-user.txt с IP адресами.
|
||||
|
||||
2) ipset/get_reestr.sh получает список доменов от rublacklist и дальше их ресолвит в ip адреса
|
||||
в файл ipset/zapret-ip.txt. В этом списке есть готовые IP адреса, но судя во всему они там в точности в том виде,
|
||||
что вносит в реестр РосКомПозор. Адреса могут меняться, позор не успевает их обновлять, а провайдеры редко
|
||||
банят по IP : вместо этого они банят http запросы с "нехорошим" заголовком "Host:" вне зависимости
|
||||
от IP адреса. Поэтому скрипт ресолвит все сам, хотя это и занимает много времени.
|
||||
Дополнительное требование - объем памяти в /tmp для сохранения туда скачанного файла, размер которого
|
||||
несколько Мб и продолжает расти. На роутерах openwrt /tmp представляет собой tmpfs , то есть ramdisk.
|
||||
В случае роутера с 32 мб памяти ее не хватит, и будут проблемы. В этом случае используйте
|
||||
следующий скрипт.
|
||||
get_reestr.sh может использовать мультипоточный ресолвер mdig (собственная разработка) или
|
||||
стандартный однопоточный dig от bind. При наличии скомпилированного mdig или скопированного в zapret/mdig бинарика
|
||||
используется он, в противном случае dig.
|
||||
Реестр РКН уже настолько огромен, что однопоточный ресолв займет вечность, а многопоточный хоть и тоже много времени,
|
||||
но хотя бы оно конечно. В скрипте можно настроить количество потоков.
|
||||
|
||||
3) ipset/get_anizapret.sh. быстро и без нагрузки на роутер получает лист с antizapret.prostovpn.org.
|
||||
|
||||
4) ipset/get_combined.sh. для провайдеров, которые блокируют по IP https, а остальное по DPI. IP https заносится в ipset ipban, остальные в ipset zapret.
|
||||
Поскольку скачивается большой список РКН, требования к месту в /tmp аналогичны 2)
|
||||
|
||||
Все варианты рассмотренных скриптов автоматически создают и заполняют ipset.
|
||||
Варианты 2-4 дополнительно вызывают вариант 1.
|
||||
|
||||
На роутерах не рекомендуется вызывать эти скрипты чаще раза за 2 суток, поскольку сохранение идет
|
||||
либо во внутреннюю флэш память роутера, либо в случае extroot - на флэшку.
|
||||
В обоих случаях слишком частая запись может убить флэшку, но если это произойдет с внутренней
|
||||
флэш памятью, то вы просто убьете роутер.
|
||||
|
||||
Принудительное обновление ipset выполняет скрипт ipset/create_ipset.sh.
|
||||
Список РКН уже достиг внушительных размеров в сотни тысяч IP адресов. Поэтому для оптимизации ipset
|
||||
применяется утилита ip2net. Она берет список отдельных IP адресов и пытается в нем найти подсети максимального размера (от /22 до /30),
|
||||
в которых заблокировано более 3/4 адресов. ip2net написан на языке C, поскольку операция ресурсоемкая. Иные способы роутер может не потянуть.
|
||||
Если ip2net скомпилирован или в каталог ip2net скопирован бинарик, то скрипт create_ipset.sh использует ipset типа hash:net, прогоняя список через ip2net.
|
||||
В противном случае используется ipset типа hash:ip, список загружается как есть.
|
||||
Соответственно, если вам не нравится ip2net, просто уберите из каталога ip2net бинарик.
|
||||
|
||||
Можно внести список доменов в ipset/zapret-hosts-user-ipban.txt. Их ip адреса будут помещены
|
||||
в отдельный ipset "ipban". Он может использоваться для принудительного завертывания всех
|
||||
соединений на прозрачный proxy "redsocks" или на VPN.
|
||||
|
||||
Фильтрация по именам доменов
|
||||
----------------------------
|
||||
|
||||
Альтернативой ipset является использование tpws со списком доменов.
|
||||
Список доменов РКН может быть получен скриптом ipset/get_hostlist.sh - кладется в ipset/zapret-hosts.txt.
|
||||
Этот скрипт автоматически добавляет к списку РКН домены из zapret-hosts-user.txt.
|
||||
tpws должен запускаться без фильтрации по ipset. Весь трафик http идет через tpws, и он решает нужно ли
|
||||
применять дурение в зависимости от поля Host: в http запросе.
|
||||
Это создает повышенную нагрузку на систему.
|
||||
Сам поиск по доменам работает очень быстро, нагрузка связана с прокачиванием объема данных через процесс.
|
||||
Вариант хорошо подходит для тех, у кого быстрая система с 128+ Мб памяти и провайдер применяет DPI.
|
||||
|
||||
Проверка провайдера
|
||||
-------------------
|
||||
|
||||
Перед настройкой нужно провести исследование какую бяку устроил вам ваш провайдер.
|
||||
|
||||
Нужно выяснить не подменяет ли он 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.
|
||||
|
||||
Проанализируйте какие методы дурения DPI работают, в соответствии с ними настройте /opt/zapret/config.
|
||||
|
||||
|
||||
Выбор параметров
|
||||
----------------
|
||||
|
||||
Файл /opt/zapret/config
|
||||
используется различными компонентами системы и содержит основные настройки.
|
||||
Его нужно просмотреть и при необходимости отредактировать.
|
||||
Выберите MODE :
|
||||
|
||||
nfqws_ipset - использовать nfqws для модификации трафика на порт 80 только на IP из ipset "zapret"
|
||||
nfqws_ipset_https - использовать nfqws для модификации трафика на порты 80 и 443 только на IP из ipset "zapret"
|
||||
nfqws_all - использовать nfqws для модификации трафика на порт 80 для всех IP
|
||||
nfqws_all_https - использовать nfqws для модификации трафика на порты 80 и 443 для всех IP
|
||||
tpws_ipset - использовать tpws для модификации трафика на порт 80 только на IP из ipset "zapret"
|
||||
tpws_ipset_https - использовать tpws для модификации трафика на порты 80 и 443 только на IP из ipset "zapret"
|
||||
tpws_all - использовать tpws для модификации трафика на порт 80 для всех IP
|
||||
tpws_all_https - использовать tpws для модификации трафика на порты 80 и 443 для всех IP
|
||||
tpws_hostlist - пропускать через tpws весь трафик на порт 80. tpws применяет дурение только к хостам из hostlist.
|
||||
ipset - только заполнить ipset. ipset может быть применен для заворота трафика на прокси или на VPN
|
||||
custom - нужно самому запрограммировать запуск демонов в init скрипте и правила iptables
|
||||
|
||||
Можно изменить опции дурения, применяемые демонами nfqws и tpws :
|
||||
|
||||
NFQWS_OPT="--wsize=3 --hostspell=HOST"
|
||||
TPWS_OPT_HTTP="--hostspell=HOST --split-http-req=method"
|
||||
TPWS_OPT_HTTPS="--split-pos=3"
|
||||
|
||||
Если ваша система не openwrt и работает как роутер, то нужно раскомментировать параметр SLAVE_ETH и вписать в него
|
||||
название внутреннего сетевого интерфейса (LAN).
|
||||
|
||||
Параметр GETLIST указывает инсталятору install_easy.sh какой скрипт дергать
|
||||
для обновления списка заблокированных ip или хостов.
|
||||
|
||||
|
||||
Пример установки на 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 https://github.com/bol-van/zapret
|
||||
|
||||
Запустить автоинсталятор бинариков. Он сам определит рабочую архитектуру и настроит все бинарики.
|
||||
/opt/zapret/install_bin.sh
|
||||
АЛЬТЕРНАТИВА : зайти в tpws,nfq,ip2net,mdig, в каждом выполнить make. Получите динамические бинарики под вашу ось.
|
||||
|
||||
Скопировать скрипт запуска :
|
||||
cp /opt/zapret/init.d/sysv/zapret /etc/init.d
|
||||
|
||||
Настроить параметры согласно разделу "Выбор параметров".
|
||||
|
||||
Принять изменения скрипта в systemd :
|
||||
systemctl daemon-reload
|
||||
|
||||
Включить автозапуск службы :
|
||||
systemctl enable zapret
|
||||
|
||||
В зависимости от выбранного MODE :
|
||||
|
||||
MODE содержит "ipset" :
|
||||
Удалить старые ip листы, если они были созданы ранее :
|
||||
rm /opt/zapret/ipset/zapret-ip.txt /opt/zapret/ipset/zapret-ip-user.txt /opt/zapret/ipset/zapret-ip-ipban.txt /opt/zapret/ipset/zapret-ip-user-ipban.txt
|
||||
По желанию прописать в /opt/zapret/ipset/zapret-hosts-user.txt свои домены.
|
||||
Выбрать каким скриптом из перечисленных будем получать список ip заблокированных адресов :
|
||||
/opt/zapret/ipset/get_user.sh
|
||||
/opt/zapret/ipset/get_antizapret.sh
|
||||
/opt/zapret/ipset/get_combined.sh
|
||||
/opt/zapret/ipset/get_reestr.sh
|
||||
Выполнить этот скрипт первый раз вручную для начального заполнения списка.
|
||||
Зашедулить задание обновления листа :
|
||||
crontab -e
|
||||
Создать строчку "0 12 * * */2 <выбранный скрипт>"
|
||||
Например :
|
||||
Создать строчку "0 12 * * */2 /opt/zapret/ipset/get_antizapret.sh"
|
||||
|
||||
MODE содержит "hostlist" :
|
||||
Удалить список доменов РКН, если он уже есть :
|
||||
rm /opt/zapret/ipset/zapret-hosts.txt
|
||||
По желанию прописать в /opt/zapret/ipset/zapret-hosts-user.txt свои домены
|
||||
ЕСЛИ вы хотите использовать список заблокированных доменов РКН:
|
||||
Выполнить :
|
||||
/opt/zapret/ipset/get_hostlist.sh
|
||||
Зашедулить задание обновления листа :
|
||||
crontab -e
|
||||
Создать строчку "0 12 * * */2 /opt/zapret/ipset/get_hostlist.sh"
|
||||
ИНАЧЕ будет использоваться только zapret-hosts-user.txt
|
||||
|
||||
MODE=custom
|
||||
Сами должны знать что делать
|
||||
|
||||
Иные MODE :
|
||||
Ничего делать не нужно
|
||||
|
||||
Запустить службу :
|
||||
systemctl start zapret
|
||||
|
||||
Попробовать зайти куда-нибудь : http://ej.ru, http://kinozal.tv, http://grani.ru.
|
||||
Если не работает, то остановить службу zapret, добавить правило в iptables вручную,
|
||||
запустить nfqws или tpws в терминале под рутом с нужными параметрами.
|
||||
Пытаться подключаться к заблоченым сайтам, смотреть вывод программы.
|
||||
Если нет никакой реакции, значит скорее всего указаны неверные параметры или ip назначения нет в ipset.
|
||||
Если реакция есть, но блокировка не обходится, значит параметры обхода подобраны неверно, или это средство
|
||||
не работает в вашем случае на вашем провайдере.
|
||||
Никто и не говорил, что это будет работать везде.
|
||||
Попробуйте снять дамп в wireshark или "tcpdump -vvv -X host <ip>", посмотрите действительно ли первый
|
||||
сегмент TCP уходит коротким и меняется ли регистр "Host:".
|
||||
|
||||
Шпаргалка по управлению службой :
|
||||
|
||||
enable auto start : systemctl enable zapret
|
||||
disable auto start : systemctl disable zapret
|
||||
start : sytemctl start zapret
|
||||
stop : systemctl stop zapret
|
||||
status, output messages : systemctl status zapret
|
||||
После изменения /etc/init.d/zapret : systemctl daemon-reload
|
||||
delete service : systemctl disable zapret ; systemctl stop zapret ; rm /etc/init.d/zapret
|
||||
|
||||
Centos 7+, Fedora
|
||||
-----------------
|
||||
|
||||
Centos с 7 версии и более-менее новые федоры построены на systemd.
|
||||
В качестве пакетного менеджера используется yum.
|
||||
|
||||
Установить пакеты :
|
||||
yum install -y curl ipset dnsutils git daemonize
|
||||
|
||||
Далее все аналогично debian.
|
||||
|
||||
OpenSUSE
|
||||
--------
|
||||
|
||||
Новые OpenSUSE основаны на systemd и менеджере пакетов zypper.
|
||||
|
||||
Установить пакеты :
|
||||
zypper install curl ipset
|
||||
|
||||
Далее все аналогично debian.
|
||||
|
||||
Простая установка
|
||||
-----------------
|
||||
|
||||
Ты простой юзер ? Не хочешь ни во что вникать, а хочешь нажать и чтобы сразу заработало ?
|
||||
Пользуешься ubuntu, debian , centos , fedora, opensuse ? Тогда этот вариант для тебя.
|
||||
Есть шансы, что оно заработает с минимумом усилий. Запусти терминал и в нем вбивай команды :
|
||||
|
||||
# su
|
||||
<введи пароль рута>
|
||||
# apt-get update
|
||||
# apt-get install git
|
||||
# cd /opt
|
||||
# git clone https://github.com/bol-van/zapret
|
||||
# zapret/install_easy.sh
|
||||
|
||||
Надоело ?
|
||||
|
||||
# /opt/zapret/uninstall_easy.sh
|
||||
# rm -r /opt/zapret
|
||||
|
||||
Это самый необходимый миниум действий.
|
||||
Если zapret уже куда-то был скачан, то можно запустить install_easy.sh прямо оттуда.
|
||||
Инсталятор сам запросит рута, скопирует файлы куда надо.
|
||||
Можно даже запускать инсталятор из "проводника" через функцию "запустить в терминале", если
|
||||
"проводник" такое позволяет.
|
||||
|
||||
Для более гибкой настройки перед запуском инсталятора следует выполнить раздел "Выбор параметров".
|
||||
|
||||
Эти скрипты будут работать и на других системах на базе systemd при условии, что
|
||||
systemd собран с поддержкой sysvinit и имеется следующий файл :
|
||||
/lib/systemd/system-generators/systemd-sysv-generator
|
||||
ИЛИ
|
||||
/usr/lib/systemd/system-generators/systemd-sysv-generator
|
||||
К сожалению, некоторые дистрибутивы имеют systemd без sysvinit support (arch linux).
|
||||
А так же есть необходимые программы :
|
||||
ipset
|
||||
curl
|
||||
Их можно установить вручную при помощи менеджера пакетов вашей ОС.
|
||||
|
||||
|
||||
Другие linux системы
|
||||
--------------------
|
||||
|
||||
Существует несколько основных систем запуска служб : sysvinit, upstart, systemd.
|
||||
Настройка зависит от системы, используемой в вашем дистрибутиве.
|
||||
Типичная стратегия - найти скрипт или конфигурацию запуска других служб и написать свой по аналогии,
|
||||
при необходимости почитывая документацию по системе запуска.
|
||||
Нужные команды можно взять из предложенных скриптов.
|
||||
|
||||
Фаерволлы
|
||||
---------
|
||||
|
||||
Если вы используете какую-то систему управления фаерволом, то она может вступать в конфликт
|
||||
с имеющимся скриптом запуска. В этом случае правила для iptables должны быть прикручены
|
||||
к вашему фаерволу отдельно от скрипта запуска tpws или nfqws.
|
||||
Именно так решается вопрос в случае с openwrt, поскольку там своя система управления фаерволом.
|
||||
При повторном применении правил она могла бы поломать настройки iptables, сделанные скриптом из init.d.
|
||||
|
||||
Что делать с openwrt/LEDE
|
||||
-------------------------
|
||||
|
||||
Установить дополнительные пакеты :
|
||||
opkg update
|
||||
opkg install iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt ipset curl
|
||||
(для новых LEDE) opkg install kmod-ipt-raw
|
||||
(опционально) opkg install bind-tools
|
||||
|
||||
ЭКОНОМИЯ МЕСТА :
|
||||
|
||||
bind-tools содержит dig (ресолвер dns от bind). он достаточно емкий по занимаемому месту, но mdig его
|
||||
полностью заменяет. при наличии mdig bind-tools не нужны.
|
||||
iptables-mod-nfqueue можно выкинуть, если не будем пользоваться nfqws
|
||||
curl можно выкинуть, если для получения ip листа будет использоваться только get_user.sh
|
||||
ipset можно выкинуть, если не будем пользоваться ipset-тами, а будем, например, использовать tpws
|
||||
со списком доменов.
|
||||
|
||||
Самая главная трудность - скомпилировать программы на C. Это можно сделать на linux x64 при помощи SDK, который
|
||||
можно скачать с официального сайта openwrt или LEDE. Но процесс кросс компиляции - это всегда сложности.
|
||||
Недостаточно запустить make как на традиционной linux системе.
|
||||
Поэтому в binaries имеются готовые статические бинарики для всех самых распространенных архитектур.
|
||||
Статическая сборка означает, что бинарик не зависит от типа libc (glibc, uclibc или musl) и наличия установленных so.
|
||||
Его можно использовать сразу. Лишь бы подходил тип CPU. У ARM и MIPS есть несколько версий.
|
||||
Скорее всего найдется рабочий вариант. Если нет - вам придется собирать самостоятельно.
|
||||
|
||||
Скопировать директорию "zapret" в /opt на роутер.
|
||||
|
||||
Запустить автоинсталятор бинариков. Он сам определит рабочую архитектуру и настроит все бинарики.
|
||||
/opt/zapret/install_bin.sh
|
||||
|
||||
Скопировать скрипт запуска :
|
||||
cp /opt/zapret/init.d/openwrt/zapret /etc/init.d
|
||||
|
||||
Настроить параметры согласно разделу "Выбор параметров".
|
||||
|
||||
В зависимости от выбранного MODE :
|
||||
|
||||
MODE содержит "ipset" :
|
||||
Удалить старые ip листы, если они были созданы ранее :
|
||||
rm /opt/zapret/ipset/zapret-ip.txt /opt/zapret/ipset/zapret-ip-user.txt /opt/zapret/ipset/zapret-ip-ipban.txt /opt/zapret/ipset/zapret-ip-user-ipban.txt
|
||||
По желанию прописать в /opt/zapret/ipset/zapret-hosts-user.txt свои домены.
|
||||
Выбрать каким скриптом из перечисленных будем получать список ip заблокированных адресов :
|
||||
/opt/zapret/ipset/get_user.sh
|
||||
/opt/zapret/ipset/get_antizapret.sh
|
||||
/opt/zapret/ipset/get_combined.sh
|
||||
/opt/zapret/ipset/get_reestr.sh
|
||||
Выполнить этот скрипт первый раз вручную для начального заполнения списка.
|
||||
Зашедулить задание обновления листа :
|
||||
crontab -e
|
||||
Создать строчку "0 12 * * */2 <выбранный скрипт>"
|
||||
Например :
|
||||
Создать строчку "0 12 * * */2 /opt/zapret/ipset/get_antizapret.sh"
|
||||
|
||||
MODE содержит "hostlist" :
|
||||
Удалить список доменов РКН, если он уже есть :
|
||||
rm /opt/zapret/ipset/zapret-hosts.txt
|
||||
По желанию прописать в /opt/zapret/ipset/zapret-hosts-user.txt свои домены
|
||||
ЕСЛИ вы хотите использовать список заблокированных доменов РКН:
|
||||
Выполнить :
|
||||
/opt/zapret/ipset/get_hostlist.sh
|
||||
Зашедулить задание обновления листа :
|
||||
crontab -e
|
||||
Создать строчку "0 12 * * */2 /opt/zapret/ipset/get_hostlist.sh"
|
||||
ИНАЧЕ будет использоваться только zapret-hosts-user.txt
|
||||
|
||||
MODE=custom
|
||||
Сами должны знать что делать
|
||||
|
||||
Иные MODE :
|
||||
Ничего делать не нужно
|
||||
|
||||
Включить автозапуск службы и запустить ее :
|
||||
/etc/init.d/zapret enable
|
||||
/etc/init.d/zapret start
|
||||
|
||||
В зависимости от выбранного в инит скрипте MODE скопировать нужный файл настроек фаервола :
|
||||
cp /opt/zapret/init.d/openwrt/firewall.zapret.$MODE /etc/firewall.zapret
|
||||
Например :
|
||||
cp /opt/zapret/init.d/openwrt/firewall.zapret.tpws_ipset_https /etc/firewall.zapret
|
||||
Проверить была ли создана ранее запись о firewall include :
|
||||
uci show firewall | grep 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
|
||||
Перезапустить фаервол :
|
||||
fw3 restart
|
||||
Посмотреть через iptables -nL или через luci вкладку "firewall" появились ли нужные правила.
|
||||
|
||||
ЭКОНОМИЯ МЕСТА : если его мало, то можно оставить в директории zapret лишь подкаталог ipset.
|
||||
Далее нужно создать подкаталоги с реально используемыми бинариками (ip2net, mdig, tpws, nfq)
|
||||
и скопировать туда из binaries рабочие executables.
|
||||
Рекомендуется оставить ip2net и mdig. Из tpws и nfq оставить лишь тот, что был выбран в init скрипте.
|
||||
|
||||
ЕСЛИ ВСЕ ПЛОХО С МЕСТОМ : тогда берите SDK и собирайте динамические бинарики. они весят меньше.
|
||||
откажитесь от работы со списком РКН. используйте только get_user.sh
|
||||
|
||||
ЕСЛИ СОВСЕМ ВСЕ УЖАСНО С МЕСТОМ : не надо устанавливать дополнительные пакеты через opkg.
|
||||
оставьте лишь /opt/zapret/tpws/tpws, /opt/zapret/config, /etc/init.d/zapret, /etc/firewall.zapret
|
||||
используйте MODE=tpws_all или tpws_all_https
|
||||
такой вариант потребует около 100 кб места
|
||||
и полностью статичен.
|
||||
отсутствуют любые загрузки, обновления, изменения файлов.
|
||||
tpws без ipset использует всего лишь DNAT, который есть по умолчанию
|
||||
|
||||
СОВЕТ : Покупайте только роутеры с USB. В USB можно воткнуть флэшку и вынести на нее корневую файловую систему
|
||||
или использовать ее в качестве оверлея. Не надо мучать себя, запихивая незапихиваемое в 8 мб встроенной флэшки.
|
||||
Для комфортной работы с zapret нужен роутер с 16 Mb встроенной памяти или USB разъемом и 64 (а лучше 128) Mb RAM.
|
||||
|
||||
|
||||
Простая установка на openwrt
|
||||
----------------------------
|
||||
|
||||
Работает только если у вас на роутере достаточно много места.
|
||||
Схема примерно такая же, как и на десктопе. Помещаем на роутер /opt/zapret,
|
||||
выполняем раздел "Выбор параметров", запускаем install_easy.sh
|
||||
|
||||
Если места достаточно, можно прямо на роутер установить git и скачать с github :
|
||||
|
||||
opkg update
|
||||
opkg install git-http
|
||||
mkdir /opt
|
||||
cd /opt
|
||||
git clone https://github.com/bol-van/zapret
|
||||
|
||||
Для экономии места перед запуском инсталятора читаем комментарии предыдущего раздела.
|
||||
Простому инсталятору требуется следующим минимум :
|
||||
|
||||
install_easy.sh
|
||||
uninstall_easy.sh
|
||||
install_bin.sh
|
||||
init.d/openwrt
|
||||
ipset/*
|
||||
binaries/<ваша архитектура>/{tpws,nfqws,ip2net,mdig}
|
||||
|
||||
Если вы закачаете zapret не в /opt/zapret, а, например, в /tmp, и запустите install_easy.sh оттуда,
|
||||
то инсталятор сам скопирует только необходимый минимум в /opt/zapret.
|
||||
|
||||
|
||||
Другие прошивки
|
||||
---------------
|
||||
|
||||
Для статических бинариков не имеет значения на чем они запущены : PC, android, приставка, роутер, любой другой девайс.
|
||||
Подойдет любая прошивка, дистрибутив linux. Статические бинарики запустятся на всем.
|
||||
Им нужно только ядро с необходимыми опциями сборки или модулями.
|
||||
Но кроме бинариков в проекте используются еще и скрипты, в которых задействуются некоторые
|
||||
стандартные программы.
|
||||
|
||||
Основные причины почему нельзя просто так взять и установить эту систему на что угодно :
|
||||
* отсутствие доступа к девайсу через shell
|
||||
* отсутствие рута
|
||||
* отсутствие раздела r/w для записи и энергонезависимого хранения файлов
|
||||
* отсутствие возможности поставить что-то в автозапуск
|
||||
* отсутствие cron
|
||||
* недостаток модулей ядра или опций его сборки
|
||||
* недостаток модулей iptables (/usr/lib/iptables/lib*.so)
|
||||
* недостаток стандартных программ (типа ipset, curl) или их кастрированность (облегченная замена)
|
||||
* кастрированный или нестандартный шелл sh
|
||||
|
||||
Если в вашей прошивке есть все необходимое, то вы можете адаптировать zapret под ваш девайс в той или иной степени.
|
||||
Может быть у вас не получится поднять все части системы, однако вы можете хотя бы попытаться
|
||||
поднять tpws и завернуть на него через -j REDIRECT весь трафик на порт 80.
|
||||
Если вам есть куда записать tpws, есть возможность выполнять команды при старте, то как минимум
|
||||
это вы сделать сможете. Скорее всего поддержка REDIRECT в ядре есть. Она точно есть на любом роутере,
|
||||
на других устройствах под вопросом. NFQUEUE, iptable_raw, 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, позволяющего собрать недостающее
|
||||
|
||||
Обход блокировки https
|
||||
----------------------
|
||||
|
||||
Как правило трюки с DPI не помогают для обхода блокировки https.
|
||||
Приходится перенаправлять трафик через сторонний хост.
|
||||
Предлагается использовать прозрачный редирект через socks5 посредством iptables+redsocks, либо iptables+iproute+vpn.
|
||||
Настройка варианта с redsocks на openwrt описана в https.txt.
|
||||
Настройка варианта с iproute+wireguard - в wireguard_iproute_openwrt.txt.
|
||||
|
||||
ИНОГДА (но нечасто) работает трюк со сплитом tls handshake на 2 части.
|
||||
Это можно сделать все теми же средствами. nfqws или tpws с параметром --split-pos.
|
||||
--split-pos - единственный параметр, который работает на не-HTTP трафике, все остальное работать не будет.
|
||||
Попробуйте, может вам повезет.
|
||||
|
||||
Почему стоит вложиться в покупку 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
|
133
docs/wireguard/010-wg-mod.patch
Normal file
133
docs/wireguard/010-wg-mod.patch
Normal file
@@ -0,0 +1,133 @@
|
||||
Index: WireGuard-0.0.20190123/src/cookie.c
|
||||
===================================================================
|
||||
--- WireGuard-0.0.20190123.orig/src/cookie.c
|
||||
+++ WireGuard-0.0.20190123/src/cookie.c
|
||||
@@ -193,6 +193,8 @@ void wg_cookie_message_create(struct mes
|
||||
xchacha20poly1305_encrypt(dst->encrypted_cookie, cookie, COOKIE_LEN,
|
||||
macs->mac1, COOKIE_LEN, dst->nonce,
|
||||
checker->cookie_encryption_key);
|
||||
+ // MOD : randomize trash
|
||||
+ dst->header.trash = gen_trash();
|
||||
}
|
||||
|
||||
void wg_cookie_message_consume(struct message_handshake_cookie *src,
|
||||
Index: WireGuard-0.0.20190123/src/messages.h
|
||||
===================================================================
|
||||
--- WireGuard-0.0.20190123.orig/src/messages.h
|
||||
+++ WireGuard-0.0.20190123/src/messages.h
|
||||
@@ -53,23 +53,41 @@ enum limits {
|
||||
MAX_QUEUED_PACKETS = 1024 /* TODO: replace this with DQL */
|
||||
};
|
||||
|
||||
+/*
|
||||
enum message_type {
|
||||
- MESSAGE_INVALID = 0,
|
||||
- MESSAGE_HANDSHAKE_INITIATION = 1,
|
||||
- MESSAGE_HANDSHAKE_RESPONSE = 2,
|
||||
- MESSAGE_HANDSHAKE_COOKIE = 3,
|
||||
- MESSAGE_DATA = 4
|
||||
+ MESSAGE_INVALID = 0,
|
||||
+ MESSAGE_HANDSHAKE_INITIATION = 1,
|
||||
+ MESSAGE_HANDSHAKE_RESPONSE = 2,
|
||||
+ MESSAGE_HANDSHAKE_COOKIE = 3,
|
||||
+ MESSAGE_DATA = 4
|
||||
};
|
||||
+*/
|
||||
+
|
||||
+// MOD : message type
|
||||
+enum message_type {
|
||||
+ MESSAGE_INVALID = 0xE319CCD0,
|
||||
+ MESSAGE_HANDSHAKE_INITIATION = 0x48ADE198,
|
||||
+ MESSAGE_HANDSHAKE_RESPONSE = 0xFCA6A8F3,
|
||||
+ MESSAGE_HANDSHAKE_COOKIE = 0x64A3BB18,
|
||||
+ MESSAGE_DATA = 0x391820AA
|
||||
+};
|
||||
+
|
||||
+// MOD : generate fast trash without true RNG
|
||||
+__le32 gen_trash(void);
|
||||
|
||||
struct message_header {
|
||||
- /* The actual layout of this that we want is:
|
||||
- * u8 type
|
||||
- * u8 reserved_zero[3]
|
||||
- *
|
||||
- * But it turns out that by encoding this as little endian,
|
||||
- * we achieve the same thing, and it makes checking faster.
|
||||
- */
|
||||
- __le32 type;
|
||||
+ /* The actual layout of this that we want is:
|
||||
+ * u8 type
|
||||
+ * u8 reserved_zero[3]
|
||||
+ *
|
||||
+ * But it turns out that by encoding this as little endian,
|
||||
+ * we achieve the same thing, and it makes checking faster.
|
||||
+ */
|
||||
+
|
||||
+ // MOD : trash field to change message size and add 4 byte offset to all fields
|
||||
+ __le32 trash;
|
||||
+
|
||||
+ __le32 type;
|
||||
};
|
||||
|
||||
struct message_macs {
|
||||
Index: WireGuard-0.0.20190123/src/noise.c
|
||||
===================================================================
|
||||
--- WireGuard-0.0.20190123.orig/src/noise.c
|
||||
+++ WireGuard-0.0.20190123/src/noise.c
|
||||
@@ -17,6 +17,24 @@
|
||||
#include <linux/highmem.h>
|
||||
#include <crypto/algapi.h>
|
||||
|
||||
+
|
||||
+// MOD : trash generator
|
||||
+__le32 gtrash = 0;
|
||||
+__le32 gen_trash(void)
|
||||
+{
|
||||
+ if (gtrash)
|
||||
+ gtrash = gtrash*1103515243 + 12345;
|
||||
+ else
|
||||
+ // first value is true random
|
||||
+ get_random_bytes_wait(>rash, sizeof(gtrash));
|
||||
+ return gtrash;
|
||||
+}
|
||||
+
|
||||
/* This implements Noise_IKpsk2:
|
||||
*
|
||||
* <- s
|
||||
@@ -515,6 +533,10 @@ wg_noise_handshake_create_initiation(str
|
||||
&handshake->entry);
|
||||
|
||||
handshake->state = HANDSHAKE_CREATED_INITIATION;
|
||||
+
|
||||
+ // MOD : randomize trash
|
||||
+ dst->header.trash = gen_trash();
|
||||
+
|
||||
ret = true;
|
||||
|
||||
out:
|
||||
@@ -655,6 +677,10 @@ bool wg_noise_handshake_create_response(
|
||||
&handshake->entry);
|
||||
|
||||
handshake->state = HANDSHAKE_CREATED_RESPONSE;
|
||||
+
|
||||
+ // MOD : randomize trash
|
||||
+ dst->header.trash = gen_trash();
|
||||
+
|
||||
ret = true;
|
||||
|
||||
out:
|
||||
Index: WireGuard-0.0.20190123/src/send.c
|
||||
===================================================================
|
||||
--- WireGuard-0.0.20190123.orig/src/send.c
|
||||
+++ WireGuard-0.0.20190123/src/send.c
|
||||
@@ -200,6 +200,10 @@ static bool encrypt_packet(struct sk_buf
|
||||
header->header.type = cpu_to_le32(MESSAGE_DATA);
|
||||
header->key_idx = keypair->remote_index;
|
||||
header->counter = cpu_to_le64(PACKET_CB(skb)->nonce);
|
||||
+
|
||||
+ // MOD : randomize trash
|
||||
+ header->header.trash = gen_trash();
|
||||
+
|
||||
pskb_put(skb, trailer, trailer_len);
|
||||
|
||||
/* Now we can encrypt the scattergather segments */
|
234
docs/wireguard/wireguard-mod.txt
Normal file
234
docs/wireguard/wireguard-mod.txt
Normal file
@@ -0,0 +1,234 @@
|
||||
Посвящено возможной блокировке в РФ VPN протоколов через DPI.
|
||||
Предпосылками являются последние законодательные акты и во всю сочащиеся "секретные" записки.
|
||||
В РФ разрабатываются и готовятся к применению более продвинутые решения по блокировке трафика.
|
||||
Вполне вероятно будут резать стандартные VPN протоколы. Нам надо быть к этому готовыми.
|
||||
|
||||
Один из возможных и перспективных путей решения данного вопроса - кустомная модификация
|
||||
исходников VPN с целью незначительного изменения протокола, ломающего стандартные модули обнаружения в DPI.
|
||||
Это относительно сложно, доступно только для гиков.
|
||||
Никто не будет разрабатывать специальные модули обнаружения в DPI, если только кто-то не сделает простое и
|
||||
удобное решение для всех, и его станут широко применять. Но это маловероятно, и даже если и так,
|
||||
то всегда можно модифицировать протокол чуток по другому. Делать моды для DPI несравненно дольше
|
||||
и дороже, чем клепать на коленке изменения протокола для wireguard.
|
||||
|
||||
Рассмотрю что нам надо пропатчить в wireguard. Модифицированный wireguard проверен на виртуалках
|
||||
с десктопным linux, он работает, сообщения в wireshark действительно не вписываются в стандартный
|
||||
протокол и не опознаются.
|
||||
|
||||
Wireguard протокол очень простой. Все сообщения описаны в messages.h
|
||||
Поставим себе целью сделать 2 простые модификации :
|
||||
1) Добавим в начало всех сообщений немного мусора, чтобы изменить размер сообщений и смещения полей
|
||||
2) Изменим коды типов сообщений
|
||||
Этого может быть вполне достаточно для обмана DPI
|
||||
|
||||
--messages.h--------------------------
|
||||
/*
|
||||
enum message_type {
|
||||
MESSAGE_INVALID = 0,
|
||||
MESSAGE_HANDSHAKE_INITIATION = 1,
|
||||
MESSAGE_HANDSHAKE_RESPONSE = 2,
|
||||
MESSAGE_HANDSHAKE_COOKIE = 3,
|
||||
MESSAGE_DATA = 4
|
||||
};
|
||||
*/
|
||||
|
||||
// MOD : message type
|
||||
enum message_type {
|
||||
MESSAGE_INVALID = 0xE319CCD0,
|
||||
MESSAGE_HANDSHAKE_INITIATION = 0x48ADE198,
|
||||
MESSAGE_HANDSHAKE_RESPONSE = 0xFCA6A8F3,
|
||||
MESSAGE_HANDSHAKE_COOKIE = 0x64A3BB18,
|
||||
MESSAGE_DATA = 0x391820AA
|
||||
};
|
||||
|
||||
// MOD : generate fast trash without true RNG
|
||||
__le32 gen_trash(void);
|
||||
|
||||
struct message_header {
|
||||
/* The actual layout of this that we want is:
|
||||
* u8 type
|
||||
* u8 reserved_zero[3]
|
||||
*
|
||||
* But it turns out that by encoding this as little endian,
|
||||
* we achieve the same thing, and it makes checking faster.
|
||||
*/
|
||||
|
||||
// MOD : trash field to change message size and add 4 byte offset to all fields
|
||||
__le32 trash;
|
||||
|
||||
__le32 type;
|
||||
};
|
||||
--------------------------------------
|
||||
|
||||
Напишем функцию для генерации trash. Функция должна быть быстрая, важно не замедлить скорость.
|
||||
Мы не расчитываем, что нас будут специально ловить, иначе бы пришлось делать полноценный обфускатор.
|
||||
Задача лишь сломать стандартный модуль обнаружения протокола wireguard. Потому истинная рандомность
|
||||
trash не важна.
|
||||
Но все же немного "трэша" не повредит. Гонки между тредами так же пофигистичны. Это же трэш.
|
||||
|
||||
--noise.c-----------------------------
|
||||
// MOD : trash generator
|
||||
__le32 gtrash = 0;
|
||||
__le32 gen_trash(void)
|
||||
{
|
||||
if (gtrash)
|
||||
gtrash = gtrash*1103515243 + 12345;
|
||||
else
|
||||
// first value is true random
|
||||
get_random_bytes_wait(>rash, sizeof(gtrash));
|
||||
return gtrash;
|
||||
}
|
||||
--------------------------------------
|
||||
|
||||
Теперь осталось найти все места, где создаются сообщения и внести туда заполнение поля trash.
|
||||
Сообщений всего 4. Их можно найти по присваиванию полю type одного из значений enum message_type.
|
||||
|
||||
2 места в noise.c в функциях wg_noise_handshake_create_initiation и wg_noise_handshake_create_response,
|
||||
1 место в cookie.c в функции wg_cookie_message_create
|
||||
Дописываем в конец инициализации структуры сообщения :
|
||||
|
||||
--------------------------------------
|
||||
// MOD : randomize trash
|
||||
dst->header.trash = gen_trash();
|
||||
--------------------------------------
|
||||
|
||||
и 1 место в send.c в функции encrypt_packet
|
||||
|
||||
--------------------------------------
|
||||
// MOD : randomize trash
|
||||
header->header.trash = gen_trash();
|
||||
--------------------------------------
|
||||
|
||||
|
||||
Вот и весь патчинг. Полный patch (версия wireguard 0.0.20190123) лежит в 010-wg-mod.patch.
|
||||
Патчинг кода - самое простое. Для десктопного linux дальше все просто.
|
||||
Пересобираем через make, устанавливаем через make install, перегружаем
|
||||
модуль wireguard, перезапускаем интерфейсы, и все готово.
|
||||
|
||||
Настоящий геморой начнется когда вы это попытаетесь засунуть на роутер под openwrt.
|
||||
Одна из больших проблем linux - отсутствие совместимости драйверов на уровне бинариков.
|
||||
Поэтому собирать необходимо в точности под вашу версию ядра и в точности под его .config.
|
||||
Вам придется либо полностью самостоятельно собирать всю прошивку, либо найти SDK в точности
|
||||
от вашей версии прошивки для вашей архитектуры и собрать модуль с помощью этого SDK.
|
||||
Последний вариант более легкий.
|
||||
Для сборки вам понадобится система на linux x86_64. Ее можно установить в виртуалке.
|
||||
Теоретически можно пользоваться WSL из win10, но на практике там очень медленное I/O,
|
||||
по крайней мере на старых версиях win10. Безумно медленное. Будете собирать вечность.
|
||||
Может в новых win10 что-то и улучшили, но я бы сразу расчитывал на полноценный linux.
|
||||
|
||||
Находим здесь вашу версию : https://downloads.openwrt.org/
|
||||
Скачиваем файл openwrt-sdk-*.tar.xz или lede-sdk-*.tar.xz
|
||||
Например : https://downloads.openwrt.org/releases/18.06.2/targets/ar71xx/generic/openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64.tar.xz
|
||||
Если ваша версия непонятна или стара, то проще будет найти последнюю прошивку и перешить роутер.
|
||||
Распаковываем SDK. Следующими командами можно собрать оригинальный вариант wireguard :
|
||||
|
||||
# scripts/feeds update -a
|
||||
# scripts/feeds install -a
|
||||
# make defconfig
|
||||
# make -j 4 package/wireguard/compile
|
||||
|
||||
Сборка будет довольно долгой. Ведь придется подтащить ядро, собрать его, собрать зависимости.
|
||||
"-j 4" означает использовать 4 потока. Впишите вместо 4 количество доступных cpu cores.
|
||||
|
||||
Получим следующие файлы :
|
||||
|
||||
openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/bin/targets/ar71xx/generic/packages/kmod-wireguard_4.9.152+0.0.20190123-1_mips_24kc.ipk
|
||||
openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/bin/packages/mips_24kc/base/wireguard-tools_0.0.20190123-1_mips_24kc.ipk
|
||||
|
||||
Но это будет оригинальный wireguard. Нам нужен патченый.
|
||||
Установим quilt и mc для нормального редактора вместо vim :
|
||||
|
||||
# sudo apt-get update
|
||||
# sudo apt-get install quilt mc
|
||||
|
||||
# make package/wireguard/clean
|
||||
# make package/wireguard/prepare V=s QUILT=1
|
||||
|
||||
|
||||
Сорцы приготовлены для сборки в :
|
||||
openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/build_dir/target-mips_24kc_musl/linux-ar71xx_generic/WireGuard-0.0.20190123/src
|
||||
|
||||
# cd build_dir/target-mips_24kc_musl/linux-ar71xx_generic/WireGuard-0.0.20190123/src
|
||||
# quilt push -a
|
||||
# quilt new 010-wg-mod.patch
|
||||
# export EDITOR=mcedit
|
||||
|
||||
Далее будет открываться редактор mcedit, в который нужно вносить изменения в каждый файл :
|
||||
|
||||
# quilt edit messages.h
|
||||
# quilt edit cookie.c
|
||||
# quilt edit noise.c
|
||||
# quilt edit send.c
|
||||
# quilt diff
|
||||
# quilt refresh
|
||||
|
||||
Получили файл патча в :
|
||||
openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/build_dir/target-mips_24kc_musl/linux-ar71xx_generic/WireGuard-0.0.20190123/patches/010-wg-mod.patch
|
||||
|
||||
Выходим в корень SDK.
|
||||
|
||||
# make package/wireguard/compile V=99
|
||||
|
||||
Если не было ошибок, то получили измененные ipk.
|
||||
Патч можно зафиксировать в описании пакета :
|
||||
|
||||
# make package/wireguard/update
|
||||
|
||||
Получим :
|
||||
openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/feeds/base/package/network/services/wireguard/patches/010-wg-mod.patch
|
||||
При последующей очистке и пересборке он будет автоматом применяться.
|
||||
|
||||
|
||||
АЛЬТЕРНАТИВА : можно не возиться с quilt.
|
||||
сделайте
|
||||
# make package/wireguard/clean
|
||||
# make package/wireguard/prepare
|
||||
и напрямую модифицируйте или копируйте файлы в
|
||||
openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/build_dir/target-mips_24kc_musl/linux-ar71xx_generic/WireGuard-0.0.20190123/src
|
||||
затем
|
||||
# make package/wireguard/compile
|
||||
|
||||
Если нужно поменять версию wireguard, то идите в
|
||||
openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/feeds/base/package/network/services/wireguard/Makefile
|
||||
поменяйте там версию в PKG_VERSION на последнюю из : https://git.zx2c4.com/WireGuard
|
||||
скачайте tar.xz с этой версией , вычислите его sha256sum, впишите в PKG_HASH
|
||||
|
||||
1 раз где-нибудь пропатчите файлы последней версии wireguard в текстовом редакторе, скопируйте в build_dir,
|
||||
сделайте версию для openwrt. эти же файлы скопируйте на ваш сервер с десктопным linux, сделайте там make / make install
|
||||
|
||||
Но имейте в виду, что build_dir - локация для временных файлов.
|
||||
make clean оттуда все снесет, включая ваши модификации. Модифицированные файлы лучше сохранить отдельно,
|
||||
чтобы потом было легко скопировать обратно.
|
||||
|
||||
Полученные ipk копируем на роутер в /tmp, устанавливаем через
|
||||
# cd /tmp
|
||||
# opkg install *.ipk
|
||||
Если требует зависимостей, то
|
||||
# opkg update
|
||||
# opkg install .... <зависимости>
|
||||
# opkg install *.ipk
|
||||
|
||||
# rmmod wireguard
|
||||
# kmodloader
|
||||
# dmesg | tail
|
||||
должны увидеть что-то вроде :
|
||||
[8985.415490] wireguard: WireGuard 0.0.20190123 loaded. See www.wireguard.com for information.
|
||||
[8985.424178] wireguard: Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||
значит модуль загрузился
|
||||
|
||||
Могут понадобиться ключи opkg --force-reinstall, --force-depends.
|
||||
--force-depends поможет при несоответствии hash версии ядра. То есть версия x.x.x та же самая, но hash конфигурации разный.
|
||||
При несоответствии x.x.x вы что-то делаете не так, работать это не будет.
|
||||
Например : 4.14.56-1-b1186491495127cc6ff81d29c00a91fc, 4.14.56-1-3f8a21a63974cfb7ee67e41f2d4b805d
|
||||
Это свидетельствует о несоответствии .config ядра при сборке прошивки и в SDK.
|
||||
Если несоответствие легкое, то может все прокатить, но при более серьезной разнице в .config модуль может не загрузиться
|
||||
или вызвать стабильные или хаотические падения ядра и перезагрузки (включая вариант беcконечной перезагрузки - bootloop).
|
||||
Так что перед --force-depends убедитесь, что знаете как лечится такая ситуация, и не стоит это делать при отсутствии физического
|
||||
доступа к девайсу.
|
||||
|
||||
Когда поднимите линк, и вдруг ничего не будет работать, то посмотрите в wireshark udp пакеты
|
||||
на порт endpoint. Они не должны начинаться с 0,1,2,3,4. В первых 4 байтах должен быть рандом,
|
||||
в следующих 4 байтах - значения из измененного enum message_type. Если пакет все еще начинается с 0..4,
|
||||
значит модуль wireguard оригинальный, что-то не собралось, не скопировалось, не перезапустилось.
|
||||
В противном случае должен подняться линк, пинги ходить. Значит вы победили, поздравляю.
|
||||
Регулятору будет намного сложнее поймать ваш VPN.
|
377
docs/wireguard/wireguard_iproute_openwrt.txt
Normal file
377
docs/wireguard/wireguard_iproute_openwrt.txt
Normal file
@@ -0,0 +1,377 @@
|
||||
Есть возможность поднять свой VPN сервер ? Не хотим использовать redsocks ?
|
||||
Хотим завертывать на VPN только часть трафика ?
|
||||
Например, из ipset zapret только порт tcp:443, из ipban - весь трафик, не только tcp ?
|
||||
Да, с VPN такое возможно.
|
||||
Опишу понятийно как настраивается policy based routing в openwrt на примере wireguard.
|
||||
Вместо wireguard можно использовать openvpn или любой другой. Но wireguard прекрасен сразу несколькими вещами.
|
||||
Главная из которых - в разы большая скорость, даже немного превышающая ipsec.
|
||||
Ведь openvpn основан на tun, а tun - всегда в разы медленнее решения в kernel mode,
|
||||
и если для PC оно может быть не так актуально, для soho роутеров - более чем.
|
||||
Wireguard может дать 50 mbps там, где openvpn еле тащит 10.
|
||||
Но есть и дополнительное требование. Wireguard работает в ядре, значит ядро должно
|
||||
быть под вашим контролем. vps на базе openvz не подойдет ! Нужен xen, kvm,
|
||||
любой другой вариант, где загружается ваше собственное ядро, а не используется
|
||||
общее, разделяемое на множество vps. В openvz вам никто не даст лезть в ядро.
|
||||
|
||||
Если вдруг окажется, что основные VPN протоколы блокируется DPI, включая wireguard,
|
||||
то стоит смотреть в сторону либо обфускации трафика до состояния нераспознаваемого
|
||||
мусора, либо маскировки под TLS (лучше на порт 443). Скорость, конечно, вы потеряете, но это
|
||||
та самая ситуация, которая описывается словами "медленно или никак".
|
||||
Маскированные под TLS протоколы DPI может распознать двумя действиями :
|
||||
пассивно через анализ статистических характеристик пакетов (время, размер, периодичность, ..)
|
||||
или активно через подключение к вашему серверу от себя и попытку поговорить с сервером по
|
||||
известным протоколам (называется active probing). Если вы подключаетесь к серверу
|
||||
с фиксированных IP, то активный пробинг можно надежно заблокировать через ограничение
|
||||
диапазонов IP адресов, с которых можно подключаться к серверу. В ином случае можно использовать
|
||||
технику "port knocking".
|
||||
Перспективным направлением так же считаю легкую собственную модификацию исходников
|
||||
существующих VPN с целью незначительного изменения протокола, которая ломает стандартные
|
||||
модули обнаружения в DPI. В wireguard можно добавить в начало пакета handshake лишнее поле,
|
||||
заполненное случайным мусором. Разумеется, в таком случае требуется держать измененную версию
|
||||
как на сервере, так и на клиенте. Если затея срабатывает, то вы получаете максимальную
|
||||
скорость, при этом полностью нагибая регулятора.
|
||||
Полезная инфа по теме : https://habr.com/ru/post/415977/
|
||||
|
||||
Понятийно необходимо выполнить следующие шаги :
|
||||
1) Поднять vpn сервер.
|
||||
2) Настроить vpn клиент. Результат этого шага - получение поднятого интерфейса vpn.
|
||||
Будь то wireguard, openvpn или любой другой тип vpn.
|
||||
3) Создать такую схему маршрутизации, при которой пакеты, помечаемые особым mark,
|
||||
попадают на vpn, а остальные идут обычным способом.
|
||||
4) Создать правила, выставляющие mark для всего трафика, который необходимо рулить на vpn.
|
||||
Критерии могут быть любые, ограниченные лишь возможностями iptables и вашим воображением.
|
||||
|
||||
Будем считать наш vpn сервер находится на ip 91.15.68.202.
|
||||
Вешать его будем на udp порт 12345. На этот же порт будем вешать и клиентов.
|
||||
Сервер работает под debian 9. Клиент работает под openwrt.
|
||||
Для vpn отведем подсеть 192.168.254.0/24.
|
||||
|
||||
--- Поднятие сервера ---
|
||||
|
||||
На сервере должны быть установлены заголовки ядра (linux-headers-...) и компилятор gcc.
|
||||
Качаем последний tar.xz с wireguard отсюда : https://git.zx2c4.com/WireGuard/
|
||||
|
||||
# tar xf WireGuard*.tar.xz
|
||||
# cd WireGuard-*/src
|
||||
# make
|
||||
# strip --strip-debug wireguard.ko
|
||||
# sudo make install
|
||||
|
||||
wireguard основан на понятии криптороутинга. Каждый пир (сервер - тоже пир)
|
||||
имеет пару открытый/закрытый ключ. Закрытый ключ остается у пира,
|
||||
открытый прописывается у его партнера. Каждый пир авторизует другого
|
||||
по знанию приватного ключа, соответствующего прописанному у него публичному ключу.
|
||||
Протокол построен таким образом, что на все неправильные udp пакеты не следует ответа.
|
||||
Не знаешь приватный ключ ? Не смог послать правильный запрос ? Долбись сколько влезет,
|
||||
я тебе ничего не отвечу. Это защищает от активного пробинга со стороны DPI и просто
|
||||
экономит ресурсы.
|
||||
Значит первым делом нужно создать 2 пары ключей : для сервера и для клиента.
|
||||
wg genkey генерит приватный ключ, wg pubkey получает из него публичный ключ.
|
||||
|
||||
# wg genkey
|
||||
oAUkmhoREtFQ5D5yZmeHEgYaSWCcLYlKe2jBP7EAGV0=
|
||||
# echo oAUkmhoREtFQ5D5yZmeHEgYaSWCcLYlKe2jBP7EAGV0= | wg pubkey
|
||||
bCdDaPYSTBZVO1HTmKD+Tztuf3PbOWGDWfz7Lb1E6C4=
|
||||
# wg genkey
|
||||
OKXX0TSlyjJmGt3/yHlHxi0AqjJ0vh+Msne3qEHk0VM=
|
||||
# echo OKXX0TSlyjJmGt3/yHlHxi0AqjJ0vh+Msne3qEHk0VM= | wg pubkey
|
||||
EELdA2XzjcKxtriOCPBXMOgxlkgpbRdIyjtc3aIpkxg=
|
||||
|
||||
Пишем конфиг
|
||||
--/etc/wireguard/wgvps.conf-------------------
|
||||
[Interface]
|
||||
PrivateKey = OKXX0TSlyjJmGt3/yHlHxi0AqjJ0vh+Msne3qEHk0VM=
|
||||
ListenPort = 12345
|
||||
|
||||
[Peer]
|
||||
#Endpoint =
|
||||
PublicKey = bCdDaPYSTBZVO1HTmKD+Tztuf3PbOWGDWfz7Lb1E6C4=
|
||||
AllowedIPs = 192.168.254.3
|
||||
PersistentKeepalive=20
|
||||
----------------------------------------------
|
||||
|
||||
Wireguard - минималистичный vpn. В нем нет никаких средств для автоконфигурации ip.
|
||||
Все придется прописывать руками.
|
||||
В wgvps.conf должны быть перечислены все пиры с их публичными ключами,
|
||||
а так же прописаны допустимые для них ip адреса.
|
||||
Назначим нашему клиенту 192.168.254.3. Сервер будет иметь ip 192.168.254.1.
|
||||
Endpoint должен быть прописан хотя бы на одном пире.
|
||||
Если endpoint настроен для пира, то wireguard будет периодически пытаться к нему подключиться.
|
||||
В схеме клиент/сервер у сервера можно не прописывать endpoint-ы пиров, что позволит
|
||||
менять ip и быть за nat. Endpoint пира настраивается динамически после успешной фазы
|
||||
проверки ключа.
|
||||
|
||||
Включаем маршрутизцию :
|
||||
# echo net.ipv4.ip_forward = 1 >>/etc/sysctl.conf
|
||||
# sysctl -p
|
||||
|
||||
Интерфейс конфигурится стандартно для дебианоподобных систем :
|
||||
|
||||
--/etc/network/interfaces.d/wgvps-------------
|
||||
auto wgvps
|
||||
iface wgvps inet static
|
||||
address 192.168.254.1
|
||||
netmask 255.255.255.0
|
||||
pre-up ip link add $IFACE type wireguard
|
||||
pre-up wg setconf $IFACE /etc/wireguard/$IFACE.conf
|
||||
post-up iptables -t nat -A POSTROUTING -o eth0 -s 192.168.254.0/24 -j MASQUERADE
|
||||
post-up iptables -A FORWARD -o eth0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
|
||||
post-down iptables -D FORWARD -o eth0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
|
||||
post-down iptables -t nat -D POSTROUTING -o eth0 -s 192.168.254.0/24 -j MASQUERADE
|
||||
post-down ip link del $IFACE
|
||||
----------------------------------------------
|
||||
|
||||
Поднятие через ifup wgvps, опускание через ifdown wgvps.
|
||||
При поднятии интерфейса заодно настраивается nat. eth0 здесь означает интерфейс vpn сервера с инетовским ip адресом.
|
||||
Если у вас какая-то система управления фаерволом, то надо настройку nat прикручивать туда.
|
||||
Пример написан для простейшего случая, когда никаких ограничений нет, таблицы iptables пустые.
|
||||
Чтобы посмотреть текущие настройки wireguard, запустите 'wg' без параметров.
|
||||
|
||||
|
||||
--- Поднятие клиента ---
|
||||
|
||||
# opkg update
|
||||
# opkg install wireguard
|
||||
|
||||
Добавляем записи в конфиги.
|
||||
|
||||
--/etc/config/network--------------------------
|
||||
config interface 'wgvps'
|
||||
option proto 'wireguard'
|
||||
option auto '1'
|
||||
option private_key 'oAUkmhoREtFQ5D5yZmeHEgYaSWCcLYlKe2jBP7EAGV0='
|
||||
option listen_port '12345'
|
||||
option metric '9'
|
||||
option mtu '1420'
|
||||
|
||||
config wireguard_wgvps
|
||||
option public_key 'EELdA2XzjcKxtriOCPBXMOgxlkgpbRdIyjtc3aIpkxg=
|
||||
list allowed_ips '0.0.0.0/0'
|
||||
option endpoint_host '91.15.68.202'
|
||||
option endpoint_port '12345'
|
||||
option route_allowed_ips '0'
|
||||
option persistent_keepalive '20'
|
||||
|
||||
config interface 'wgvps_ip'
|
||||
option proto 'static'
|
||||
option ifname '@wgvps'
|
||||
list ipaddr '192.168.254.3/24'
|
||||
|
||||
config route
|
||||
option interface 'wgvps'
|
||||
option target '0.0.0.0/0'
|
||||
option table '100'
|
||||
|
||||
config rule
|
||||
option mark '0x800/0x800'
|
||||
option priority '100'
|
||||
option lookup '100'
|
||||
------------------------------------------------
|
||||
|
||||
--/etc/config/firewall--------------------------
|
||||
config zone
|
||||
option name 'tunvps'
|
||||
option output 'ACCEPT'
|
||||
option input 'REJECT'
|
||||
option masq '1'
|
||||
option mtu_fix '1'
|
||||
option forward 'REJECT'
|
||||
option network 'wgvps wgvps_ip'
|
||||
|
||||
config forwarding
|
||||
option dest 'tunvps'
|
||||
option src 'lan'
|
||||
|
||||
config rule
|
||||
option name 'Allow-ICMP-tunvps'
|
||||
option src 'tunvps'
|
||||
option proto 'icmp'
|
||||
option target 'ACCEPT'
|
||||
|
||||
config rule
|
||||
option target 'ACCEPT'
|
||||
option src 'wan'
|
||||
option proto 'udp'
|
||||
option family 'ipv4'
|
||||
option src_port '12345'
|
||||
option src_ip '91.15.68.202'
|
||||
option name 'WG-VPS'
|
||||
------------------------------------------------
|
||||
|
||||
Что тут было сделано :
|
||||
*) Настроен интерфейс wireguard. Указан собственный приватный ключ.
|
||||
*) Настроен пир-партнер с указанием его публичнго ключа и endpoint (ip:port нашего сервера)
|
||||
такая настройка заставит периодически долбиться на сервер по указанному ip
|
||||
route_allowed_ip '0' запрещает автоматическое создание маршрута
|
||||
allowed_ips '0.0.0.0/0' разрешает пакеты с любым адресом источника.
|
||||
ведь мы собираемся подключаться к любым ip в инете
|
||||
persistent_keepalive '20' помогает исключить дропание mapping на nat-е, если мы сидим за ним,
|
||||
да и вообще полезная вещь, чтобы не было подвисших пиров
|
||||
*) Статическая конфигурация ip интерфейса wgvps.
|
||||
*) Маршрут default route на wgvps в отдельной таблице маршрутизации с номером 100. Аналог команды ip route add .. table 100
|
||||
*) Правило использовать таблицу 100 при выставлении в mark бита 0x800. Аналог команды ip rule.
|
||||
*) Отдельная зона фаервола для VPN - 'tunvps'. В принципе ее можно не создавать, можете приписать интерфейс к зоне wan.
|
||||
Но в случае с отдельной зоной можно настроить особые правила на подключения с vpn сервера в сторону клиента.
|
||||
*) Разрешение форвардинга между локалкой за роутером и wgvps.
|
||||
*) Разрешение принимать icmp от vpn сервера, включая пинги. ICMP жизненно важны для правильного функционирования ip сети !
|
||||
*) И обязательно проткнуть дырку в фаерволе, чтобы принимать пакеты wireguard со стороны инетовского ip vpn сервера.
|
||||
|
||||
# fw3 restart
|
||||
# ifup wgvps
|
||||
# ifconfig wgvps
|
||||
# ping 192.168.254.1
|
||||
|
||||
Если все хорошо, должны ходить пинги.
|
||||
С сервера не помешает :
|
||||
# ping 192.168.254.3
|
||||
|
||||
|
||||
--- Маркировка трафика ---
|
||||
|
||||
Завернем на vpn все из ipset zapret на tcp:443 и все из ipban.
|
||||
OUTPUT относится к исходящим с роутера пакетам, PREROUTING - ко всем остальным.
|
||||
Если с роутера ничего заруливать не надо, можно опустить все до команд с PREROUTING.
|
||||
|
||||
--/etc/firewall.user----------------------------
|
||||
. /lib/functions/network.sh
|
||||
|
||||
network_find_wan wan_iface
|
||||
|
||||
for ext_iface in $wan_iface; do
|
||||
network_get_device DEVICE $ext_iface
|
||||
|
||||
iptables -t mangle -C OUTPUT -p tcp --dport 443 -o $DEVICE -m set --match-set zapret dst -j MARK --set-mark 0x800/0x800 ||
|
||||
iptables -t mangle -I OUTPUT -p tcp --dport 443 -o $DEVICE -m set --match-set zapret dst -j MARK --set-mark 0x800/0x800
|
||||
iptables -t mangle -C OUTPUT -o $DEVICE -m set --match-set ipban dst -j MARK --set-mark 0x800/0x800 ||
|
||||
iptables -t mangle -I OUTPUT -o $DEVICE -m set --match-set ipban dst -j MARK --set-mark 0x800/0x800
|
||||
done
|
||||
|
||||
iptables -t mangle -C PREROUTING -p tcp --dport 443 -m set --match-set zapret dst -j MARK --set-mark 0x800/0x800 ||
|
||||
iptables -t mangle -I PREROUTING -p tcp --dport 443 -m set --match-set zapret dst -j MARK --set-mark 0x800/0x800
|
||||
iptables -t mangle -C PREROUTING -m set --match-set ipban dst -j MARK --set-mark 0x800/0x800 ||
|
||||
iptables -t mangle -I PREROUTING -m set --match-set ipban dst -j MARK --set-mark 0x800/0x800
|
||||
------------------------------------------------
|
||||
|
||||
# fw3 restart
|
||||
|
||||
|
||||
--- По поводу двойного NAT ---
|
||||
|
||||
В описанной конфигурации nat выполняется дважды : на роутере-клиенте происходит замена адреса источника из LAN
|
||||
на 192.168.254.3 и на сервере замена 192.168.254.3 на внешний адрес сервера в инете.
|
||||
Зачем так делать ? Исключительно для простоты настройки. Но если вы готовы чуток еще поднапрячься и не хотите двойного nat,
|
||||
то можете вписать в /etc/config/firewall "masq '0'", на сервер дописать маршрут до вашей подсети lan.
|
||||
Чтобы не делать это для каждого клиента, можно отвести под всех клиентов диапазон 192.168.0.0-192.168.127.255
|
||||
и прописать его одним маршрутом.
|
||||
|
||||
--/etc/network/interfaces.d/wgvps-------------
|
||||
post-up ip route add dev $IFACE 192.168.0.0/17
|
||||
post-down ip route del dev $IFACE 192.168.0.0/17
|
||||
----------------------------------------------
|
||||
|
||||
Так же необходимо указать wireguard дополнительные разрешенные ip для peer :
|
||||
|
||||
--/etc/wireguard/wgvps.conf-------------------
|
||||
[Peer]
|
||||
PublicKey = bCdDaPYSTBZVO1HTmKD+Tztuf3PbOWGDWfz7Lb1E6C4=
|
||||
AllowedIPs = 192.168.254.3, 192.168.2.0/24
|
||||
----------------------------------------------
|
||||
|
||||
Всем клиентам придется назначать различные диапазоны адресов в lan и индивидуально прописывать AllowedIPs
|
||||
для каждого peer.
|
||||
|
||||
# ifdown wgvps ; ifup wgvps
|
||||
|
||||
На клиенте разрешим форвард icmp, чтобы работал пинг и корректно определялось mtu.
|
||||
|
||||
--/etc/config/firewall--------------------------
|
||||
config rule
|
||||
option name 'Allow-ICMP-tunvps'
|
||||
option src 'tunvps'
|
||||
option dest 'lan'
|
||||
option proto 'icmp'
|
||||
option target 'ACCEPT'
|
||||
------------------------------------------------
|
||||
|
||||
# fw3 restart
|
||||
|
||||
Сейчас уже можно с vpn сервера пингануть ip адрес внутри локалки клиента. Пинги должны ходить.
|
||||
|
||||
Отсутствие двойного NAT значительно облегчает проброс портов с внешнего IP vpn сервера в локалку какого-либо клиента.
|
||||
Для этого надо выполнить 2 действия : добавить разрешение в фаервол на клиенте и сделать dnat на сервере.
|
||||
Пример форварда портов 5001 и 5201 на 192.168.2.2 :
|
||||
|
||||
--/etc/config/firewall--------------------------
|
||||
config rule
|
||||
option target 'ACCEPT'
|
||||
option src 'tunvps'
|
||||
option dest 'lan'
|
||||
option proto 'tcp udp'
|
||||
option dest_port '5001 5201'
|
||||
option dest_ip '192.168.2.2'
|
||||
option name 'IPERF'
|
||||
------------------------------------------------
|
||||
|
||||
# fw3 restart
|
||||
|
||||
--/etc/network/interfaces.d/wgvps-------------
|
||||
post-up iptables -t nat -A PREROUTING -i eth0 -p tcp -m multiport --dports 5001,5201 -j DNAT --to-destination 192.168.2.2
|
||||
post-up iptables -t nat -A POSTROUTING -o $IFACE -d 192.168.2.2 -p tcp -m multiport --dports 5001,5201 -j MASQUERADE
|
||||
post-up iptables -t nat -A PREROUTING -i eth0 -p udp -m multiport --dports 5001,5201 -j DNAT --to-destination 192.168.2.2
|
||||
post-up iptables -t nat -A POSTROUTING -o $IFACE -d 192.168.2.2 -p udp -m multiport --dports 5001,5201 -j MASQUERADE
|
||||
post-down iptables -t nat -D PREROUTING -i eth0 -p tcp -m multiport --dports 5001,5201 -j DNAT --to-destination 192.168.2.2
|
||||
post-down iptables -t nat -D POSTROUTING -o $IFACE -d 192.168.2.2 -p tcp -m multiport --dports 5001,5201 -j MASQUERADE
|
||||
post-down iptables -t nat -D PREROUTING -i eth0 -p udp -m multiport --dports 5001,5201 -j DNAT --to-destination 192.168.2.2
|
||||
post-down iptables -t nat -D POSTROUTING -o $IFACE -d 192.168.2.2 -p udp -m multiport --dports 5001,5201 -j MASQUERADE
|
||||
----------------------------------------------
|
||||
|
||||
# ifdown wgvps ; ifup wgvps
|
||||
|
||||
Пример приведен для iperf и iperf3, чтобы показать как пробрасывать несколько портов tcp+udp с минимальным количеством команд.
|
||||
Проброс tcp и udp порта так же необходим для полноценной работы bittorrent клиента, чтобы работали входящие.
|
||||
|
||||
--- Как мне отправлять на vpn весь трафик с bittorrent ? ---
|
||||
|
||||
Можно поступить так : посмотрите порт в настройках torrent клиента, убедитесь, что не поставлено "случайный порт",
|
||||
добавьте на роутер правило маркировки по порту источника.
|
||||
Но мне предпочтительно иное решение. На windows есть замечательная возможность
|
||||
прописать правило установки поля качества обслуживания в заголовках ip пакетов в зависимости от процесса-источника.
|
||||
Для windows 7/2008R2 необходимо будет установить ключик реестра и перезагрузить комп :
|
||||
# reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\QoS /v "Do not use NLA" /t REG_SZ /d "1"
|
||||
Редактировать политику можно в : gpedit.msc -> Computer Configuration -> Windows Settings -> Policy-based QoS
|
||||
На win 10 ключик реестра больше не работает, правила qos в gpedit применяются только для профиля домена.
|
||||
Необходимо пользоваться командой powershell New-NetQosPolicy. Гуглите хелп по ней. Пример :
|
||||
# powershell New-NetQosPolicy -Name "torrent" -AppPathNameMatchCondition "qbittorrent.exe" -DSCPAction 1
|
||||
Однозначно требуется проверка в wireshark или netmon успешности установки поля dscp. Если там по-прежнему 0x00,
|
||||
значит что-то не сработало. 0x04 означает DSCP=1 (dscp находится в старших 6 битах).
|
||||
|
||||
На роутере в фаер прописываем правило :
|
||||
|
||||
--/etc/config/firewall--------------------------
|
||||
config rule
|
||||
option target 'MARK'
|
||||
option src 'lan'
|
||||
option proto 'all'
|
||||
option extra '-m dscp --dscp 1'
|
||||
option name 'route-dscp-1'
|
||||
option set_mark '0x0800/0x0800'
|
||||
------------------------------------------------
|
||||
|
||||
# fw3 restart
|
||||
|
||||
Теперь все с полем dscp "1" идет на vpn. Клиент сам решает какой трафик ему нужно забрасывать
|
||||
на vpn, перенастраивать роутер не нужно.
|
||||
На linux клиенте проще всего будет выставлять dscp в iptables по номеру порта источника :
|
||||
|
||||
--/etc/rc.local---------------------------------
|
||||
iptables -t mangle -A OUTPUT -p tcp --sport 23444 -j DSCP --set-dscp 1
|
||||
iptables -t mangle -A OUTPUT -p udp --sport 23444 -j DSCP --set-dscp 1
|
||||
------------------------------------------------
|
||||
|
||||
можно привязываться к pid процесса, но тогда нужно перенастраивать iptables при каждом перезапуске
|
||||
торент клиента, это требует рута, и все становится очень неудобно.
|
||||
|
||||
--- А если не заработало ? ---
|
||||
|
||||
Мануал пишется не как копипастная инструкция, а как помощь уже соображающему.
|
||||
В руки вам ifconfig, ip, iptables, tcpdump, ping. В умелых руках творят чудеса.
|
Reference in New Issue
Block a user