Боремся с блокировками с помощью Trojan TCP на слабых устройствах c OpenWRT

В данной статье рассмотрим как:

  • Настроить обход блокировок с помощью Trojan TCP, tun2socks и bird2 (BGP) на устройствах с 8 Мб ПЗУ и 64 ОЗУ (8/64)

  • настроить существующее подключение к OpenVPN серверу, которое могло или может перестать работать, через Trojan TCP туннель (Websocket этой реализацией не поддерживается)

  • Собрать прошивку с Trojan, kmod-tun, zram и bird2 на базе OpenWRT 21.02.7 для устройств с 8/64 (более новые версии (>22.03) занимают больше места и этот набор пакетов уже не поместится в 8 Мб)

Понадобятся:

  • Существующий сервер OpenVPN и настроенный клиент на OpenWRT

  • Конфиг Trojan вашего либо чужого сервера. (О том как настроить свой сервер и где искать сервера расскажу в статье)

  • Сервер, ПК или виртуальная машина с Linux для сборки прошивки

Оглавление:

  • 1.Сборка прошивки на базе OpenWRT 21.02.7 (не нужно для устройств с 16 Мб памяти)

    2. Настройка туннеля Trojan

    3. 1. Настройка tun2socks и обхода блокировок с помощью BGP (bird2)

    3. 2. Настройка клиента OpenVPN через Trojan TCP

Целью данной статьи было найти способ (способы) который подходил бы для большинства устройств на OpenWRT и давал бы некий запас прочности по устойчивости к блокировкам, (shadowsocks старой версии уже в явной зоне риска к сожалению). Этой цели будет посвящена эта и несколько последующих статей, сконцентрированы они в первую очередь на устройствах с 8/64, 16/64 и 16/128 (ПЗУ/ОЗУ) конфигурациях памяти. Решения для устройств с количеством памяти подробно описаны в моих предыдущих статьях и статьях коллег по цеху.

1. Сборка прошивки для 8/64 на базе OpenWRT 21.02.7

Владельцы устройств с ПЗУ 16Мб и имеющие свободные 3Мб памяти могут пропустить этот пункт (и использовать в т.ч. и версию 23.05) и перейти к п.2

Проблемой устройств 8/64 является слишком ограниченное свободное место в ПЗУ из-за чего необходимые пакеты невозможно установить через opkg из-за чего единственным способом собрать вместе необходимые пакеты является сборка прошивки через OpenWRT Buildroot

Подробно сборка описана в wiki проекта openwrt.org, я опишу только необходимые шаги для сборки.

Моя среда сборки это виртуальная машина Debian 11 в VirtualBox, рекомендуется не менее 10 Гб свободного места на диске и не менее 4 Гб RAM

Устанавливаем необходимые для сборки пакеты:

sudo apt install binutils bzip2 diffutils flex libc-dev libz-dev perl python3.7 rsync subversion unzip ncurses-dev git-core build-essential libssl-dev libncurses5-dev gawk zlib1g-dev subversion mercurial

Далее скачиваем исходный код OpenWRT версии 21.02.7

git clone https://github.com/openwrt/openwrt.git -b v21.02.7

Добавляем репозитории и обновляем списки:

cd openwrt
echo -e "src-git small https://github.com/kenzok8/small \nsrc-git kenzo https://github.com/kenzok8/openwrt-packages" >> feeds.conf.default
./scripts/feeds update -a
./scripts/feeds install -a

Далее OpenWrt проверит отсутствующие пакеты в вашей системе сборки и предложит выбрать архитектуру вашего устройства и модель, а также пакеты для сборки.

make menuconfig

В меню необходимо выбрать ваше устройство и сохранить конфигурацию (кнопка Save).

