Pull to refresh

Решаем проблему блокировок (и YouTube) за 5 минут на роутере Mikrotik через контейнеры и без VPN

Level of difficultyMedium
Reading time12 min
Views160K

Всем привет! Это моя первая статья на хабре, которая точно кому-то пригодится в данное время. Здесь я расскажу как ускорить ютуб и разблокировать доступ к некоторым заблокированным ресурсам прямо на роутере Mikrotik и без VPN.

В моем случае используется MikroTik hAP ax3. Стоит упомянуть, что подойдут только роутеры с архитектурой ARM, ARM64 или x86 (CHR), которые и поддерживают контейнеры.

А мне можно? Какая у меня архитектура?
Место, куда нужно посмотреть и убедиться в подходящей архитектуре железа, прежде чем приступать к настройкам
Место, куда нужно посмотреть и убедиться в подходящей архитектуре железа, прежде чем приступать к настройкам

  • Прошивку желательно использовать >= 7.16, т.к. только в ней завезли DNS Forward запросы с использованием встроенного DoH.

Кто подходит под эти условия, велком под кат)


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

  • Перед началом настройки рекомендую сделать бэкап конфигурации, чтобы быстро вернуться в рабочее состояние и начать заново при необходимости.

По настройке контейнеров есть официальная вики, но постараюсь всё кратко описать здесь.

Если команда /system/device-mode print показывает container: yes , то все ок, если нет, то для включения режима контейнеров на устройстве нужно выполнить следующую команду и следовать инструкциям в консоли:

/system/device-mode/update container=yes

Скорее всего придется скачать и доустановить пакеты Extra packages - Container для вашей платформы. Можно сделать так же из консоли предварительно изменив в пути номер версии установленной ROS:

/tool fetch https://upgrade.mikrotik.com/routeros/7.16/container-7.16-arm64.npk
# или
/tool fetch https://upgrade.mikrotik.com/routeros/7.16/container-7.16-arm.npk
# и ребут для установки
/system/reboot

Для установки контейнеров не рекомендуется использовать внутреннюю память, поэтому на роутерах нужна внешняя память USB это флешка или жесткий диск и желательно USB 3.0 и выше отформатированный в ext3/ext4.

Флешку, и не обязательно USB 3.0, можно отформатировать через раздел System - Disks

Форматирование USB флешки
Выбираем свой диск и жмем Format Drive
Выбираем свой диск и жмем Format Drive
Выбираем свой диск и формат файловой системы и после нажимаем Start
Выбираем свой диск и формат файловой системы и после нажимаем Start

Есть еще вариант установить контейнеры в RAM память, для тех у кого нет USB разъема, мало встроенной памяти или много RAM: https://youtu.be/KO9wbarVPOk

Для тех кто хочет очень быстро настроиться

Замени usb1 на свой корректный путь!

/tool fetch https://cacerts.digicert.com/DigiCertGlobalRootG2.crt.pem
/certificate import file-name=DigiCertGlobalRootG2.crt.pem passphrase=""
/ip dns set use-doh-server=https://1.1.1.1/dns-query verify-doh-cert=yes

/interface/bridge add name=Bridge-Docker port-cost-mode=short
/ip/address add address=192.168.254.1/24 interface=Bridge-Docker network=192.168.254.0
/interface/veth add address=192.168.254.2/24 gateway=192.168.254.1 name=BYEDPI-TUN
/interface/bridge/port add bridge=Bridge-Docker interface=BYEDPI-TUN

/container/config set registry-url=https://registry-1.docker.io tmpdir=/usb1/docker/pull

/container/add remote-image=wiktorbgu/byedpi-hev-socks5-tunnel:mikro interface=BYEDPI-TUN cmd="--disorder 1 --auto=torst --tlsrec 1+s" root-dir=/usb1/docker/byedpi-hev-socks5-tunnel start-on-boot=yes

# set to default
/ip/dns set address-list-extra-time=0s 

/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=googlevideo.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=youtube.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=youtubei.googleapis.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=ytimg.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=youtu.be type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=ggpht.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=rutracker.org type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=rutracker.cc type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=medium.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=facebook.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=fbcdn.net type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=x.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=twitter.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=linkedin.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=prntscr.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=prnt.sc type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=t.co type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=protonvpn.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=nnmclub.to type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=ntc.party type=FWD

/routing/table add disabled=no fib name=dpi_mark

/ip/route add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=192.168.254.2%Bridge-Docker pref-src="" routing-table=dpi_mark scope=30 suppress-hw-offload=no target-scope=10

