Чиним замедление YouTube на уровне роутера

в 14:35, , рубрики: dpi, embedded, goodbyedpi, keenetic, linux, OpenWrt, YouTube, блокировки, замедление, Роскомнадзор
:(

:(

Всех категорический приветствую. Буквально первого августа, прямо в ночь, стал у меня жутко лагать YouTube. Естественно, мне это сильно не понравилось. Ну, что же, давайте разбираться, почему и как это исправить в условиях моей личной сети.

Что случилось?
Хорошо описано произошедшее здесь, на хабре - https://habr.com/ru/articles/832678/
Если совсем кратко, своими словами - во время установки SSL соединения в открытом виде домен передается к которому мы подключаемся(так называемое SNI). И если это googlevideo.com то начинают твориться "интересные вещи". Можно проверить это локально коммандами из статьи.

$ curl https://speedtest.selectel.ru/100MB -o/dev/null

В терминале моего ноутбука

В терминале моего ноутбука

Как видите скорость загрузки весьма приличная. А теперь попробуем подключиться к тому же серверу, но передав другой домен при хендшейке.

$ curl --connect-to ::speedtest.selectel.ru https://manifest.googlevideo.com/100MB -k -o/dev/null

В терминале моего ноутбука

В терминале моего ноутбука

Вот и всё, приплыли...

Что делать?
Очевидно, что нас режут по домену с помощью DPI. Уже существуют довольно известные проекты, типа Goodbye DPI. Но он под венду, коей у меня дома вообще нету, да и требует установки на единичный компьютер и не позволяет вылечить всю мою домашнюю сеть. Спасибо автору, прямо в ридми он собрал список проектов делающие аналогичные трюки под другие операционки. Вся суть этих проектов, в том, что бы как то извратить передаваемую в открытом виде строку домена. Если совсем просто объяснять на пальцах, то в случае открытого HTTP запроста поменять заголовок Host например вот так:

Host: googlevideo.com
vs
hoSt:googlevideo.com  # поменян регистр и убран пробел

И те, странные штуковины, творящие чудные вещи, не смогут считать корретно проанализировать трафик и что-то сделать. В случае TLS подключения, я так понял, что просто берется TLS пакет и бьется на несколько TCPшных, так, чтобы части строки с доменом находились в разных TCP пакетах. И заодно меняют порядок TCP пакетов, сначала конец, потом начало шлют. Сам протокол TCP это дозволяет и на конечном сервере все будет работать корректно. А вот чудесные железки слишком глупы и их авторы явно спек не читали. Вот такое вот милое соревнование.

Мне же, напомню, хотелось вылечить всю мою домашнюю сеть, а для этого сделать это нужно прямо на роутере. Роутер у меня Zyxel Keenetic Giga III, которому уже наверное лет десять... Keentic уже стал отдельным брендом без Zyxel, а роутер у меня все это время работал как часы. Я начал думать обновиться и купить какой нибудь роутер, на который можно было бы поставить OpenWrt. Мануал далее валиден для любого роутера под линуксом имеющий iptables и init.d.

Почитав немного, какого же оказалось мое удивление, что на довольно таки закрытый Zyxel можно поставить набор бинарей линукса и менеджер пакетов OPKG от OpenWrt. Роутер был довольно дорогим, не зря я за него деньги отдавал, спустя столько лет он смог меня удивить. Пару абзацев далее - можно пропустить, если у вас не Keentic. Сейчас мы будем запускать OPKG на моем роутере. Вообще есть целый мануал от производителя как это делать. Я опишу очень кратко.

Для начало надо будет зайти в веб интерфейс и доставить все компненты OPKG.

UI роутера где доставляем компоненты родной прошивки
UI роутера где доставляем компоненты родной прошивки

Внутренней памяти, как водится обычно, в таких устройствах - кот наплаках, с трудом под прошивку. Не беда. Берем USB флешку, форматируем в EXT4. В корне делаем директорию install и кладем набор бинерей с оффсайта(точнее по ссылке на проект entware с официальной документации). В моем случае под платформу mipsel - https://bin.entware.net/mipselsf-k3.4/installer/EN_mipsel-installer.tar.gz Побродив по https://bin.entware.net/ можно найти аналогичный интсаллер для ARM или mips на bigendian, если у вас какой то хитрый keenetic. Далее, втыкаем флешку в роутер, если все хорошо, роутер сам развернет и удалит архив. А мы сможем подключиться по ssh на порт 222.

Кстати, если вы ошибетесь в платформе, лучше просто идите на ssh роутера на 22 порту и пробуйте в консоле exec sh .

Если не та платформа - будет четко видна ошибка. Я сразу не понял какой у меня проц, пришлось перебирать.

Если файл есть и не для той платформы - то exec format error. Если файла нет, то четко пишет что нету.

Если файл есть и не для той платформы - то exec format error. Если файла нет, то четко пишет что нету.

Пароль для входа по ssh на 22 такой же как веб интерфейсе. На 222 логин пароль - root/keenetic. После первого входа не забываем сделать passwd и поменять пароль. Если все удалось, то либо через ssh подключение на 222 порт, либо через exec sh мы наконец то получаем почти полноценный линукс на зюкселе. Ура! И огромное спасибо производителю за эту фишку.

А вот мы и на роутере, в линуксе

А вот мы и на роутере, в линуксе

Ну а теперь часть общая для роутеров с OpenWrt или аналогичным линуксом. Все что нам осталось сделать, это поставить софтину, которая будет крутить-вертеть и хотеть обмануть TCP пакеты и завернуть весь трафик на эту софтину. Софта навалом такого. Для начала давайте сразу поставим что нам может потребоваться, в моем случае:

# opkg update
# opkg install ipset curl gzip grep git-http gcc make cmake

Если у вас мало места - можете ничего не ставить. Через scp можете закинуть бинарь и все.

Теперь я начал выбирать проект, что запуститься. Мне довольно понравился вот этот. Просто потому, что он с пол пинка собрался из сырцов прям на роутере, запустился и заработал. Но, к сожалению, он дает только SOCKS прокси и настраивать каждое устройство в домашней сети у меня никакого желания нету. Лезем дальше, нашелся проект zapret. Выглядит очень здорово, но его автоматические скрипты установки начали слишком много ошибок писать, больше того, в чем я готов разбираться и доставить проект штатно. Да и код скриптов тоже сложноват. Ну да ладно, беглое прочтение ридми сказало мне, что есть бинарик, которые делает все что нужно, он даже лежит собранный прямо в репе для разных платформ. Вот он то мне и нужен. А скрипты, ладно, без них сам все сделаю. Итого, вот что нужно:

# opkg update
# opkg install iptables
# mkdir git
# cd git
# git clone https://github.com/bol-van/zapret.git
# cd zapret
# ./install_bin.sh
# cd /opt/etc/init.d/
# vi S51tpws

И далее вставить код сервиса, который написал я.

#!/bin/sh

SCRIPT=/opt/root/git/zapret/tpws/tpws
PIDFILE=/var/run/tpws.pid
ARGS="--daemon --bind-addr 192.168.0.1 --port 999 --disorder --tlsrec=sni --split-pos=2 --pidfile $PIDFILE"


start() {
  if [ -f $PIDFILE ] && kill -0 $(cat $PIDFILE); then
    echo 'Service TPWS is already running' >&2
    return 1
  fi
  $SCRIPT $ARGS
  iptables -t nat -A PREROUTING -i br0 -p tcp --dport 80 -j REDIRECT --to-port 999
  iptables -t nat -A PREROUTING -i br0 -p tcp --dport 443 -j REDIRECT --to-port 999
  echo 'Started TPWS service'
}

stop() {
  if [ ! -f "$PIDFILE" ] || ! kill -0 $(cat "$PIDFILE"); then
    echo 'Service TPWS is not running' >&2
    return 1
  fi
  echo 'Stopping TPWS service...'
  kill -15 $(cat "$PIDFILE") && rm -f "$PIDFILE"
  iptables -t nat -D PREROUTING -i br0 -p tcp --dport 80 -j REDIRECT --to-port 999
  iptables -t nat -D PREROUTING -i br0 -p tcp --dport 443 -j REDIRECT --to-port 999
}

status() {
  if [ -f $PIDFILE ] && kill -0 $(cat $PIDFILE); then
    echo 'Service TPWS is running'
  else
    echo 'Service TPWS is stopped'
  fi
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  status)
    status
    ;;
  restart)
    stop
    start
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|status}"
esac

Далее

# chmod +x /opt/etc/init.d/S51tpws
# /opt/etc/init.d/S51tpws start

Замеряем

На моем ноутбуке, после запуска сервиса на роутере

На моем ноутбуке, после запуска сервиса на роутере

Пробуем YouTube ручками и видим глазками, что он стал работать оооочень быстро.

Небольшие пояснения. Код выше использует лишь один бинарь из проекта zapret - tpws . У него интерфейс прозрачной прокси, которая коверкает пакеты обманывая DPI. У этого бинаря куча флажков для старта. В коде сервиса init.d я указал аргументы для запуска, которые работают для меня. Можете убрать --daemon и запускать просто в терминале играясь с параметрами. Незабудьте прописать маршруты на ваш сервис в iptables перед тем как вращать его руками. В моем случае прямо в коде сервиса маршруты добавляются и удаляются.

Из специфичного. init.d на зюкселе почему то лежит в /opt/etc. На голой OpenWrt скорее всего в корне /etc. Префикс S51 файла сервиса S51tpws взят откуда-то из потрохов entware, без этого префикса сервис не стартует при запуске сам. Опять же, в голой OpenWrt скорее всего не нужно. br0 - имя интерфейса локальной сети, на ней айпи моего роутера 192.168.0.1. Чтобы сервис tpws слушал на этом интерфейсе только(а не на ещё и внешнем), я его же прописал среди аргуметов на запуск сервиса.

Вот собственное и все. Теперь весь трафик идущий на внешние порты 80 и 443 из моей сети обрабатываются и извращаются сервисом tpws. Я думаю, что далеко не секрет, если я скажу, что скорее всего, ютьюб будет полностью забанен в обозримом будущем. Исходя из этого, данное решение носит временный характер. Либо же, возможно, в будущем там будет другой бинарь, который весь трафик будет отправлять по ICMP на мою приватную виртуалку где нибудь в Нидерландах... Главное начало, и такая конструкция на домашнем роутере мне очень по душе. Всем спасибо, если дочитали до конца.

p.s. я даю полное согласие на перепечатку данной статьи в любых источниках. Объявляю ее public domain. Делайте, что хотите, но лучше улучшайте и развивайте :)

Автор: nkha

Источник

  1. Роберт:

    Здравствуйте, подскажите, уже весь гугл перерыл затыкаюсь на шаге git clone https://github.com/bol-van/zapret.git

    постоянно возращает fatal: could not create leading directories of ‘zapret/.git’

    Уже флешки менял, вопрос разные методами форматировал, но в какую не хочет

  2. Kirkman:

    Попробуйте загружать файлы через smb или web-интерфейс роутера

  3. Юрий:

    что не так делаю?

    BusyBox v1.31.1 (2022-04-19 16:55:37 +05) built-in shell (ash)
    Enter ‘help’ for a list of built-in commands.

    /home/root # mkdir git
    /home/root # cd git
    /home/root/git # git clone https://github.com/bol-van/zapret.git
    -sh: git: not found
    /home/root/git # https://www.pvsm.ru/linux/393054
    -sh: https://www.pvsm.ru/linux/393054: not found
    /home/root/git # clone https://github.com/bol-van/zapret.git
    -sh: clone: not found
    /home/root/git # https://www.pvsm.ru/linux/393054
    -sh: https://www.pvsm.ru/linux/393054: not found
    /home/root/git # clone https://github.com/bol-van/zapret.git
    -sh: clone: not found
    /home/root/git # git clone https://github.com/bol-van/zapret.git
    -sh: git: not found
    /home/root/git # clone https://github.com/bol-van/zapret.git
    -sh: clone: not found
    /home/root/git #

  4. Юрий:

    пробую через веб интерфейс роутера ввести mkdir git
    пишет:dir: can’t create directory ‘git’: Read-only file system

  5. Юрий:

    АРхир не распаковывает роутер с флешки:
    USB disconnect, device number 4
    Aug 11 06:00:17 kernel: usb 1-1: new high-speed USB device number 5 using ehci-platform
    Aug 11 06:00:17 kernel: usb 1-1: New USB device found, idVendor=346d, idProduct=5678
    Aug 11 06:00:17 kernel: usb 1-1: Product: Disk 2.0
    Aug 11 06:00:17 kernel: usb 1-1: Manufacturer: USB
    Aug 11 06:00:17 kernel: usb 1-1: SerialNumber: 2965381145545257679
    Aug 11 06:00:17 kernel: scsi3 : usb-storage 1-1:1.0
    Aug 11 06:00:20 kernel: scsi 3:0:0:0: Direct-Access VendorCo ProductCode 2.00 PQ: 0 ANSI: 4
    Aug 11 06:00:20 kernel: sd 3:0:0:0: [sdb] 61440000 512-byte logical blocks: (31.4 GB/29.2 GiB)
    Aug 11 06:00:20 kernel: sd 3:0:0:0: Attached scsi generic sg0 type 0
    Aug 11 06:00:20 kernel: sd 3:0:0:0: [sdb] Write Protect is off
    Aug 11 06:00:20 kernel: sd 3:0:0:0: [sdb] Mode Sense: 03 00 00 00
    Aug 11 06:00:20 kernel: sd 3:0:0:0: [sdb] No Caching mode page found
    Aug 11 06:00:20 kernel: sd 3:0:0:0: [sdb] Assuming drive cache: write through
    Aug 11 06:00:20 kernel: sd 3:0:0:0: [sdb] No Caching mode page found
    Aug 11 06:00:20 kernel: sd 3:0:0:0: [sdb] Assuming drive cache: write through
    Aug 11 06:00:20 kernel: sdb: sdb1
    Aug 11 06:00:20 kernel: sd 3:0:0:0: [sdb] No Caching mode page found
    Aug 11 06:00:20 kernel: sd 3:0:0:0: [sdb] Assuming drive cache: write through
    Aug 11 06:00:20 kernel: sd 3:0:0:0: [sdb] Attached SCSI removable disk
    Aug 11 06:00:20 usb_modeswitch: no rule for device 346d:5678
    Aug 11 06:00:21 kernel: EXT4-fs (sdb1): recovery complete
    Aug 11 06:00:21 kernel: EXT4-fs (sdb1): mounted filesystem with ordered data mode. Opts: (null)
    Aug 11 06:00:26 wsdd2[624]: Hangup received.
    Aug 11 06:00:26 WSDD2: daemon is started
    Aug 11 06:00:26 Samba Server: daemon is started

  6. Юрий:

    /home/root # exec sh

    захожу по ssh :

    BusyBox v1.31.1 (2022-04-19 16:55:37 +05) built-in shell (ash)
    Enter ‘help’ for a list of built-in commands.

    /home/root # opkg update
    sh: opkg: not found
    /home/root #

    почему пишет такую ошибку?
    я в настройках роутера we1626 включил доступ по ssh (тюнингованная прошивка) И в этой прошиве выбрал в поле Разрешить запуск Optware? – выбрал Entware

  7. максим:

    Добрый день
    Встал на моменте
    cd /opt/etc/init.d/
    пишет
    ash: cd: can’t cd to /opt/etc/init.d/: No such file or directory
    подскажите что делать дальше?

  8. Юрий:

    /opt/home/admin # opkg update
    Downloading http://bin.entware.net/mipselsf-k3.4/Packages.gz
    Updated list of available packages in /opt/var/opkg-lists/entware
    /opt/home/admin # opkg install iptables
    Installing iptables (1.4.21-4) to root…
    Downloading http://bin.entware.net/mipselsf-k3.4/iptables_1.4.21-4_mipsel-3.4.ipk
    Configuring iptables.
    /opt/home/admin # mkdir git
    /opt/home/admin # cd git
    /opt/home/admin/git # git clone https://github.com/bol-van/zapret.git
    -sh: git: not found
    /opt/home/admin/git # https://www.pvsm.ru/linux/393054
    -sh: https://www.pvsm.ru/linux/393054: not found
    /opt/home/admin/git # clone https://github.com/bol-van/zapret.git
    -sh: clone: not found
    /opt/home/admin/git # https://www.pvsm.ru/linux/393054^C
    /opt/home/admin/git #
    что делать дальлше?

  9. Юрий:

    /opt/home/admin # cd /
    / # cd opt
    /opt # cd etc
    /opt/etc # opkg update
    Downloading http://bin.entware.net/mipselsf-k3.4/Packages.gz
    Updated list of available packages in /opt/var/opkg-lists/entware
    /opt/etc # opkg install iptable
    Unknown package ‘iptable’.
    Collected errors:
    * opkg_install_cmd: Cannot install package iptable.
    /opt/etc # opkg install iptables
    Package iptables (1.4.21-4) installed in root is up to date.
    /opt/etc # mkdir git
    /opt/etc # cd git
    /opt/etc/git # clone https://github.com/bol-van/zapret.git
    -sh: clone: not found
    что делать?

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js