В сборку необходимо добавить пакеты:

  1. luci (Web-интерфейс надстройка для OpenWRT)

  2. kmod-tun (TUN модуль ядра)

  3. zram-swap (создаёт в оперативной памяти сжатое блочное устройство (другими словами,  RAM-диск со сжатием данных «на лету»)

  4. bird2c (для использования BGP для получения маршрутов от antifilter.download,  antifilter.network)

    и использовать параметры уменьшения размера прошивки (sstrip)

Это можно сделать при помощи конфигуратора либо следующей командой:

echo -e "CONFIG_USE_MKLIBS=y \nCONFIG_STRIP_KERNEL_EXPORTS=y \nCONFIG_KERNEL_PROC_STRIPPED=y \nCONFIG_PACKAGE_luci=y \nCONFIG_PACKAGE_zram-swap=y \nCONFIG_PACKAGE_bird2c=y \nCONFIG_PACKAGE_kmod-tun=y" >> .config

после чего повторно запустить проверку:

make menuconfig

Убедиться что устройство выбрано правильно и настройки не потеряны и сохранить конфигурацию повторно (Save).

После чего запускаем сборку образа (на 8 потоках):

make -j9

Команда запускает сборку на 8 потоках (ядрах) (8+1), можете ввести нужное вам количество вместо -j9 (например -j5 для сборки на 4 потоках)

Ждём окончания сборки (около 1 часа), после чего скачиваем файлы из папки ~/openwrt/bin/targets/$платформа/$архитектура/

Для обновления существующей прошивки OpenWRT понадобится файл оканчивающийся на *-sysupgrade.bin

После чего заходим в интерфейс вашего роутера, переходим в Система — Восстановление/обновление

d108e60a6fa09f1b0d930da9469853ea.png

И загружаем собранный образ, галку сохранить настройки убрать (можно настройки сохранить, но возможно проблемы, не рекомендую).

В случае вашего роутера могут быть отличия по способу прошивки, рекомендую посетить тему по вашему устройству на сайте OpenWRT [OpenWrt Wiki] Table of Hardware дабы случайно не получить кирпич вместо роутера.

Ждём окончания обновления роутера.

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

4bd6270573d9a4bfc36a9190407b5f84.png

Разобравшись с интернетом, переходим к пункту 2.

2.Настройка туннеля Trojan

Владельцы устройств с 16Мб ПЗУ пропустившие предыдущий пункт должны установить пакет trojan:

Для этого сначала необходимо добавить репозиторий:

sed -i 's/option check_signature/# option check_signature/g' /etc/opkg.conf
echo "src/gz custom_generic https://raw.githubusercontent.com/lrdrdn/my-opkg-repo/main/generic" >> /etc/opkg/customfeeds.conf
echo "src/gz custom_arch https://raw.githubusercontent.com/lrdrdn/my-opkg-repo/main/$(grep "OPENWRT_ARCH" /etc/os-release | awk -F '"' '{print $2}')" >> /etc/opkg/customfeeds.conf

И установить пакет:

opkg update
opkg install trojan

Далее общие инструкции:

необходимо создать конфигурацию Trojan TCP:

Редактируем файл /etc/config/trojan.json

{
  "run_type": "client",
  "local_addr": "127.0.0.1",
  "local_port": 1080,
  "remote_addr": "АДРЕС ИЛИ IP СЕРВЕРА TROJAN TCP",
  "remote_port": ПОРТ СЕРВЕРА,
  "password": [
    "ПАРОЛЬ СЕРВЕРА"
  ],
  "log_level": 1,
  "ssl": {
    "verify": true,
    "verify_hostname": true,
    "cert": "",
    "cipher": "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA",
    "cipher_tls13": "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384",
    "sni": "",
    "alpn": [
      "h2",
      "http/1.1"
    ],
    "reuse_session": true,
    "session_ticket": false,
    "curves": ""
  },
  "tcp": {
    "no_delay": true,
    "keep_alive": true,
    "reuse_port": false,
    "fast_open": false,
    "fast_open_qlen": 20
  }
}

"run_type": "client" - Согласно документации проекта
"local_addr": "127.0.0.1"
— На каком адресе слушает socks5 сервер
"local_port": 1080 -
На каком порту слушает socks5 сервер
"remote_addr": "АДРЕС ИЛИ IP СЕРВЕРА TROJAN TCP"
 — Адрес сервера Trojan TCP
"remote_port": ПОРТ СЕРВЕРА
"password": [
"ПАРОЛЬ СЕРВЕРА"

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

trojan://PASSWORD@HOSTNAME: PORT#LUTrojan28TLS%29

Для настройки собственного сервера c Trojan TCP можно воспользоваться инструкциями Раз, Два, и Три . Также в т.ч. и на Хабре есть компании предоставляющие услуги VPN и Прокси, включая Trojan TCP.

Далее создаём службу автозапуска:

Редактируем файл /etc/init.d/trojan:

#!/bin/sh /etc/rc.common
USE_PROCD=1

# starts after network starts
START=72
# stops before networking stops
STOP=72

PROG=/usr/sbin/trojan
CONFIG="/etc/config/trojan.json"


start_service() {
  procd_open_instance
  procd_set_param user root
  procd_set_param command "$PROG" -c "$CONFIG"
  procd_set_param stdout 1
  procd_set_param stderr 1
  procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
  procd_close_instance
    echo "Trojan TCP daemon is working!"
}

start() {
    start_service
}
boot() {
    # This gets run at boot-time.
    start
}

shutdown() {
    # This gets run at shutdown/reboot.
    stop
}

stop_service() {
    service_stop "$PROG"
    echo "Trojan TCP daemon has stopped!"
}

reload_service() {
    stop
    sleep 3s
    echo "Trojan TCP daemon restarted!"
    start
}

Сохраняем файл

Задаем права запуска:

chmod +x /etc/init.d/trojan

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

ln -s /etc/init.d/trojan /etc/rc.d/S72trojan

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

Далее необходимо добавить статический маршрут к серверу Trojan:

Переходим в Сеть — Статические маршруты

568e5c1360cc07bc1482b292bac41ced.png

И добавляем маршрут до вашего сервера, не забываем указать ваш шлюз по умолчанию (можно посмотреть на странице Состояние или командой route)

bda4c54986de28f26589ec564ade60b5.png

Не забываем проверить доступность сервера после добавления маршрута

ping $Ваш_Сервер__TROJAN

Теперь можем запустить службу Trojan:

/etc/init.d/trojan start

3.1 Настройка tun2socks и обхода блокировок с помощью BGP

Далее настроим tun2socks (требует установленного пакета kmod-tun) для создания интерфейса в системе в который будет направляться трафик, бинарный файл tun2socks занимает 9Мб, поэтому будем использовать установку в ОЗУ и скачивание при запуске системы

Создаём службу tun2socks:

Редактируем файл /etc/init.d/tun2socks:

#!/bin/sh /etc/rc.common
USE_PROCD=1

# starts after network starts
START=99
# stops before networking stops
STOP=89

PROG=/tmp/tun2socks
IF="tun2"
LOGLEVEL="warning"
HOST="127.0.0.1"
PORT="1080"
#ARCH=$(grep "OPENWRT_ARCH" /etc/os-release | awk -F '"' '{print $2}')

#Check for tun2socks then download tun2socks binary from Sourceforge to RAM
before_start() {
if [ ! -f "/tmp/tun2socks*" ]; then
  ARCH=$(grep "OPENWRT_ARCH" /etc/os-release | awk -F '"' '{print $2}')
  wget https://master.dl.sourceforge.net/project/outline-install-wrt/v2.5.1/tun2socks-linux-$ARCH?viasf=1 -O /tmp/tun2socks
 # Check wget's exit status
    if [ 0 -ne 0 ]; then
        echo "Download failed. No file for your Router's architecture"
        exit 1
   fi
fi
#Executing chmod +x command
chmod +x /tmp/tun2socks
}

start_service() {
    before_start
    procd_open_instance
    procd_set_param user root
    procd_set_param command "$PROG" -device "$IF"  -proxy "$HOST":"$PORT" -loglevel "$LOGLEVEL"
    procd_set_param stdout 1
    procd_set_param stderr 1
    procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
    procd_close_instance
    echo "tun2socks is working!"
}

boot() {
    # This gets run at boot-time.
    start
}

shutdown() {
    # This gets run at shutdown/reboot.
    stop
}

stop_service() {
    service_stop "$PROG"
    echo "tun2socks has stopped!"
}

reload_service() {
    stop
    sleep 3s
    echo "tun2socks restarted!"
    start
}
start() {
    before_start
    start_service
}

Данная служба при каждом запуске проверяем наличие файла /tmp/tun2socks и при его отсутствии скачивает его, после чего запускает интерфейс tun2 c прокси 127.0.0.1:1080 (параметры прописаны в переменных IF=«tun2», HOST=»127.0.0.1», PORT=»1080»)

Разрешаем права запуска службы:

chmod +x /etc/init.d/tun2socks

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

ln -s /etc/init.d/tun2socks /etc/rc.d/S99tun2socks

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

Согласно документации tun2socks рекомендуется присвоить интерфейсу ip адрес (на практике маршрутизация работает и перенаправлением в dev tun2)

Для этого в /etc/config/network добавим следующее содержание:

config interface 'tunnel'
        option device 'tun2'
        option proto 'static'
        option ipaddr '172.16.10.1'
        option netmask '255.255.255.252'

Диапазон 172.16.10.0/30 выбран случайно, может быть любой диапазон частных адресов

Так же создаём зону и правило в /etc/config/firewall

config zone
        option name 'proxy'
        option forward 'REJECT'
        option output 'ACCEPT'
        option input 'REJECT'
        option masq '1'
        option mtu_fix '1'
        option device 'tun2'
        option family 'ipv4'
config forwarding
option name 'lan-proxy'
option dest 'proxy'
option src 'lan'
option family 'ipv4'

Перезагружаем сеть

/etc/init.d/network restart

Далее запускаем службу tun2socks:

/etc/init.d/tun2socks start

Далее необходимо настроить обход блокировок по спискам адресов с помощью bird2, для этого есть отличная статья @itdog Точечный обход блокировок на роутере OpenWrt c помощью BGP / Хабр (habr.com), после чего процесс настройки окончен. Для использования списков BGP antifilter.network используйте IP-адрес 51.75.66.20, номер автономной системы 65444

3.2 Настройка клиента OpenVPN через Trojan TCP

Если вы используете OpenVPN для обхода блокировок и не хотели бы лишних действий с настройкой tun2socks вы можете проксировать OpenVPN через Trojan TCP:

переходим во вкладку VPN — OpenVPN

dfd9a46afbd9eb7d35ff7117d660b348.png

Вносим изменения в текущую конфигурацию

5f42a41ad49abc52181a8b92472a75cb.png8ff67a34cb07e0729edbfb5f3add3175.png

После строки remote,  добавляем на новой строке запись socks-proxy 127.0.0.1 1080

Теперь OpenVPN клиент будет подключаться к серверу через socks5 прокси который мы настроили ранее.

Сохраняем.

b05f068fba1afd7b497f8e0495cbe7bb.png

Перезапускаем соединение двойным нажатием кнопки Start/Stop.

Проверяем работу OpenVPN.

Послесловие

Для устройств 8/64 мною было найдено не так много вариантов умещающихся в память устройства и устойчивых к блокировкам, это:

  • Связка shadowsocks-libev + kcptun-client

  • Собственно trojan

  • ShadowsocksR-libev

  • trojan-plus — форк trojan с некоторыми дополнительными фичами

    Для устройств 16/64 выбор значительно больше, чему и планирую посвятить следующие статьи

© Habrahabr.ru