/ip firewall mangle add action=mark-connection chain=prerouting connection-mark=no-mark dst-address-list=za_dpi_FWD in-interface-list=LAN new-connection-mark=to_dpi passthrough=yes
/ip firewall mangle add action=mark-routing chain=prerouting comment="To DPI" connection-mark=to_dpi in-interface-list=LAN new-routing-mark=dpi_mark passthrough=no routing-mark=!dpi_mark

/ip firewall filter set [find action=fasttrack-connection] packet-mark=no-mark connection-mark=no-mark

/ip/firewall/address-list/ add address=10.0.0.0/8 list=local
/ip/firewall/address-list/ add address=172.16.0.0/12 list=local
/ip/firewall/address-list/ add address=192.168.0.0/16 list=local

/ip firewall nat add action=redirect chain=dstnat dst-address-list=!local dst-port=53 in-interface-list=LAN protocol=udp
/ip firewall nat add action=redirect chain=dstnat dst-address-list=!local dst-port=53 in-interface-list=LAN protocol=tcp

:delay 10s

/container start [find interface=BYEDPI-TUN]

И желательно перезагрузить роутер и свои устройства =) Готово!

Далее мы создаем бридж для контейнеров, задаем ему адрес, создаем интерфейс VETH с адресом и добавляем в бридж:

/interface/bridge add name=Bridge-Docker port-cost-mode=short
/ip/address add address=192.168.254.1/24 interface=Bridge-Docker network=192.168.254.0
/interface/veth add address=192.168.254.2/24 gateway=192.168.254.1 name=BYEDPI-TUN
/interface/bridge/port add bridge=Bridge-Docker interface=BYEDPI-TUN
UI настройки Bridge, VETH (скрины старые от 2х контейнерной связки)
настройки бриджа и VETH
настройки бриджа и VETH

Установим URL-адрес реестра для загрузки контейнеров из реестра Docker и установим каталог извлечения tmpdir для подключенного usb носителя:

  • Здесь и далее следите за верным указанием имени вашего USB диска

/container/config set registry-url=https://registry-1.docker.io tmpdir=/usb1/docker/pull
UI Container config
настройки Container
настройки Container

Скачиваем образ контейнера, привязываем его к созданному интерфейсу VETH и ставим на автоматический запуск при загрузке устройства:

  • В контейнере при запуске используется набор команд byedpi в аргументе cmd, которые вам возможно придется подбирать для своего провайдера (у меня дом.ру), чтобы обходить DPI, справку по настройке параметров можно посмотреть на гитхабе проекта.

/container/add remote-image=wiktorbgu/byedpi-hev-socks5-tunnel:mikro interface=BYEDPI-TUN cmd="--disorder 1 --auto=torst --tlsrec 1+s" root-dir=/usb1/docker/byedpi-hev-socks5-tunnel start-on-boot=yes

Если кому-то нужен вариант использования только контейнера BYEDPI-SOCKS с указанием его IP адреса и порта (192.168.254.5:1080) в настройках или плагинах браузера, такой вариант удобно использовать сразу для проверки обхода DPI провайдера.

Для этого можете установить контейнер byedpi (менее 100кб!) https://hub.docker.com/r/wiktorbgu/byedpi-mikrotik

/interface/veth add address=192.168.254.5/24 gateway=192.168.254.1 name=BYEDPI-SOCKS 
/interface/bridge/port add bridge=Bridge-Docker interface=BYEDPI-SOCKS 
/container/add remote-image=wiktorbgu/byedpi-mikrotik interface=BYEDPI-SOCKS cmd="--disorder 1 --auto=torst --tlsrec 1+s" root-dir=/usb1/docker/byedpi-mikrotik start-on-boot=yes 
  • Я использую браузер Мозила и плагин FoxyProxy. Настраивается он достаточно просто, например, для ютуба можно экспортировать настройки, так же есть очень удобная фича в окне плагина "Set tab proxy", отлично подходит для проверок работоспособности сайта, чтобы не выискивать все используемые им хосты, а включить прокси только в текущей вкладке.

UI плагина FoxyProxy
Включение прокси на вкладку
Включение прокси на вкладку
Настройки FoxyProxy
Настройки FoxyProxy

Сначала рассмотрим настройку без получаемых маршрутов для роутинга на наши контейнеры по BGP

Будем использовать DNS Forward и списки хостов, которые будем пускать через контейнер туннель анти dpi системы :)

Обязательно должен быть настроен DoH DNS, ибо можно получить "подарок" от провайдера с липовыми адресами используя не шифрованные запросы DNS.

Выбирайте на свой вкус, я использую первый.

Для настройки DNS 1.1.1.1 (импортируется один сертификат):

/tool fetch https://cacerts.digicert.com/DigiCertGlobalRootG2.crt.pem
/certificate import file-name=DigiCertGlobalRootG2.crt.pem passphrase=""
/ip dns set use-doh-server=https://1.1.1.1/dns-query verify-doh-cert=yes

