Установка программы модификации сетевых пакетов NFQWS на роутер Keenetiс

от автора

Привет, Хабр!

Сегодня рассмотрим вариант установки утилиты модификации сетевых пакетов Zapret на роутеры Keenetic. В отличии от простого использования на конкретных устройствах, при установке на роутер появляется возможность обрабатывать трафик идущий от всех устройств, подключенных к домашней локальной сети (ПК, смартфоны и смарт телевизоры).

Указанная утилита предлагает два основных режима работы – это TPWS или NFQWS. При использовании в режиме TPWS есть недостатки, заключающиеся в том, что в этом режиме не модифицируется протокол QUIC (HTTP/3), а также приложение YouTube на смарт телевизорах с WebOS или Android TV перестает вообще запускаться.

Информация по протоколам YouTube и возникающим проблемам при использовании

Для начала попробуем определиться с тем, какие протоколы используются YouTube на различных устройствах:

  • В браузерах на ПК может использоваться как новый протокол QUIC (трафик идет по протоколу UDP на порт 443), так и классический HTTPS (трафик идет по протоколу TCP на порт 443). Однако, у меня хоть в браузере и включена поддержка протокола QUIC, но YouTube мне так и не удалось через него заставить работать — все время трафик идет через HTTPS;

  • В приложении YouTube на Android, напротив, уже изначально используется протокол QUIC. Выяснилось это сразу после запуска TPWS – в браузерах на ПК все работало без проблем, а вот на Android устройствах, как без использования данной утилиты;

  • С приложением YouTube на WebOS еще куда запутаннее: там загрузка интерфейса идет по протоколу HTTPS (TCP порт 443), а видео протоколу QUIC (UDP порт 443). Но в случаи, если подключение по QUIC не доступно, тогда приложения, что на Android устройствах, что WebOS переходят на протокол HTTPS. Так чтобы на телевизоре и телефоне YouTube не тормозил при работе с TPWS, необходимо блокировать трафик UDP на порт 443, для того, чтобы заставить приложения подключатся по протоколу HTTPS. Но это не решит проблему с поломкой загрузки интерфейса приложения на WebOS (Android TV) при работе с TPWS.

В качестве вариантов решения данной проблемы при использовании утилиты в режиме TPWS, я вижу три возможных варианта:

  1. Подбирать параметры запуска TPWS (но их там не так много), чтобы они не ломали загрузку приложения YouTube, а все остальное работало, как должно. Мне этого так и не удалось дробится.

  2. Вычислить доменные адреса, по которым приложения YouTube загружает интерфейс и включить их в exclude список TPWS. Должно работать если эти домены не заблокированы;

  3. И самый неправильный способ – это останавливать работу TPWS на время первоначальной загрузки интерфейса приложения, а за тем для просмотра видео запускать его.

Я пошел другим более гибким и правильным путем, использования утилиты zapret в режиме NFQWS. Этот режим имеет ряд преимуществ пред режимом TPWS – больше параметров модификации сетевых пакетов, а также возможность модификации трафика по протоколу QUIC.

Инструкция по установке NFQWS на роутер keenetic

Данная инструкция будет выполнятся на примере роутера Keenetic ultra (kn-1810).

Для установки утилиты zapret, необходимо сначала сначала подготовить внешний USB-накопитель и установить на него систему пакетов репозитория Entware согласно инструкции — Установка-системы-пакетов-репозитория-Entware-на-USB-накопитель.

После развертывания Entware на роутере с помощью терминальной программы Putty создаем SSH подключения, с указанием IP-адрес роутера (по умолчанию 192.168.1.1) и порта 222. Дальше авторизуемся с использованием логина: root и пароля: keenetic.

Далее можно приступать непосредственно к установке утилиты NFQWS:

