Боремся с блокировками с помощью 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).
В сборку необходимо добавить пакеты:
luci (Web-интерфейс надстройка для OpenWRT)
kmod-tun (TUN модуль ядра)
zram-swap (создаёт в оперативной памяти сжатое блочное устройство (другими словами, RAM-диск со сжатием данных «на лету»)
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
После чего заходим в интерфейс вашего роутера, переходим в Система — Восстановление/обновление
И загружаем собранный образ, галку сохранить настройки убрать (можно настройки сохранить, но возможно проблемы, не рекомендую).
В случае вашего роутера могут быть отличия по способу прошивки, рекомендую посетить тему по вашему устройству на сайте OpenWRT [OpenWrt Wiki] Table of Hardware дабы случайно не получить кирпич вместо роутера.
Ждём окончания обновления роутера.
Далее потребуется первичная настройка роутера, необходимо обеспечить подключение к интернету согласно настройкам вашего провайдера.
Разобравшись с интернетом, переходим к пункту 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" -
Согласно документации проекта
— На каком адресе слушает socks5 сервер
"local_addr": "127.0.0.1"
На каком порту слушает socks5 сервер
"local_port": 1080 -
— Адрес сервера Trojan TCP
"remote_addr": "АДРЕС ИЛИ IP СЕРВЕРА 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:
Переходим в Сеть — Статические маршруты
И добавляем маршрут до вашего сервера, не забываем указать ваш шлюз по умолчанию (можно посмотреть на странице Состояние или командой route)
Не забываем проверить доступность сервера после добавления маршрута
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
Вносим изменения в текущую конфигурацию
После строки remote, добавляем на новой строке запись socks-proxy 127.0.0.1 1080
Теперь OpenVPN клиент будет подключаться к серверу через socks5 прокси который мы настроили ранее.
Сохраняем.
Перезапускаем соединение двойным нажатием кнопки Start/Stop.
Проверяем работу OpenVPN.
Послесловие
Для устройств 8/64 мною было найдено не так много вариантов умещающихся в память устройства и устойчивых к блокировкам, это:
Связка shadowsocks-libev + kcptun-client
Собственно trojan
ShadowsocksR-libev
trojan-plus — форк trojan с некоторыми дополнительными фичами
Для устройств 16/64 выбор значительно больше, чему и планирую посвятить следующие статьи