Для настройки DNS 9.9.9.9 и аналогичных (импортируется много сертификатов):

/tool fetch url=https://curl.se/ca/cacert.pem
/certificate import file-name=cacert.pem passphrase=""
/ip dns set use-doh-server=https://9.9.9.9/dns-query verify-doh-cert=yes

Затем добавим хосты, которые нужно пускать через контейнер анти DPI:

# set to default
/ip/dns set address-list-extra-time=0s
# address list
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=googlevideo.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=youtube.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=youtubei.googleapis.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=ytimg.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=youtu.be type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=ggpht.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=rutracker.org type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=rutracker.cc type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=medium.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=facebook.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=fbcdn.net type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=x.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=twitter.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=linkedin.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=prntscr.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=prnt.sc type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=t.co type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=protonvpn.com type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=nnmclub.to type=FWD
/ip/dns/static/ add address-list=za_dpi_FWD forward-to=localhost match-subdomain=yes name=ntc.party type=FWD
  • Указанные домены с их поддоменами будут добавляться в список za_dpi_FWD, называется он так, чтобы быть в конце всех списков при сортировке по имени списка)

UI DNS static

Добавляем новую таблицу маршрутизации:

/routing table add disabled=no fib name=dpi_mark

И добавляем маршрут в эту таблицу на наш шлюз контейнер:

/ip route add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=192.168.254.2%Bridge-Docker pref-src="" routing-table=dpi_mark scope=30 suppress-hw-offload=no target-scope=10

Теперь добавим mangle правила, чтобы заворачивать все полученные в список хосты в таблицу маршрутизации dpi_mark где весь трафик пойдет на наш анти dpi туннель:

/ip firewall mangle add action=mark-connection chain=prerouting connection-mark=no-mark dst-address-list=za_dpi_FWD in-interface-list=LAN new-connection-mark=to_dpi passthrough=yes
/ip firewall mangle add action=mark-routing chain=prerouting comment="To DPI" connection-mark=to_dpi in-interface-list=LAN new-routing-mark=dpi_mark passthrough=no routing-mark=!dpi_mark
UI таблица маршрутов и mangle mark route

Так же в файерволе (IP - Firewall - Filter Rules) правило forward fasttrack connection нужно обновить, исключив маркированный трафик, так сайты из списков будут открываться быстрее. Если вы его не используете (выключили/удалили), то можно оставить как есть.

/ip firewall filter set [find action=fasttrack-connection] packet-mark=no-mark connection-mark=no-mark
UI Firewall fasttrack

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

Предварительно добавим адреса локальных сетей, чтобы не перехватывать запросы DNS не идущие на внешние сервисы:

/ip/firewall/address-list/ add address=10.0.0.0/8 list=local
/ip/firewall/address-list/ add address=172.16.0.0/12 list=local
/ip/firewall/address-list/ add address=192.168.0.0/16 list=local
/ip firewall nat add action=redirect chain=dstnat dst-address-list=!local dst-port=53 in-interface-list=LAN protocol=udp
/ip firewall nat add action=redirect chain=dstnat dst-address-list=!local dst-port=53 in-interface-list=LAN protocol=tcp
/container start [find interface=BYEDPI-SOCKS]
/container start [find interface=BYEDPI-TUN]
UI Firewall NAT

Перезагружаем роутер! Готово! Можно начинать тестировать ютуб и сайты из добавленного списка, но с одним замечанием, нужно либо перезагрузить все устройства, что иногда сделать проще всего, чтобы на них очистился кеш DNS запросов, либо очистить его вручную и на роутере в том числе. Иначе необходимые адреса не попадут в списки для роутинга.

Все это прекрасно совмещается с аналогичным выходом на vpn ресурсов по другому списку хостов в DNS FWD, которые не обходятся таким способом, но здесь не об этом.

Теперь рассмотрим настройку с получаемыми маршрутами по BGP в т.ч. для Ютуба

Допустим мы уже получаем какие-то маршруты по BGP от сервисов antifilter и дополнительно хотим получать адреса для Ютуба чтобы сразу направить их на наши контейнеры.

UI BGP подключение
Основные настройки BGP
Основные настройки BGP
Фильтр bgp_in, в который далее будем вносить маршруты.
Фильтр bgp_in, в который далее будем вносить маршруты.

Включаем этот список на сайте antifilter для получения на роутер.
Включаем этот список на сайте antifilter для получения на роутер.

В таком случае нужно ко всем вышеперечисленным настройкам создать новую таблицу маршрутизации clear_out

/routing table add disabled=no fib name=clear_out

С маршрутом в интернет для этой таблицы, который у вас есть по дефолту, у меня это выше стоящий GPON роутер 192.168.1.100:

/ip route add disabled=no distance=24 dst-address=0.0.0.0/0 gateway=192.168.1.100 pref-src="" routing-table=clear_out scope=30 suppress-hw-offload=no target-scope=10

UI таблица маршрутов
По сути нужно скопировать основной маршрут в интернет без указания VRF и с указанием новой таблицы роутинга
По сути нужно скопировать основной маршрут в интернет без указания VRF и с указанием новой таблицы роутинга

Далее в фильтрах роутинга /routing/filter нужно для Ютуба прописать наш шлюз TUN2SOCKS:

if (bgp-communities includes 65444:770) {set gw 192.168.254.2%Bridge-Docker; accept;} else {set gw 10.10.0.1%wireguard-client-vpn; accept;}

UI фильтры маршрутов
Вносим в тот фильтр chain, который выбран в настройках BGP - Filter - Input filter
Вносим в тот фильтр chain, который выбран в настройках BGP - Filter - Input filter

Скорее всего у большинства по bgp приходят роуты в main routing table, а теперь после выполнения последней команды есть роуты и на шлюз контейнера tun2socks

UI BGP и Route list
По bgp приходят роуты в routing table main
По bgp приходят роуты в routing table main
Полученные по bgp маршруты для Ютуба
Полученные по bgp маршруты для Ютуба

в таком случае сам контейнер byedpi выводим в отдельную таблицу маршрутизации clear_out которая выходит прямо в интернет, чтобы не зациклить маршрутизацию адресов ютуба и всего что отправляется на шлюз контейнера в таблице main, т.к. ничего не будет работать.

/ip firewall mangle add action=mark-routing chain=prerouting comment="BYEDPI mark route to clear_out" new-routing-mark=clear_out passthrough=no src-address=192.168.254.2

UI mangle mark routing
По счетчикам видно срабатывание правила. Стоит приоритетнее, чем правило по спискам.
По счетчикам видно срабатывание правила. Стоит приоритетнее, чем правило по спискам.

Это правило отлично подходит для проверки работоспособности, т.к. есть счетчики на правилах. Либо же его можно заменить аналогичным другим правилом в другом разделе:

правила в /ip/firewall/mangleприоритетнее чем в/routing/rule !

/routing rule add action=lookup comment="BYEDPI-SOCKS mark route to clear_out" disabled=no src-address=192.168.254.2/32 table=clear_out

UI routing rules

Выбирайте на вкус и цвет, есть ли какая-то разница в производительности, не знаю. Иногда лучше видеть всё в настройках mangle, в одном месте так сказать.

  • После аналогичной настройки для контейнера BYEDPI-SOCKS (192.168.254.5:1080) он перестает быть напрямую доступным из локальной сети, поэтому чтобы использовать его из браузера как socks5 прокси нужно скопировать в таблицу clear_out маршрут в вашу локальную сеть, откуда идет обращение, например это bridge.

Заключение

Большинство опытных пользователей получают маршруты по BGP и просто всё отправляют на VPN, простые пользователи борятся с проблемами доступа к заблокированным ресурсам разными бесплатными VPN'ами, вторых можно понять, да и первых, у кого старые роутеры без поддержки контейнеров.

После погружения в тему для меня стало удивлением, что много сайтов начали работать без VPN, поэтому меня привлекла логичная идея локально "лечить" трафик прямо на роутере.

После настройки этих двух контейнеров я даже отказался от BGP, потому что не так много сайтов я использую которые не доступны, все они прекрасно работают по спискам DNS FWD, тестирую уже неделю и полёт отличный.

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

Спасибо всем за внимание!

UPD. 17.09.2024:

Статья обновлена, контейнер tun2socks заменен на hev-socks5-tunnel чтобы избежать лишних манипуляций с его настройками.

Так же сегодня вышло обновление byedpi, можете удалить и переустановить контейнер.

Ищите и пробуйте готовые варианты команд для запуска byedpi если с указанными в статье настройками ютуб не запустился:

https://github.com/hufrea/byedpi/discussions
https://github.com/dovecoteescapee/ByeDPIAndroid/discussions

По поводу ТВ я тестровал на Samsung с Tizen OS, результат тут.

UPD. 7.11.2024:

Собрал свой контейнер 2в1 byedpi + hev-socks5-tunnel https://hub.docker.com/r/wiktorbgu/byedpi-hev-socks5-tunnel и исправил текущую инструкцию. Так же посмотрите другие мои образы, они могут вас заинтересовать.

Спасибо за ваши донаты и тем кто обращается за платной настройкой) таким образом вы поддерживаете создание новых решений и поддержку существующих!

Tags:
Hubs:
If this publication inspired you and you want to support the author, do not hesitate to click on the button
Total votes 109: ↑109 and ↓0+128
Comments225

Articles