Устанавливаем пакеты с помощью команды:

  1. opkg install coreutils-sort curl git-http grep gzip ipset iptables kmod_ndms xtables-addons_legacy

  2. Приходим папку opt:

    cd /opt/

  3. Скачиваем Zapret с github:

    git clone --depth=1 https://github.com/bol-van/zapret.git

  4. Для начала узнаем имя внешнего сетевого интерфейса (WAN) на роутере. Его можно узнать воспользовавшись командой ifconfig, которая выведет все сетевые интерфейсы в системе. Просто находим тот интерфейс, у которого будет ваш внешний IP адрес. В моем случаи – это eth3.

  5. Переходим в папку zapret и выполняем скрипт:

    cd zapret
    ./install_easy.sh

  6. Далее делаем отвечаем на все вопросы, как скриншоте:

    Выполнение скрипта install_easy.sh

    Выполнение скрипта install_easy.sh
  7. Выбираем свой ранее найденное имя внешнего сетевого интерфейса (WAN):

    Выбираем имя внешнего сетевого интерфейса (WAN)

    Выбираем имя внешнего сетевого интерфейса (WAN)
  8. Продолжаем отвечать на все вопросы:

    Завершение выполнения скрипта install_easy.sh

    Завершение выполнения скрипта install_easy.sh
  9. Правим скрипт c именем zapret в командной строке с помощью предпочитаемого текстового редактора (в качестве примера vi) или можно зайти с компьютера через сеть на USB-накопитель (если он расшарен с помощью сервера SMB) и редактировать в текстовом редакторе на компьютере:

    vi /opt/zapret/init.d/sysv/zapret

    Добавляем в функцию do_start() код загрузки модулей ядра linux (xt_multiport.ko, xt_connbytes.ko, xt_NFQUEUE.ko), так как они по умолчанию не загружаются, а без них iptables будет выдавать ошибки при попытке приметь необходимые правила.

    Для перенаправления исходящего и проходящего в сторону внешнего интерфейса трафика на очередь NFQUEUE, в функции do_start() и do_stop() закомментируем строчки с вызовами zapret_apply_firewall в zapret_unapply_firewall и туда же добавляем свои правила iptables. В данных командах необходимо заменить название внешнего интернет интерфейса (WAN) eth3 на свой.

    Затем в секции restart-fw|restart_fw закомментируем строчки с вызовами zapret_apply_firewall в zapret_unapply_firewall и туда же добавляем те же правила iptables, что уже писали выше, но в обратном порядке.

    #!/bin/sh ### BEGIN INIT INFO # Provides:zapret # Required-Start:$local_fs $network # Required-Stop:$local_fs $network # Default-Start:     2 3 4 5 # Default-Stop:      0 1 6 ### END INIT INFO  SCRIPT=$(readlink -f "$0") EXEDIR=$(dirname "$SCRIPT") ZAPRET_BASE=$(readlink -f "$EXEDIR/../..") . "$EXEDIR/functions"  NAME=zapret DESC=anti-zapret  do_start() {      if lsmod | grep "xt_multiport " &> /dev/null ;  then echo "xt_multiport.ko is already loaded"     else         if insmod /lib/modules/$(uname -r)/xt_multiport.ko &> /dev/null; then echo "iptable_raw.ko loaded"         else echo "Cannot find xt_multiport.ko kernel module, aborting" exit 1         fi fi       if lsmod | grep "xt_connbytes " &> /dev/null ;  then         echo "xt_connbytes.ko is already loaded"     else         if insmod /lib/modules/$(uname -r)/xt_connbytes.ko &> /dev/null; then echo "xt_connbytes.ko loaded"         else echo "Cannot find xt_connbytes.ko kernel module, aborting" exit 1         fi fi  if lsmod | grep "xt_NFQUEUE " &> /dev/null ;  then         echo "xt_NFQUEUE.ko is already loaded"     else         if insmod /lib/modules/$(uname -r)/xt_NFQUEUE.ko &> /dev/null; then             echo "xt_NFQUEUE.ko loaded"         else             echo "Cannot find xt_NFQUEUE.ko kernel module, aborting"             exit 1         fi     fi   zapret_run_daemons #[ "$INIT_APPLY_FW" != "1" ] || { zapret_apply_firewall; }     iptables -t mangle -I POSTROUTING -o eth3 -p tcp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass     iptables -t mangle -I POSTROUTING -o eth3 -p tcp --dport 80 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass iptables -t mangle -I POSTROUTING -o eth3 -p udp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 210 --queue-bypass iptables -t nat -A POSTROUTING -o eth3 -j MASQUERADE  } do_stop() { zapret_stop_daemons #[ "$INIT_APPLY_FW" != "1" ] || zapret_unapply_firewall iptables -t mangle -D POSTROUTING -o eth3 -p tcp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass     iptables -t mangle -D POSTROUTING -o eth3 -p tcp --dport 80 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass iptables -t mangle -D POSTROUTING -o eth3 -p udp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 210 --queue-bypass iptables -t nat -D POSTROUTING -o eth3 -j MASQUERADE }  case "$1" in start) do_start ;;  stop) do_stop ;;  restart) do_stop do_start ;;  start-fw|start_fw) zapret_apply_firewall ;; stop-fw|stop_fw) zapret_unapply_firewall ;;  restart-fw|restart_fw) #zapret_unapply_firewall #zapret_apply_firewall iptables -t mangle -D POSTROUTING -o eth3 -p tcp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass     iptables -t mangle -D POSTROUTING -o eth3 -p tcp --dport 80 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass iptables -t mangle -D POSTROUTING -o eth3 -p udp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 210 --queue-bypass iptables -t nat -D POSTROUTING -o eth3 -j MASQUERADE  iptables -t mangle -I POSTROUTING -o eth3 -p tcp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass     iptables -t mangle -I POSTROUTING -o eth3 -p tcp --dport 80 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass iptables -t mangle -I POSTROUTING -o eth3 -p udp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 210 --queue-bypass iptables -t nat -A POSTROUTING -o eth3 -j MASQUERADE ;;  start-daemons|start_daemons) zapret_run_daemons ;; stop-daemons|stop_daemons) zapret_stop_daemons ;; restart-daemons|restart_daemons) zapret_stop_daemons zapret_run_daemons ;;  reload-ifsets|reload_ifsets) zapret_reload_ifsets ;; list-ifsets|list_ifsets) zapret_list_ifsets ;; list-table|list_table) zapret_list_table ;;    *) N=/etc/init.d/$NAME echo "Usage: $N {start|stop|restart|start-fw|stop-fw|restart-fw|start-daemons|stop-daemons|restart-daemons|reload-ifsets|list-ifsets|list-table}" >&2 exit 1 ;; esac  exit 0

    Все на этом правка скрипта zapret закончена, сохраняем и выходим из текстового редактора.

    В качестве небольшого пояснения по данным правилам iptables:

    Команда перенаправляет исходящий и проходящий в сторону внешнего интерфейса eth3 трафик HTTP (TCP порт 80) на очередь NFQUEUE №200:

    iptables -t mangle -I POSTROUTING -o eth3 -p tcp --dport 80 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass

    Команда перенаправляет исходящий и проходящий в сторону внешнего интерфейса eth3 трафик HTTPS (TCP порт 443) на очередь NFQUEUE №200:

    iptables -t mangle -I POSTROUTING -o eth3 -p tcp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass

    Команда перенаправляет исходящий и проходящий в сторону внешнего интерфейса eth3 трафик QUIC (UDP порт 443) на очередь NFQUEUE №210:

     iptables -t mangle -I POSTROUTING -o eth3 -p udp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 210 --queue-bypass

    Также согласно комментарию автора данной утилиты для успешной работы с протоком QUIC через NFQWS на роутера Keenetic необходимо добавить маскарад на исходящий интерфейс WAN:

    iptables -t nat -A POSTROUTING -o eth3 -j MASQUERADE

    Данные правила представлены для случая использования протокола IPv4, а в случаи также использования протокола IPv6 необходимо добавлять аналогичные правила, но с использованием команды ip6tables.

    При запуске скрипта zapret в режиме поддержки протокола QUIC будут подыматься два отдельных процесса NFQWS, первый будет обрабатывать трафик по протоколам HTTP и HTTPS на очереди NFQUEUE №200, а второй трафик протокола QUIC на очереди NFQUEUE №210.

  10. После сохранения файла zapret делаем ссылку на скрипт zapret в автозагрузку:

    ln -fs /opt/zapret/init.d/sysv/zapret /opt/etc/init.d/S90-zapret

  11. Далее необходимо создать скрип, чтобы брандмауэр netfilter не забывал настроенные выше правила (иначе система быстро перезапишет наши правила). Делаем это также в командной строке с помощью текстового редактора:

    vi /opt/etc/ndm/netfilter.d/000-zapret.sh

    Вставляем в файл следующий код:

    #!/bin/sh [ "$type" == "ip6tables" ] && exit 0 [ "$table" != "mangle" ] && exit 0 /opt/zapret/init.d/sysv/zapret restart-fw 

    И даем право на исполнения скрипту 000-zapret.sh с помощью команды:

    chmod +x /opt/etc/ndm/netfilter.d/000-zapret.sh

    Данный скрип будет вызывать наш ранее правленый скрипт zapret с параметром restart-fw, где мы прописали правила iptables.

  12. Аналогично создаем скрипт отключения проверки контрольной суммы пакетов:

    vi /opt/etc/init.d/S00fix

    Вставляем в файл следующий код:

    #!/bin/sh start() {     echo 0 > /proc/sys/net/netfilter/nf_conntrack_checksum } stop() {     echo 1 > /proc/sys/net/netfilter/nf_conntrack_checksum } case "$1" in     'start')         start         ;;     'stop')         stop         ;;     *)         stop         start         ;; esac exit 0

    Также не забываем дать права на исполнения данному скрипту:

    chmod +x /opt/etc/init.d/S00fix

  13. И теперь в конце настроим конфиг NFQWS, находящийся по пути /opt/zapret/config.

    В командной строке с помощью текстового редактора или лучше с компьютера через сеть редактируем:

    vi /opt/zapret/config

  14. Необходимо внести следующие правки:

    Раскомментировать строчку

    WS_USER=nobody

    Для включения режима модификации NFQWS трафика протокола QUIC изменить MODE_QUIC на:

    MODE_QUIC=1

    Далее необходимо прописать параметры для запуска процессов NFQWS. Тут нужно подбирать под себя, какие параметры дадут нужный результат.

    В моем случаи для протоколов HTTP и HTTPS (с данными параметрами будет запущен первый процесс NFQWS):

    NFQWS_OPT_DESYNC="--dpi-desync=fake,disorder2 --dpi-desync-split-pos=1 --dpi-desync-ttl=6 --dpi-desync-fooling=badsum --dpi-desync-repeats=6 --dpi-desync-any-protocol --dpi-desync-cutoff=d4"

    И для протокола QUIC (с данными параметрами будет запущен второй процесс NFQWS):

    NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake,disorder2 --dpi-desync-repeats=6 --dpi-desync-any-protocol --dpi-desync-cutoff=d4"

    Мой готовый конфиг:

    # this file is included from init scripts # change values here  # can help in case /tmp has not enough space #TMPDIR=/opt/zapret/tmp  # redefine user for zapret daemons. required on Keenetic WS_USER=nobody  # override firewall type : iptables,nftables,ipfw FWTYPE=iptables  # options for ipsets # maximum number of elements in sets. also used for nft sets SET_MAXELEM=522288 # too low hashsize can cause memory allocation errors on low RAM systems , even if RAM is enough # too large hashsize will waste lots of RAM IPSET_OPT="hashsize 262144 maxelem $SET_MAXELEM" # dynamically generate additional ip. $1 = ipset/nfset/table name #IPSET_HOOK="/etc/zapret.ipset.hook"  # options for ip2net. "-4" or "-6" auto added by ipset create script IP2NET_OPT4="--prefix-length=22-30 --v4-threshold=3/4" IP2NET_OPT6="--prefix-length=56-64 --v6-threshold=5" # options for auto hostlist AUTOHOSTLIST_RETRANS_THRESHOLD=3 AUTOHOSTLIST_FAIL_THRESHOLD=3 AUTOHOSTLIST_FAIL_TIME=60 # 1 = debug autohostlist positives to ipset/zapret-hosts-auto-debug.log AUTOHOSTLIST_DEBUGLOG=0  # number of parallel threads for domain list resolves MDIG_THREADS=30  # ipset/*.sh can compress large lists GZIP_LISTS=1 # command to reload ip/host lists after update # comment or leave empty for auto backend selection : ipset or ipfw if present # on BSD systems with PF no auto reloading happens. you must provide your own command # set to "-" to disable reload #LISTS_RELOAD="pfctl -f /etc/pf.conf"  # override ports #HTTP_PORTS=80-81,85 #HTTPS_PORTS=443,500-501 #QUIC_PORTS=443,444  # CHOOSE OPERATION MODE # MODE : nfqws,tpws,tpws-socks,filter,custom # nfqws : nfqws for dpi desync # tpws : tpws transparent mode # tpws-socks : tpws socks mode # filter : no daemon, just create ipset or download hostlist # custom : custom mode. should modify custom init script and add your own code MODE=nfqws # apply fooling to http MODE_HTTP=1 # for nfqws only. support http keep alives. enable only if DPI checks for http request in any outgoing packet MODE_HTTP_KEEPALIVE=0 # apply fooling to https MODE_HTTPS=1 # apply fooling to quic MODE_QUIC=1 # none,ipset,hostlist,autohostlist MODE_FILTER=ipset  # CHOOSE NFQWS DAEMON OPTIONS for DPI desync mode. run "nfq/nfqws --help" for option list DESYNC_MARK=0x40000000 DESYNC_MARK_POSTNAT=0x20000000 NFQWS_OPT_DESYNC="--dpi-desync=fake,disorder2 --dpi-desync-split-pos=1 --dpi-desync-ttl=6 --dpi-desync-fooling=badsum --dpi-desync-repeats=6 --dpi-desync-any-protocol --dpi-desync-cutoff=d4"  #NFQWS_OPT_DESYNC_HTTP= #NFQWS_OPT_DESYNC_HTTPS= #NFQWS_OPT_DESYNC_HTTP6= #NFQWS_OPT_DESYNC_HTTPS6= NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake,disorder2 --dpi-desync-repeats=6 --dpi-desync-any-protocol --dpi-desync-cutoff=d4" #NFQWS_OPT_DESYNC_QUIC6=  # CHOOSE TPWS DAEMON OPTIONS. run "tpws/tpws --help" for option list TPWS_OPT="--hostspell=HOST --split-http-req=method --split-pos=3 --oob"  # openwrt only : donttouch,none,software,hardware FLOWOFFLOAD=donttouch  # openwrt: specify networks to be treated as LAN. default is "lan" #OPENWRT_LAN="lan lan2 lan3" # openwrt: specify networks to be treated as WAN. default wans are interfaces with default route #OPENWRT_WAN4="wan vpn" #OPENWRT_WAN6="wan6 vpn6"  # for routers based on desktop linux and macos. has no effect in openwrt. # CHOOSE LAN and optinally WAN/WAN6 NETWORK INTERFACES # or leave them commented if its not router # it's possible to specify multiple interfaces like this : IFACE_LAN="eth0 eth1 eth2" # if IFACE_WAN6 is not defined it take the value of IFACE_WAN IFACE_LAN=br0 IFACE_WAN=eth3 #IFACE_WAN6="ipsec0 wireguard0 he_net"  # should start/stop command of init scripts apply firewall rules ? # not applicable to openwrt with firewall3+iptables INIT_APPLY_FW=1 # firewall apply hooks #INIT_FW_PRE_UP_HOOK="/etc/firewall.zapret.hook.pre_up" #INIT_FW_POST_UP_HOOK="/etc/firewall.zapret.hook.post_up" #INIT_FW_PRE_DOWN_HOOK="/etc/firewall.zapret.hook.pre_down" #INIT_FW_POST_DOWN_HOOK="/etc/firewall.zapret.hook.post_down"  # do not work with ipv4 #DISABLE_IPV4=1 # do not work with ipv6 DISABLE_IPV6=0  # select which init script will be used to get ip or host list # possible values : get_user.sh get_antizapret.sh get_combined.sh get_reestr.sh get_hostlist.sh # comment if not required GETLIST=get_user.sh
  15. На этом настройка роутера завершена и можно запускать в работу NFQWS и проверять работоспособность с помощью команды:

    /opt/zapret/init.d/sysv/zapret start

    Для перезагрузки NFQWS использовать команду:

    /opt/zapret/init.d/sysv/zapret restart

    Для остановки NFQWS использовать команду:

    /opt/zapret/init.d/sysv/zapret stop

  16. Также в случаи, если есть проблема доступам к сайтам по доменным именам необходимо заменить в настройках роутера DNS-серверы провайдера на публичные. Прописываем IP адреса DNS — 8.8.8.8 и 8.8.4.4, и не забываем поставить галочку игнорировать DNS предлагаемые провайдером интернета:

    Настройки роутера для работы с публичными DNS-серверами

    Настройки роутера для работы с публичными DNS-серверами

    В случаи проблем с доступностью или скоростью доступа к некоторым сайтом меняем параметры в NFQWS_OPT_DESYNC_QUIC и/или NFQWS_OPT_DESYNC, перезагружаем утилиту NFQWS с помощью команды и опять проверяем, и так делаем по циклу пока не получим нужный результат.


ссылка на оригинал статьи https://habr.com/ru/articles/834826/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *