<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://wiki.mywolfram.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80</id>
	<title>wolfram - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.mywolfram.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80"/>
	<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80"/>
	<updated>2026-05-28T19:56:05Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=1004</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=1004"/>
		<updated>2026-05-13T05:04:44Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* Подключитесь по SSH к роутеру и выполните одну команду: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
[[Файл:Keenetic architecture overview.png|центр|мини|633x633пкс|Общая схема: keen-pbr по адресу домена решает, отправить трафик в туннель singtun (sing-box → VPN-сервер) или пустить через nfqws2 + прямой WAN.]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Какая у вас прошивка ==&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужен ли вам отдельный шаг включения компонентов прошивки.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. подсекцию «Только для оригинального Keenetic» ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, всё уже в образе прошивки порта — пропускайте подсекцию ниже и сразу переходите к «Выбор URL установщика»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как понять, какая у вас:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; видна модель устройства. Маркетинговое имя &amp;quot;Keenetic Hero&amp;quot; и модель &amp;quot;KN-...&amp;quot; — это оригинальный Keenetic. Имя другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) + KeeneticOS — это порт сообщества. Дополнительный признак порта — на странице компонентов сообщение «Не удалось получить список компонентов от сервера» (своего сервера обновлений у порта нет).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Только для оригинального Keenetic ==&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|База Entware&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Монтирование ext4-флешки&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Командная строка роутера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|База iptables для Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Доп. модули (&amp;lt;code&amp;gt;xt_set&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;xt_multiport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;conntrack-extra&amp;lt;/code&amp;gt;) — &#039;&#039;&#039;критично&#039;&#039;&#039; для keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора — &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и ждите 2–5 минут, роутер перезагрузится сам.&lt;br /&gt;
&lt;br /&gt;
== Выбор URL установщика ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (одной строкой)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как узнать архитектуру:&#039;&#039;&#039; &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; → видна модель и процессор. Большинство бытовых моделей — MIPS (верхняя строка). Сомневаетесь — берите mipsel; если не подходит, установщик ругнётся, роутер от этого не сломается.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Что вам понадобится ==&lt;br /&gt;
Перед тем как идти в командную строку, держите под рукой два значения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Откуда взять&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UUID USB-диска&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в веб-CLI Keenetic (см. шаг 3 в 1.1), поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;URL установщика&#039;&#039;&#039;&lt;br /&gt;
|Из таблицы «Выбор URL установщика» выше — по архитектуре&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Entware через командную строку ==&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Подключите USB-флешку.&#039;&#039;&#039; Воткните флешку в USB-порт роутера. Откройте веб-интерфейс: &#039;&#039;&#039;Приложения → USB-диски и принтеры&#039;&#039;&#039; — диск должен появиться в списке. Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; → &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
#: [[File:keenetic_usb_disks.png|center|Страница «USB-диски и принтеры» в веб-интерфейсе Keenetic с подключённой USB-флешкой и опцией «Форматировать» в EXT4.|мини|994x994пкс]]&lt;br /&gt;
# &#039;&#039;&#039;Откройте встроенный веб-CLI Keenetic:&#039;&#039;&#039; &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; (или подставьте свой LAN-IP роутера, если он другой). Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Узнайте UUID диска:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: В ответе найдите блок с вашей флешкой и поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Длинная строка вида &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; — это и есть нужное значение, скопируйте его.&lt;br /&gt;
# &#039;&#039;&#039;Запустите установку Entware.&#039;&#039;&#039; Подставьте &#039;&#039;&#039;свой UUID&#039;&#039;&#039; и &#039;&#039;&#039;URL по архитектуре&#039;&#039;&#039; (из таблицы «Выбор URL установщика» выше):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Пример с реальными подставленными значениями (mipsel):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &#039;&#039;&#039;Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде остаться не должно.&#039;&#039;&#039; Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — обязательны. После UUID и перед URL — ровно один пробел.&lt;br /&gt;
# &#039;&#039;&#039;Сразу включите DNS-override и сохраните конфиг:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; заставит KeeneticOS отдавать DNS-запросы клиентов в Entware-овский dnsmasq, который потом будет управляться keen-pbr. Без этого keen-pbr не сможет перехватывать DNS и маршрутизация по доменам работать не будет. Опция применится после reboot ниже.&lt;br /&gt;
# &#039;&#039;&#039;Дождитесь окончания установки.&#039;&#039;&#039; Откройте журнал в веб-интерфейсе: &amp;lt;code&amp;gt;http://192.168.1.1/diagnostics/general/log&amp;lt;/code&amp;gt; (если LAN-IP другой — подставьте). Установщик пишет туда что делает: качает &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;, распаковывает в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, ставит базовые пакеты. Это занимает 2–5 минут. Ждите финальной строки &amp;lt;code&amp;gt;Entware installed&amp;lt;/code&amp;gt;.&lt;br /&gt;
#: [[File:keenetic_log_entware_installed.png|center|Системный журнал Keenetic (/diagnostics/general/log) с финальной строкой «Entware installed» — установка завершилась успешно, можно перезагружать роутер.|мини|804x804пкс]]&lt;br /&gt;
#: &amp;lt;div style=&amp;quot;padding: 8px 12px; margin: 8px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&#039;&#039;&#039;Не перезагружайте роутер до этой строки в журнале!&#039;&#039;&#039; Если ребутнуть роутер посреди установки, файлы Entware на флешке останутся неконсистентными, и на следующих этапах посыпятся странные ошибки.&amp;lt;/div&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Перезагрузите роутер из веб-CLI:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;system reboot&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Через 1–2 минуты роутер поднимется обратно. После reboot применятся: монтирование Entware с флешки в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, автозапуск его сервисов, а главное — &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; из шага 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Если установщик молчит:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; молчит, если OPKG-диск уже был назначен раньше. В журнале нет строк про загрузку &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;? Сбросьте назначение диска и повторите шаги 4–5:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID&amp;gt;:/ &amp;lt;URL&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Первое подключение по SSH ==&lt;br /&gt;
&lt;br /&gt;
После перезагрузки Entware поднимает встроенный SSH-сервер на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На Windows — открываете PowerShell и подключаетесь одной командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(LAN-IP роутера другой — подставьте.)&lt;br /&gt;
&lt;br /&gt;
Параметры подключения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|LAN-IP роутера (&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; по умолчанию)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; (заводской)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При первом подключении SSH спросит fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; дефолтный &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем. Если SSH когда-нибудь будет проброшен наружу — роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите ходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце документа. Для базовой установки это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всё готово для установки утилит.&#039;&#039;&#039; Переходите к Этапу 2.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; &lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Так как у нас первый чистый запуск нужно установить несколько стандартных вещей:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install wget-ssl curl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
[[Файл:Singbox-helper-g.png|центр|мини|1034x1034пкс|Главный экран приложения Singbox-helper]]&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
[[Файл:Singbox-helper-con.png|центр|мини|850x850пкс|Пример успешного подключения в Singbox-helper]]&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
[[Файл:Keen-pbr-g.png|центр|мини|1043x1043пкс|Keen-pbr - пример главного экрана]]&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
[[File:keenpbr_outbounds.png|center|Страница «Outbounds (выходы)» в веб-интерфейсе keen-pbr со списком из трёх выходов: wan, block, vpn (interface=singtun).|мини|1005x1005пкс]]&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&lt;br /&gt;
Такие можно брать на &#039;&#039;&#039;[https://github.com/itdoginfo/allow-domains allow-domains]&#039;&#039;&#039; - тот же podckop использует именно эти списки &amp;quot;Russia inside, Telegram и так далее.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Дополнение:&#039;&#039;&#039; &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; это первый список что мы создали, их может быть сколько угодно, можно добавлять несколько. Например создать Russia inside на основе raw ссылки, и Telegram на основе Subnets.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
sh /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка запустит скрипт в первый раз принудительно.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;[http://192.168.10.1:90 http://192.168.1.1:90]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ввести логин и пароль,  те же что применяются для входа по ssh.&lt;br /&gt;
[[Файл:Nfqws2-g-p.png|центр|мини|914x914пкс|Пример главного окна Nfqws2]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
[[Файл:Keenetic architecture detailed.png|центр|мини|1031x1031пкс|Полная схема трафика через роутер: DNS-запросы клиента идут в keen-pbr dnsmasq → Quad9, ответы накапливаются в ipset; TCP-трафик в iptables маркируется и уходит либо в singtun (sing-box → VPN-узел), либо через WAN с DPI-обходом nfqws2.]]&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.8. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.9. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=1003</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=1003"/>
		<updated>2026-05-12T20:37:22Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* Шаг 3. Создать правило маршрутизации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
[[Файл:Keenetic architecture overview.png|центр|мини|633x633пкс|Общая схема: keen-pbr по адресу домена решает, отправить трафик в туннель singtun (sing-box → VPN-сервер) или пустить через nfqws2 + прямой WAN.]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Какая у вас прошивка ==&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужен ли вам отдельный шаг включения компонентов прошивки.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. подсекцию «Только для оригинального Keenetic» ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, всё уже в образе прошивки порта — пропускайте подсекцию ниже и сразу переходите к «Выбор URL установщика»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как понять, какая у вас:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; видна модель устройства. Маркетинговое имя &amp;quot;Keenetic Hero&amp;quot; и модель &amp;quot;KN-...&amp;quot; — это оригинальный Keenetic. Имя другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) + KeeneticOS — это порт сообщества. Дополнительный признак порта — на странице компонентов сообщение «Не удалось получить список компонентов от сервера» (своего сервера обновлений у порта нет).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Только для оригинального Keenetic ==&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|База Entware&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Монтирование ext4-флешки&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Командная строка роутера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|База iptables для Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Доп. модули (&amp;lt;code&amp;gt;xt_set&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;xt_multiport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;conntrack-extra&amp;lt;/code&amp;gt;) — &#039;&#039;&#039;критично&#039;&#039;&#039; для keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора — &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и ждите 2–5 минут, роутер перезагрузится сам.&lt;br /&gt;
&lt;br /&gt;
== Выбор URL установщика ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (одной строкой)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как узнать архитектуру:&#039;&#039;&#039; &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; → видна модель и процессор. Большинство бытовых моделей — MIPS (верхняя строка). Сомневаетесь — берите mipsel; если не подходит, установщик ругнётся, роутер от этого не сломается.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Что вам понадобится ==&lt;br /&gt;
Перед тем как идти в командную строку, держите под рукой два значения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Откуда взять&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UUID USB-диска&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в веб-CLI Keenetic (см. шаг 3 в 1.1), поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;URL установщика&#039;&#039;&#039;&lt;br /&gt;
|Из таблицы «Выбор URL установщика» выше — по архитектуре&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Entware через командную строку ==&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Подключите USB-флешку.&#039;&#039;&#039; Воткните флешку в USB-порт роутера. Откройте веб-интерфейс: &#039;&#039;&#039;Приложения → USB-диски и принтеры&#039;&#039;&#039; — диск должен появиться в списке. Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; → &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
#: [[File:keenetic_usb_disks.png|center|Страница «USB-диски и принтеры» в веб-интерфейсе Keenetic с подключённой USB-флешкой и опцией «Форматировать» в EXT4.|мини|994x994пкс]]&lt;br /&gt;
# &#039;&#039;&#039;Откройте встроенный веб-CLI Keenetic:&#039;&#039;&#039; &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; (или подставьте свой LAN-IP роутера, если он другой). Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Узнайте UUID диска:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: В ответе найдите блок с вашей флешкой и поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Длинная строка вида &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; — это и есть нужное значение, скопируйте его.&lt;br /&gt;
# &#039;&#039;&#039;Запустите установку Entware.&#039;&#039;&#039; Подставьте &#039;&#039;&#039;свой UUID&#039;&#039;&#039; и &#039;&#039;&#039;URL по архитектуре&#039;&#039;&#039; (из таблицы «Выбор URL установщика» выше):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Пример с реальными подставленными значениями (mipsel):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &#039;&#039;&#039;Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде остаться не должно.&#039;&#039;&#039; Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — обязательны. После UUID и перед URL — ровно один пробел.&lt;br /&gt;
# &#039;&#039;&#039;Сразу включите DNS-override и сохраните конфиг:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; заставит KeeneticOS отдавать DNS-запросы клиентов в Entware-овский dnsmasq, который потом будет управляться keen-pbr. Без этого keen-pbr не сможет перехватывать DNS и маршрутизация по доменам работать не будет. Опция применится после reboot ниже.&lt;br /&gt;
# &#039;&#039;&#039;Дождитесь окончания установки.&#039;&#039;&#039; Откройте журнал в веб-интерфейсе: &amp;lt;code&amp;gt;http://192.168.1.1/diagnostics/general/log&amp;lt;/code&amp;gt; (если LAN-IP другой — подставьте). Установщик пишет туда что делает: качает &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;, распаковывает в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, ставит базовые пакеты. Это занимает 2–5 минут. Ждите финальной строки &amp;lt;code&amp;gt;Entware installed&amp;lt;/code&amp;gt;.&lt;br /&gt;
#: [[File:keenetic_log_entware_installed.png|center|Системный журнал Keenetic (/diagnostics/general/log) с финальной строкой «Entware installed» — установка завершилась успешно, можно перезагружать роутер.|мини|804x804пкс]]&lt;br /&gt;
#: &amp;lt;div style=&amp;quot;padding: 8px 12px; margin: 8px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&#039;&#039;&#039;Не перезагружайте роутер до этой строки в журнале!&#039;&#039;&#039; Если ребутнуть роутер посреди установки, файлы Entware на флешке останутся неконсистентными, и на следующих этапах посыпятся странные ошибки.&amp;lt;/div&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Перезагрузите роутер из веб-CLI:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;system reboot&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Через 1–2 минуты роутер поднимется обратно. После reboot применятся: монтирование Entware с флешки в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, автозапуск его сервисов, а главное — &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; из шага 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Если установщик молчит:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; молчит, если OPKG-диск уже был назначен раньше. В журнале нет строк про загрузку &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;? Сбросьте назначение диска и повторите шаги 4–5:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID&amp;gt;:/ &amp;lt;URL&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Первое подключение по SSH ==&lt;br /&gt;
&lt;br /&gt;
После перезагрузки Entware поднимает встроенный SSH-сервер на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На Windows — открываете PowerShell и подключаетесь одной командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(LAN-IP роутера другой — подставьте.)&lt;br /&gt;
&lt;br /&gt;
Параметры подключения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|LAN-IP роутера (&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; по умолчанию)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; (заводской)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При первом подключении SSH спросит fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; дефолтный &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем. Если SSH когда-нибудь будет проброшен наружу — роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите ходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце документа. Для базовой установки это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всё готово для установки утилит.&#039;&#039;&#039; Переходите к Этапу 2.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; &lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Так как у нас первый чистый запуск нужно установить несколько стандартных вещей:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install wget-ssl curl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
[[Файл:Singbox-helper-g.png|центр|мини|1034x1034пкс|Главный экран приложения Singbox-helper]]&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
[[Файл:Singbox-helper-con.png|центр|мини|850x850пкс|Пример успешного подключения в Singbox-helper]]&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
[[Файл:Keen-pbr-g.png|центр|мини|1043x1043пкс|Keen-pbr - пример главного экрана]]&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
[[File:keenpbr_outbounds.png|center|Страница «Outbounds (выходы)» в веб-интерфейсе keen-pbr со списком из трёх выходов: wan, block, vpn (interface=singtun).|мини|1005x1005пкс]]&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&lt;br /&gt;
Такие можно брать на &#039;&#039;&#039;[https://github.com/itdoginfo/allow-domains allow-domains]&#039;&#039;&#039; - тот же podckop использует именно эти списки &amp;quot;Russia inside, Telegram и так далее.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Дополнение:&#039;&#039;&#039; &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; это первый список что мы создали, их может быть сколько угодно, можно добавлять несколько. Например создать Russia inside на основе raw ссылки, и Telegram на основе Subnets.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
sh /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;[http://192.168.10.1:90 http://192.168.1.1:90]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ввести логин и пароль,  те же что применяются для входа по ssh.&lt;br /&gt;
[[Файл:Nfqws2-g-p.png|центр|мини|914x914пкс|Пример главного окна Nfqws2]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
[[Файл:Keenetic architecture detailed.png|центр|мини|1031x1031пкс|Полная схема трафика через роутер: DNS-запросы клиента идут в keen-pbr dnsmasq → Quad9, ответы накапливаются в ipset; TCP-трафик в iptables маркируется и уходит либо в singtun (sing-box → VPN-узел), либо через WAN с DPI-обходом nfqws2.]]&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.8. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.9. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=1002</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=1002"/>
		<updated>2026-05-12T20:33:37Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* Шаг 2. Создать список доменов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
[[Файл:Keenetic architecture overview.png|центр|мини|633x633пкс|Общая схема: keen-pbr по адресу домена решает, отправить трафик в туннель singtun (sing-box → VPN-сервер) или пустить через nfqws2 + прямой WAN.]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Какая у вас прошивка ==&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужен ли вам отдельный шаг включения компонентов прошивки.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. подсекцию «Только для оригинального Keenetic» ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, всё уже в образе прошивки порта — пропускайте подсекцию ниже и сразу переходите к «Выбор URL установщика»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как понять, какая у вас:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; видна модель устройства. Маркетинговое имя &amp;quot;Keenetic Hero&amp;quot; и модель &amp;quot;KN-...&amp;quot; — это оригинальный Keenetic. Имя другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) + KeeneticOS — это порт сообщества. Дополнительный признак порта — на странице компонентов сообщение «Не удалось получить список компонентов от сервера» (своего сервера обновлений у порта нет).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Только для оригинального Keenetic ==&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|База Entware&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Монтирование ext4-флешки&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Командная строка роутера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|База iptables для Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Доп. модули (&amp;lt;code&amp;gt;xt_set&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;xt_multiport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;conntrack-extra&amp;lt;/code&amp;gt;) — &#039;&#039;&#039;критично&#039;&#039;&#039; для keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора — &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и ждите 2–5 минут, роутер перезагрузится сам.&lt;br /&gt;
&lt;br /&gt;
== Выбор URL установщика ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (одной строкой)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как узнать архитектуру:&#039;&#039;&#039; &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; → видна модель и процессор. Большинство бытовых моделей — MIPS (верхняя строка). Сомневаетесь — берите mipsel; если не подходит, установщик ругнётся, роутер от этого не сломается.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Что вам понадобится ==&lt;br /&gt;
Перед тем как идти в командную строку, держите под рукой два значения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Откуда взять&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UUID USB-диска&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в веб-CLI Keenetic (см. шаг 3 в 1.1), поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;URL установщика&#039;&#039;&#039;&lt;br /&gt;
|Из таблицы «Выбор URL установщика» выше — по архитектуре&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Entware через командную строку ==&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Подключите USB-флешку.&#039;&#039;&#039; Воткните флешку в USB-порт роутера. Откройте веб-интерфейс: &#039;&#039;&#039;Приложения → USB-диски и принтеры&#039;&#039;&#039; — диск должен появиться в списке. Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; → &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
#: [[File:keenetic_usb_disks.png|center|Страница «USB-диски и принтеры» в веб-интерфейсе Keenetic с подключённой USB-флешкой и опцией «Форматировать» в EXT4.|мини|994x994пкс]]&lt;br /&gt;
# &#039;&#039;&#039;Откройте встроенный веб-CLI Keenetic:&#039;&#039;&#039; &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; (или подставьте свой LAN-IP роутера, если он другой). Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Узнайте UUID диска:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: В ответе найдите блок с вашей флешкой и поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Длинная строка вида &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; — это и есть нужное значение, скопируйте его.&lt;br /&gt;
# &#039;&#039;&#039;Запустите установку Entware.&#039;&#039;&#039; Подставьте &#039;&#039;&#039;свой UUID&#039;&#039;&#039; и &#039;&#039;&#039;URL по архитектуре&#039;&#039;&#039; (из таблицы «Выбор URL установщика» выше):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Пример с реальными подставленными значениями (mipsel):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &#039;&#039;&#039;Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде остаться не должно.&#039;&#039;&#039; Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — обязательны. После UUID и перед URL — ровно один пробел.&lt;br /&gt;
# &#039;&#039;&#039;Сразу включите DNS-override и сохраните конфиг:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; заставит KeeneticOS отдавать DNS-запросы клиентов в Entware-овский dnsmasq, который потом будет управляться keen-pbr. Без этого keen-pbr не сможет перехватывать DNS и маршрутизация по доменам работать не будет. Опция применится после reboot ниже.&lt;br /&gt;
# &#039;&#039;&#039;Дождитесь окончания установки.&#039;&#039;&#039; Откройте журнал в веб-интерфейсе: &amp;lt;code&amp;gt;http://192.168.1.1/diagnostics/general/log&amp;lt;/code&amp;gt; (если LAN-IP другой — подставьте). Установщик пишет туда что делает: качает &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;, распаковывает в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, ставит базовые пакеты. Это занимает 2–5 минут. Ждите финальной строки &amp;lt;code&amp;gt;Entware installed&amp;lt;/code&amp;gt;.&lt;br /&gt;
#: [[File:keenetic_log_entware_installed.png|center|Системный журнал Keenetic (/diagnostics/general/log) с финальной строкой «Entware installed» — установка завершилась успешно, можно перезагружать роутер.|мини|804x804пкс]]&lt;br /&gt;
#: &amp;lt;div style=&amp;quot;padding: 8px 12px; margin: 8px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&#039;&#039;&#039;Не перезагружайте роутер до этой строки в журнале!&#039;&#039;&#039; Если ребутнуть роутер посреди установки, файлы Entware на флешке останутся неконсистентными, и на следующих этапах посыпятся странные ошибки.&amp;lt;/div&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Перезагрузите роутер из веб-CLI:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;system reboot&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Через 1–2 минуты роутер поднимется обратно. После reboot применятся: монтирование Entware с флешки в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, автозапуск его сервисов, а главное — &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; из шага 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Если установщик молчит:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; молчит, если OPKG-диск уже был назначен раньше. В журнале нет строк про загрузку &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;? Сбросьте назначение диска и повторите шаги 4–5:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID&amp;gt;:/ &amp;lt;URL&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Первое подключение по SSH ==&lt;br /&gt;
&lt;br /&gt;
После перезагрузки Entware поднимает встроенный SSH-сервер на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На Windows — открываете PowerShell и подключаетесь одной командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(LAN-IP роутера другой — подставьте.)&lt;br /&gt;
&lt;br /&gt;
Параметры подключения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|LAN-IP роутера (&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; по умолчанию)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; (заводской)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При первом подключении SSH спросит fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; дефолтный &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем. Если SSH когда-нибудь будет проброшен наружу — роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите ходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце документа. Для базовой установки это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всё готово для установки утилит.&#039;&#039;&#039; Переходите к Этапу 2.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; &lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Так как у нас первый чистый запуск нужно установить несколько стандартных вещей:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install wget-ssl curl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
[[Файл:Singbox-helper-g.png|центр|мини|1034x1034пкс|Главный экран приложения Singbox-helper]]&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
[[Файл:Singbox-helper-con.png|центр|мини|850x850пкс|Пример успешного подключения в Singbox-helper]]&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
[[Файл:Keen-pbr-g.png|центр|мини|1043x1043пкс|Keen-pbr - пример главного экрана]]&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
[[File:keenpbr_outbounds.png|center|Страница «Outbounds (выходы)» в веб-интерфейсе keen-pbr со списком из трёх выходов: wan, block, vpn (interface=singtun).|мини|1005x1005пкс]]&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&lt;br /&gt;
Такие можно брать на &#039;&#039;&#039;[https://github.com/itdoginfo/allow-domains allow-domains]&#039;&#039;&#039; - тот же podckop использует именно эти списки &amp;quot;Russia inside, Russia Outside и так далее.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
sh /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;[http://192.168.10.1:90 http://192.168.1.1:90]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ввести логин и пароль,  те же что применяются для входа по ssh.&lt;br /&gt;
[[Файл:Nfqws2-g-p.png|центр|мини|914x914пкс|Пример главного окна Nfqws2]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
[[Файл:Keenetic architecture detailed.png|центр|мини|1031x1031пкс|Полная схема трафика через роутер: DNS-запросы клиента идут в keen-pbr dnsmasq → Quad9, ответы накапливаются в ipset; TCP-трафик в iptables маркируется и уходит либо в singtun (sing-box → VPN-узел), либо через WAN с DPI-обходом nfqws2.]]&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.8. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.9. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=1001</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=1001"/>
		<updated>2026-05-12T20:28:58Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* 2.3. Применение узла */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
[[Файл:Keenetic architecture overview.png|центр|мини|633x633пкс|Общая схема: keen-pbr по адресу домена решает, отправить трафик в туннель singtun (sing-box → VPN-сервер) или пустить через nfqws2 + прямой WAN.]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Какая у вас прошивка ==&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужен ли вам отдельный шаг включения компонентов прошивки.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. подсекцию «Только для оригинального Keenetic» ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, всё уже в образе прошивки порта — пропускайте подсекцию ниже и сразу переходите к «Выбор URL установщика»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как понять, какая у вас:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; видна модель устройства. Маркетинговое имя &amp;quot;Keenetic Hero&amp;quot; и модель &amp;quot;KN-...&amp;quot; — это оригинальный Keenetic. Имя другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) + KeeneticOS — это порт сообщества. Дополнительный признак порта — на странице компонентов сообщение «Не удалось получить список компонентов от сервера» (своего сервера обновлений у порта нет).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Только для оригинального Keenetic ==&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|База Entware&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Монтирование ext4-флешки&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Командная строка роутера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|База iptables для Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Доп. модули (&amp;lt;code&amp;gt;xt_set&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;xt_multiport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;conntrack-extra&amp;lt;/code&amp;gt;) — &#039;&#039;&#039;критично&#039;&#039;&#039; для keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора — &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и ждите 2–5 минут, роутер перезагрузится сам.&lt;br /&gt;
&lt;br /&gt;
== Выбор URL установщика ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (одной строкой)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как узнать архитектуру:&#039;&#039;&#039; &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; → видна модель и процессор. Большинство бытовых моделей — MIPS (верхняя строка). Сомневаетесь — берите mipsel; если не подходит, установщик ругнётся, роутер от этого не сломается.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Что вам понадобится ==&lt;br /&gt;
Перед тем как идти в командную строку, держите под рукой два значения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Откуда взять&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UUID USB-диска&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в веб-CLI Keenetic (см. шаг 3 в 1.1), поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;URL установщика&#039;&#039;&#039;&lt;br /&gt;
|Из таблицы «Выбор URL установщика» выше — по архитектуре&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Entware через командную строку ==&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Подключите USB-флешку.&#039;&#039;&#039; Воткните флешку в USB-порт роутера. Откройте веб-интерфейс: &#039;&#039;&#039;Приложения → USB-диски и принтеры&#039;&#039;&#039; — диск должен появиться в списке. Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; → &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
#: [[File:keenetic_usb_disks.png|center|Страница «USB-диски и принтеры» в веб-интерфейсе Keenetic с подключённой USB-флешкой и опцией «Форматировать» в EXT4.|мини|994x994пкс]]&lt;br /&gt;
# &#039;&#039;&#039;Откройте встроенный веб-CLI Keenetic:&#039;&#039;&#039; &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; (или подставьте свой LAN-IP роутера, если он другой). Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Узнайте UUID диска:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: В ответе найдите блок с вашей флешкой и поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Длинная строка вида &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; — это и есть нужное значение, скопируйте его.&lt;br /&gt;
# &#039;&#039;&#039;Запустите установку Entware.&#039;&#039;&#039; Подставьте &#039;&#039;&#039;свой UUID&#039;&#039;&#039; и &#039;&#039;&#039;URL по архитектуре&#039;&#039;&#039; (из таблицы «Выбор URL установщика» выше):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Пример с реальными подставленными значениями (mipsel):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &#039;&#039;&#039;Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде остаться не должно.&#039;&#039;&#039; Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — обязательны. После UUID и перед URL — ровно один пробел.&lt;br /&gt;
# &#039;&#039;&#039;Сразу включите DNS-override и сохраните конфиг:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; заставит KeeneticOS отдавать DNS-запросы клиентов в Entware-овский dnsmasq, который потом будет управляться keen-pbr. Без этого keen-pbr не сможет перехватывать DNS и маршрутизация по доменам работать не будет. Опция применится после reboot ниже.&lt;br /&gt;
# &#039;&#039;&#039;Дождитесь окончания установки.&#039;&#039;&#039; Откройте журнал в веб-интерфейсе: &amp;lt;code&amp;gt;http://192.168.1.1/diagnostics/general/log&amp;lt;/code&amp;gt; (если LAN-IP другой — подставьте). Установщик пишет туда что делает: качает &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;, распаковывает в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, ставит базовые пакеты. Это занимает 2–5 минут. Ждите финальной строки &amp;lt;code&amp;gt;Entware installed&amp;lt;/code&amp;gt;.&lt;br /&gt;
#: [[File:keenetic_log_entware_installed.png|center|Системный журнал Keenetic (/diagnostics/general/log) с финальной строкой «Entware installed» — установка завершилась успешно, можно перезагружать роутер.|мини|804x804пкс]]&lt;br /&gt;
#: &amp;lt;div style=&amp;quot;padding: 8px 12px; margin: 8px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&#039;&#039;&#039;Не перезагружайте роутер до этой строки в журнале!&#039;&#039;&#039; Если ребутнуть роутер посреди установки, файлы Entware на флешке останутся неконсистентными, и на следующих этапах посыпятся странные ошибки.&amp;lt;/div&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Перезагрузите роутер из веб-CLI:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;system reboot&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Через 1–2 минуты роутер поднимется обратно. После reboot применятся: монтирование Entware с флешки в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, автозапуск его сервисов, а главное — &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; из шага 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Если установщик молчит:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; молчит, если OPKG-диск уже был назначен раньше. В журнале нет строк про загрузку &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;? Сбросьте назначение диска и повторите шаги 4–5:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID&amp;gt;:/ &amp;lt;URL&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Первое подключение по SSH ==&lt;br /&gt;
&lt;br /&gt;
После перезагрузки Entware поднимает встроенный SSH-сервер на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На Windows — открываете PowerShell и подключаетесь одной командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(LAN-IP роутера другой — подставьте.)&lt;br /&gt;
&lt;br /&gt;
Параметры подключения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|LAN-IP роутера (&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; по умолчанию)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; (заводской)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При первом подключении SSH спросит fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; дефолтный &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем. Если SSH когда-нибудь будет проброшен наружу — роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите ходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце документа. Для базовой установки это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всё готово для установки утилит.&#039;&#039;&#039; Переходите к Этапу 2.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; &lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Так как у нас первый чистый запуск нужно установить несколько стандартных вещей:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install wget-ssl curl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
[[Файл:Singbox-helper-g.png|центр|мини|1034x1034пкс|Главный экран приложения Singbox-helper]]&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
[[Файл:Singbox-helper-con.png|центр|мини|850x850пкс|Пример успешного подключения в Singbox-helper]]&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
[[Файл:Keen-pbr-g.png|центр|мини|1043x1043пкс|Keen-pbr - пример главного экрана]]&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
[[File:keenpbr_outbounds.png|center|Страница «Outbounds (выходы)» в веб-интерфейсе keen-pbr со списком из трёх выходов: wan, block, vpn (interface=singtun).|мини|1005x1005пкс]]&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
sh /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;[http://192.168.10.1:90 http://192.168.1.1:90]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ввести логин и пароль,  те же что применяются для входа по ssh.&lt;br /&gt;
[[Файл:Nfqws2-g-p.png|центр|мини|914x914пкс|Пример главного окна Nfqws2]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
[[Файл:Keenetic architecture detailed.png|центр|мини|1031x1031пкс|Полная схема трафика через роутер: DNS-запросы клиента идут в keen-pbr dnsmasq → Quad9, ответы накапливаются в ipset; TCP-трафик в iptables маркируется и уходит либо в singtun (sing-box → VPN-узел), либо через WAN с DPI-обходом nfqws2.]]&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.8. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.9. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=1000</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=1000"/>
		<updated>2026-05-12T20:25:53Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* 2.1. Подключение фида singbox-helper и установка */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
[[Файл:Keenetic architecture overview.png|центр|мини|633x633пкс|Общая схема: keen-pbr по адресу домена решает, отправить трафик в туннель singtun (sing-box → VPN-сервер) или пустить через nfqws2 + прямой WAN.]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Какая у вас прошивка ==&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужен ли вам отдельный шаг включения компонентов прошивки.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. подсекцию «Только для оригинального Keenetic» ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, всё уже в образе прошивки порта — пропускайте подсекцию ниже и сразу переходите к «Выбор URL установщика»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как понять, какая у вас:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; видна модель устройства. Маркетинговое имя &amp;quot;Keenetic Hero&amp;quot; и модель &amp;quot;KN-...&amp;quot; — это оригинальный Keenetic. Имя другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) + KeeneticOS — это порт сообщества. Дополнительный признак порта — на странице компонентов сообщение «Не удалось получить список компонентов от сервера» (своего сервера обновлений у порта нет).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Только для оригинального Keenetic ==&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|База Entware&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Монтирование ext4-флешки&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Командная строка роутера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|База iptables для Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Доп. модули (&amp;lt;code&amp;gt;xt_set&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;xt_multiport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;conntrack-extra&amp;lt;/code&amp;gt;) — &#039;&#039;&#039;критично&#039;&#039;&#039; для keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора — &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и ждите 2–5 минут, роутер перезагрузится сам.&lt;br /&gt;
&lt;br /&gt;
== Выбор URL установщика ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (одной строкой)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как узнать архитектуру:&#039;&#039;&#039; &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; → видна модель и процессор. Большинство бытовых моделей — MIPS (верхняя строка). Сомневаетесь — берите mipsel; если не подходит, установщик ругнётся, роутер от этого не сломается.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Что вам понадобится ==&lt;br /&gt;
Перед тем как идти в командную строку, держите под рукой два значения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Откуда взять&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UUID USB-диска&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в веб-CLI Keenetic (см. шаг 3 в 1.1), поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;URL установщика&#039;&#039;&#039;&lt;br /&gt;
|Из таблицы «Выбор URL установщика» выше — по архитектуре&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Entware через командную строку ==&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Подключите USB-флешку.&#039;&#039;&#039; Воткните флешку в USB-порт роутера. Откройте веб-интерфейс: &#039;&#039;&#039;Приложения → USB-диски и принтеры&#039;&#039;&#039; — диск должен появиться в списке. Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; → &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
#: [[File:keenetic_usb_disks.png|center|Страница «USB-диски и принтеры» в веб-интерфейсе Keenetic с подключённой USB-флешкой и опцией «Форматировать» в EXT4.|мини|994x994пкс]]&lt;br /&gt;
# &#039;&#039;&#039;Откройте встроенный веб-CLI Keenetic:&#039;&#039;&#039; &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; (или подставьте свой LAN-IP роутера, если он другой). Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Узнайте UUID диска:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: В ответе найдите блок с вашей флешкой и поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Длинная строка вида &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; — это и есть нужное значение, скопируйте его.&lt;br /&gt;
# &#039;&#039;&#039;Запустите установку Entware.&#039;&#039;&#039; Подставьте &#039;&#039;&#039;свой UUID&#039;&#039;&#039; и &#039;&#039;&#039;URL по архитектуре&#039;&#039;&#039; (из таблицы «Выбор URL установщика» выше):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Пример с реальными подставленными значениями (mipsel):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &#039;&#039;&#039;Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде остаться не должно.&#039;&#039;&#039; Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — обязательны. После UUID и перед URL — ровно один пробел.&lt;br /&gt;
# &#039;&#039;&#039;Сразу включите DNS-override и сохраните конфиг:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; заставит KeeneticOS отдавать DNS-запросы клиентов в Entware-овский dnsmasq, который потом будет управляться keen-pbr. Без этого keen-pbr не сможет перехватывать DNS и маршрутизация по доменам работать не будет. Опция применится после reboot ниже.&lt;br /&gt;
# &#039;&#039;&#039;Дождитесь окончания установки.&#039;&#039;&#039; Откройте журнал в веб-интерфейсе: &amp;lt;code&amp;gt;http://192.168.1.1/diagnostics/general/log&amp;lt;/code&amp;gt; (если LAN-IP другой — подставьте). Установщик пишет туда что делает: качает &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;, распаковывает в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, ставит базовые пакеты. Это занимает 2–5 минут. Ждите финальной строки &amp;lt;code&amp;gt;Entware installed&amp;lt;/code&amp;gt;.&lt;br /&gt;
#: [[File:keenetic_log_entware_installed.png|center|Системный журнал Keenetic (/diagnostics/general/log) с финальной строкой «Entware installed» — установка завершилась успешно, можно перезагружать роутер.|мини|804x804пкс]]&lt;br /&gt;
#: &amp;lt;div style=&amp;quot;padding: 8px 12px; margin: 8px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&#039;&#039;&#039;Не перезагружайте роутер до этой строки в журнале!&#039;&#039;&#039; Если ребутнуть роутер посреди установки, файлы Entware на флешке останутся неконсистентными, и на следующих этапах посыпятся странные ошибки.&amp;lt;/div&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Перезагрузите роутер из веб-CLI:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;system reboot&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Через 1–2 минуты роутер поднимется обратно. После reboot применятся: монтирование Entware с флешки в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, автозапуск его сервисов, а главное — &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; из шага 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Если установщик молчит:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; молчит, если OPKG-диск уже был назначен раньше. В журнале нет строк про загрузку &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;? Сбросьте назначение диска и повторите шаги 4–5:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID&amp;gt;:/ &amp;lt;URL&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Первое подключение по SSH ==&lt;br /&gt;
&lt;br /&gt;
После перезагрузки Entware поднимает встроенный SSH-сервер на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На Windows — открываете PowerShell и подключаетесь одной командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(LAN-IP роутера другой — подставьте.)&lt;br /&gt;
&lt;br /&gt;
Параметры подключения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|LAN-IP роутера (&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; по умолчанию)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; (заводской)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При первом подключении SSH спросит fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; дефолтный &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем. Если SSH когда-нибудь будет проброшен наружу — роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите ходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце документа. Для базовой установки это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всё готово для установки утилит.&#039;&#039;&#039; Переходите к Этапу 2.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; &lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Так как у нас первый чистый запуск нужно установить несколько стандартных вещей:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install wget-ssl curl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
[[Файл:Singbox-helper-g.png|центр|мини|1034x1034пкс|Главный экран приложения Singbox-helper]]&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
[[Файл:Singbox-helper-con.png|центр|мини|850x850пкс|Пример успешного подключения в Singbox-helper]]&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. UI покажет жёлтое предупреждение под распознанными параметрами. Решение — попросить владельца сервера переключить транспорт на &amp;lt;code&amp;gt;ws&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grpc&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;tcp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
[[Файл:Keen-pbr-g.png|центр|мини|1043x1043пкс|Keen-pbr - пример главного экрана]]&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
[[File:keenpbr_outbounds.png|center|Страница «Outbounds (выходы)» в веб-интерфейсе keen-pbr со списком из трёх выходов: wan, block, vpn (interface=singtun).|мини|1005x1005пкс]]&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
sh /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;[http://192.168.10.1:90 http://192.168.1.1:90]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ввести логин и пароль,  те же что применяются для входа по ssh.&lt;br /&gt;
[[Файл:Nfqws2-g-p.png|центр|мини|914x914пкс|Пример главного окна Nfqws2]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
[[Файл:Keenetic architecture detailed.png|центр|мини|1031x1031пкс|Полная схема трафика через роутер: DNS-запросы клиента идут в keen-pbr dnsmasq → Quad9, ответы накапливаются в ipset; TCP-трафик в iptables маркируется и уходит либо в singtun (sing-box → VPN-узел), либо через WAN с DPI-обходом nfqws2.]]&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.8. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.9. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=999</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=999"/>
		<updated>2026-05-12T18:47:49Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* 3.4. Скрипт правил NAT и FORWARD */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
[[Файл:Keenetic architecture overview.png|центр|мини|633x633пкс|Общая схема: keen-pbr по адресу домена решает, отправить трафик в туннель singtun (sing-box → VPN-сервер) или пустить через nfqws2 + прямой WAN.]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Какая у вас прошивка ==&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужен ли вам отдельный шаг включения компонентов прошивки.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. подсекцию «Только для оригинального Keenetic» ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, всё уже в образе прошивки порта — пропускайте подсекцию ниже и сразу переходите к «Выбор URL установщика»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как понять, какая у вас:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; видна модель устройства. Маркетинговое имя &amp;quot;Keenetic Hero&amp;quot; и модель &amp;quot;KN-...&amp;quot; — это оригинальный Keenetic. Имя другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) + KeeneticOS — это порт сообщества. Дополнительный признак порта — на странице компонентов сообщение «Не удалось получить список компонентов от сервера» (своего сервера обновлений у порта нет).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Только для оригинального Keenetic ==&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|База Entware&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Монтирование ext4-флешки&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Командная строка роутера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|База iptables для Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Доп. модули (&amp;lt;code&amp;gt;xt_set&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;xt_multiport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;conntrack-extra&amp;lt;/code&amp;gt;) — &#039;&#039;&#039;критично&#039;&#039;&#039; для keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора — &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и ждите 2–5 минут, роутер перезагрузится сам.&lt;br /&gt;
&lt;br /&gt;
== Выбор URL установщика ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (одной строкой)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как узнать архитектуру:&#039;&#039;&#039; &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; → видна модель и процессор. Большинство бытовых моделей — MIPS (верхняя строка). Сомневаетесь — берите mipsel; если не подходит, установщик ругнётся, роутер от этого не сломается.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Что вам понадобится ==&lt;br /&gt;
Перед тем как идти в командную строку, держите под рукой два значения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Откуда взять&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UUID USB-диска&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в веб-CLI Keenetic (см. шаг 3 в 1.1), поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;URL установщика&#039;&#039;&#039;&lt;br /&gt;
|Из таблицы «Выбор URL установщика» выше — по архитектуре&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Entware через командную строку ==&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Подключите USB-флешку.&#039;&#039;&#039; Воткните флешку в USB-порт роутера. Откройте веб-интерфейс: &#039;&#039;&#039;Приложения → USB-диски и принтеры&#039;&#039;&#039; — диск должен появиться в списке. Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; → &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
#: [[File:keenetic_usb_disks.png|center|Страница «USB-диски и принтеры» в веб-интерфейсе Keenetic с подключённой USB-флешкой и опцией «Форматировать» в EXT4.|мини|994x994пкс]]&lt;br /&gt;
# &#039;&#039;&#039;Откройте встроенный веб-CLI Keenetic:&#039;&#039;&#039; &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; (или подставьте свой LAN-IP роутера, если он другой). Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Узнайте UUID диска:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: В ответе найдите блок с вашей флешкой и поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Длинная строка вида &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; — это и есть нужное значение, скопируйте его.&lt;br /&gt;
# &#039;&#039;&#039;Запустите установку Entware.&#039;&#039;&#039; Подставьте &#039;&#039;&#039;свой UUID&#039;&#039;&#039; и &#039;&#039;&#039;URL по архитектуре&#039;&#039;&#039; (из таблицы «Выбор URL установщика» выше):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Пример с реальными подставленными значениями (mipsel):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &#039;&#039;&#039;Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде остаться не должно.&#039;&#039;&#039; Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — обязательны. После UUID и перед URL — ровно один пробел.&lt;br /&gt;
# &#039;&#039;&#039;Сразу включите DNS-override и сохраните конфиг:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; заставит KeeneticOS отдавать DNS-запросы клиентов в Entware-овский dnsmasq, который потом будет управляться keen-pbr. Без этого keen-pbr не сможет перехватывать DNS и маршрутизация по доменам работать не будет. Опция применится после reboot ниже.&lt;br /&gt;
# &#039;&#039;&#039;Дождитесь окончания установки.&#039;&#039;&#039; Откройте журнал в веб-интерфейсе: &amp;lt;code&amp;gt;http://192.168.1.1/diagnostics/general/log&amp;lt;/code&amp;gt; (если LAN-IP другой — подставьте). Установщик пишет туда что делает: качает &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;, распаковывает в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, ставит базовые пакеты. Это занимает 2–5 минут. Ждите финальной строки &amp;lt;code&amp;gt;Entware installed&amp;lt;/code&amp;gt;.&lt;br /&gt;
#: [[File:keenetic_log_entware_installed.png|center|Системный журнал Keenetic (/diagnostics/general/log) с финальной строкой «Entware installed» — установка завершилась успешно, можно перезагружать роутер.|мини|804x804пкс]]&lt;br /&gt;
#: &amp;lt;div style=&amp;quot;padding: 8px 12px; margin: 8px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&#039;&#039;&#039;Не перезагружайте роутер до этой строки в журнале!&#039;&#039;&#039; Если ребутнуть роутер посреди установки, файлы Entware на флешке останутся неконсистентными, и на следующих этапах посыпятся странные ошибки.&amp;lt;/div&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Перезагрузите роутер из веб-CLI:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;system reboot&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Через 1–2 минуты роутер поднимется обратно. После reboot применятся: монтирование Entware с флешки в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, автозапуск его сервисов, а главное — &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; из шага 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Если установщик молчит:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; молчит, если OPKG-диск уже был назначен раньше. В журнале нет строк про загрузку &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;? Сбросьте назначение диска и повторите шаги 4–5:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID&amp;gt;:/ &amp;lt;URL&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Первое подключение по SSH ==&lt;br /&gt;
&lt;br /&gt;
После перезагрузки Entware поднимает встроенный SSH-сервер на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На Windows — открываете PowerShell и подключаетесь одной командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(LAN-IP роутера другой — подставьте.)&lt;br /&gt;
&lt;br /&gt;
Параметры подключения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|LAN-IP роутера (&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; по умолчанию)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; (заводской)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При первом подключении SSH спросит fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; дефолтный &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем. Если SSH когда-нибудь будет проброшен наружу — роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите ходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце документа. Для базовой установки это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всё готово для установки утилит.&#039;&#039;&#039; Переходите к Этапу 2.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; &lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Так как у нас первый чистый запуск нужно установить несколько стандартных вещей:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install wget-ssl curl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про место:&#039;&#039;&#039; &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; занимает ~62 МБ распакованных, плюс ~7 МБ сам helper, плюс Entware-окружение. На встроенной флэш-памяти роутера не помещается — Entware &#039;&#039;&#039;должен&#039;&#039;&#039; быть на USB (см. Этап 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
[[Файл:Singbox-helper-g.png|центр|мини|1034x1034пкс|Главный экран приложения Singbox-helper]]&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
[[Файл:Singbox-helper-con.png|центр|мини|850x850пкс|Пример успешного подключения в Singbox-helper]]&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. UI покажет жёлтое предупреждение под распознанными параметрами. Решение — попросить владельца сервера переключить транспорт на &amp;lt;code&amp;gt;ws&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grpc&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;tcp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
[[Файл:Keen-pbr-g.png|центр|мини|1043x1043пкс|Keen-pbr - пример главного экрана]]&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
[[File:keenpbr_outbounds.png|center|Страница «Outbounds (выходы)» в веб-интерфейсе keen-pbr со списком из трёх выходов: wan, block, vpn (interface=singtun).|мини|1005x1005пкс]]&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
sh /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;[http://192.168.10.1:90 http://192.168.1.1:90]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ввести логин и пароль,  те же что применяются для входа по ssh.&lt;br /&gt;
[[Файл:Nfqws2-g-p.png|центр|мини|914x914пкс|Пример главного окна Nfqws2]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
[[Файл:Keenetic architecture detailed.png|центр|мини|1031x1031пкс|Полная схема трафика через роутер: DNS-запросы клиента идут в keen-pbr dnsmasq → Quad9, ответы накапливаются в ipset; TCP-трафик в iptables маркируется и уходит либо в singtun (sing-box → VPN-узел), либо через WAN с DPI-обходом nfqws2.]]&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.8. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.9. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=998</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=998"/>
		<updated>2026-05-12T18:46:08Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* 2.1. Подключение фида singbox-helper и установка */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
[[Файл:Keenetic architecture overview.png|центр|мини|633x633пкс|Общая схема: keen-pbr по адресу домена решает, отправить трафик в туннель singtun (sing-box → VPN-сервер) или пустить через nfqws2 + прямой WAN.]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Какая у вас прошивка ==&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужен ли вам отдельный шаг включения компонентов прошивки.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. подсекцию «Только для оригинального Keenetic» ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, всё уже в образе прошивки порта — пропускайте подсекцию ниже и сразу переходите к «Выбор URL установщика»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как понять, какая у вас:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; видна модель устройства. Маркетинговое имя &amp;quot;Keenetic Hero&amp;quot; и модель &amp;quot;KN-...&amp;quot; — это оригинальный Keenetic. Имя другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) + KeeneticOS — это порт сообщества. Дополнительный признак порта — на странице компонентов сообщение «Не удалось получить список компонентов от сервера» (своего сервера обновлений у порта нет).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Только для оригинального Keenetic ==&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|База Entware&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Монтирование ext4-флешки&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Командная строка роутера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|База iptables для Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Доп. модули (&amp;lt;code&amp;gt;xt_set&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;xt_multiport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;conntrack-extra&amp;lt;/code&amp;gt;) — &#039;&#039;&#039;критично&#039;&#039;&#039; для keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора — &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и ждите 2–5 минут, роутер перезагрузится сам.&lt;br /&gt;
&lt;br /&gt;
== Выбор URL установщика ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (одной строкой)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как узнать архитектуру:&#039;&#039;&#039; &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; → видна модель и процессор. Большинство бытовых моделей — MIPS (верхняя строка). Сомневаетесь — берите mipsel; если не подходит, установщик ругнётся, роутер от этого не сломается.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Что вам понадобится ==&lt;br /&gt;
Перед тем как идти в командную строку, держите под рукой два значения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Откуда взять&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UUID USB-диска&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в веб-CLI Keenetic (см. шаг 3 в 1.1), поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;URL установщика&#039;&#039;&#039;&lt;br /&gt;
|Из таблицы «Выбор URL установщика» выше — по архитектуре&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Entware через командную строку ==&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Подключите USB-флешку.&#039;&#039;&#039; Воткните флешку в USB-порт роутера. Откройте веб-интерфейс: &#039;&#039;&#039;Приложения → USB-диски и принтеры&#039;&#039;&#039; — диск должен появиться в списке. Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; → &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
#: [[File:keenetic_usb_disks.png|center|Страница «USB-диски и принтеры» в веб-интерфейсе Keenetic с подключённой USB-флешкой и опцией «Форматировать» в EXT4.|мини|994x994пкс]]&lt;br /&gt;
# &#039;&#039;&#039;Откройте встроенный веб-CLI Keenetic:&#039;&#039;&#039; &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; (или подставьте свой LAN-IP роутера, если он другой). Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Узнайте UUID диска:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: В ответе найдите блок с вашей флешкой и поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Длинная строка вида &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; — это и есть нужное значение, скопируйте его.&lt;br /&gt;
# &#039;&#039;&#039;Запустите установку Entware.&#039;&#039;&#039; Подставьте &#039;&#039;&#039;свой UUID&#039;&#039;&#039; и &#039;&#039;&#039;URL по архитектуре&#039;&#039;&#039; (из таблицы «Выбор URL установщика» выше):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Пример с реальными подставленными значениями (mipsel):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &#039;&#039;&#039;Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде остаться не должно.&#039;&#039;&#039; Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — обязательны. После UUID и перед URL — ровно один пробел.&lt;br /&gt;
# &#039;&#039;&#039;Сразу включите DNS-override и сохраните конфиг:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; заставит KeeneticOS отдавать DNS-запросы клиентов в Entware-овский dnsmasq, который потом будет управляться keen-pbr. Без этого keen-pbr не сможет перехватывать DNS и маршрутизация по доменам работать не будет. Опция применится после reboot ниже.&lt;br /&gt;
# &#039;&#039;&#039;Дождитесь окончания установки.&#039;&#039;&#039; Откройте журнал в веб-интерфейсе: &amp;lt;code&amp;gt;http://192.168.1.1/diagnostics/general/log&amp;lt;/code&amp;gt; (если LAN-IP другой — подставьте). Установщик пишет туда что делает: качает &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;, распаковывает в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, ставит базовые пакеты. Это занимает 2–5 минут. Ждите финальной строки &amp;lt;code&amp;gt;Entware installed&amp;lt;/code&amp;gt;.&lt;br /&gt;
#: [[File:keenetic_log_entware_installed.png|center|Системный журнал Keenetic (/diagnostics/general/log) с финальной строкой «Entware installed» — установка завершилась успешно, можно перезагружать роутер.|мини|804x804пкс]]&lt;br /&gt;
#: &amp;lt;div style=&amp;quot;padding: 8px 12px; margin: 8px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&#039;&#039;&#039;Не перезагружайте роутер до этой строки в журнале!&#039;&#039;&#039; Если ребутнуть роутер посреди установки, файлы Entware на флешке останутся неконсистентными, и на следующих этапах посыпятся странные ошибки.&amp;lt;/div&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Перезагрузите роутер из веб-CLI:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;system reboot&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Через 1–2 минуты роутер поднимется обратно. После reboot применятся: монтирование Entware с флешки в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, автозапуск его сервисов, а главное — &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; из шага 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Если установщик молчит:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; молчит, если OPKG-диск уже был назначен раньше. В журнале нет строк про загрузку &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;? Сбросьте назначение диска и повторите шаги 4–5:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID&amp;gt;:/ &amp;lt;URL&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Первое подключение по SSH ==&lt;br /&gt;
&lt;br /&gt;
После перезагрузки Entware поднимает встроенный SSH-сервер на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На Windows — открываете PowerShell и подключаетесь одной командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(LAN-IP роутера другой — подставьте.)&lt;br /&gt;
&lt;br /&gt;
Параметры подключения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|LAN-IP роутера (&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; по умолчанию)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; (заводской)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При первом подключении SSH спросит fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; дефолтный &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем. Если SSH когда-нибудь будет проброшен наружу — роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите ходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце документа. Для базовой установки это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всё готово для установки утилит.&#039;&#039;&#039; Переходите к Этапу 2.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; &lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Так как у нас первый чистый запуск нужно установить несколько стандартных вещей:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install wget-ssl curl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про место:&#039;&#039;&#039; &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; занимает ~62 МБ распакованных, плюс ~7 МБ сам helper, плюс Entware-окружение. На встроенной флэш-памяти роутера не помещается — Entware &#039;&#039;&#039;должен&#039;&#039;&#039; быть на USB (см. Этап 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
[[Файл:Singbox-helper-g.png|центр|мини|1034x1034пкс|Главный экран приложения Singbox-helper]]&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
[[Файл:Singbox-helper-con.png|центр|мини|850x850пкс|Пример успешного подключения в Singbox-helper]]&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. UI покажет жёлтое предупреждение под распознанными параметрами. Решение — попросить владельца сервера переключить транспорт на &amp;lt;code&amp;gt;ws&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grpc&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;tcp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
[[Файл:Keen-pbr-g.png|центр|мини|1043x1043пкс|Keen-pbr - пример главного экрана]]&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
[[File:keenpbr_outbounds.png|center|Страница «Outbounds (выходы)» в веб-интерфейсе keen-pbr со списком из трёх выходов: wan, block, vpn (interface=singtun).|мини|1005x1005пкс]]&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
sh /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок.&lt;br /&gt;
&lt;br /&gt;
== 3.5. Тестирование ==&lt;br /&gt;
На клиентском устройстве, подключённом к Keenetic:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Очистите кеш DNS&#039;&#039;&#039; (важно — без этого старые ответы остаются):&lt;br /&gt;
#* Windows: &amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; в PowerShell.&lt;br /&gt;
#* Android / iOS: переподключиться к Wi-Fi (off → on).&lt;br /&gt;
#* macOS: &amp;lt;code&amp;gt;sudo dscacheutil -flushcache&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Перезапустите браузер (у него свой DNS-кеш).&lt;br /&gt;
# Откройте сайт из списка bypass.&lt;br /&gt;
# Параллельно откройте &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; в браузере. Адрес должен быть тот же, который вы видели в шаге «IP через TUN» на вкладке Главная UI singbox-helper (т.е. IP вашего VPN-провайдера, а не домашний WAN-IP).&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;[http://192.168.10.1:90 http://192.168.1.1:90]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ввести логин и пароль,  те же что применяются для входа по ssh.&lt;br /&gt;
[[Файл:Nfqws2-g-p.png|центр|мини|914x914пкс|Пример главного окна Nfqws2]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
[[Файл:Keenetic architecture detailed.png|центр|мини|1031x1031пкс|Полная схема трафика через роутер: DNS-запросы клиента идут в keen-pbr dnsmasq → Quad9, ответы накапливаются в ipset; TCP-трафик в iptables маркируется и уходит либо в singtun (sing-box → VPN-узел), либо через WAN с DPI-обходом nfqws2.]]&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.8. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.9. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=997</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=997"/>
		<updated>2026-05-12T18:14:43Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
[[Файл:Keenetic architecture overview.png|центр|мини|633x633пкс|Общая схема: keen-pbr по адресу домена решает, отправить трафик в туннель singtun (sing-box → VPN-сервер) или пустить через nfqws2 + прямой WAN.]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Какая у вас прошивка ==&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужен ли вам отдельный шаг включения компонентов прошивки.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. подсекцию «Только для оригинального Keenetic» ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, всё уже в образе прошивки порта — пропускайте подсекцию ниже и сразу переходите к «Выбор URL установщика»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как понять, какая у вас:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; видна модель устройства. Маркетинговое имя &amp;quot;Keenetic Hero&amp;quot; и модель &amp;quot;KN-...&amp;quot; — это оригинальный Keenetic. Имя другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) + KeeneticOS — это порт сообщества. Дополнительный признак порта — на странице компонентов сообщение «Не удалось получить список компонентов от сервера» (своего сервера обновлений у порта нет).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Только для оригинального Keenetic ==&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|База Entware&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Монтирование ext4-флешки&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Командная строка роутера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|База iptables для Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Доп. модули (&amp;lt;code&amp;gt;xt_set&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;xt_multiport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;conntrack-extra&amp;lt;/code&amp;gt;) — &#039;&#039;&#039;критично&#039;&#039;&#039; для keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора — &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и ждите 2–5 минут, роутер перезагрузится сам.&lt;br /&gt;
&lt;br /&gt;
== Выбор URL установщика ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (одной строкой)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как узнать архитектуру:&#039;&#039;&#039; &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; → видна модель и процессор. Большинство бытовых моделей — MIPS (верхняя строка). Сомневаетесь — берите mipsel; если не подходит, установщик ругнётся, роутер от этого не сломается.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Что вам понадобится ==&lt;br /&gt;
Перед тем как идти в командную строку, держите под рукой два значения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Откуда взять&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UUID USB-диска&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в веб-CLI Keenetic (см. шаг 3 в 1.1), поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;URL установщика&#039;&#039;&#039;&lt;br /&gt;
|Из таблицы «Выбор URL установщика» выше — по архитектуре&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Entware через командную строку ==&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Подключите USB-флешку.&#039;&#039;&#039; Воткните флешку в USB-порт роутера. Откройте веб-интерфейс: &#039;&#039;&#039;Приложения → USB-диски и принтеры&#039;&#039;&#039; — диск должен появиться в списке. Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; → &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
#: [[File:keenetic_usb_disks.png|center|Страница «USB-диски и принтеры» в веб-интерфейсе Keenetic с подключённой USB-флешкой и опцией «Форматировать» в EXT4.|мини|994x994пкс]]&lt;br /&gt;
# &#039;&#039;&#039;Откройте встроенный веб-CLI Keenetic:&#039;&#039;&#039; &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; (или подставьте свой LAN-IP роутера, если он другой). Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Узнайте UUID диска:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: В ответе найдите блок с вашей флешкой и поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Длинная строка вида &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; — это и есть нужное значение, скопируйте его.&lt;br /&gt;
# &#039;&#039;&#039;Запустите установку Entware.&#039;&#039;&#039; Подставьте &#039;&#039;&#039;свой UUID&#039;&#039;&#039; и &#039;&#039;&#039;URL по архитектуре&#039;&#039;&#039; (из таблицы «Выбор URL установщика» выше):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Пример с реальными подставленными значениями (mipsel):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &#039;&#039;&#039;Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде остаться не должно.&#039;&#039;&#039; Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — обязательны. После UUID и перед URL — ровно один пробел.&lt;br /&gt;
# &#039;&#039;&#039;Сразу включите DNS-override и сохраните конфиг:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; заставит KeeneticOS отдавать DNS-запросы клиентов в Entware-овский dnsmasq, который потом будет управляться keen-pbr. Без этого keen-pbr не сможет перехватывать DNS и маршрутизация по доменам работать не будет. Опция применится после reboot ниже.&lt;br /&gt;
# &#039;&#039;&#039;Дождитесь окончания установки.&#039;&#039;&#039; Откройте журнал в веб-интерфейсе: &amp;lt;code&amp;gt;http://192.168.1.1/diagnostics/general/log&amp;lt;/code&amp;gt; (если LAN-IP другой — подставьте). Установщик пишет туда что делает: качает &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;, распаковывает в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, ставит базовые пакеты. Это занимает 2–5 минут. Ждите финальной строки &amp;lt;code&amp;gt;Entware installed&amp;lt;/code&amp;gt;.&lt;br /&gt;
#: [[File:keenetic_log_entware_installed.png|center|Системный журнал Keenetic (/diagnostics/general/log) с финальной строкой «Entware installed» — установка завершилась успешно, можно перезагружать роутер.|мини|804x804пкс]]&lt;br /&gt;
#: &amp;lt;div style=&amp;quot;padding: 8px 12px; margin: 8px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&#039;&#039;&#039;Не перезагружайте роутер до этой строки в журнале!&#039;&#039;&#039; Если ребутнуть роутер посреди установки, файлы Entware на флешке останутся неконсистентными, и на следующих этапах посыпятся странные ошибки.&amp;lt;/div&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Перезагрузите роутер из веб-CLI:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;system reboot&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Через 1–2 минуты роутер поднимется обратно. После reboot применятся: монтирование Entware с флешки в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, автозапуск его сервисов, а главное — &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; из шага 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Если установщик молчит:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; молчит, если OPKG-диск уже был назначен раньше. В журнале нет строк про загрузку &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;? Сбросьте назначение диска и повторите шаги 4–5:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID&amp;gt;:/ &amp;lt;URL&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Первое подключение по SSH ==&lt;br /&gt;
&lt;br /&gt;
После перезагрузки Entware поднимает встроенный SSH-сервер на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На Windows — открываете PowerShell и подключаетесь одной командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(LAN-IP роутера другой — подставьте.)&lt;br /&gt;
&lt;br /&gt;
Параметры подключения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|LAN-IP роутера (&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; по умолчанию)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; (заводской)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При первом подключении SSH спросит fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; дефолтный &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем. Если SSH когда-нибудь будет проброшен наружу — роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите ходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце документа. Для базовой установки это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всё готово для установки утилит.&#039;&#039;&#039; Переходите к Этапу 2.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; &lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про место:&#039;&#039;&#039; &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; занимает ~62 МБ распакованных, плюс ~7 МБ сам helper, плюс Entware-окружение. На встроенной флэш-памяти роутера не помещается — Entware &#039;&#039;&#039;должен&#039;&#039;&#039; быть на USB (см. Этап 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
[[Файл:Singbox-helper-g.png|центр|мини|1034x1034пкс|Главный экран приложения Singbox-helper]]&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
[[Файл:Singbox-helper-con.png|центр|мини|850x850пкс|Пример успешного подключения в Singbox-helper]]&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. UI покажет жёлтое предупреждение под распознанными параметрами. Решение — попросить владельца сервера переключить транспорт на &amp;lt;code&amp;gt;ws&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grpc&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;tcp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
[[Файл:Keen-pbr-g.png|центр|мини|1043x1043пкс|Keen-pbr - пример главного экрана]]&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
[[File:keenpbr_outbounds.png|center|Страница «Outbounds (выходы)» в веб-интерфейсе keen-pbr со списком из трёх выходов: wan, block, vpn (interface=singtun).|мини|1005x1005пкс]]&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
sh /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок.&lt;br /&gt;
&lt;br /&gt;
== 3.5. Тестирование ==&lt;br /&gt;
На клиентском устройстве, подключённом к Keenetic:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Очистите кеш DNS&#039;&#039;&#039; (важно — без этого старые ответы остаются):&lt;br /&gt;
#* Windows: &amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; в PowerShell.&lt;br /&gt;
#* Android / iOS: переподключиться к Wi-Fi (off → on).&lt;br /&gt;
#* macOS: &amp;lt;code&amp;gt;sudo dscacheutil -flushcache&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Перезапустите браузер (у него свой DNS-кеш).&lt;br /&gt;
# Откройте сайт из списка bypass.&lt;br /&gt;
# Параллельно откройте &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; в браузере. Адрес должен быть тот же, который вы видели в шаге «IP через TUN» на вкладке Главная UI singbox-helper (т.е. IP вашего VPN-провайдера, а не домашний WAN-IP).&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;[http://192.168.10.1:90 http://192.168.1.1:90]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ввести логин и пароль,  те же что применяются для входа по ssh.&lt;br /&gt;
[[Файл:Nfqws2-g-p.png|центр|мини|914x914пкс|Пример главного окна Nfqws2]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
[[Файл:Keenetic architecture detailed.png|центр|мини|1031x1031пкс|Полная схема трафика через роутер: DNS-запросы клиента идут в keen-pbr dnsmasq → Quad9, ответы накапливаются в ipset; TCP-трафик в iptables маркируется и уходит либо в singtun (sing-box → VPN-узел), либо через WAN с DPI-обходом nfqws2.]]&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.8. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.9. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Keenetic_architecture_overview.png&amp;diff=996</id>
		<title>Файл:Keenetic architecture overview.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Keenetic_architecture_overview.png&amp;diff=996"/>
		<updated>2026-05-12T18:14:09Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Общая схема: keen-pbr по адресу домена решает, отправить трафик в туннель singtun (sing-box → VPN-сервер) или пустить через nfqws2 + прямой WAN.&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Keenetic_architecture_detailed.png&amp;diff=995</id>
		<title>Файл:Keenetic architecture detailed.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Keenetic_architecture_detailed.png&amp;diff=995"/>
		<updated>2026-05-12T18:13:17Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Общая схема: keen-pbr по адресу домена решает, отправить трафик в туннель singtun (sing-box → VPN-сервер) или пустить через nfqws2 + прямой WAN.&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=994</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=994"/>
		<updated>2026-05-12T18:02:07Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                          KEENETIC РОУТЕР&lt;br /&gt;
&lt;br /&gt;
  ┌──────────────────────────────────────────────────────────────┐&lt;br /&gt;
  │                                                              │&lt;br /&gt;
  │  ┌────────────────┐                                          │&lt;br /&gt;
  │  │   keen-pbr     │  --- адрес домена в списке? ---          │&lt;br /&gt;
  │  │   (по доменам) │            │           │                 │&lt;br /&gt;
  │  └────────────────┘            │ ДА        │ НЕТ             │&lt;br /&gt;
  │                                ▼           ▼                 │&lt;br /&gt;
  │                       ┌────────────┐  ┌────────────┐         │&lt;br /&gt;
  │                       │  singtun   │  │   nfqws2   │         │&lt;br /&gt;
  │                       │ (sing-box) │  │  DPI fix   │         │&lt;br /&gt;
  │                       └────────────┘  └────────────┘         │&lt;br /&gt;
  │                            │                │                │&lt;br /&gt;
  └────────────────────────────┼────────────────┼────────────────┘&lt;br /&gt;
                               │                │&lt;br /&gt;
                          ┌────▼────┐      ┌────▼────┐&lt;br /&gt;
                          │  VPN-   │      │  Прямой │&lt;br /&gt;
                          │  сервер │      │  WAN    │&lt;br /&gt;
                          └─────────┘      └─────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&#039;&#039;(Здесь схему можно перерисовать в Mermaid или Excalidraw и заменить блок.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Какая у вас прошивка ==&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужен ли вам отдельный шаг включения компонентов прошивки.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. подсекцию «Только для оригинального Keenetic» ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, всё уже в образе прошивки порта — пропускайте подсекцию ниже и сразу переходите к «Выбор URL установщика»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как понять, какая у вас:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; видна модель устройства. Маркетинговое имя &amp;quot;Keenetic Hero&amp;quot; и модель &amp;quot;KN-...&amp;quot; — это оригинальный Keenetic. Имя другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) + KeeneticOS — это порт сообщества. Дополнительный признак порта — на странице компонентов сообщение «Не удалось получить список компонентов от сервера» (своего сервера обновлений у порта нет).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Только для оригинального Keenetic ==&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|База Entware&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Монтирование ext4-флешки&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Командная строка роутера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|База iptables для Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Доп. модули (&amp;lt;code&amp;gt;xt_set&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;xt_multiport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;conntrack-extra&amp;lt;/code&amp;gt;) — &#039;&#039;&#039;критично&#039;&#039;&#039; для keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора — &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и ждите 2–5 минут, роутер перезагрузится сам.&lt;br /&gt;
&lt;br /&gt;
== Выбор URL установщика ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (одной строкой)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как узнать архитектуру:&#039;&#039;&#039; &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; → видна модель и процессор. Большинство бытовых моделей — MIPS (верхняя строка). Сомневаетесь — берите mipsel; если не подходит, установщик ругнётся, роутер от этого не сломается.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Что вам понадобится ==&lt;br /&gt;
Перед тем как идти в командную строку, держите под рукой два значения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Откуда взять&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UUID USB-диска&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в веб-CLI Keenetic (см. шаг 3 в 1.1), поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;URL установщика&#039;&#039;&#039;&lt;br /&gt;
|Из таблицы «Выбор URL установщика» выше — по архитектуре&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Entware через командную строку ==&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Подключите USB-флешку.&#039;&#039;&#039; Воткните флешку в USB-порт роутера. Откройте веб-интерфейс: &#039;&#039;&#039;Приложения → USB-диски и принтеры&#039;&#039;&#039; — диск должен появиться в списке. Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; → &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
#: [[File:keenetic_usb_disks.png|center|Страница «USB-диски и принтеры» в веб-интерфейсе Keenetic с подключённой USB-флешкой и опцией «Форматировать» в EXT4.|мини|994x994пкс]]&lt;br /&gt;
# &#039;&#039;&#039;Откройте встроенный веб-CLI Keenetic:&#039;&#039;&#039; &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; (или подставьте свой LAN-IP роутера, если он другой). Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Узнайте UUID диска:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: В ответе найдите блок с вашей флешкой и поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Длинная строка вида &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; — это и есть нужное значение, скопируйте его.&lt;br /&gt;
# &#039;&#039;&#039;Запустите установку Entware.&#039;&#039;&#039; Подставьте &#039;&#039;&#039;свой UUID&#039;&#039;&#039; и &#039;&#039;&#039;URL по архитектуре&#039;&#039;&#039; (из таблицы «Выбор URL установщика» выше):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Пример с реальными подставленными значениями (mipsel):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &#039;&#039;&#039;Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде остаться не должно.&#039;&#039;&#039; Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — обязательны. После UUID и перед URL — ровно один пробел.&lt;br /&gt;
# &#039;&#039;&#039;Сразу включите DNS-override и сохраните конфиг:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; заставит KeeneticOS отдавать DNS-запросы клиентов в Entware-овский dnsmasq, который потом будет управляться keen-pbr. Без этого keen-pbr не сможет перехватывать DNS и маршрутизация по доменам работать не будет. Опция применится после reboot ниже.&lt;br /&gt;
# &#039;&#039;&#039;Дождитесь окончания установки.&#039;&#039;&#039; Откройте журнал в веб-интерфейсе: &amp;lt;code&amp;gt;http://192.168.1.1/diagnostics/general/log&amp;lt;/code&amp;gt; (если LAN-IP другой — подставьте). Установщик пишет туда что делает: качает &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;, распаковывает в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, ставит базовые пакеты. Это занимает 2–5 минут. Ждите финальной строки &amp;lt;code&amp;gt;Entware installed&amp;lt;/code&amp;gt;.&lt;br /&gt;
#: [[File:keenetic_log_entware_installed.png|center|Системный журнал Keenetic (/diagnostics/general/log) с финальной строкой «Entware installed» — установка завершилась успешно, можно перезагружать роутер.|мини|804x804пкс]]&lt;br /&gt;
#: &amp;lt;div style=&amp;quot;padding: 8px 12px; margin: 8px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&#039;&#039;&#039;Не перезагружайте роутер до этой строки в журнале!&#039;&#039;&#039; Если ребутнуть роутер посреди установки, файлы Entware на флешке останутся неконсистентными, и на следующих этапах посыпятся странные ошибки.&amp;lt;/div&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Перезагрузите роутер из веб-CLI:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;system reboot&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Через 1–2 минуты роутер поднимется обратно. После reboot применятся: монтирование Entware с флешки в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, автозапуск его сервисов, а главное — &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; из шага 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Если установщик молчит:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; молчит, если OPKG-диск уже был назначен раньше. В журнале нет строк про загрузку &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;? Сбросьте назначение диска и повторите шаги 4–5:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID&amp;gt;:/ &amp;lt;URL&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Первое подключение по SSH ==&lt;br /&gt;
&lt;br /&gt;
После перезагрузки Entware поднимает встроенный SSH-сервер на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На Windows — открываете PowerShell и подключаетесь одной командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(LAN-IP роутера другой — подставьте.)&lt;br /&gt;
&lt;br /&gt;
Параметры подключения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|LAN-IP роутера (&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; по умолчанию)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; (заводской)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При первом подключении SSH спросит fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; дефолтный &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем. Если SSH когда-нибудь будет проброшен наружу — роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите ходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце документа. Для базовой установки это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всё готово для установки утилит.&#039;&#039;&#039; Переходите к Этапу 2.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; &lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про место:&#039;&#039;&#039; &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; занимает ~62 МБ распакованных, плюс ~7 МБ сам helper, плюс Entware-окружение. На встроенной флэш-памяти роутера не помещается — Entware &#039;&#039;&#039;должен&#039;&#039;&#039; быть на USB (см. Этап 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
[[Файл:Singbox-helper-g.png|центр|мини|1034x1034пкс|Главный экран приложения Singbox-helper]]&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
[[Файл:Singbox-helper-con.png|центр|мини|850x850пкс|Пример успешного подключения в Singbox-helper]]&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. UI покажет жёлтое предупреждение под распознанными параметрами. Решение — попросить владельца сервера переключить транспорт на &amp;lt;code&amp;gt;ws&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grpc&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;tcp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
[[Файл:Keen-pbr-g.png|центр|мини|1043x1043пкс|Keen-pbr - пример главного экрана]]&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
[[File:keenpbr_outbounds.png|center|Страница «Outbounds (выходы)» в веб-интерфейсе keen-pbr со списком из трёх выходов: wan, block, vpn (interface=singtun).|мини|1005x1005пкс]]&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
sh /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок.&lt;br /&gt;
&lt;br /&gt;
== 3.5. Тестирование ==&lt;br /&gt;
На клиентском устройстве, подключённом к Keenetic:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Очистите кеш DNS&#039;&#039;&#039; (важно — без этого старые ответы остаются):&lt;br /&gt;
#* Windows: &amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; в PowerShell.&lt;br /&gt;
#* Android / iOS: переподключиться к Wi-Fi (off → on).&lt;br /&gt;
#* macOS: &amp;lt;code&amp;gt;sudo dscacheutil -flushcache&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Перезапустите браузер (у него свой DNS-кеш).&lt;br /&gt;
# Откройте сайт из списка bypass.&lt;br /&gt;
# Параллельно откройте &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; в браузере. Адрес должен быть тот же, который вы видели в шаге «IP через TUN» на вкладке Главная UI singbox-helper (т.е. IP вашего VPN-провайдера, а не домашний WAN-IP).&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;[http://192.168.10.1:90 http://192.168.1.1:90]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ввести логин и пароль,  те же что применяются для входа по ssh.&lt;br /&gt;
[[Файл:Nfqws2-g-p.png|центр|мини|914x914пкс|Пример главного окна Nfqws2]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                  K E E N E T I C   Р О У Т Е Р&lt;br /&gt;
   ┌───────────────────────────────────────────────────────────────────────────┐&lt;br /&gt;
   │                                                                           │&lt;br /&gt;
   │   ┌──────────────┐                                                        │&lt;br /&gt;
LAN│   │  DNS-запрос  │                                                        │&lt;br /&gt;
───┼──►│  от клиента  │                                                        │&lt;br /&gt;
   │   └──────┬───────┘                                                        │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │          ▼                                                                │&lt;br /&gt;
   │   ┌──────────────┐  upstream  ┌────────────────┐                          │&lt;br /&gt;
   │   │  keen-pbr    │  через     │  Quad9 9.9.9.9 │                          │&lt;br /&gt;
   │   │  dnsmasq     │ ─────────► │                │                          │&lt;br /&gt;
   │   │  на :53      │            │                │                          │&lt;br /&gt;
   │   └──────┬───────┘            └────────────────┘                          │&lt;br /&gt;
   │          │ IP → ipset                                                     │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │   ┌──────▼──────────────────────────────────────────────┐                 │&lt;br /&gt;
LAN│   │  iptables / маршрутизация                           │                 │&lt;br /&gt;
───┼──►│  ├ если dst-IP в ipset bypass:                      │                 │&lt;br /&gt;
TCP│   │  │   fwmark → ip rule → table 151 → singtun         │                 │&lt;br /&gt;
   │   │  │                                                  │                 │&lt;br /&gt;
   │   │  └ иначе:                                           │                 │&lt;br /&gt;
   │   │      обычный WAN-маршрут                            │                 │&lt;br /&gt;
   │   │      └ nfqws2 ловит первые пакеты                   │                 │&lt;br /&gt;
   │   │        и модифицирует для обхода DPI                │                 │&lt;br /&gt;
   │   └────┬──────────────────────────────────────────┬─────┘                 │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          ▼                       │&lt;br /&gt;
   │   ┌─────────┐                            ┌────────────────┐               │&lt;br /&gt;
   │   │ singtun │                            │ WAN-интерфейс  │               │&lt;br /&gt;
   │   │ (TUN)   │                            │ (ваш провайдер)│               │&lt;br /&gt;
   │   └────┬────┘                            └────────┬───────┘               │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          │                       │&lt;br /&gt;
   │   ┌─────────────┐                                 │                       │&lt;br /&gt;
   │   │  sing-box   │                                 │                       │&lt;br /&gt;
   │   │  outbound:  │                                 │                       │&lt;br /&gt;
   │   │  hysteria2  │                                 │                       │&lt;br /&gt;
   │   └──────┬──────┘                                 │                       │&lt;br /&gt;
   │          │                                        │                       │&lt;br /&gt;
   └──────────┼────────────────────────────────────────┼───────────────────────┘&lt;br /&gt;
              │                                        │&lt;br /&gt;
              ▼                                        ▼&lt;br /&gt;
        ┌───────────┐                            ┌───────────┐&lt;br /&gt;
        │ VPN-узел  │                            │ Любой     │&lt;br /&gt;
        │ провайдера│                            │ интернет  │&lt;br /&gt;
        └───────────┘                            └───────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Здесь можно перерисовать в Mermaid/Excalidraw для финальной картинки.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.8. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.9. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Nfqws2-g-p.png&amp;diff=993</id>
		<title>Файл:Nfqws2-g-p.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Nfqws2-g-p.png&amp;diff=993"/>
		<updated>2026-05-12T18:01:31Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Nfqws2-g-p&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Keen-pbr-g.png&amp;diff=992</id>
		<title>Файл:Keen-pbr-g.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Keen-pbr-g.png&amp;diff=992"/>
		<updated>2026-05-12T17:53:21Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Keen-pbr-g&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Singbox-helper-con.png&amp;diff=991</id>
		<title>Файл:Singbox-helper-con.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Singbox-helper-con.png&amp;diff=991"/>
		<updated>2026-05-12T17:51:14Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Singbox-helper-con&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Singbox-helper-g.png&amp;diff=990</id>
		<title>Файл:Singbox-helper-g.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Singbox-helper-g.png&amp;diff=990"/>
		<updated>2026-05-12T17:49:33Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Singbox-helper-g&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Keenpbr_outbounds.png&amp;diff=989</id>
		<title>Файл:Keenpbr outbounds.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Keenpbr_outbounds.png&amp;diff=989"/>
		<updated>2026-05-12T17:45:28Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Keenetic_log_entware_installed.png&amp;diff=988</id>
		<title>Файл:Keenetic log entware installed.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Keenetic_log_entware_installed.png&amp;diff=988"/>
		<updated>2026-05-12T17:43:54Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Keenetic_usb_disks.png&amp;diff=987</id>
		<title>Файл:Keenetic usb disks.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Keenetic_usb_disks.png&amp;diff=987"/>
		<updated>2026-05-12T17:43:03Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=986</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=986"/>
		<updated>2026-05-12T17:42:15Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* Только для оригинального Keenetic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                          KEENETIC РОУТЕР&lt;br /&gt;
&lt;br /&gt;
  ┌──────────────────────────────────────────────────────────────┐&lt;br /&gt;
  │                                                              │&lt;br /&gt;
  │  ┌────────────────┐                                          │&lt;br /&gt;
  │  │   keen-pbr     │  --- адрес домена в списке? ---          │&lt;br /&gt;
  │  │   (по доменам) │            │           │                 │&lt;br /&gt;
  │  └────────────────┘            │ ДА        │ НЕТ             │&lt;br /&gt;
  │                                ▼           ▼                 │&lt;br /&gt;
  │                       ┌────────────┐  ┌────────────┐         │&lt;br /&gt;
  │                       │  singtun   │  │   nfqws2   │         │&lt;br /&gt;
  │                       │ (sing-box) │  │  DPI fix   │         │&lt;br /&gt;
  │                       └────────────┘  └────────────┘         │&lt;br /&gt;
  │                            │                │                │&lt;br /&gt;
  └────────────────────────────┼────────────────┼────────────────┘&lt;br /&gt;
                               │                │&lt;br /&gt;
                          ┌────▼────┐      ┌────▼────┐&lt;br /&gt;
                          │  VPN-   │      │  Прямой │&lt;br /&gt;
                          │  сервер │      │  WAN    │&lt;br /&gt;
                          └─────────┘      └─────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&#039;&#039;(Здесь схему можно перерисовать в Mermaid или Excalidraw и заменить блок.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Какая у вас прошивка ==&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужен ли вам отдельный шаг включения компонентов прошивки.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. подсекцию «Только для оригинального Keenetic» ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, всё уже в образе прошивки порта — пропускайте подсекцию ниже и сразу переходите к «Выбор URL установщика»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как понять, какая у вас:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; видна модель устройства. Маркетинговое имя &amp;quot;Keenetic Hero&amp;quot; и модель &amp;quot;KN-...&amp;quot; — это оригинальный Keenetic. Имя другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) + KeeneticOS — это порт сообщества. Дополнительный признак порта — на странице компонентов сообщение «Не удалось получить список компонентов от сервера» (своего сервера обновлений у порта нет).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Только для оригинального Keenetic ==&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|База Entware&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Монтирование ext4-флешки&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Командная строка роутера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|База iptables для Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Доп. модули (&amp;lt;code&amp;gt;xt_set&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;xt_multiport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;conntrack-extra&amp;lt;/code&amp;gt;) — &#039;&#039;&#039;критично&#039;&#039;&#039; для keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора — &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и ждите 2–5 минут, роутер перезагрузится сам.&lt;br /&gt;
&lt;br /&gt;
== Выбор URL установщика ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (одной строкой)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как узнать архитектуру:&#039;&#039;&#039; &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; → видна модель и процессор. Большинство бытовых моделей — MIPS (верхняя строка). Сомневаетесь — берите mipsel; если не подходит, установщик ругнётся, роутер от этого не сломается.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Что вам понадобится ==&lt;br /&gt;
Перед тем как идти в командную строку, держите под рукой два значения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Откуда взять&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UUID USB-диска&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в веб-CLI Keenetic (см. шаг 3 в 1.1), поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;URL установщика&#039;&#039;&#039;&lt;br /&gt;
|Из таблицы «Выбор URL установщика» выше — по архитектуре&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Entware через командную строку ==&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Подключите USB-флешку.&#039;&#039;&#039; Воткните флешку в USB-порт роутера. Откройте веб-интерфейс: &#039;&#039;&#039;Приложения → USB-диски и принтеры&#039;&#039;&#039; — диск должен появиться в списке. Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; → &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
#: [[File:keenetic_usb_disks.png|frame|center|Страница «USB-диски и принтеры» в веб-интерфейсе Keenetic с подключённой USB-флешкой и опцией «Форматировать» в EXT4.]]&lt;br /&gt;
# &#039;&#039;&#039;Откройте встроенный веб-CLI Keenetic:&#039;&#039;&#039; &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; (или подставьте свой LAN-IP роутера, если он другой). Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Узнайте UUID диска:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: В ответе найдите блок с вашей флешкой и поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Длинная строка вида &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; — это и есть нужное значение, скопируйте его.&lt;br /&gt;
# &#039;&#039;&#039;Запустите установку Entware.&#039;&#039;&#039; Подставьте &#039;&#039;&#039;свой UUID&#039;&#039;&#039; и &#039;&#039;&#039;URL по архитектуре&#039;&#039;&#039; (из таблицы «Выбор URL установщика» выше):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Пример с реальными подставленными значениями (mipsel):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &#039;&#039;&#039;Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде остаться не должно.&#039;&#039;&#039; Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — обязательны. После UUID и перед URL — ровно один пробел.&lt;br /&gt;
# &#039;&#039;&#039;Сразу включите DNS-override и сохраните конфиг:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; заставит KeeneticOS отдавать DNS-запросы клиентов в Entware-овский dnsmasq, который потом будет управляться keen-pbr. Без этого keen-pbr не сможет перехватывать DNS и маршрутизация по доменам работать не будет. Опция применится после reboot ниже.&lt;br /&gt;
# &#039;&#039;&#039;Дождитесь окончания установки.&#039;&#039;&#039; Откройте журнал в веб-интерфейсе: &amp;lt;code&amp;gt;http://192.168.1.1/diagnostics/general/log&amp;lt;/code&amp;gt; (если LAN-IP другой — подставьте). Установщик пишет туда что делает: качает &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;, распаковывает в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, ставит базовые пакеты. Это занимает 2–5 минут. Ждите финальной строки &amp;lt;code&amp;gt;Entware installed&amp;lt;/code&amp;gt;.&lt;br /&gt;
#: [[File:keenetic_log_entware_installed.png|frame|center|Системный журнал Keenetic (/diagnostics/general/log) с финальной строкой «Entware installed» — установка завершилась успешно, можно перезагружать роутер.]]&lt;br /&gt;
#: &amp;lt;div style=&amp;quot;padding: 8px 12px; margin: 8px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&#039;&#039;&#039;Не перезагружайте роутер до этой строки в журнале!&#039;&#039;&#039; Если ребутнуть роутер посреди установки, файлы Entware на флешке останутся неконсистентными, и на следующих этапах посыпятся странные ошибки.&amp;lt;/div&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Перезагрузите роутер из веб-CLI:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;system reboot&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Через 1–2 минуты роутер поднимется обратно. После reboot применятся: монтирование Entware с флешки в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, автозапуск его сервисов, а главное — &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; из шага 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Если установщик молчит:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; молчит, если OPKG-диск уже был назначен раньше. В журнале нет строк про загрузку &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;? Сбросьте назначение диска и повторите шаги 4–5:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID&amp;gt;:/ &amp;lt;URL&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Первое подключение по SSH ==&lt;br /&gt;
&lt;br /&gt;
После перезагрузки Entware поднимает встроенный SSH-сервер на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На Windows — открываете PowerShell и подключаетесь одной командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(LAN-IP роутера другой — подставьте.)&lt;br /&gt;
&lt;br /&gt;
Параметры подключения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|LAN-IP роутера (&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; по умолчанию)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; (заводской)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При первом подключении SSH спросит fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; дефолтный &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем. Если SSH когда-нибудь будет проброшен наружу — роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите ходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце документа. Для базовой установки это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всё готово для установки утилит.&#039;&#039;&#039; Переходите к Этапу 2.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; &lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про место:&#039;&#039;&#039; &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; занимает ~62 МБ распакованных, плюс ~7 МБ сам helper, плюс Entware-окружение. На встроенной флэш-памяти роутера не помещается — Entware &#039;&#039;&#039;должен&#039;&#039;&#039; быть на USB (см. Этап 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. UI покажет жёлтое предупреждение под распознанными параметрами. Решение — попросить владельца сервера переключить транспорт на &amp;lt;code&amp;gt;ws&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grpc&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;tcp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
[[File:keenpbr_outbounds.png|frame|center|Страница «Outbounds (выходы)» в веб-интерфейсе keen-pbr со списком из трёх выходов: wan, block, vpn (interface=singtun).]]&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
[[File:keenpbr_routing_rules.png|frame|center|Страница «Правила маршрутизации» в веб-интерфейсе keen-pbr с активным правилом #2 bypass → vpn (и опционально #1 local_list → block).]]&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
sh /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок.&lt;br /&gt;
&lt;br /&gt;
== 3.5. Тестирование ==&lt;br /&gt;
На клиентском устройстве, подключённом к Keenetic:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Очистите кеш DNS&#039;&#039;&#039; (важно — без этого старые ответы остаются):&lt;br /&gt;
#* Windows: &amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; в PowerShell.&lt;br /&gt;
#* Android / iOS: переподключиться к Wi-Fi (off → on).&lt;br /&gt;
#* macOS: &amp;lt;code&amp;gt;sudo dscacheutil -flushcache&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Перезапустите браузер (у него свой DNS-кеш).&lt;br /&gt;
# Откройте сайт из списка bypass.&lt;br /&gt;
# Параллельно откройте &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; в браузере. Адрес должен быть тот же, который вы видели в шаге «IP через TUN» на вкладке Главная UI singbox-helper (т.е. IP вашего VPN-провайдера, а не домашний WAN-IP).&lt;br /&gt;
&lt;br /&gt;
[[File:client_ipify_through_tunnel.png|frame|center|Страница https://api.ipify.org, открытая на клиентском устройстве, показывает IP туннеля (а не домашний WAN-IP) — значит маршрутизация bypass-домена через singtun работает.]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Замечание про «failed» в конце установки:&#039;&#039;&#039; В выводе установщика вы можете увидеть строку:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Starting /opt/sbin/lighttpd...              failed.&lt;br /&gt;
NFQWS2 Web Interface installed: http://192.168.10.1:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Это &#039;&#039;&#039;не ошибка&#039;&#039;&#039;. lighttpd пытается стартануть до того, как все его модули (php8-mod-curl, php8-mod-session, mod-rewrite, mod-redirect) полностью зарегистрировались. Через несколько секунд стартовый скрипт &amp;lt;code&amp;gt;S80lighttpd&amp;lt;/code&amp;gt; успешно поднимает сервис. Достаточно проверить:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pgrep -af lighttpd&lt;br /&gt;
netstat -tlnup | grep :90&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Оба должны показать запущенный процесс на порту 90. Если веб-интерфейс открывается на &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt; — всё в порядке.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.10.1:90&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для доступа из другой подсети — открыть порт &amp;lt;code&amp;gt;90&amp;lt;/code&amp;gt; в фаерволе Keenetic (по аналогии с keen-pbr WebUI).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                  K E E N E T I C   Р О У Т Е Р&lt;br /&gt;
   ┌───────────────────────────────────────────────────────────────────────────┐&lt;br /&gt;
   │                                                                           │&lt;br /&gt;
   │   ┌──────────────┐                                                        │&lt;br /&gt;
LAN│   │  DNS-запрос  │                                                        │&lt;br /&gt;
───┼──►│  от клиента  │                                                        │&lt;br /&gt;
   │   └──────┬───────┘                                                        │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │          ▼                                                                │&lt;br /&gt;
   │   ┌──────────────┐  upstream  ┌────────────────┐                          │&lt;br /&gt;
   │   │  keen-pbr    │  через     │  Quad9 9.9.9.9 │                          │&lt;br /&gt;
   │   │  dnsmasq     │ ─────────► │                │                          │&lt;br /&gt;
   │   │  на :53      │            │                │                          │&lt;br /&gt;
   │   └──────┬───────┘            └────────────────┘                          │&lt;br /&gt;
   │          │ IP → ipset                                                     │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │   ┌──────▼──────────────────────────────────────────────┐                 │&lt;br /&gt;
LAN│   │  iptables / маршрутизация                           │                 │&lt;br /&gt;
───┼──►│  ├ если dst-IP в ipset bypass:                      │                 │&lt;br /&gt;
TCP│   │  │   fwmark → ip rule → table 151 → singtun         │                 │&lt;br /&gt;
   │   │  │                                                  │                 │&lt;br /&gt;
   │   │  └ иначе:                                           │                 │&lt;br /&gt;
   │   │      обычный WAN-маршрут                            │                 │&lt;br /&gt;
   │   │      └ nfqws2 ловит первые пакеты                   │                 │&lt;br /&gt;
   │   │        и модифицирует для обхода DPI                │                 │&lt;br /&gt;
   │   └────┬──────────────────────────────────────────┬─────┘                 │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          ▼                       │&lt;br /&gt;
   │   ┌─────────┐                            ┌────────────────┐               │&lt;br /&gt;
   │   │ singtun │                            │ WAN-интерфейс  │               │&lt;br /&gt;
   │   │ (TUN)   │                            │ (ваш провайдер)│               │&lt;br /&gt;
   │   └────┬────┘                            └────────┬───────┘               │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          │                       │&lt;br /&gt;
   │   ┌─────────────┐                                 │                       │&lt;br /&gt;
   │   │  sing-box   │                                 │                       │&lt;br /&gt;
   │   │  outbound:  │                                 │                       │&lt;br /&gt;
   │   │  hysteria2  │                                 │                       │&lt;br /&gt;
   │   └──────┬──────┘                                 │                       │&lt;br /&gt;
   │          │                                        │                       │&lt;br /&gt;
   └──────────┼────────────────────────────────────────┼───────────────────────┘&lt;br /&gt;
              │                                        │&lt;br /&gt;
              ▼                                        ▼&lt;br /&gt;
        ┌───────────┐                            ┌───────────┐&lt;br /&gt;
        │ VPN-узел  │                            │ Любой     │&lt;br /&gt;
        │ провайдера│                            │ интернет  │&lt;br /&gt;
        └───────────┘                            └───────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Здесь можно перерисовать в Mermaid/Excalidraw для финальной картинки.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.8. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.9. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=985</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=985"/>
		<updated>2026-05-12T17:41:07Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                          KEENETIC РОУТЕР&lt;br /&gt;
&lt;br /&gt;
  ┌──────────────────────────────────────────────────────────────┐&lt;br /&gt;
  │                                                              │&lt;br /&gt;
  │  ┌────────────────┐                                          │&lt;br /&gt;
  │  │   keen-pbr     │  --- адрес домена в списке? ---          │&lt;br /&gt;
  │  │   (по доменам) │            │           │                 │&lt;br /&gt;
  │  └────────────────┘            │ ДА        │ НЕТ             │&lt;br /&gt;
  │                                ▼           ▼                 │&lt;br /&gt;
  │                       ┌────────────┐  ┌────────────┐         │&lt;br /&gt;
  │                       │  singtun   │  │   nfqws2   │         │&lt;br /&gt;
  │                       │ (sing-box) │  │  DPI fix   │         │&lt;br /&gt;
  │                       └────────────┘  └────────────┘         │&lt;br /&gt;
  │                            │                │                │&lt;br /&gt;
  └────────────────────────────┼────────────────┼────────────────┘&lt;br /&gt;
                               │                │&lt;br /&gt;
                          ┌────▼────┐      ┌────▼────┐&lt;br /&gt;
                          │  VPN-   │      │  Прямой │&lt;br /&gt;
                          │  сервер │      │  WAN    │&lt;br /&gt;
                          └─────────┘      └─────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&#039;&#039;(Здесь схему можно перерисовать в Mermaid или Excalidraw и заменить блок.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Какая у вас прошивка ==&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужен ли вам отдельный шаг включения компонентов прошивки.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. подсекцию «Только для оригинального Keenetic» ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, всё уже в образе прошивки порта — пропускайте подсекцию ниже и сразу переходите к «Выбор URL установщика»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как понять, какая у вас:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; видна модель устройства. Маркетинговое имя &amp;quot;Keenetic Hero&amp;quot; и модель &amp;quot;KN-...&amp;quot; — это оригинальный Keenetic. Имя другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) + KeeneticOS — это порт сообщества. Дополнительный признак порта — на странице компонентов сообщение «Не удалось получить список компонентов от сервера» (своего сервера обновлений у порта нет).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Только для оригинального Keenetic ==&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|База Entware&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Монтирование ext4-флешки&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Командная строка роутера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|База iptables для Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Доп. модули (&amp;lt;code&amp;gt;xt_set&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;xt_multiport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;conntrack-extra&amp;lt;/code&amp;gt;) — &#039;&#039;&#039;критично&#039;&#039;&#039; для keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора — &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и ждите 2–5 минут, роутер перезагрузится сам.&lt;br /&gt;
&lt;br /&gt;
[[File:keenetic_components_select.png|frame|center|Страница «Обновления и компоненты» в веб-интерфейсе Keenetic с открытым окном «Показать компоненты» и отмеченными OPKG, Ext, SSH, Netfilter и Netfilter addons.]]&lt;br /&gt;
&lt;br /&gt;
== Выбор URL установщика ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (одной строкой)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как узнать архитектуру:&#039;&#039;&#039; &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; → видна модель и процессор. Большинство бытовых моделей — MIPS (верхняя строка). Сомневаетесь — берите mipsel; если не подходит, установщик ругнётся, роутер от этого не сломается.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Что вам понадобится ==&lt;br /&gt;
Перед тем как идти в командную строку, держите под рукой два значения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Откуда взять&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UUID USB-диска&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в веб-CLI Keenetic (см. шаг 3 в 1.1), поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;URL установщика&#039;&#039;&#039;&lt;br /&gt;
|Из таблицы «Выбор URL установщика» выше — по архитектуре&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Entware через командную строку ==&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Подключите USB-флешку.&#039;&#039;&#039; Воткните флешку в USB-порт роутера. Откройте веб-интерфейс: &#039;&#039;&#039;Приложения → USB-диски и принтеры&#039;&#039;&#039; — диск должен появиться в списке. Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; → &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
#: [[File:keenetic_usb_disks.png|frame|center|Страница «USB-диски и принтеры» в веб-интерфейсе Keenetic с подключённой USB-флешкой и опцией «Форматировать» в EXT4.]]&lt;br /&gt;
# &#039;&#039;&#039;Откройте встроенный веб-CLI Keenetic:&#039;&#039;&#039; &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; (или подставьте свой LAN-IP роутера, если он другой). Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Узнайте UUID диска:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: В ответе найдите блок с вашей флешкой и поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Длинная строка вида &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; — это и есть нужное значение, скопируйте его.&lt;br /&gt;
# &#039;&#039;&#039;Запустите установку Entware.&#039;&#039;&#039; Подставьте &#039;&#039;&#039;свой UUID&#039;&#039;&#039; и &#039;&#039;&#039;URL по архитектуре&#039;&#039;&#039; (из таблицы «Выбор URL установщика» выше):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Пример с реальными подставленными значениями (mipsel):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &#039;&#039;&#039;Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде остаться не должно.&#039;&#039;&#039; Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — обязательны. После UUID и перед URL — ровно один пробел.&lt;br /&gt;
# &#039;&#039;&#039;Сразу включите DNS-override и сохраните конфиг:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; заставит KeeneticOS отдавать DNS-запросы клиентов в Entware-овский dnsmasq, который потом будет управляться keen-pbr. Без этого keen-pbr не сможет перехватывать DNS и маршрутизация по доменам работать не будет. Опция применится после reboot ниже.&lt;br /&gt;
# &#039;&#039;&#039;Дождитесь окончания установки.&#039;&#039;&#039; Откройте журнал в веб-интерфейсе: &amp;lt;code&amp;gt;http://192.168.1.1/diagnostics/general/log&amp;lt;/code&amp;gt; (если LAN-IP другой — подставьте). Установщик пишет туда что делает: качает &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;, распаковывает в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, ставит базовые пакеты. Это занимает 2–5 минут. Ждите финальной строки &amp;lt;code&amp;gt;Entware installed&amp;lt;/code&amp;gt;.&lt;br /&gt;
#: [[File:keenetic_log_entware_installed.png|frame|center|Системный журнал Keenetic (/diagnostics/general/log) с финальной строкой «Entware installed» — установка завершилась успешно, можно перезагружать роутер.]]&lt;br /&gt;
#: &amp;lt;div style=&amp;quot;padding: 8px 12px; margin: 8px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&#039;&#039;&#039;Не перезагружайте роутер до этой строки в журнале!&#039;&#039;&#039; Если ребутнуть роутер посреди установки, файлы Entware на флешке останутся неконсистентными, и на следующих этапах посыпятся странные ошибки.&amp;lt;/div&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Перезагрузите роутер из веб-CLI:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;system reboot&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Через 1–2 минуты роутер поднимется обратно. После reboot применятся: монтирование Entware с флешки в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, автозапуск его сервисов, а главное — &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; из шага 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Если установщик молчит:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; молчит, если OPKG-диск уже был назначен раньше. В журнале нет строк про загрузку &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;? Сбросьте назначение диска и повторите шаги 4–5:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID&amp;gt;:/ &amp;lt;URL&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Первое подключение по SSH ==&lt;br /&gt;
&lt;br /&gt;
После перезагрузки Entware поднимает встроенный SSH-сервер на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На Windows — открываете PowerShell и подключаетесь одной командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(LAN-IP роутера другой — подставьте.)&lt;br /&gt;
&lt;br /&gt;
Параметры подключения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|LAN-IP роутера (&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; по умолчанию)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; (заводской)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При первом подключении SSH спросит fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; дефолтный &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем. Если SSH когда-нибудь будет проброшен наружу — роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите ходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце документа. Для базовой установки это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всё готово для установки утилит.&#039;&#039;&#039; Переходите к Этапу 2.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; &lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про место:&#039;&#039;&#039; &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; занимает ~62 МБ распакованных, плюс ~7 МБ сам helper, плюс Entware-окружение. На встроенной флэш-памяти роутера не помещается — Entware &#039;&#039;&#039;должен&#039;&#039;&#039; быть на USB (см. Этап 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. UI покажет жёлтое предупреждение под распознанными параметрами. Решение — попросить владельца сервера переключить транспорт на &amp;lt;code&amp;gt;ws&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grpc&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;tcp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
[[File:keenpbr_outbounds.png|frame|center|Страница «Outbounds (выходы)» в веб-интерфейсе keen-pbr со списком из трёх выходов: wan, block, vpn (interface=singtun).]]&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
[[File:keenpbr_routing_rules.png|frame|center|Страница «Правила маршрутизации» в веб-интерфейсе keen-pbr с активным правилом #2 bypass → vpn (и опционально #1 local_list → block).]]&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
sh /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок.&lt;br /&gt;
&lt;br /&gt;
== 3.5. Тестирование ==&lt;br /&gt;
На клиентском устройстве, подключённом к Keenetic:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Очистите кеш DNS&#039;&#039;&#039; (важно — без этого старые ответы остаются):&lt;br /&gt;
#* Windows: &amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; в PowerShell.&lt;br /&gt;
#* Android / iOS: переподключиться к Wi-Fi (off → on).&lt;br /&gt;
#* macOS: &amp;lt;code&amp;gt;sudo dscacheutil -flushcache&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Перезапустите браузер (у него свой DNS-кеш).&lt;br /&gt;
# Откройте сайт из списка bypass.&lt;br /&gt;
# Параллельно откройте &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; в браузере. Адрес должен быть тот же, который вы видели в шаге «IP через TUN» на вкладке Главная UI singbox-helper (т.е. IP вашего VPN-провайдера, а не домашний WAN-IP).&lt;br /&gt;
&lt;br /&gt;
[[File:client_ipify_through_tunnel.png|frame|center|Страница https://api.ipify.org, открытая на клиентском устройстве, показывает IP туннеля (а не домашний WAN-IP) — значит маршрутизация bypass-домена через singtun работает.]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Замечание про «failed» в конце установки:&#039;&#039;&#039; В выводе установщика вы можете увидеть строку:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Starting /opt/sbin/lighttpd...              failed.&lt;br /&gt;
NFQWS2 Web Interface installed: http://192.168.10.1:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Это &#039;&#039;&#039;не ошибка&#039;&#039;&#039;. lighttpd пытается стартануть до того, как все его модули (php8-mod-curl, php8-mod-session, mod-rewrite, mod-redirect) полностью зарегистрировались. Через несколько секунд стартовый скрипт &amp;lt;code&amp;gt;S80lighttpd&amp;lt;/code&amp;gt; успешно поднимает сервис. Достаточно проверить:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pgrep -af lighttpd&lt;br /&gt;
netstat -tlnup | grep :90&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Оба должны показать запущенный процесс на порту 90. Если веб-интерфейс открывается на &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt; — всё в порядке.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.10.1:90&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для доступа из другой подсети — открыть порт &amp;lt;code&amp;gt;90&amp;lt;/code&amp;gt; в фаерволе Keenetic (по аналогии с keen-pbr WebUI).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                  K E E N E T I C   Р О У Т Е Р&lt;br /&gt;
   ┌───────────────────────────────────────────────────────────────────────────┐&lt;br /&gt;
   │                                                                           │&lt;br /&gt;
   │   ┌──────────────┐                                                        │&lt;br /&gt;
LAN│   │  DNS-запрос  │                                                        │&lt;br /&gt;
───┼──►│  от клиента  │                                                        │&lt;br /&gt;
   │   └──────┬───────┘                                                        │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │          ▼                                                                │&lt;br /&gt;
   │   ┌──────────────┐  upstream  ┌────────────────┐                          │&lt;br /&gt;
   │   │  keen-pbr    │  через     │  Quad9 9.9.9.9 │                          │&lt;br /&gt;
   │   │  dnsmasq     │ ─────────► │                │                          │&lt;br /&gt;
   │   │  на :53      │            │                │                          │&lt;br /&gt;
   │   └──────┬───────┘            └────────────────┘                          │&lt;br /&gt;
   │          │ IP → ipset                                                     │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │   ┌──────▼──────────────────────────────────────────────┐                 │&lt;br /&gt;
LAN│   │  iptables / маршрутизация                           │                 │&lt;br /&gt;
───┼──►│  ├ если dst-IP в ipset bypass:                      │                 │&lt;br /&gt;
TCP│   │  │   fwmark → ip rule → table 151 → singtun         │                 │&lt;br /&gt;
   │   │  │                                                  │                 │&lt;br /&gt;
   │   │  └ иначе:                                           │                 │&lt;br /&gt;
   │   │      обычный WAN-маршрут                            │                 │&lt;br /&gt;
   │   │      └ nfqws2 ловит первые пакеты                   │                 │&lt;br /&gt;
   │   │        и модифицирует для обхода DPI                │                 │&lt;br /&gt;
   │   └────┬──────────────────────────────────────────┬─────┘                 │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          ▼                       │&lt;br /&gt;
   │   ┌─────────┐                            ┌────────────────┐               │&lt;br /&gt;
   │   │ singtun │                            │ WAN-интерфейс  │               │&lt;br /&gt;
   │   │ (TUN)   │                            │ (ваш провайдер)│               │&lt;br /&gt;
   │   └────┬────┘                            └────────┬───────┘               │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          │                       │&lt;br /&gt;
   │   ┌─────────────┐                                 │                       │&lt;br /&gt;
   │   │  sing-box   │                                 │                       │&lt;br /&gt;
   │   │  outbound:  │                                 │                       │&lt;br /&gt;
   │   │  hysteria2  │                                 │                       │&lt;br /&gt;
   │   └──────┬──────┘                                 │                       │&lt;br /&gt;
   │          │                                        │                       │&lt;br /&gt;
   └──────────┼────────────────────────────────────────┼───────────────────────┘&lt;br /&gt;
              │                                        │&lt;br /&gt;
              ▼                                        ▼&lt;br /&gt;
        ┌───────────┐                            ┌───────────┐&lt;br /&gt;
        │ VPN-узел  │                            │ Любой     │&lt;br /&gt;
        │ провайдера│                            │ интернет  │&lt;br /&gt;
        └───────────┘                            └───────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Здесь можно перерисовать в Mermaid/Excalidraw для финальной картинки.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.8. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.9. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=984</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=984"/>
		<updated>2026-05-12T16:57:39Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                          KEENETIC РОУТЕР&lt;br /&gt;
&lt;br /&gt;
  ┌──────────────────────────────────────────────────────────────┐&lt;br /&gt;
  │                                                              │&lt;br /&gt;
  │  ┌────────────────┐                                          │&lt;br /&gt;
  │  │   keen-pbr     │  --- адрес домена в списке? ---          │&lt;br /&gt;
  │  │   (по доменам) │            │           │                 │&lt;br /&gt;
  │  └────────────────┘            │ ДА        │ НЕТ             │&lt;br /&gt;
  │                                ▼           ▼                 │&lt;br /&gt;
  │                       ┌────────────┐  ┌────────────┐         │&lt;br /&gt;
  │                       │  singtun   │  │   nfqws2   │         │&lt;br /&gt;
  │                       │ (sing-box) │  │  DPI fix   │         │&lt;br /&gt;
  │                       └────────────┘  └────────────┘         │&lt;br /&gt;
  │                            │                │                │&lt;br /&gt;
  └────────────────────────────┼────────────────┼────────────────┘&lt;br /&gt;
                               │                │&lt;br /&gt;
                          ┌────▼────┐      ┌────▼────┐&lt;br /&gt;
                          │  VPN-   │      │  Прямой │&lt;br /&gt;
                          │  сервер │      │  WAN    │&lt;br /&gt;
                          └─────────┘      └─────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&#039;&#039;(Здесь схему можно перерисовать в Mermaid или Excalidraw и заменить блок.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Какая у вас прошивка ==&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужен ли вам отдельный шаг включения компонентов прошивки.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. подсекцию «Только для оригинального Keenetic» ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, всё уже в образе прошивки порта — пропускайте подсекцию ниже и сразу переходите к «Выбор URL установщика»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как понять, какая у вас:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; видна модель устройства. Маркетинговое имя &amp;quot;Keenetic Hero&amp;quot; и модель &amp;quot;KN-...&amp;quot; — это оригинальный Keenetic. Имя другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) + KeeneticOS — это порт сообщества. Дополнительный признак порта — на странице компонентов сообщение «Не удалось получить список компонентов от сервера» (своего сервера обновлений у порта нет).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Только для оригинального Keenetic ==&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|База Entware&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Монтирование ext4-флешки&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Командная строка роутера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|База iptables для Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Доп. модули (&amp;lt;code&amp;gt;xt_set&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;xt_multiport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;conntrack-extra&amp;lt;/code&amp;gt;) — &#039;&#039;&#039;критично&#039;&#039;&#039; для keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора — &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и ждите 2–5 минут, роутер перезагрузится сам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Обновления и компоненты&amp;quot; с открытым окном &amp;quot;Показать компоненты&amp;quot;.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Выбор URL установщика ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (одной строкой)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Как узнать архитектуру:&#039;&#039;&#039; &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; → видна модель и процессор. Большинство бытовых моделей — MIPS (верхняя строка). Сомневаетесь — берите mipsel; если не подходит, установщик ругнётся, роутер от этого не сломается.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Что вам понадобится ==&lt;br /&gt;
Перед тем как идти в командную строку, держите под рукой два значения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Откуда взять&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UUID USB-диска&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в веб-CLI Keenetic (см. шаг 3 в 1.1), поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;URL установщика&#039;&#039;&#039;&lt;br /&gt;
|Из таблицы «Выбор URL установщика» выше — по архитектуре&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Entware через командную строку ==&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Подключите USB-флешку.&#039;&#039;&#039; Воткните флешку в USB-порт роутера. Откройте веб-интерфейс: &#039;&#039;&#039;Приложения → USB-диски и принтеры&#039;&#039;&#039; — диск должен появиться в списке. Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; → &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
#: &#039;&#039;(Скриншот: страница «USB-диски и принтеры» с подключённой флешкой.)&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;Откройте встроенный веб-CLI Keenetic:&#039;&#039;&#039; &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; (или подставьте свой LAN-IP роутера, если он другой). Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Узнайте UUID диска:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: В ответе найдите блок с вашей флешкой и поле &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Длинная строка вида &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; — это и есть нужное значение, скопируйте его.&lt;br /&gt;
# &#039;&#039;&#039;Запустите установку Entware.&#039;&#039;&#039; Подставьте &#039;&#039;&#039;свой UUID&#039;&#039;&#039; и &#039;&#039;&#039;URL по архитектуре&#039;&#039;&#039; (из таблицы «Выбор URL установщика» выше):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Пример с реальными подставленными значениями (mipsel):&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &#039;&#039;&#039;Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде остаться не должно.&#039;&#039;&#039; Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — обязательны. После UUID и перед URL — ровно один пробел.&lt;br /&gt;
# &#039;&#039;&#039;Сразу включите DNS-override и сохраните конфиг:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; заставит KeeneticOS отдавать DNS-запросы клиентов в Entware-овский dnsmasq, который потом будет управляться keen-pbr. Без этого keen-pbr не сможет перехватывать DNS и маршрутизация по доменам работать не будет. Опция применится после reboot ниже.&lt;br /&gt;
# &#039;&#039;&#039;Дождитесь окончания установки.&#039;&#039;&#039; Откройте журнал в веб-интерфейсе: &amp;lt;code&amp;gt;http://192.168.1.1/diagnostics/general/log&amp;lt;/code&amp;gt; (если LAN-IP другой — подставьте). Установщик пишет туда что делает: качает &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;, распаковывает в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, ставит базовые пакеты. Это занимает 2–5 минут. Ждите финальной строки &amp;lt;code&amp;gt;Entware installed&amp;lt;/code&amp;gt;.&lt;br /&gt;
#: &#039;&#039;(Скриншот: журнал с финальной строкой «Entware installed».)&#039;&#039;&lt;br /&gt;
#: &amp;lt;div style=&amp;quot;padding: 8px 12px; margin: 8px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&#039;&#039;&#039;Не перезагружайте роутер до этой строки в журнале!&#039;&#039;&#039; Если ребутнуть роутер посреди установки, файлы Entware на флешке останутся неконсистентными, и на следующих этапах посыпятся странные ошибки.&amp;lt;/div&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Перезагрузите роутер из веб-CLI:&#039;&#039;&#039;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;system reboot&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: Через 1–2 минуты роутер поднимется обратно. После reboot применятся: монтирование Entware с флешки в &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, автозапуск его сервисов, а главное — &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; из шага 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Если установщик молчит:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; молчит, если OPKG-диск уже был назначен раньше. В журнале нет строк про загрузку &amp;lt;code&amp;gt;installer.tar.gz&amp;lt;/code&amp;gt;? Сбросьте назначение диска и повторите шаги 4–5:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID&amp;gt;:/ &amp;lt;URL&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Первое подключение по SSH ==&lt;br /&gt;
&lt;br /&gt;
После перезагрузки Entware поднимает встроенный SSH-сервер на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На Windows — открываете PowerShell и подключаетесь одной командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(LAN-IP роутера другой — подставьте.)&lt;br /&gt;
&lt;br /&gt;
Параметры подключения:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|LAN-IP роутера (&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; по умолчанию)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; (заводской)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При первом подключении SSH спросит fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; дефолтный &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем. Если SSH когда-нибудь будет проброшен наружу — роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите ходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце документа. Для базовой установки это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Всё готово для установки утилит.&#039;&#039;&#039; Переходите к Этапу 2.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; &lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про место:&#039;&#039;&#039; &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; занимает ~62 МБ распакованных, плюс ~7 МБ сам helper, плюс Entware-окружение. На встроенной флэш-памяти роутера не помещается — Entware &#039;&#039;&#039;должен&#039;&#039;&#039; быть на USB (см. Этап 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. UI покажет жёлтое предупреждение под распознанными параметрами. Решение — попросить владельца сервера переключить транспорт на &amp;lt;code&amp;gt;ws&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grpc&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;tcp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Outbounds (выходы)&amp;quot; с тремя строками: wan, block, vpn.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Правила маршрутизации&amp;quot; с активным правилом #2 bypass → vpn.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
sh /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок.&lt;br /&gt;
&lt;br /&gt;
== 3.5. Тестирование ==&lt;br /&gt;
На клиентском устройстве, подключённом к Keenetic:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Очистите кеш DNS&#039;&#039;&#039; (важно — без этого старые ответы остаются):&lt;br /&gt;
#* Windows: &amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; в PowerShell.&lt;br /&gt;
#* Android / iOS: переподключиться к Wi-Fi (off → on).&lt;br /&gt;
#* macOS: &amp;lt;code&amp;gt;sudo dscacheutil -flushcache&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Перезапустите браузер (у него свой DNS-кеш).&lt;br /&gt;
# Откройте сайт из списка bypass.&lt;br /&gt;
# Параллельно откройте &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; в браузере. Адрес должен быть тот же, который вы видели в шаге «IP через TUN» на вкладке Главная UI singbox-helper (т.е. IP вашего VPN-провайдера, а не домашний WAN-IP).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница api.ipify.org с подменённым IP.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Замечание про «failed» в конце установки:&#039;&#039;&#039; В выводе установщика вы можете увидеть строку:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Starting /opt/sbin/lighttpd...              failed.&lt;br /&gt;
NFQWS2 Web Interface installed: http://192.168.10.1:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Это &#039;&#039;&#039;не ошибка&#039;&#039;&#039;. lighttpd пытается стартануть до того, как все его модули (php8-mod-curl, php8-mod-session, mod-rewrite, mod-redirect) полностью зарегистрировались. Через несколько секунд стартовый скрипт &amp;lt;code&amp;gt;S80lighttpd&amp;lt;/code&amp;gt; успешно поднимает сервис. Достаточно проверить:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pgrep -af lighttpd&lt;br /&gt;
netstat -tlnup | grep :90&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Оба должны показать запущенный процесс на порту 90. Если веб-интерфейс открывается на &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt; — всё в порядке.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.10.1:90&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для доступа из другой подсети — открыть порт &amp;lt;code&amp;gt;90&amp;lt;/code&amp;gt; в фаерволе Keenetic (по аналогии с keen-pbr WebUI).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                  K E E N E T I C   Р О У Т Е Р&lt;br /&gt;
   ┌───────────────────────────────────────────────────────────────────────────┐&lt;br /&gt;
   │                                                                           │&lt;br /&gt;
   │   ┌──────────────┐                                                        │&lt;br /&gt;
LAN│   │  DNS-запрос  │                                                        │&lt;br /&gt;
───┼──►│  от клиента  │                                                        │&lt;br /&gt;
   │   └──────┬───────┘                                                        │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │          ▼                                                                │&lt;br /&gt;
   │   ┌──────────────┐  upstream  ┌────────────────┐                          │&lt;br /&gt;
   │   │  keen-pbr    │  через     │  Quad9 9.9.9.9 │                          │&lt;br /&gt;
   │   │  dnsmasq     │ ─────────► │                │                          │&lt;br /&gt;
   │   │  на :53      │            │                │                          │&lt;br /&gt;
   │   └──────┬───────┘            └────────────────┘                          │&lt;br /&gt;
   │          │ IP → ipset                                                     │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │   ┌──────▼──────────────────────────────────────────────┐                 │&lt;br /&gt;
LAN│   │  iptables / маршрутизация                           │                 │&lt;br /&gt;
───┼──►│  ├ если dst-IP в ipset bypass:                      │                 │&lt;br /&gt;
TCP│   │  │   fwmark → ip rule → table 151 → singtun         │                 │&lt;br /&gt;
   │   │  │                                                  │                 │&lt;br /&gt;
   │   │  └ иначе:                                           │                 │&lt;br /&gt;
   │   │      обычный WAN-маршрут                            │                 │&lt;br /&gt;
   │   │      └ nfqws2 ловит первые пакеты                   │                 │&lt;br /&gt;
   │   │        и модифицирует для обхода DPI                │                 │&lt;br /&gt;
   │   └────┬──────────────────────────────────────────┬─────┘                 │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          ▼                       │&lt;br /&gt;
   │   ┌─────────┐                            ┌────────────────┐               │&lt;br /&gt;
   │   │ singtun │                            │ WAN-интерфейс  │               │&lt;br /&gt;
   │   │ (TUN)   │                            │ (ваш провайдер)│               │&lt;br /&gt;
   │   └────┬────┘                            └────────┬───────┘               │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          │                       │&lt;br /&gt;
   │   ┌─────────────┐                                 │                       │&lt;br /&gt;
   │   │  sing-box   │                                 │                       │&lt;br /&gt;
   │   │  outbound:  │                                 │                       │&lt;br /&gt;
   │   │  hysteria2  │                                 │                       │&lt;br /&gt;
   │   └──────┬──────┘                                 │                       │&lt;br /&gt;
   │          │                                        │                       │&lt;br /&gt;
   └──────────┼────────────────────────────────────────┼───────────────────────┘&lt;br /&gt;
              │                                        │&lt;br /&gt;
              ▼                                        ▼&lt;br /&gt;
        ┌───────────┐                            ┌───────────┐&lt;br /&gt;
        │ VPN-узел  │                            │ Любой     │&lt;br /&gt;
        │ провайдера│                            │ интернет  │&lt;br /&gt;
        └───────────┘                            └───────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Здесь можно перерисовать в Mermaid/Excalidraw для финальной картинки.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.8. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.9. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=983</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=983"/>
		<updated>2026-05-12T16:32:51Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* Подключитесь по SSH к роутеру и выполните одну команду: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                          KEENETIC РОУТЕР&lt;br /&gt;
&lt;br /&gt;
  ┌──────────────────────────────────────────────────────────────┐&lt;br /&gt;
  │                                                              │&lt;br /&gt;
  │  ┌────────────────┐                                          │&lt;br /&gt;
  │  │   keen-pbr     │  --- адрес домена в списке? ---          │&lt;br /&gt;
  │  │   (по доменам) │            │           │                 │&lt;br /&gt;
  │  └────────────────┘            │ ДА        │ НЕТ             │&lt;br /&gt;
  │                                ▼           ▼                 │&lt;br /&gt;
  │                       ┌────────────┐  ┌────────────┐         │&lt;br /&gt;
  │                       │  singtun   │  │   nfqws2   │         │&lt;br /&gt;
  │                       │ (sing-box) │  │  DPI fix   │         │&lt;br /&gt;
  │                       └────────────┘  └────────────┘         │&lt;br /&gt;
  │                            │                │                │&lt;br /&gt;
  └────────────────────────────┼────────────────┼────────────────┘&lt;br /&gt;
                               │                │&lt;br /&gt;
                          ┌────▼────┐      ┌────▼────┐&lt;br /&gt;
                          │  VPN-   │      │  Прямой │&lt;br /&gt;
                          │  сервер │      │  WAN    │&lt;br /&gt;
                          └─────────┘      └─────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&#039;&#039;(Здесь схему можно перерисовать в Mermaid или Excalidraw и заменить блок.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Подготовка USB-накопителя ==&lt;br /&gt;
=== Подключение и форматирование ===&lt;br /&gt;
# Воткните флешку в USB-порт роутера.&lt;br /&gt;
# Откройте веб-интерфейс Keenetic: &#039;&#039;&#039;Приложения&#039;&#039;&#039; → &#039;&#039;&#039;USB-диски и принтеры&#039;&#039;&#039;.&lt;br /&gt;
# В списке появится диск. Откройте его параметры.&lt;br /&gt;
# Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; и выберите &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;USB-диски&amp;quot; в веб-интерфейсе Keenetic с подключённым диском и кнопкой &amp;quot;Форматировать&amp;quot;.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Узнайте UUID диска через CLI ===&lt;br /&gt;
У диска есть уникальный &#039;&#039;&#039;UUID&#039;&#039;&#039; (длинная строка вида &amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;), который понадобится для установки Entware. Веб-интерфейс Keenetic показывает UUID на странице диска, &#039;&#039;&#039;но не позволяет его выделить и скопировать&#039;&#039;&#039; — поэтому удобнее получить его через встроенную командную строку.&lt;br /&gt;
&lt;br /&gt;
# Откройте в браузере адрес &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; — это встроенный веб-CLI Keenetic. Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Выполните команду:&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# В ответе найдите блок с вашей флешкой и строку &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Пример вывода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;media&amp;quot;: {&lt;br /&gt;
        &amp;quot;Media0&amp;quot;: {&lt;br /&gt;
            &amp;quot;bus&amp;quot;: &amp;quot;usb&amp;quot;,&lt;br /&gt;
            &amp;quot;manufacturer&amp;quot;: &amp;quot;SanDisk&amp;quot;,&lt;br /&gt;
            &amp;quot;product&amp;quot;: &amp;quot;Ultra&amp;quot;,&lt;br /&gt;
            &amp;quot;state&amp;quot;: &amp;quot;ACTIVE&amp;quot;,&lt;br /&gt;
            &amp;quot;partition&amp;quot;: [&lt;br /&gt;
                {&lt;br /&gt;
                    &amp;quot;uuid&amp;quot;: &amp;quot;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;quot;,&lt;br /&gt;
                    &amp;quot;fstype&amp;quot;: &amp;quot;ext4&amp;quot;,&lt;br /&gt;
                    &amp;quot;state&amp;quot;: &amp;quot;MOUNTED&amp;quot;,&lt;br /&gt;
                    ...&lt;br /&gt;
                }&lt;br /&gt;
            ]&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скопируйте значение поля &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt; — оно понадобится в следующем шаге.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — пока вы в CLI, можно сразу включить DNS Override.&#039;&#039;&#039; Эта опция понадобится позже для keen-pbr — она заставляет KeeneticOS отдавать DNS-трафик в Entware-овский dnsmasq. Чтобы не возвращаться в CLI отдельно, выполните прямо сейчас:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Опция применится после ближайшей перезагрузки роутера (она будет в конце Этапа 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Компоненты KeeneticOS ==&lt;br /&gt;
=== Какая у вас прошивка? ===&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужно ли вам что-то включать на этом этапе:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (роутер, который продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, все нужные пакеты уже включены в образ прошивки этого порта — переходите к разделу 1.3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — как понять, какая у вас прошивка:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; (главная страница веб-интерфейса) видна модель устройства. Если рядом с моделью стоит знакомое маркетинговое имя Keenetic (например, &amp;quot;Keenetic Hero&amp;quot;) и модель начинается с &amp;quot;KN-&amp;quot; — это оригинальный Keenetic. Если вы видите название роутера другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) и при этом отображается KeeneticOS — у вас порт сообщества.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Признак порта сообщества:&#039;&#039;&#039; На странице с компонентами окно &amp;quot;Компоненты операционной системы&amp;quot; может показывать сообщение &amp;quot;Не удалось получить список компонентов от сервера&amp;quot; — это нормально для портированных сборок, у которых нет своего сервера обновлений. В этом случае шаг с компонентами &#039;&#039;&#039;не нужен&#039;&#039;&#039; — переходите к разделу 1.3.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Только для оригинального Keenetic ===&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в более старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент (точное название в UI)&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|Базовая инфраструктура Entware — без этого нельзя ставить пакеты на USB&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Чтобы роутер мог монтировать ext4-диск&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Доступ к командной строке роутера&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Кроме того, &#039;&#039;&#039;желательно&#039;&#039;&#039; проверить наличие следующих компонентов (точные названия в интерфейсе могут отличаться от версии к версии — ищите по словам):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Что искать в списке&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|Базовые модули iptables для работы фаервола Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Дополнительные модули (xt_set, xt_multiport, conntrack-extra) — &#039;&#039;&#039;критично&#039;&#039;&#039; для работы keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора нажмите &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и подождите 2–5 минут. Роутер перезагрузится самостоятельно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Обновления и компоненты&amp;quot; с открытым окном &amp;quot;Показать компоненты&amp;quot; и отмеченными нужными пунктами.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В KeeneticOS 5 и новее компонент &#039;&#039;&#039;Протокол IPv6&#039;&#039;&#039; включён по умолчанию и не может быть отключён — это нормально.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Установка Entware через командную строку ==&lt;br /&gt;
=== Открытие командной строки роутера ===&lt;br /&gt;
Если вы вышли из CLI после шага 1.1 — откройте снова: &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt;. Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Запуск установки Entware ===&lt;br /&gt;
Команда состоит из &#039;&#039;&#039;двух частей, которые вы должны подставить сами&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;UUID вашего USB-диска&#039;&#039;&#039; — тот, который вы получили командой &amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в разделе &#039;&#039;&#039;1.1&#039;&#039;&#039; (длинная строка вида &amp;lt;code&amp;gt;d5f39712-7ae1-...&amp;lt;/code&amp;gt;).&lt;br /&gt;
# &#039;&#039;&#039;URL установщика&#039;&#039;&#039; — выбирается по архитектуре вашего роутера (см. таблицу ниже).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — не копируйте команду как есть!&#039;&#039;&#039; В шаблоне ниже фигурные скобки &amp;lt;code&amp;gt;&amp;lt;...&amp;gt;&amp;lt;/code&amp;gt; — это места, куда нужно подставить &#039;&#039;&#039;ваши&#039;&#039;&#039; значения. Если оставить шаблон с угловыми скобками или скопировать чужой UUID — установка не сработает.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Шаблон команды ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выбор URL установщика ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (целиком)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство моделей Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — как узнать архитектуру:&#039;&#039;&#039; Откройте &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; в веб-интерфейсе → видно модель устройства и процессор. Для большинства бытовых моделей это MIPS — берите верхнюю строку таблицы. Если сомневаетесь — пишите команду с &amp;lt;code&amp;gt;mipsel&amp;lt;/code&amp;gt;: если архитектура не подходит, установка скажет об этом ошибкой, и вы не сломаете роутер.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Пример с подставленными значениями ====&lt;br /&gt;
Допустим, ваш UUID — &amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;, архитектура — mipsel. Тогда команда полностью выглядит так:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Это &#039;&#039;&#039;пример&#039;&#039;&#039; — UUID &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; здесь приведён только для иллюстрации. У &#039;&#039;&#039;вашего&#039;&#039;&#039; диска UUID будет &#039;&#039;&#039;другой&#039;&#039;&#039;. Подставьте именно свой со страницы &amp;quot;Диски и принтеры&amp;quot;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Проверочный чек-лист перед нажатием Enter ====&lt;br /&gt;
* Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — &#039;&#039;&#039;обязательны&#039;&#039;&#039;.&lt;br /&gt;
* URL — &#039;&#039;&#039;одной строкой&#039;&#039;&#039;, без пробелов и переносов.&lt;br /&gt;
* После UUID и перед URL — &#039;&#039;&#039;ровно один пробел&#039;&#039;&#039;.&lt;br /&gt;
* Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде &#039;&#039;&#039;не должно остаться&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Сохранение конфигурации и перезагрузка ===&lt;br /&gt;
После того как установка прошла без ошибок, сохраните конфигурацию и перезагрузите роутер:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перезагрузка нужна, чтобы применился &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt;, который вы включили на шаге 1.1. Ожидайте 1–2 минуты, пока роутер поднимется обратно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — если установщик &amp;quot;молчит&amp;quot;:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; не работает, если OPKG-диск уже был назначен раньше. Если в логе вы не видите строк про загрузку &amp;lt;code&amp;gt;mipsel-installer.tar.gz&amp;lt;/code&amp;gt; — сбросьте диск и повторите:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Проверка установки ===&lt;br /&gt;
Откройте журнал: &#039;&#039;&#039;Диагностика&#039;&#039;&#039; → &#039;&#039;&#039;Системный журнал&#039;&#039;&#039;. Должны появиться строки примерно такого содержания:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Opkg::Manager: downloading installer...&lt;br /&gt;
Opkg::Manager: extracting to /opt...&lt;br /&gt;
Opkg::Manager: ...&lt;br /&gt;
Entware installed.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения установки на роутере поднимется встроенный SSH-сервер Entware на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Первое подключение по SSH ==&lt;br /&gt;
Подключитесь к роутеру с компьютера. На Windows — через PuTTY или через стандартный &amp;lt;code&amp;gt;ssh.exe&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; (LAN-адрес роутера)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Из PowerShell это одна строка:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При первом подключении ssh попросит подтвердить fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа смените пароль:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Дефолтный пароль &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем — если SSH будет проброшен наружу, роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите заходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце этого документа. Для базовой установки sing-box / keen-pbr / nfqws2 это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; &lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про место:&#039;&#039;&#039; &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; занимает ~62 МБ распакованных, плюс ~7 МБ сам helper, плюс Entware-окружение. На встроенной флэш-памяти роутера не помещается — Entware &#039;&#039;&#039;должен&#039;&#039;&#039; быть на USB (см. Этап 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. UI покажет жёлтое предупреждение под распознанными параметрами. Решение — попросить владельца сервера переключить транспорт на &amp;lt;code&amp;gt;ws&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grpc&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;tcp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Outbounds (выходы)&amp;quot; с тремя строками: wan, block, vpn.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Правила маршрутизации&amp;quot; с активным правилом #2 bypass → vpn.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
sh /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок.&lt;br /&gt;
&lt;br /&gt;
== 3.5. Тестирование ==&lt;br /&gt;
На клиентском устройстве, подключённом к Keenetic:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Очистите кеш DNS&#039;&#039;&#039; (важно — без этого старые ответы остаются):&lt;br /&gt;
#* Windows: &amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; в PowerShell.&lt;br /&gt;
#* Android / iOS: переподключиться к Wi-Fi (off → on).&lt;br /&gt;
#* macOS: &amp;lt;code&amp;gt;sudo dscacheutil -flushcache&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Перезапустите браузер (у него свой DNS-кеш).&lt;br /&gt;
# Откройте сайт из списка bypass.&lt;br /&gt;
# Параллельно откройте &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; в браузере. Адрес должен быть тот же, который вы видели в шаге «IP через TUN» на вкладке Главная UI singbox-helper (т.е. IP вашего VPN-провайдера, а не домашний WAN-IP).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница api.ipify.org с подменённым IP.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Замечание про «failed» в конце установки:&#039;&#039;&#039; В выводе установщика вы можете увидеть строку:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Starting /opt/sbin/lighttpd...              failed.&lt;br /&gt;
NFQWS2 Web Interface installed: http://192.168.10.1:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Это &#039;&#039;&#039;не ошибка&#039;&#039;&#039;. lighttpd пытается стартануть до того, как все его модули (php8-mod-curl, php8-mod-session, mod-rewrite, mod-redirect) полностью зарегистрировались. Через несколько секунд стартовый скрипт &amp;lt;code&amp;gt;S80lighttpd&amp;lt;/code&amp;gt; успешно поднимает сервис. Достаточно проверить:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pgrep -af lighttpd&lt;br /&gt;
netstat -tlnup | grep :90&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Оба должны показать запущенный процесс на порту 90. Если веб-интерфейс открывается на &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt; — всё в порядке.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.10.1:90&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для доступа из другой подсети — открыть порт &amp;lt;code&amp;gt;90&amp;lt;/code&amp;gt; в фаерволе Keenetic (по аналогии с keen-pbr WebUI).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                  K E E N E T I C   Р О У Т Е Р&lt;br /&gt;
   ┌───────────────────────────────────────────────────────────────────────────┐&lt;br /&gt;
   │                                                                           │&lt;br /&gt;
   │   ┌──────────────┐                                                        │&lt;br /&gt;
LAN│   │  DNS-запрос  │                                                        │&lt;br /&gt;
───┼──►│  от клиента  │                                                        │&lt;br /&gt;
   │   └──────┬───────┘                                                        │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │          ▼                                                                │&lt;br /&gt;
   │   ┌──────────────┐  upstream  ┌────────────────┐                          │&lt;br /&gt;
   │   │  keen-pbr    │  через     │  Quad9 9.9.9.9 │                          │&lt;br /&gt;
   │   │  dnsmasq     │ ─────────► │                │                          │&lt;br /&gt;
   │   │  на :53      │            │                │                          │&lt;br /&gt;
   │   └──────┬───────┘            └────────────────┘                          │&lt;br /&gt;
   │          │ IP → ipset                                                     │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │   ┌──────▼──────────────────────────────────────────────┐                 │&lt;br /&gt;
LAN│   │  iptables / маршрутизация                           │                 │&lt;br /&gt;
───┼──►│  ├ если dst-IP в ipset bypass:                      │                 │&lt;br /&gt;
TCP│   │  │   fwmark → ip rule → table 151 → singtun         │                 │&lt;br /&gt;
   │   │  │                                                  │                 │&lt;br /&gt;
   │   │  └ иначе:                                           │                 │&lt;br /&gt;
   │   │      обычный WAN-маршрут                            │                 │&lt;br /&gt;
   │   │      └ nfqws2 ловит первые пакеты                   │                 │&lt;br /&gt;
   │   │        и модифицирует для обхода DPI                │                 │&lt;br /&gt;
   │   └────┬──────────────────────────────────────────┬─────┘                 │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          ▼                       │&lt;br /&gt;
   │   ┌─────────┐                            ┌────────────────┐               │&lt;br /&gt;
   │   │ singtun │                            │ WAN-интерфейс  │               │&lt;br /&gt;
   │   │ (TUN)   │                            │ (ваш провайдер)│               │&lt;br /&gt;
   │   └────┬────┘                            └────────┬───────┘               │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          │                       │&lt;br /&gt;
   │   ┌─────────────┐                                 │                       │&lt;br /&gt;
   │   │  sing-box   │                                 │                       │&lt;br /&gt;
   │   │  outbound:  │                                 │                       │&lt;br /&gt;
   │   │  hysteria2  │                                 │                       │&lt;br /&gt;
   │   └──────┬──────┘                                 │                       │&lt;br /&gt;
   │          │                                        │                       │&lt;br /&gt;
   └──────────┼────────────────────────────────────────┼───────────────────────┘&lt;br /&gt;
              │                                        │&lt;br /&gt;
              ▼                                        ▼&lt;br /&gt;
        ┌───────────┐                            ┌───────────┐&lt;br /&gt;
        │ VPN-узел  │                            │ Любой     │&lt;br /&gt;
        │ провайдера│                            │ интернет  │&lt;br /&gt;
        └───────────┘                            └───────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Здесь можно перерисовать в Mermaid/Excalidraw для финальной картинки.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.8. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.9. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=982</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=982"/>
		<updated>2026-05-12T16:02:07Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* А.5. Скрипт пересоздания /var/empty при загрузке */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                          KEENETIC РОУТЕР&lt;br /&gt;
&lt;br /&gt;
  ┌──────────────────────────────────────────────────────────────┐&lt;br /&gt;
  │                                                              │&lt;br /&gt;
  │  ┌────────────────┐                                          │&lt;br /&gt;
  │  │   keen-pbr     │  --- адрес домена в списке? ---          │&lt;br /&gt;
  │  │   (по доменам) │            │           │                 │&lt;br /&gt;
  │  └────────────────┘            │ ДА        │ НЕТ             │&lt;br /&gt;
  │                                ▼           ▼                 │&lt;br /&gt;
  │                       ┌────────────┐  ┌────────────┐         │&lt;br /&gt;
  │                       │  singtun   │  │   nfqws2   │         │&lt;br /&gt;
  │                       │ (sing-box) │  │  DPI fix   │         │&lt;br /&gt;
  │                       └────────────┘  └────────────┘         │&lt;br /&gt;
  │                            │                │                │&lt;br /&gt;
  └────────────────────────────┼────────────────┼────────────────┘&lt;br /&gt;
                               │                │&lt;br /&gt;
                          ┌────▼────┐      ┌────▼────┐&lt;br /&gt;
                          │  VPN-   │      │  Прямой │&lt;br /&gt;
                          │  сервер │      │  WAN    │&lt;br /&gt;
                          └─────────┘      └─────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&#039;&#039;(Здесь схему можно перерисовать в Mermaid или Excalidraw и заменить блок.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Подготовка USB-накопителя ==&lt;br /&gt;
=== Подключение и форматирование ===&lt;br /&gt;
# Воткните флешку в USB-порт роутера.&lt;br /&gt;
# Откройте веб-интерфейс Keenetic: &#039;&#039;&#039;Приложения&#039;&#039;&#039; → &#039;&#039;&#039;USB-диски и принтеры&#039;&#039;&#039;.&lt;br /&gt;
# В списке появится диск. Откройте его параметры.&lt;br /&gt;
# Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; и выберите &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;USB-диски&amp;quot; в веб-интерфейсе Keenetic с подключённым диском и кнопкой &amp;quot;Форматировать&amp;quot;.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Узнайте UUID диска через CLI ===&lt;br /&gt;
У диска есть уникальный &#039;&#039;&#039;UUID&#039;&#039;&#039; (длинная строка вида &amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;), который понадобится для установки Entware. Веб-интерфейс Keenetic показывает UUID на странице диска, &#039;&#039;&#039;но не позволяет его выделить и скопировать&#039;&#039;&#039; — поэтому удобнее получить его через встроенную командную строку.&lt;br /&gt;
&lt;br /&gt;
# Откройте в браузере адрес &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; — это встроенный веб-CLI Keenetic. Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Выполните команду:&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# В ответе найдите блок с вашей флешкой и строку &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Пример вывода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;media&amp;quot;: {&lt;br /&gt;
        &amp;quot;Media0&amp;quot;: {&lt;br /&gt;
            &amp;quot;bus&amp;quot;: &amp;quot;usb&amp;quot;,&lt;br /&gt;
            &amp;quot;manufacturer&amp;quot;: &amp;quot;SanDisk&amp;quot;,&lt;br /&gt;
            &amp;quot;product&amp;quot;: &amp;quot;Ultra&amp;quot;,&lt;br /&gt;
            &amp;quot;state&amp;quot;: &amp;quot;ACTIVE&amp;quot;,&lt;br /&gt;
            &amp;quot;partition&amp;quot;: [&lt;br /&gt;
                {&lt;br /&gt;
                    &amp;quot;uuid&amp;quot;: &amp;quot;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;quot;,&lt;br /&gt;
                    &amp;quot;fstype&amp;quot;: &amp;quot;ext4&amp;quot;,&lt;br /&gt;
                    &amp;quot;state&amp;quot;: &amp;quot;MOUNTED&amp;quot;,&lt;br /&gt;
                    ...&lt;br /&gt;
                }&lt;br /&gt;
            ]&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скопируйте значение поля &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt; — оно понадобится в следующем шаге.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — пока вы в CLI, можно сразу включить DNS Override.&#039;&#039;&#039; Эта опция понадобится позже для keen-pbr — она заставляет KeeneticOS отдавать DNS-трафик в Entware-овский dnsmasq. Чтобы не возвращаться в CLI отдельно, выполните прямо сейчас:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Опция применится после ближайшей перезагрузки роутера (она будет в конце Этапа 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Компоненты KeeneticOS ==&lt;br /&gt;
=== Какая у вас прошивка? ===&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужно ли вам что-то включать на этом этапе:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (роутер, который продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, все нужные пакеты уже включены в образ прошивки этого порта — переходите к разделу 1.3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — как понять, какая у вас прошивка:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; (главная страница веб-интерфейса) видна модель устройства. Если рядом с моделью стоит знакомое маркетинговое имя Keenetic (например, &amp;quot;Keenetic Hero&amp;quot;) и модель начинается с &amp;quot;KN-&amp;quot; — это оригинальный Keenetic. Если вы видите название роутера другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) и при этом отображается KeeneticOS — у вас порт сообщества.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Признак порта сообщества:&#039;&#039;&#039; На странице с компонентами окно &amp;quot;Компоненты операционной системы&amp;quot; может показывать сообщение &amp;quot;Не удалось получить список компонентов от сервера&amp;quot; — это нормально для портированных сборок, у которых нет своего сервера обновлений. В этом случае шаг с компонентами &#039;&#039;&#039;не нужен&#039;&#039;&#039; — переходите к разделу 1.3.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Только для оригинального Keenetic ===&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в более старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент (точное название в UI)&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|Базовая инфраструктура Entware — без этого нельзя ставить пакеты на USB&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Чтобы роутер мог монтировать ext4-диск&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Доступ к командной строке роутера&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Кроме того, &#039;&#039;&#039;желательно&#039;&#039;&#039; проверить наличие следующих компонентов (точные названия в интерфейсе могут отличаться от версии к версии — ищите по словам):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Что искать в списке&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|Базовые модули iptables для работы фаервола Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Дополнительные модули (xt_set, xt_multiport, conntrack-extra) — &#039;&#039;&#039;критично&#039;&#039;&#039; для работы keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора нажмите &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и подождите 2–5 минут. Роутер перезагрузится самостоятельно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Обновления и компоненты&amp;quot; с открытым окном &amp;quot;Показать компоненты&amp;quot; и отмеченными нужными пунктами.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В KeeneticOS 5 и новее компонент &#039;&#039;&#039;Протокол IPv6&#039;&#039;&#039; включён по умолчанию и не может быть отключён — это нормально.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Установка Entware через командную строку ==&lt;br /&gt;
=== Открытие командной строки роутера ===&lt;br /&gt;
Если вы вышли из CLI после шага 1.1 — откройте снова: &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt;. Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Запуск установки Entware ===&lt;br /&gt;
Команда состоит из &#039;&#039;&#039;двух частей, которые вы должны подставить сами&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;UUID вашего USB-диска&#039;&#039;&#039; — тот, который вы получили командой &amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в разделе &#039;&#039;&#039;1.1&#039;&#039;&#039; (длинная строка вида &amp;lt;code&amp;gt;d5f39712-7ae1-...&amp;lt;/code&amp;gt;).&lt;br /&gt;
# &#039;&#039;&#039;URL установщика&#039;&#039;&#039; — выбирается по архитектуре вашего роутера (см. таблицу ниже).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — не копируйте команду как есть!&#039;&#039;&#039; В шаблоне ниже фигурные скобки &amp;lt;code&amp;gt;&amp;lt;...&amp;gt;&amp;lt;/code&amp;gt; — это места, куда нужно подставить &#039;&#039;&#039;ваши&#039;&#039;&#039; значения. Если оставить шаблон с угловыми скобками или скопировать чужой UUID — установка не сработает.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Шаблон команды ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выбор URL установщика ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (целиком)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство моделей Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — как узнать архитектуру:&#039;&#039;&#039; Откройте &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; в веб-интерфейсе → видно модель устройства и процессор. Для большинства бытовых моделей это MIPS — берите верхнюю строку таблицы. Если сомневаетесь — пишите команду с &amp;lt;code&amp;gt;mipsel&amp;lt;/code&amp;gt;: если архитектура не подходит, установка скажет об этом ошибкой, и вы не сломаете роутер.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Пример с подставленными значениями ====&lt;br /&gt;
Допустим, ваш UUID — &amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;, архитектура — mipsel. Тогда команда полностью выглядит так:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Это &#039;&#039;&#039;пример&#039;&#039;&#039; — UUID &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; здесь приведён только для иллюстрации. У &#039;&#039;&#039;вашего&#039;&#039;&#039; диска UUID будет &#039;&#039;&#039;другой&#039;&#039;&#039;. Подставьте именно свой со страницы &amp;quot;Диски и принтеры&amp;quot;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Проверочный чек-лист перед нажатием Enter ====&lt;br /&gt;
* Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — &#039;&#039;&#039;обязательны&#039;&#039;&#039;.&lt;br /&gt;
* URL — &#039;&#039;&#039;одной строкой&#039;&#039;&#039;, без пробелов и переносов.&lt;br /&gt;
* После UUID и перед URL — &#039;&#039;&#039;ровно один пробел&#039;&#039;&#039;.&lt;br /&gt;
* Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде &#039;&#039;&#039;не должно остаться&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Сохранение конфигурации и перезагрузка ===&lt;br /&gt;
После того как установка прошла без ошибок, сохраните конфигурацию и перезагрузите роутер:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перезагрузка нужна, чтобы применился &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt;, который вы включили на шаге 1.1. Ожидайте 1–2 минуты, пока роутер поднимется обратно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — если установщик &amp;quot;молчит&amp;quot;:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; не работает, если OPKG-диск уже был назначен раньше. Если в логе вы не видите строк про загрузку &amp;lt;code&amp;gt;mipsel-installer.tar.gz&amp;lt;/code&amp;gt; — сбросьте диск и повторите:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Проверка установки ===&lt;br /&gt;
Откройте журнал: &#039;&#039;&#039;Диагностика&#039;&#039;&#039; → &#039;&#039;&#039;Системный журнал&#039;&#039;&#039;. Должны появиться строки примерно такого содержания:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Opkg::Manager: downloading installer...&lt;br /&gt;
Opkg::Manager: extracting to /opt...&lt;br /&gt;
Opkg::Manager: ...&lt;br /&gt;
Entware installed.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения установки на роутере поднимется встроенный SSH-сервер Entware на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Первое подключение по SSH ==&lt;br /&gt;
Подключитесь к роутеру с компьютера. На Windows — через PuTTY или через стандартный &amp;lt;code&amp;gt;ssh.exe&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; (LAN-адрес роутера)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Из PowerShell это одна строка:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При первом подключении ssh попросит подтвердить fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа смените пароль:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Дефолтный пароль &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем — если SSH будет проброшен наружу, роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите заходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце этого документа. Для базовой установки sing-box / keen-pbr / nfqws2 это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; &lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про место:&#039;&#039;&#039; &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; занимает ~62 МБ распакованных, плюс ~7 МБ сам helper, плюс Entware-окружение. На встроенной флэш-памяти роутера не помещается — Entware &#039;&#039;&#039;должен&#039;&#039;&#039; быть на USB (см. Этап 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. UI покажет жёлтое предупреждение под распознанными параметрами. Решение — попросить владельца сервера переключить транспорт на &amp;lt;code&amp;gt;ws&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grpc&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;tcp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Outbounds (выходы)&amp;quot; с тремя строками: wan, block, vpn.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Правила маршрутизации&amp;quot; с активным правилом #2 bypass → vpn.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
ls -la /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок.&lt;br /&gt;
&lt;br /&gt;
== 3.5. Тестирование ==&lt;br /&gt;
На клиентском устройстве, подключённом к Keenetic:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Очистите кеш DNS&#039;&#039;&#039; (важно — без этого старые ответы остаются):&lt;br /&gt;
#* Windows: &amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; в PowerShell.&lt;br /&gt;
#* Android / iOS: переподключиться к Wi-Fi (off → on).&lt;br /&gt;
#* macOS: &amp;lt;code&amp;gt;sudo dscacheutil -flushcache&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Перезапустите браузер (у него свой DNS-кеш).&lt;br /&gt;
# Откройте сайт из списка bypass.&lt;br /&gt;
# Параллельно откройте &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; в браузере. Адрес должен быть тот же, который вы видели в шаге «IP через TUN» на вкладке Главная UI singbox-helper (т.е. IP вашего VPN-провайдера, а не домашний WAN-IP).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница api.ipify.org с подменённым IP.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Замечание про «failed» в конце установки:&#039;&#039;&#039; В выводе установщика вы можете увидеть строку:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Starting /opt/sbin/lighttpd...              failed.&lt;br /&gt;
NFQWS2 Web Interface installed: http://192.168.10.1:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Это &#039;&#039;&#039;не ошибка&#039;&#039;&#039;. lighttpd пытается стартануть до того, как все его модули (php8-mod-curl, php8-mod-session, mod-rewrite, mod-redirect) полностью зарегистрировались. Через несколько секунд стартовый скрипт &amp;lt;code&amp;gt;S80lighttpd&amp;lt;/code&amp;gt; успешно поднимает сервис. Достаточно проверить:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pgrep -af lighttpd&lt;br /&gt;
netstat -tlnup | grep :90&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Оба должны показать запущенный процесс на порту 90. Если веб-интерфейс открывается на &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt; — всё в порядке.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.10.1:90&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для доступа из другой подсети — открыть порт &amp;lt;code&amp;gt;90&amp;lt;/code&amp;gt; в фаерволе Keenetic (по аналогии с keen-pbr WebUI).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                  K E E N E T I C   Р О У Т Е Р&lt;br /&gt;
   ┌───────────────────────────────────────────────────────────────────────────┐&lt;br /&gt;
   │                                                                           │&lt;br /&gt;
   │   ┌──────────────┐                                                        │&lt;br /&gt;
LAN│   │  DNS-запрос  │                                                        │&lt;br /&gt;
───┼──►│  от клиента  │                                                        │&lt;br /&gt;
   │   └──────┬───────┘                                                        │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │          ▼                                                                │&lt;br /&gt;
   │   ┌──────────────┐  upstream  ┌────────────────┐                          │&lt;br /&gt;
   │   │  keen-pbr    │  через     │  Quad9 9.9.9.9 │                          │&lt;br /&gt;
   │   │  dnsmasq     │ ─────────► │                │                          │&lt;br /&gt;
   │   │  на :53      │            │                │                          │&lt;br /&gt;
   │   └──────┬───────┘            └────────────────┘                          │&lt;br /&gt;
   │          │ IP → ipset                                                     │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │   ┌──────▼──────────────────────────────────────────────┐                 │&lt;br /&gt;
LAN│   │  iptables / маршрутизация                           │                 │&lt;br /&gt;
───┼──►│  ├ если dst-IP в ipset bypass:                      │                 │&lt;br /&gt;
TCP│   │  │   fwmark → ip rule → table 151 → singtun         │                 │&lt;br /&gt;
   │   │  │                                                  │                 │&lt;br /&gt;
   │   │  └ иначе:                                           │                 │&lt;br /&gt;
   │   │      обычный WAN-маршрут                            │                 │&lt;br /&gt;
   │   │      └ nfqws2 ловит первые пакеты                   │                 │&lt;br /&gt;
   │   │        и модифицирует для обхода DPI                │                 │&lt;br /&gt;
   │   └────┬──────────────────────────────────────────┬─────┘                 │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          ▼                       │&lt;br /&gt;
   │   ┌─────────┐                            ┌────────────────┐               │&lt;br /&gt;
   │   │ singtun │                            │ WAN-интерфейс  │               │&lt;br /&gt;
   │   │ (TUN)   │                            │ (ваш провайдер)│               │&lt;br /&gt;
   │   └────┬────┘                            └────────┬───────┘               │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          │                       │&lt;br /&gt;
   │   ┌─────────────┐                                 │                       │&lt;br /&gt;
   │   │  sing-box   │                                 │                       │&lt;br /&gt;
   │   │  outbound:  │                                 │                       │&lt;br /&gt;
   │   │  hysteria2  │                                 │                       │&lt;br /&gt;
   │   └──────┬──────┘                                 │                       │&lt;br /&gt;
   │          │                                        │                       │&lt;br /&gt;
   └──────────┼────────────────────────────────────────┼───────────────────────┘&lt;br /&gt;
              │                                        │&lt;br /&gt;
              ▼                                        ▼&lt;br /&gt;
        ┌───────────┐                            ┌───────────┐&lt;br /&gt;
        │ VPN-узел  │                            │ Любой     │&lt;br /&gt;
        │ провайдера│                            │ интернет  │&lt;br /&gt;
        └───────────┘                            └───────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Здесь можно перерисовать в Mermaid/Excalidraw для финальной картинки.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.8. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.9. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=981</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=981"/>
		<updated>2026-05-12T15:33:36Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                          KEENETIC РОУТЕР&lt;br /&gt;
&lt;br /&gt;
  ┌──────────────────────────────────────────────────────────────┐&lt;br /&gt;
  │                                                              │&lt;br /&gt;
  │  ┌────────────────┐                                          │&lt;br /&gt;
  │  │   keen-pbr     │  --- адрес домена в списке? ---          │&lt;br /&gt;
  │  │   (по доменам) │            │           │                 │&lt;br /&gt;
  │  └────────────────┘            │ ДА        │ НЕТ             │&lt;br /&gt;
  │                                ▼           ▼                 │&lt;br /&gt;
  │                       ┌────────────┐  ┌────────────┐         │&lt;br /&gt;
  │                       │  singtun   │  │   nfqws2   │         │&lt;br /&gt;
  │                       │ (sing-box) │  │  DPI fix   │         │&lt;br /&gt;
  │                       └────────────┘  └────────────┘         │&lt;br /&gt;
  │                            │                │                │&lt;br /&gt;
  └────────────────────────────┼────────────────┼────────────────┘&lt;br /&gt;
                               │                │&lt;br /&gt;
                          ┌────▼────┐      ┌────▼────┐&lt;br /&gt;
                          │  VPN-   │      │  Прямой │&lt;br /&gt;
                          │  сервер │      │  WAN    │&lt;br /&gt;
                          └─────────┘      └─────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&#039;&#039;(Здесь схему можно перерисовать в Mermaid или Excalidraw и заменить блок.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Подготовка USB-накопителя ==&lt;br /&gt;
=== Подключение и форматирование ===&lt;br /&gt;
# Воткните флешку в USB-порт роутера.&lt;br /&gt;
# Откройте веб-интерфейс Keenetic: &#039;&#039;&#039;Приложения&#039;&#039;&#039; → &#039;&#039;&#039;USB-диски и принтеры&#039;&#039;&#039;.&lt;br /&gt;
# В списке появится диск. Откройте его параметры.&lt;br /&gt;
# Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; и выберите &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;USB-диски&amp;quot; в веб-интерфейсе Keenetic с подключённым диском и кнопкой &amp;quot;Форматировать&amp;quot;.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Узнайте UUID диска через CLI ===&lt;br /&gt;
У диска есть уникальный &#039;&#039;&#039;UUID&#039;&#039;&#039; (длинная строка вида &amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;), который понадобится для установки Entware. Веб-интерфейс Keenetic показывает UUID на странице диска, &#039;&#039;&#039;но не позволяет его выделить и скопировать&#039;&#039;&#039; — поэтому удобнее получить его через встроенную командную строку.&lt;br /&gt;
&lt;br /&gt;
# Откройте в браузере адрес &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; — это встроенный веб-CLI Keenetic. Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Выполните команду:&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# В ответе найдите блок с вашей флешкой и строку &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Пример вывода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;media&amp;quot;: {&lt;br /&gt;
        &amp;quot;Media0&amp;quot;: {&lt;br /&gt;
            &amp;quot;bus&amp;quot;: &amp;quot;usb&amp;quot;,&lt;br /&gt;
            &amp;quot;manufacturer&amp;quot;: &amp;quot;SanDisk&amp;quot;,&lt;br /&gt;
            &amp;quot;product&amp;quot;: &amp;quot;Ultra&amp;quot;,&lt;br /&gt;
            &amp;quot;state&amp;quot;: &amp;quot;ACTIVE&amp;quot;,&lt;br /&gt;
            &amp;quot;partition&amp;quot;: [&lt;br /&gt;
                {&lt;br /&gt;
                    &amp;quot;uuid&amp;quot;: &amp;quot;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;quot;,&lt;br /&gt;
                    &amp;quot;fstype&amp;quot;: &amp;quot;ext4&amp;quot;,&lt;br /&gt;
                    &amp;quot;state&amp;quot;: &amp;quot;MOUNTED&amp;quot;,&lt;br /&gt;
                    ...&lt;br /&gt;
                }&lt;br /&gt;
            ]&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скопируйте значение поля &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt; — оно понадобится в следующем шаге.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — пока вы в CLI, можно сразу включить DNS Override.&#039;&#039;&#039; Эта опция понадобится позже для keen-pbr — она заставляет KeeneticOS отдавать DNS-трафик в Entware-овский dnsmasq. Чтобы не возвращаться в CLI отдельно, выполните прямо сейчас:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Опция применится после ближайшей перезагрузки роутера (она будет в конце Этапа 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Компоненты KeeneticOS ==&lt;br /&gt;
=== Какая у вас прошивка? ===&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужно ли вам что-то включать на этом этапе:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (роутер, который продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, все нужные пакеты уже включены в образ прошивки этого порта — переходите к разделу 1.3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — как понять, какая у вас прошивка:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; (главная страница веб-интерфейса) видна модель устройства. Если рядом с моделью стоит знакомое маркетинговое имя Keenetic (например, &amp;quot;Keenetic Hero&amp;quot;) и модель начинается с &amp;quot;KN-&amp;quot; — это оригинальный Keenetic. Если вы видите название роутера другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) и при этом отображается KeeneticOS — у вас порт сообщества.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Признак порта сообщества:&#039;&#039;&#039; На странице с компонентами окно &amp;quot;Компоненты операционной системы&amp;quot; может показывать сообщение &amp;quot;Не удалось получить список компонентов от сервера&amp;quot; — это нормально для портированных сборок, у которых нет своего сервера обновлений. В этом случае шаг с компонентами &#039;&#039;&#039;не нужен&#039;&#039;&#039; — переходите к разделу 1.3.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Только для оригинального Keenetic ===&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в более старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент (точное название в UI)&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|Базовая инфраструктура Entware — без этого нельзя ставить пакеты на USB&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Чтобы роутер мог монтировать ext4-диск&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Доступ к командной строке роутера&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Кроме того, &#039;&#039;&#039;желательно&#039;&#039;&#039; проверить наличие следующих компонентов (точные названия в интерфейсе могут отличаться от версии к версии — ищите по словам):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Что искать в списке&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|Базовые модули iptables для работы фаервола Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Дополнительные модули (xt_set, xt_multiport, conntrack-extra) — &#039;&#039;&#039;критично&#039;&#039;&#039; для работы keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора нажмите &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и подождите 2–5 минут. Роутер перезагрузится самостоятельно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Обновления и компоненты&amp;quot; с открытым окном &amp;quot;Показать компоненты&amp;quot; и отмеченными нужными пунктами.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В KeeneticOS 5 и новее компонент &#039;&#039;&#039;Протокол IPv6&#039;&#039;&#039; включён по умолчанию и не может быть отключён — это нормально.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Установка Entware через командную строку ==&lt;br /&gt;
=== Открытие командной строки роутера ===&lt;br /&gt;
Если вы вышли из CLI после шага 1.1 — откройте снова: &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt;. Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Запуск установки Entware ===&lt;br /&gt;
Команда состоит из &#039;&#039;&#039;двух частей, которые вы должны подставить сами&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;UUID вашего USB-диска&#039;&#039;&#039; — тот, который вы получили командой &amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в разделе &#039;&#039;&#039;1.1&#039;&#039;&#039; (длинная строка вида &amp;lt;code&amp;gt;d5f39712-7ae1-...&amp;lt;/code&amp;gt;).&lt;br /&gt;
# &#039;&#039;&#039;URL установщика&#039;&#039;&#039; — выбирается по архитектуре вашего роутера (см. таблицу ниже).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — не копируйте команду как есть!&#039;&#039;&#039; В шаблоне ниже фигурные скобки &amp;lt;code&amp;gt;&amp;lt;...&amp;gt;&amp;lt;/code&amp;gt; — это места, куда нужно подставить &#039;&#039;&#039;ваши&#039;&#039;&#039; значения. Если оставить шаблон с угловыми скобками или скопировать чужой UUID — установка не сработает.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Шаблон команды ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выбор URL установщика ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (целиком)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство моделей Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — как узнать архитектуру:&#039;&#039;&#039; Откройте &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; в веб-интерфейсе → видно модель устройства и процессор. Для большинства бытовых моделей это MIPS — берите верхнюю строку таблицы. Если сомневаетесь — пишите команду с &amp;lt;code&amp;gt;mipsel&amp;lt;/code&amp;gt;: если архитектура не подходит, установка скажет об этом ошибкой, и вы не сломаете роутер.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Пример с подставленными значениями ====&lt;br /&gt;
Допустим, ваш UUID — &amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;, архитектура — mipsel. Тогда команда полностью выглядит так:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Это &#039;&#039;&#039;пример&#039;&#039;&#039; — UUID &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; здесь приведён только для иллюстрации. У &#039;&#039;&#039;вашего&#039;&#039;&#039; диска UUID будет &#039;&#039;&#039;другой&#039;&#039;&#039;. Подставьте именно свой со страницы &amp;quot;Диски и принтеры&amp;quot;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Проверочный чек-лист перед нажатием Enter ====&lt;br /&gt;
* Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — &#039;&#039;&#039;обязательны&#039;&#039;&#039;.&lt;br /&gt;
* URL — &#039;&#039;&#039;одной строкой&#039;&#039;&#039;, без пробелов и переносов.&lt;br /&gt;
* После UUID и перед URL — &#039;&#039;&#039;ровно один пробел&#039;&#039;&#039;.&lt;br /&gt;
* Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде &#039;&#039;&#039;не должно остаться&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Сохранение конфигурации и перезагрузка ===&lt;br /&gt;
После того как установка прошла без ошибок, сохраните конфигурацию и перезагрузите роутер:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перезагрузка нужна, чтобы применился &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt;, который вы включили на шаге 1.1. Ожидайте 1–2 минуты, пока роутер поднимется обратно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — если установщик &amp;quot;молчит&amp;quot;:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; не работает, если OPKG-диск уже был назначен раньше. Если в логе вы не видите строк про загрузку &amp;lt;code&amp;gt;mipsel-installer.tar.gz&amp;lt;/code&amp;gt; — сбросьте диск и повторите:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Проверка установки ===&lt;br /&gt;
Откройте журнал: &#039;&#039;&#039;Диагностика&#039;&#039;&#039; → &#039;&#039;&#039;Системный журнал&#039;&#039;&#039;. Должны появиться строки примерно такого содержания:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Opkg::Manager: downloading installer...&lt;br /&gt;
Opkg::Manager: extracting to /opt...&lt;br /&gt;
Opkg::Manager: ...&lt;br /&gt;
Entware installed.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения установки на роутере поднимется встроенный SSH-сервер Entware на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Первое подключение по SSH ==&lt;br /&gt;
Подключитесь к роутеру с компьютера. На Windows — через PuTTY или через стандартный &amp;lt;code&amp;gt;ssh.exe&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; (LAN-адрес роутера)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Из PowerShell это одна строка:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При первом подключении ssh попросит подтвердить fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа смените пароль:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Дефолтный пароль &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем — если SSH будет проброшен наружу, роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите заходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце этого документа. Для базовой установки sing-box / keen-pbr / nfqws2 это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; &lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про место:&#039;&#039;&#039; &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; занимает ~62 МБ распакованных, плюс ~7 МБ сам helper, плюс Entware-окружение. На встроенной флэш-памяти роутера не помещается — Entware &#039;&#039;&#039;должен&#039;&#039;&#039; быть на USB (см. Этап 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. UI покажет жёлтое предупреждение под распознанными параметрами. Решение — попросить владельца сервера переключить транспорт на &amp;lt;code&amp;gt;ws&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grpc&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;tcp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Outbounds (выходы)&amp;quot; с тремя строками: wan, block, vpn.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Правила маршрутизации&amp;quot; с активным правилом #2 bypass → vpn.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
ls -la /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок.&lt;br /&gt;
&lt;br /&gt;
== 3.5. Тестирование ==&lt;br /&gt;
На клиентском устройстве, подключённом к Keenetic:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Очистите кеш DNS&#039;&#039;&#039; (важно — без этого старые ответы остаются):&lt;br /&gt;
#* Windows: &amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; в PowerShell.&lt;br /&gt;
#* Android / iOS: переподключиться к Wi-Fi (off → on).&lt;br /&gt;
#* macOS: &amp;lt;code&amp;gt;sudo dscacheutil -flushcache&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Перезапустите браузер (у него свой DNS-кеш).&lt;br /&gt;
# Откройте сайт из списка bypass.&lt;br /&gt;
# Параллельно откройте &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; в браузере. Адрес должен быть тот же, который вы видели в шаге «IP через TUN» на вкладке Главная UI singbox-helper (т.е. IP вашего VPN-провайдера, а не домашний WAN-IP).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница api.ipify.org с подменённым IP.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Замечание про «failed» в конце установки:&#039;&#039;&#039; В выводе установщика вы можете увидеть строку:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Starting /opt/sbin/lighttpd...              failed.&lt;br /&gt;
NFQWS2 Web Interface installed: http://192.168.10.1:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Это &#039;&#039;&#039;не ошибка&#039;&#039;&#039;. lighttpd пытается стартануть до того, как все его модули (php8-mod-curl, php8-mod-session, mod-rewrite, mod-redirect) полностью зарегистрировались. Через несколько секунд стартовый скрипт &amp;lt;code&amp;gt;S80lighttpd&amp;lt;/code&amp;gt; успешно поднимает сервис. Достаточно проверить:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pgrep -af lighttpd&lt;br /&gt;
netstat -tlnup | grep :90&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Оба должны показать запущенный процесс на порту 90. Если веб-интерфейс открывается на &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt; — всё в порядке.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.10.1:90&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для доступа из другой подсети — открыть порт &amp;lt;code&amp;gt;90&amp;lt;/code&amp;gt; в фаерволе Keenetic (по аналогии с keen-pbr WebUI).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                  K E E N E T I C   Р О У Т Е Р&lt;br /&gt;
   ┌───────────────────────────────────────────────────────────────────────────┐&lt;br /&gt;
   │                                                                           │&lt;br /&gt;
   │   ┌──────────────┐                                                        │&lt;br /&gt;
LAN│   │  DNS-запрос  │                                                        │&lt;br /&gt;
───┼──►│  от клиента  │                                                        │&lt;br /&gt;
   │   └──────┬───────┘                                                        │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │          ▼                                                                │&lt;br /&gt;
   │   ┌──────────────┐  upstream  ┌────────────────┐                          │&lt;br /&gt;
   │   │  keen-pbr    │  через     │  Quad9 9.9.9.9 │                          │&lt;br /&gt;
   │   │  dnsmasq     │ ─────────► │                │                          │&lt;br /&gt;
   │   │  на :53      │            │                │                          │&lt;br /&gt;
   │   └──────┬───────┘            └────────────────┘                          │&lt;br /&gt;
   │          │ IP → ipset                                                     │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │   ┌──────▼──────────────────────────────────────────────┐                 │&lt;br /&gt;
LAN│   │  iptables / маршрутизация                           │                 │&lt;br /&gt;
───┼──►│  ├ если dst-IP в ipset bypass:                      │                 │&lt;br /&gt;
TCP│   │  │   fwmark → ip rule → table 151 → singtun         │                 │&lt;br /&gt;
   │   │  │                                                  │                 │&lt;br /&gt;
   │   │  └ иначе:                                           │                 │&lt;br /&gt;
   │   │      обычный WAN-маршрут                            │                 │&lt;br /&gt;
   │   │      └ nfqws2 ловит первые пакеты                   │                 │&lt;br /&gt;
   │   │        и модифицирует для обхода DPI                │                 │&lt;br /&gt;
   │   └────┬──────────────────────────────────────────┬─────┘                 │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          ▼                       │&lt;br /&gt;
   │   ┌─────────┐                            ┌────────────────┐               │&lt;br /&gt;
   │   │ singtun │                            │ WAN-интерфейс  │               │&lt;br /&gt;
   │   │ (TUN)   │                            │ (ваш провайдер)│               │&lt;br /&gt;
   │   └────┬────┘                            └────────┬───────┘               │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          │                       │&lt;br /&gt;
   │   ┌─────────────┐                                 │                       │&lt;br /&gt;
   │   │  sing-box   │                                 │                       │&lt;br /&gt;
   │   │  outbound:  │                                 │                       │&lt;br /&gt;
   │   │  hysteria2  │                                 │                       │&lt;br /&gt;
   │   └──────┬──────┘                                 │                       │&lt;br /&gt;
   │          │                                        │                       │&lt;br /&gt;
   └──────────┼────────────────────────────────────────┼───────────────────────┘&lt;br /&gt;
              │                                        │&lt;br /&gt;
              ▼                                        ▼&lt;br /&gt;
        ┌───────────┐                            ┌───────────┐&lt;br /&gt;
        │ VPN-узел  │                            │ Любой     │&lt;br /&gt;
        │ провайдера│                            │ интернет  │&lt;br /&gt;
        └───────────┘                            └───────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Здесь можно перерисовать в Mermaid/Excalidraw для финальной картинки.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Скрипт пересоздания /var/empty при загрузке ==&lt;br /&gt;
Каталог &amp;lt;code&amp;gt;/var&amp;lt;/code&amp;gt; на роутере — это tmpfs (RAM-диск), он очищается при каждой загрузке. Создадим стартовый скрипт, который воссоздаёт &amp;lt;code&amp;gt;/var/empty&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/init.d/S39sshd-prep &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
chown root:root /var/empty&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.8. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.9. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.10. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=980</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=980"/>
		<updated>2026-05-12T15:29:28Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039; + &#039;&#039;&#039;singbox-helper&#039;&#039;&#039;&lt;br /&gt;
|sing-box — универсальный туннельный движок, поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается выборочный трафик. singbox-helper — обёртка над ним: ставит как зависимость, даёт веб-UI на &amp;lt;code&amp;gt;:8765&amp;lt;/code&amp;gt;, по вставленной ссылке (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, ...) сама генерирует &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                          KEENETIC РОУТЕР&lt;br /&gt;
&lt;br /&gt;
  ┌──────────────────────────────────────────────────────────────┐&lt;br /&gt;
  │                                                              │&lt;br /&gt;
  │  ┌────────────────┐                                          │&lt;br /&gt;
  │  │   keen-pbr     │  --- адрес домена в списке? ---          │&lt;br /&gt;
  │  │   (по доменам) │            │           │                 │&lt;br /&gt;
  │  └────────────────┘            │ ДА        │ НЕТ             │&lt;br /&gt;
  │                                ▼           ▼                 │&lt;br /&gt;
  │                       ┌────────────┐  ┌────────────┐         │&lt;br /&gt;
  │                       │  singtun   │  │   nfqws2   │         │&lt;br /&gt;
  │                       │ (sing-box) │  │  DPI fix   │         │&lt;br /&gt;
  │                       └────────────┘  └────────────┘         │&lt;br /&gt;
  │                            │                │                │&lt;br /&gt;
  └────────────────────────────┼────────────────┼────────────────┘&lt;br /&gt;
                               │                │&lt;br /&gt;
                          ┌────▼────┐      ┌────▼────┐&lt;br /&gt;
                          │  VPN-   │      │  Прямой │&lt;br /&gt;
                          │  сервер │      │  WAN    │&lt;br /&gt;
                          └─────────┘      └─────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&#039;&#039;(Здесь схему можно перерисовать в Mermaid или Excalidraw и заменить блок.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Подготовка USB-накопителя ==&lt;br /&gt;
=== Подключение и форматирование ===&lt;br /&gt;
# Воткните флешку в USB-порт роутера.&lt;br /&gt;
# Откройте веб-интерфейс Keenetic: &#039;&#039;&#039;Приложения&#039;&#039;&#039; → &#039;&#039;&#039;USB-диски и принтеры&#039;&#039;&#039;.&lt;br /&gt;
# В списке появится диск. Откройте его параметры.&lt;br /&gt;
# Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; и выберите &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;USB-диски&amp;quot; в веб-интерфейсе Keenetic с подключённым диском и кнопкой &amp;quot;Форматировать&amp;quot;.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Узнайте UUID диска через CLI ===&lt;br /&gt;
У диска есть уникальный &#039;&#039;&#039;UUID&#039;&#039;&#039; (длинная строка вида &amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;), который понадобится для установки Entware. Веб-интерфейс Keenetic показывает UUID на странице диска, &#039;&#039;&#039;но не позволяет его выделить и скопировать&#039;&#039;&#039; — поэтому удобнее получить его через встроенную командную строку.&lt;br /&gt;
&lt;br /&gt;
# Откройте в браузере адрес &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; — это встроенный веб-CLI Keenetic. Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Выполните команду:&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# В ответе найдите блок с вашей флешкой и строку &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Пример вывода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;media&amp;quot;: {&lt;br /&gt;
        &amp;quot;Media0&amp;quot;: {&lt;br /&gt;
            &amp;quot;bus&amp;quot;: &amp;quot;usb&amp;quot;,&lt;br /&gt;
            &amp;quot;manufacturer&amp;quot;: &amp;quot;SanDisk&amp;quot;,&lt;br /&gt;
            &amp;quot;product&amp;quot;: &amp;quot;Ultra&amp;quot;,&lt;br /&gt;
            &amp;quot;state&amp;quot;: &amp;quot;ACTIVE&amp;quot;,&lt;br /&gt;
            &amp;quot;partition&amp;quot;: [&lt;br /&gt;
                {&lt;br /&gt;
                    &amp;quot;uuid&amp;quot;: &amp;quot;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;quot;,&lt;br /&gt;
                    &amp;quot;fstype&amp;quot;: &amp;quot;ext4&amp;quot;,&lt;br /&gt;
                    &amp;quot;state&amp;quot;: &amp;quot;MOUNTED&amp;quot;,&lt;br /&gt;
                    ...&lt;br /&gt;
                }&lt;br /&gt;
            ]&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скопируйте значение поля &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt; — оно понадобится в следующем шаге.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — пока вы в CLI, можно сразу включить DNS Override.&#039;&#039;&#039; Эта опция понадобится позже для keen-pbr — она заставляет KeeneticOS отдавать DNS-трафик в Entware-овский dnsmasq. Чтобы не возвращаться в CLI отдельно, выполните прямо сейчас:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Опция применится после ближайшей перезагрузки роутера (она будет в конце Этапа 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Компоненты KeeneticOS ==&lt;br /&gt;
=== Какая у вас прошивка? ===&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужно ли вам что-то включать на этом этапе:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (роутер, который продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, все нужные пакеты уже включены в образ прошивки этого порта — переходите к разделу 1.3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — как понять, какая у вас прошивка:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; (главная страница веб-интерфейса) видна модель устройства. Если рядом с моделью стоит знакомое маркетинговое имя Keenetic (например, &amp;quot;Keenetic Hero&amp;quot;) и модель начинается с &amp;quot;KN-&amp;quot; — это оригинальный Keenetic. Если вы видите название роутера другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) и при этом отображается KeeneticOS — у вас порт сообщества.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Признак порта сообщества:&#039;&#039;&#039; На странице с компонентами окно &amp;quot;Компоненты операционной системы&amp;quot; может показывать сообщение &amp;quot;Не удалось получить список компонентов от сервера&amp;quot; — это нормально для портированных сборок, у которых нет своего сервера обновлений. В этом случае шаг с компонентами &#039;&#039;&#039;не нужен&#039;&#039;&#039; — переходите к разделу 1.3.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Только для оригинального Keenetic ===&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в более старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент (точное название в UI)&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|Базовая инфраструктура Entware — без этого нельзя ставить пакеты на USB&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Чтобы роутер мог монтировать ext4-диск&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Доступ к командной строке роутера&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Кроме того, &#039;&#039;&#039;желательно&#039;&#039;&#039; проверить наличие следующих компонентов (точные названия в интерфейсе могут отличаться от версии к версии — ищите по словам):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Что искать в списке&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|Базовые модули iptables для работы фаервола Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Дополнительные модули (xt_set, xt_multiport, conntrack-extra) — &#039;&#039;&#039;критично&#039;&#039;&#039; для работы keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора нажмите &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и подождите 2–5 минут. Роутер перезагрузится самостоятельно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Обновления и компоненты&amp;quot; с открытым окном &amp;quot;Показать компоненты&amp;quot; и отмеченными нужными пунктами.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В KeeneticOS 5 и новее компонент &#039;&#039;&#039;Протокол IPv6&#039;&#039;&#039; включён по умолчанию и не может быть отключён — это нормально.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Установка Entware через командную строку ==&lt;br /&gt;
=== Открытие командной строки роутера ===&lt;br /&gt;
Если вы вышли из CLI после шага 1.1 — откройте снова: &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt;. Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Запуск установки Entware ===&lt;br /&gt;
Команда состоит из &#039;&#039;&#039;двух частей, которые вы должны подставить сами&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;UUID вашего USB-диска&#039;&#039;&#039; — тот, который вы получили командой &amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в разделе &#039;&#039;&#039;1.1&#039;&#039;&#039; (длинная строка вида &amp;lt;code&amp;gt;d5f39712-7ae1-...&amp;lt;/code&amp;gt;).&lt;br /&gt;
# &#039;&#039;&#039;URL установщика&#039;&#039;&#039; — выбирается по архитектуре вашего роутера (см. таблицу ниже).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — не копируйте команду как есть!&#039;&#039;&#039; В шаблоне ниже фигурные скобки &amp;lt;code&amp;gt;&amp;lt;...&amp;gt;&amp;lt;/code&amp;gt; — это места, куда нужно подставить &#039;&#039;&#039;ваши&#039;&#039;&#039; значения. Если оставить шаблон с угловыми скобками или скопировать чужой UUID — установка не сработает.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Шаблон команды ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выбор URL установщика ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (целиком)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство моделей Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — как узнать архитектуру:&#039;&#039;&#039; Откройте &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; в веб-интерфейсе → видно модель устройства и процессор. Для большинства бытовых моделей это MIPS — берите верхнюю строку таблицы. Если сомневаетесь — пишите команду с &amp;lt;code&amp;gt;mipsel&amp;lt;/code&amp;gt;: если архитектура не подходит, установка скажет об этом ошибкой, и вы не сломаете роутер.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Пример с подставленными значениями ====&lt;br /&gt;
Допустим, ваш UUID — &amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;, архитектура — mipsel. Тогда команда полностью выглядит так:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Это &#039;&#039;&#039;пример&#039;&#039;&#039; — UUID &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; здесь приведён только для иллюстрации. У &#039;&#039;&#039;вашего&#039;&#039;&#039; диска UUID будет &#039;&#039;&#039;другой&#039;&#039;&#039;. Подставьте именно свой со страницы &amp;quot;Диски и принтеры&amp;quot;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Проверочный чек-лист перед нажатием Enter ====&lt;br /&gt;
* Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — &#039;&#039;&#039;обязательны&#039;&#039;&#039;.&lt;br /&gt;
* URL — &#039;&#039;&#039;одной строкой&#039;&#039;&#039;, без пробелов и переносов.&lt;br /&gt;
* После UUID и перед URL — &#039;&#039;&#039;ровно один пробел&#039;&#039;&#039;.&lt;br /&gt;
* Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде &#039;&#039;&#039;не должно остаться&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Сохранение конфигурации и перезагрузка ===&lt;br /&gt;
После того как установка прошла без ошибок, сохраните конфигурацию и перезагрузите роутер:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перезагрузка нужна, чтобы применился &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt;, который вы включили на шаге 1.1. Ожидайте 1–2 минуты, пока роутер поднимется обратно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — если установщик &amp;quot;молчит&amp;quot;:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; не работает, если OPKG-диск уже был назначен раньше. Если в логе вы не видите строк про загрузку &amp;lt;code&amp;gt;mipsel-installer.tar.gz&amp;lt;/code&amp;gt; — сбросьте диск и повторите:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Проверка установки ===&lt;br /&gt;
Откройте журнал: &#039;&#039;&#039;Диагностика&#039;&#039;&#039; → &#039;&#039;&#039;Системный журнал&#039;&#039;&#039;. Должны появиться строки примерно такого содержания:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Opkg::Manager: downloading installer...&lt;br /&gt;
Opkg::Manager: extracting to /opt...&lt;br /&gt;
Opkg::Manager: ...&lt;br /&gt;
Entware installed.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения установки на роутере поднимется встроенный SSH-сервер Entware на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Первое подключение по SSH ==&lt;br /&gt;
Подключитесь к роутеру с компьютера. На Windows — через PuTTY или через стандартный &amp;lt;code&amp;gt;ssh.exe&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; (LAN-адрес роутера)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Из PowerShell это одна строка:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При первом подключении ssh попросит подтвердить fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа смените пароль:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Дефолтный пароль &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем — если SSH будет проброшен наружу, роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите заходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце этого документа. Для базовой установки sing-box / keen-pbr / nfqws2 это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box (через singbox-helper) =&lt;br /&gt;
sing-box — движок туннеля. Раньше его ставили вручную (&amp;lt;code&amp;gt;opkg install sing-box-go&amp;lt;/code&amp;gt;) и сами писали &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; на 60+ строк JSON. Теперь весь этот шаг делает утилита &amp;lt;b&amp;gt;singbox-helper&amp;lt;/b&amp;gt; — она:&lt;br /&gt;
&lt;br /&gt;
* подтягивает &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; как зависимость opkg (62 МБ, ставится автоматически);&lt;br /&gt;
* даёт веб-интерфейс на &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; с 4-я вкладками (Главная / Настройки / Логи / Бэкапы);&lt;br /&gt;
* по вставленной ссылке узла (&amp;lt;code&amp;gt;vless://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hysteria2://&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;socks5://&amp;lt;/code&amp;gt;) сама собирает корректный &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;, бэкапит старый, рестартит sing-box и прогоняет диагностику.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Подключение фида singbox-helper и установка ==&lt;br /&gt;
Подключитесь по SSH и добавьте репозиторий пакетов:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
opkg увидит зависимость &amp;lt;code&amp;gt;Depends: sing-box-go&amp;lt;/code&amp;gt; и поставит обе утилиты сразу. На выходе:&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt; — наш бинарь (~7 МБ);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/sbin/sing-box&amp;lt;/code&amp;gt; — sing-box-go от Entware (~62 МБ распакованных);&lt;br /&gt;
* &amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; — init-скрипты, прописаны в автозагрузку;&lt;br /&gt;
* демон singbox-helper уже стартует и слушает &amp;lt;code&amp;gt;0.0.0.0:8765&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про место:&#039;&#039;&#039; &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; занимает ~62 МБ распакованных, плюс ~7 МБ сам helper, плюс Entware-окружение. На встроенной флэш-памяти роутера не помещается — Entware &#039;&#039;&#039;должен&#039;&#039;&#039; быть на USB (см. Этап 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — другая архитектура:&#039;&#039;&#039; Команда выше — для &amp;lt;code&amp;gt;mipsel-3.4&amp;lt;/code&amp;gt; (Keenetic / Xiaomi на MT7621/MT7620 — основная масса устройств). Для новых Keenetic Hopper/Hero/Giga на ARM64 — поменяйте URL на &amp;lt;code&amp;gt;...github.io/sing-box-helper/aarch64-3.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Открытие веб-интерфейса ==&lt;br /&gt;
В браузере: &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP-вашего-роутера&amp;amp;gt;:8765&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;http://192.168.10.1:8765&amp;lt;/code&amp;gt;; LAN-IP видно в веб-интерфейсе Keenetic в карточке «Домашняя сеть»).&lt;br /&gt;
&lt;br /&gt;
Откроется страница с четырьмя вкладками: &#039;&#039;&#039;Главная&#039;&#039;&#039;, &#039;&#039;&#039;Настройки&#039;&#039;&#039;, &#039;&#039;&#039;Логи&#039;&#039;&#039;, &#039;&#039;&#039;Бэкапы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
На «Главной» сверху видно состояние:&lt;br /&gt;
* &#039;&#039;&#039;sing-box&#039;&#039;&#039; — running / не запущен (после свежей установки — running с заглушечным конфигом);&lt;br /&gt;
* &#039;&#039;&#039;TUN-интерфейс&#039;&#039;&#039; — UP / down;&lt;br /&gt;
* &#039;&#039;&#039;Текущий узел&#039;&#039;&#039; — пусто (мы ещё не применили ссылку).&lt;br /&gt;
&lt;br /&gt;
== 2.3. Применение узла ==&lt;br /&gt;
В блоке «Применить узел» вставьте ссылку из вашей VPN-панели (3x-ui, Marzban, Hiddify и т.п.). Поддерживаются:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Схема&lt;br /&gt;
!Что это&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;hysteria2://пароль@сервер:порт&amp;lt;/code&amp;gt;&lt;br /&gt;
|Hysteria2 (синоним &amp;lt;code&amp;gt;hy2://&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://uuid@сервер:порт?type=tcp&amp;amp;security=tls&amp;amp;...&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS vanilla (TCP / WS / gRPC / h2 / httpupgrade)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vless://...?security=reality&amp;amp;pbk=...&amp;amp;flow=xtls-rprx-vision&amp;lt;/code&amp;gt;&lt;br /&gt;
|VLESS + REALITY (+ Vision)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный SOCKS-upstream — если на роутере уже работает naive-proxy / mieru-client, sing-box можно использовать как обёртку с TUN над ним&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Жмёте &#039;&#039;&#039;[ Применить ]&#039;&#039;&#039;. Утилита:&lt;br /&gt;
&lt;br /&gt;
# Парсит URI и валидирует обязательные параметры (порт, ключи REALITY и т.п.). Если ссылка кривая — отказ с понятной ошибкой.&lt;br /&gt;
# Делает TCP-probe до &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; с таймаутом 3 секунды. Если сервер недоступен — отказ &#039;&#039;&#039;до&#039;&#039;&#039; рестарта sing-box, чтобы не дёргать рабочий туннель зря.&lt;br /&gt;
# Бэкапит текущий &amp;lt;code&amp;gt;/opt/etc/sing-box/config.json&amp;lt;/code&amp;gt; в &amp;lt;code&amp;gt;config.json.bak-YYYYMMDD-HHMMSS&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Генерирует новый &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt;: TUN-inbound (&amp;lt;code&amp;gt;auto_route:false&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;strict_route:false&amp;lt;/code&amp;gt; — обязательно для совместимости с keen-pbr), mixed-inbound с автодетектом LAN-IP, outbound из URI с тегом &amp;lt;code&amp;gt;proxy&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;route.final=proxy&amp;lt;/code&amp;gt;, sniff + hijack-dns rules.&lt;br /&gt;
# Рестартит sing-box через &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box restart&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Сохраняет URI + label + время применения в &amp;lt;code&amp;gt;/opt/etc/singbox-helper/state.json&amp;lt;/code&amp;gt; (метаданные, которых сам sing-box не знает).&lt;br /&gt;
# Запускает блок диагностики «Проверка работы».&lt;br /&gt;
&lt;br /&gt;
Через несколько секунд под формой появится блок &#039;&#039;&#039;«Проверка работы»&#039;&#039;&#039; с пятью шагами:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Доступность узла&#039;&#039;&#039; — TCP-connect &amp;lt;code&amp;gt;server:port&amp;lt;/code&amp;gt; со временем отклика.&lt;br /&gt;
# &#039;&#039;&#039;sing-box процесс&#039;&#039;&#039; — PID и версия.&lt;br /&gt;
# &#039;&#039;&#039;Интерфейс singtun&#039;&#039;&#039; — UP / down.&lt;br /&gt;
# &#039;&#039;&#039;Прямой IP&#039;&#039;&#039; — что отвечает &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; через WAN.&lt;br /&gt;
# &#039;&#039;&#039;IP через TUN&#039;&#039;&#039; — то же, но &amp;lt;code&amp;gt;curl --interface singtun&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Должен отличаться&#039;&#039;&#039; от прямого.&lt;br /&gt;
&lt;br /&gt;
Если все 5 шагов зелёные — туннель работает.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Особый случай — xhttp:&#039;&#039;&#039; Узлы с параметром &amp;lt;code&amp;gt;type=xhttp&amp;lt;/code&amp;gt; на REALITY-серверах из 3x-ui &#039;&#039;&#039;не подключатся&#039;&#039;&#039;. sing-box 1.13 не имеет нативного xhttp-транспорта; helper маппит его в &amp;lt;code&amp;gt;httpupgrade&amp;lt;/code&amp;gt; как best-effort, но реальные xhttp-серверы отвечают &amp;lt;code&amp;gt;400 Bad Request&amp;lt;/code&amp;gt;. UI покажет жёлтое предупреждение под распознанными параметрами. Решение — попросить владельца сервера переключить транспорт на &amp;lt;code&amp;gt;ws&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grpc&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;tcp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. Что лежит на диске после установки ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Путь&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/bin/singbox-helper&amp;lt;/code&amp;gt;&lt;br /&gt;
|Бинарь утилиты (CLI + HTTP-сервер в одном).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper&amp;lt;/code&amp;gt;&lt;br /&gt;
|Init-скрипт демона. &amp;lt;code&amp;gt;{start|stop|restart|check}&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|Init-скрипт самого sing-box (поставлен пакетом &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt;).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/sing-box/config.json&amp;lt;/code&amp;gt;&lt;br /&gt;
|Сгенерированный конфиг для sing-box. &#039;&#039;&#039;Источник истины&#039;&#039;&#039; — все запросы UI &amp;lt;code&amp;gt;/api/status&amp;lt;/code&amp;gt; читают именно его, а не in-memory кэш.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/sing-box/config.json.bak-*&amp;lt;/code&amp;gt;&lt;br /&gt;
|Бэкапы. Создаются перед каждым «Применить»; держатся последние 10 (настраивается).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/singbox-helper/config.yaml&amp;lt;/code&amp;gt;&lt;br /&gt;
|YAML-настройки утилиты (создаётся при первом сохранении на вкладке «Настройки»). Отсутствие файла = встроенные defaults.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/singbox-helper/state.json&amp;lt;/code&amp;gt;&lt;br /&gt;
|Метаданные текущего узла: URI, метка (&amp;lt;code&amp;gt;#fragment&amp;lt;/code&amp;gt;), &amp;lt;code&amp;gt;applied_at&amp;lt;/code&amp;gt;. Используются UI чтобы показать «какая именно ссылка сейчас применена».&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Управление сервисами:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper {start|stop|restart|check}&lt;br /&gt;
/opt/etc/init.d/S99sing-box       {start|stop|restart|check}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обновление в будущем — обычным opkg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
state.json и config.yaml &#039;&#039;&#039;переживают&#039;&#039;&#039; обновление.&lt;br /&gt;
&lt;br /&gt;
== 2.5. (Опционально) Ручная проверка туннеля из консоли ==&lt;br /&gt;
UI уже прогнал диагностику в §2.3, но если хочется убедиться независимо — те же запросы из SSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Прямой IP (через ваш WAN)&lt;br /&gt;
curl -sS https://api.ipify.org&lt;br /&gt;
echo&lt;br /&gt;
&lt;br /&gt;
# IP через TUN — должен отличаться&lt;br /&gt;
curl -sS --interface singtun --max-time 8 https://api.ipify.org&lt;br /&gt;
echo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают — туннель не работает. Зайдите на вкладку &#039;&#039;&#039;Логи&#039;&#039;&#039; в UI, выберите источник &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt; — там будет конкретная причина.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Outbounds (выходы)&amp;quot; с тремя строками: wan, block, vpn.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Правила маршрутизации&amp;quot; с активным правилом #2 bypass → vpn.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
ls -la /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя TUN-интерфейса sing-box. singbox-helper в сгенерированном &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; по умолчанию ставит &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; — это совпадает с тем, что ожидают keen-pbr и этот NAT-скрипт. Менять не нужно. Если очень хочется — переименуйте в &#039;&#039;&#039;Настройках&#039;&#039;&#039; UI singbox-helper (поле «Имя интерфейса») и здесь синхронно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок.&lt;br /&gt;
&lt;br /&gt;
== 3.5. Тестирование ==&lt;br /&gt;
На клиентском устройстве, подключённом к Keenetic:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Очистите кеш DNS&#039;&#039;&#039; (важно — без этого старые ответы остаются):&lt;br /&gt;
#* Windows: &amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; в PowerShell.&lt;br /&gt;
#* Android / iOS: переподключиться к Wi-Fi (off → on).&lt;br /&gt;
#* macOS: &amp;lt;code&amp;gt;sudo dscacheutil -flushcache&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Перезапустите браузер (у него свой DNS-кеш).&lt;br /&gt;
# Откройте сайт из списка bypass.&lt;br /&gt;
# Параллельно откройте &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; в браузере. Адрес должен быть тот же, который вы видели в шаге «IP через TUN» на вкладке Главная UI singbox-helper (т.е. IP вашего VPN-провайдера, а не домашний WAN-IP).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница api.ipify.org с подменённым IP.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Замечание про «failed» в конце установки:&#039;&#039;&#039; В выводе установщика вы можете увидеть строку:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Starting /opt/sbin/lighttpd...              failed.&lt;br /&gt;
NFQWS2 Web Interface installed: http://192.168.10.1:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Это &#039;&#039;&#039;не ошибка&#039;&#039;&#039;. lighttpd пытается стартануть до того, как все его модули (php8-mod-curl, php8-mod-session, mod-rewrite, mod-redirect) полностью зарегистрировались. Через несколько секунд стартовый скрипт &amp;lt;code&amp;gt;S80lighttpd&amp;lt;/code&amp;gt; успешно поднимает сервис. Достаточно проверить:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pgrep -af lighttpd&lt;br /&gt;
netstat -tlnup | grep :90&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Оба должны показать запущенный процесс на порту 90. Если веб-интерфейс открывается на &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt; — всё в порядке.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.10.1:90&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для доступа из другой подсети — открыть порт &amp;lt;code&amp;gt;90&amp;lt;/code&amp;gt; в фаерволе Keenetic (по аналогии с keen-pbr WebUI).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                  K E E N E T I C   Р О У Т Е Р&lt;br /&gt;
   ┌───────────────────────────────────────────────────────────────────────────┐&lt;br /&gt;
   │                                                                           │&lt;br /&gt;
   │   ┌──────────────┐                                                        │&lt;br /&gt;
LAN│   │  DNS-запрос  │                                                        │&lt;br /&gt;
───┼──►│  от клиента  │                                                        │&lt;br /&gt;
   │   └──────┬───────┘                                                        │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │          ▼                                                                │&lt;br /&gt;
   │   ┌──────────────┐  upstream  ┌────────────────┐                          │&lt;br /&gt;
   │   │  keen-pbr    │  через     │  Quad9 9.9.9.9 │                          │&lt;br /&gt;
   │   │  dnsmasq     │ ─────────► │                │                          │&lt;br /&gt;
   │   │  на :53      │            │                │                          │&lt;br /&gt;
   │   └──────┬───────┘            └────────────────┘                          │&lt;br /&gt;
   │          │ IP → ipset                                                     │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │   ┌──────▼──────────────────────────────────────────────┐                 │&lt;br /&gt;
LAN│   │  iptables / маршрутизация                           │                 │&lt;br /&gt;
───┼──►│  ├ если dst-IP в ipset bypass:                      │                 │&lt;br /&gt;
TCP│   │  │   fwmark → ip rule → table 151 → singtun         │                 │&lt;br /&gt;
   │   │  │                                                  │                 │&lt;br /&gt;
   │   │  └ иначе:                                           │                 │&lt;br /&gt;
   │   │      обычный WAN-маршрут                            │                 │&lt;br /&gt;
   │   │      └ nfqws2 ловит первые пакеты                   │                 │&lt;br /&gt;
   │   │        и модифицирует для обхода DPI                │                 │&lt;br /&gt;
   │   └────┬──────────────────────────────────────────┬─────┘                 │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          ▼                       │&lt;br /&gt;
   │   ┌─────────┐                            ┌────────────────┐               │&lt;br /&gt;
   │   │ singtun │                            │ WAN-интерфейс  │               │&lt;br /&gt;
   │   │ (TUN)   │                            │ (ваш провайдер)│               │&lt;br /&gt;
   │   └────┬────┘                            └────────┬───────┘               │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          │                       │&lt;br /&gt;
   │   ┌─────────────┐                                 │                       │&lt;br /&gt;
   │   │  sing-box   │                                 │                       │&lt;br /&gt;
   │   │  outbound:  │                                 │                       │&lt;br /&gt;
   │   │  hysteria2  │                                 │                       │&lt;br /&gt;
   │   └──────┬──────┘                                 │                       │&lt;br /&gt;
   │          │                                        │                       │&lt;br /&gt;
   └──────────┼────────────────────────────────────────┼───────────────────────┘&lt;br /&gt;
              │                                        │&lt;br /&gt;
              ▼                                        ▼&lt;br /&gt;
        ┌───────────┐                            ┌───────────┐&lt;br /&gt;
        │ VPN-узел  │                            │ Любой     │&lt;br /&gt;
        │ провайдера│                            │ интернет  │&lt;br /&gt;
        └───────────┘                            └───────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Здесь можно перерисовать в Mermaid/Excalidraw для финальной картинки.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade singbox-helper sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
postinst-хуки соответствующих пакетов перезапускают свои сервисы сами; runtime-данные (&amp;lt;code&amp;gt;state.json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;, бэкапы) переживают &amp;lt;code&amp;gt;opkg upgrade&amp;lt;/code&amp;gt;. Если что-то осталось висеть со старой версией — перезапустите вручную (&amp;lt;code&amp;gt;/opt/etc/init.d/S98singbox-helper restart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;S99sing-box restart&amp;lt;/code&amp;gt;) или перезагрузите роутер.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S98singbox-helper check     # рекомендую: дальше его UI покажет состояние sing-box&lt;br /&gt;
/opt/etc/init.d/S99sing-box       status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr       status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq        status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2         status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Подсказка:&#039;&#039;&#039; На &amp;lt;code&amp;gt;http://&amp;amp;lt;LAN-IP&amp;amp;gt;:8765&amp;lt;/code&amp;gt; на вкладке &#039;&#039;&#039;Главная&#039;&#039;&#039; сразу видно состояние sing-box (PID, версия) и TUN-интерфейса. На вкладке &#039;&#039;&#039;Логи&#039;&#039;&#039; можно почитать &amp;lt;code&amp;gt;sing-box&amp;lt;/code&amp;gt;-лог (фильтр поверх &amp;lt;code&amp;gt;ndmc show log&amp;lt;/code&amp;gt;) и собственный лог helper&#039;а, не залезая в SSH.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box (через singbox-helper, подтянет sing-box-go как зависимость) ===&lt;br /&gt;
echo &#039;src/gz singbox-helper https://wolfram0108.github.io/sing-box-helper/mipsel-3.4&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install singbox-helper curl nano wget-ssl&lt;br /&gt;
# UI: http://&amp;lt;LAN-IP&amp;gt;:8765 → вставить URI узла → Применить&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Скрипт пересоздания /var/empty при загрузке ==&lt;br /&gt;
Каталог &amp;lt;code&amp;gt;/var&amp;lt;/code&amp;gt; на роутере — это tmpfs (RAM-диск), он очищается при каждой загрузке. Создадим стартовый скрипт, который воссоздаёт &amp;lt;code&amp;gt;/var/empty&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/init.d/S39sshd-prep &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
chown root:root /var/empty&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.8. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.9. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.10. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=979</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=979"/>
		<updated>2026-05-12T10:14:47Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|Универсальный туннельный движок. Поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный сетевой интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который можно завернуть выборочный трафик.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                          KEENETIC РОУТЕР&lt;br /&gt;
&lt;br /&gt;
  ┌──────────────────────────────────────────────────────────────┐&lt;br /&gt;
  │                                                              │&lt;br /&gt;
  │  ┌────────────────┐                                          │&lt;br /&gt;
  │  │   keen-pbr     │  --- адрес домена в списке? ---          │&lt;br /&gt;
  │  │   (по доменам) │            │           │                 │&lt;br /&gt;
  │  └────────────────┘            │ ДА        │ НЕТ             │&lt;br /&gt;
  │                                ▼           ▼                 │&lt;br /&gt;
  │                       ┌────────────┐  ┌────────────┐         │&lt;br /&gt;
  │                       │  singtun   │  │   nfqws2   │         │&lt;br /&gt;
  │                       │ (sing-box) │  │  DPI fix   │         │&lt;br /&gt;
  │                       └────────────┘  └────────────┘         │&lt;br /&gt;
  │                            │                │                │&lt;br /&gt;
  └────────────────────────────┼────────────────┼────────────────┘&lt;br /&gt;
                               │                │&lt;br /&gt;
                          ┌────▼────┐      ┌────▼────┐&lt;br /&gt;
                          │  VPN-   │      │  Прямой │&lt;br /&gt;
                          │  сервер │      │  WAN    │&lt;br /&gt;
                          └─────────┘      └─────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&#039;&#039;(Здесь схему можно перерисовать в Mermaid или Excalidraw и заменить блок.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Подготовка USB-накопителя ==&lt;br /&gt;
=== Подключение и форматирование ===&lt;br /&gt;
# Воткните флешку в USB-порт роутера.&lt;br /&gt;
# Откройте веб-интерфейс Keenetic: &#039;&#039;&#039;Приложения&#039;&#039;&#039; → &#039;&#039;&#039;USB-диски и принтеры&#039;&#039;&#039;.&lt;br /&gt;
# В списке появится диск. Откройте его параметры.&lt;br /&gt;
# Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; и выберите &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;USB-диски&amp;quot; в веб-интерфейсе Keenetic с подключённым диском и кнопкой &amp;quot;Форматировать&amp;quot;.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Узнайте UUID диска через CLI ===&lt;br /&gt;
У диска есть уникальный &#039;&#039;&#039;UUID&#039;&#039;&#039; (длинная строка вида &amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;), который понадобится для установки Entware. Веб-интерфейс Keenetic показывает UUID на странице диска, &#039;&#039;&#039;но не позволяет его выделить и скопировать&#039;&#039;&#039; — поэтому удобнее получить его через встроенную командную строку.&lt;br /&gt;
&lt;br /&gt;
# Откройте в браузере адрес &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; — это встроенный веб-CLI Keenetic. Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Выполните команду:&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;show media&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# В ответе найдите блок с вашей флешкой и строку &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt;. Пример вывода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;media&amp;quot;: {&lt;br /&gt;
        &amp;quot;Media0&amp;quot;: {&lt;br /&gt;
            &amp;quot;bus&amp;quot;: &amp;quot;usb&amp;quot;,&lt;br /&gt;
            &amp;quot;manufacturer&amp;quot;: &amp;quot;SanDisk&amp;quot;,&lt;br /&gt;
            &amp;quot;product&amp;quot;: &amp;quot;Ultra&amp;quot;,&lt;br /&gt;
            &amp;quot;state&amp;quot;: &amp;quot;ACTIVE&amp;quot;,&lt;br /&gt;
            &amp;quot;partition&amp;quot;: [&lt;br /&gt;
                {&lt;br /&gt;
                    &amp;quot;uuid&amp;quot;: &amp;quot;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;quot;,&lt;br /&gt;
                    &amp;quot;fstype&amp;quot;: &amp;quot;ext4&amp;quot;,&lt;br /&gt;
                    &amp;quot;state&amp;quot;: &amp;quot;MOUNTED&amp;quot;,&lt;br /&gt;
                    ...&lt;br /&gt;
                }&lt;br /&gt;
            ]&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скопируйте значение поля &amp;lt;code&amp;gt;uuid&amp;lt;/code&amp;gt; внутри &amp;lt;code&amp;gt;partition&amp;lt;/code&amp;gt; — оно понадобится в следующем шаге.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — пока вы в CLI, можно сразу включить DNS Override.&#039;&#039;&#039; Эта опция понадобится позже для keen-pbr — она заставляет KeeneticOS отдавать DNS-трафик в Entware-овский dnsmasq. Чтобы не возвращаться в CLI отдельно, выполните прямо сейчас:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Опция применится после ближайшей перезагрузки роутера (она будет в конце Этапа 1).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Компоненты KeeneticOS ==&lt;br /&gt;
=== Какая у вас прошивка? ===&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужно ли вам что-то включать на этом этапе:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (роутер, который продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, все нужные пакеты уже включены в образ прошивки этого порта — переходите к разделу 1.3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — как понять, какая у вас прошивка:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; (главная страница веб-интерфейса) видна модель устройства. Если рядом с моделью стоит знакомое маркетинговое имя Keenetic (например, &amp;quot;Keenetic Hero&amp;quot;) и модель начинается с &amp;quot;KN-&amp;quot; — это оригинальный Keenetic. Если вы видите название роутера другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) и при этом отображается KeeneticOS — у вас порт сообщества.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Признак порта сообщества:&#039;&#039;&#039; На странице с компонентами окно &amp;quot;Компоненты операционной системы&amp;quot; может показывать сообщение &amp;quot;Не удалось получить список компонентов от сервера&amp;quot; — это нормально для портированных сборок, у которых нет своего сервера обновлений. В этом случае шаг с компонентами &#039;&#039;&#039;не нужен&#039;&#039;&#039; — переходите к разделу 1.3.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Только для оригинального Keenetic ===&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в более старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент (точное название в UI)&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|Базовая инфраструктура Entware — без этого нельзя ставить пакеты на USB&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Чтобы роутер мог монтировать ext4-диск&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Доступ к командной строке роутера&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Кроме того, &#039;&#039;&#039;желательно&#039;&#039;&#039; проверить наличие следующих компонентов (точные названия в интерфейсе могут отличаться от версии к версии — ищите по словам):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Что искать в списке&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|Базовые модули iptables для работы фаервола Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Дополнительные модули (xt_set, xt_multiport, conntrack-extra) — &#039;&#039;&#039;критично&#039;&#039;&#039; для работы keen-pbr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
После выбора нажмите &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и подождите 2–5 минут. Роутер перезагрузится самостоятельно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Обновления и компоненты&amp;quot; с открытым окном &amp;quot;Показать компоненты&amp;quot; и отмеченными нужными пунктами.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В KeeneticOS 5 и новее компонент &#039;&#039;&#039;Протокол IPv6&#039;&#039;&#039; включён по умолчанию и не может быть отключён — это нормально.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Установка Entware через командную строку ==&lt;br /&gt;
=== Открытие командной строки роутера ===&lt;br /&gt;
Если вы вышли из CLI после шага 1.1 — откройте снова: &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt;. Должно появиться приглашение &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Запуск установки Entware ===&lt;br /&gt;
Команда состоит из &#039;&#039;&#039;двух частей, которые вы должны подставить сами&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;UUID вашего USB-диска&#039;&#039;&#039; — тот, который вы получили командой &amp;lt;code&amp;gt;show media&amp;lt;/code&amp;gt; в разделе &#039;&#039;&#039;1.1&#039;&#039;&#039; (длинная строка вида &amp;lt;code&amp;gt;d5f39712-7ae1-...&amp;lt;/code&amp;gt;).&lt;br /&gt;
# &#039;&#039;&#039;URL установщика&#039;&#039;&#039; — выбирается по архитектуре вашего роутера (см. таблицу ниже).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — не копируйте команду как есть!&#039;&#039;&#039; В шаблоне ниже фигурные скобки &amp;lt;code&amp;gt;&amp;lt;...&amp;gt;&amp;lt;/code&amp;gt; — это места, куда нужно подставить &#039;&#039;&#039;ваши&#039;&#039;&#039; значения. Если оставить шаблон с угловыми скобками или скопировать чужой UUID — установка не сработает.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Шаблон команды ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выбор URL установщика ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (целиком)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство моделей Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — как узнать архитектуру:&#039;&#039;&#039; Откройте &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; в веб-интерфейсе → видно модель устройства и процессор. Для большинства бытовых моделей это MIPS — берите верхнюю строку таблицы. Если сомневаетесь — пишите команду с &amp;lt;code&amp;gt;mipsel&amp;lt;/code&amp;gt;: если архитектура не подходит, установка скажет об этом ошибкой, и вы не сломаете роутер.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Пример с подставленными значениями ====&lt;br /&gt;
Допустим, ваш UUID — &amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;, архитектура — mipsel. Тогда команда полностью выглядит так:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Это &#039;&#039;&#039;пример&#039;&#039;&#039; — UUID &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; здесь приведён только для иллюстрации. У &#039;&#039;&#039;вашего&#039;&#039;&#039; диска UUID будет &#039;&#039;&#039;другой&#039;&#039;&#039;. Подставьте именно свой со страницы &amp;quot;Диски и принтеры&amp;quot;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Проверочный чек-лист перед нажатием Enter ====&lt;br /&gt;
* Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — &#039;&#039;&#039;обязательны&#039;&#039;&#039;.&lt;br /&gt;
* URL — &#039;&#039;&#039;одной строкой&#039;&#039;&#039;, без пробелов и переносов.&lt;br /&gt;
* После UUID и перед URL — &#039;&#039;&#039;ровно один пробел&#039;&#039;&#039;.&lt;br /&gt;
* Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде &#039;&#039;&#039;не должно остаться&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Сохранение конфигурации и перезагрузка ===&lt;br /&gt;
После того как установка прошла без ошибок, сохраните конфигурацию и перезагрузите роутер:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перезагрузка нужна, чтобы применился &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt;, который вы включили на шаге 1.1. Ожидайте 1–2 минуты, пока роутер поднимется обратно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — если установщик &amp;quot;молчит&amp;quot;:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; не работает, если OPKG-диск уже был назначен раньше. Если в логе вы не видите строк про загрузку &amp;lt;code&amp;gt;mipsel-installer.tar.gz&amp;lt;/code&amp;gt; — сбросьте диск и повторите:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Проверка установки ===&lt;br /&gt;
Откройте журнал: &#039;&#039;&#039;Диагностика&#039;&#039;&#039; → &#039;&#039;&#039;Системный журнал&#039;&#039;&#039;. Должны появиться строки примерно такого содержания:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Opkg::Manager: downloading installer...&lt;br /&gt;
Opkg::Manager: extracting to /opt...&lt;br /&gt;
Opkg::Manager: ...&lt;br /&gt;
Entware installed.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения установки на роутере поднимется встроенный SSH-сервер Entware на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Первое подключение по SSH ==&lt;br /&gt;
Подключитесь к роутеру с компьютера. На Windows — через PuTTY или через стандартный &amp;lt;code&amp;gt;ssh.exe&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; (LAN-адрес роутера)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Из PowerShell это одна строка:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При первом подключении ssh попросит подтвердить fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа смените пароль:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Введите новый пароль дважды.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Дефолтный пароль &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем — если SSH будет проброшен наружу, роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Хотите заходить по ключу, без ввода пароля?&#039;&#039;&#039; См. &#039;&#039;&#039;[[#Приложение А. OpenSSH с ключом (опционально)|Приложение А]]&#039;&#039;&#039; в конце этого документа. Для базовой установки sing-box / keen-pbr / nfqws2 это &#039;&#039;&#039;не нужно&#039;&#039;&#039; — переходите к Этапу 2.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box =&lt;br /&gt;
sing-box — это движок туннеля. Он умеет «слушать» виртуальный TUN-интерфейс и пересылать всё, что туда прилетит, через выбранный протокол (VLESS, Hysteria2, и др.) на удалённый сервер.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Установка пакета ==&lt;br /&gt;
Подключитесь к роутеру по SSH и выполните:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install sing-box-go curl nano wget-ssl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Пакет &amp;lt;code&amp;gt;sing-box-go&amp;lt;/code&amp;gt; занимает &#039;&#039;&#039;около 62 МБ&#039;&#039;&#039; в распакованном виде. Установка во встроенную память роутера (без USB) почти всегда невозможна — поэтому Entware должен быть на USB.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sing-box version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый вывод:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sing-box version 1.13.3&lt;br /&gt;
&lt;br /&gt;
Environment: go1.26.1 linux/mipsle&lt;br /&gt;
Tags: ... with_quic ... with_clash_api ... with_gvisor ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Обратите внимание на флаги в выводе. &amp;lt;code&amp;gt;with_quic&amp;lt;/code&amp;gt; означает поддержку Hysteria/Hysteria2/TUIC. &amp;lt;code&amp;gt;with_clash_api&amp;lt;/code&amp;gt; — встроенный API для подключения веб-дашбордов. Если этих флагов нет — версия урезана, нужна другая сборка.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Создание конфига ==&lt;br /&gt;
sing-box читает конфиг из &amp;lt;code&amp;gt;/opt/etc/sing-box/config.json&amp;lt;/code&amp;gt;. Заводской пример нам не подойдёт — там настроен серверный режим Shadowsocks. Создадим клиентский конфиг.&lt;br /&gt;
&lt;br /&gt;
=== Пример: Hysteria2-узел в туннеле ===&lt;br /&gt;
Предположим, ваш провайдер выдал ссылку вида:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hysteria2://ПАРОЛЬ@ВАШ_СЕРВЕР:ПОРТ&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Запишите рабочий конфиг:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/sing-box/config.json &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;log&amp;quot;: { &amp;quot;level&amp;quot;: &amp;quot;info&amp;quot;, &amp;quot;timestamp&amp;quot;: true },&lt;br /&gt;
  &amp;quot;dns&amp;quot;: {&lt;br /&gt;
    &amp;quot;servers&amp;quot;: [&lt;br /&gt;
      { &amp;quot;type&amp;quot;: &amp;quot;udp&amp;quot;, &amp;quot;tag&amp;quot;: &amp;quot;dns-direct&amp;quot;, &amp;quot;server&amp;quot;: &amp;quot;1.1.1.1&amp;quot; }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;strategy&amp;quot;: &amp;quot;ipv4_only&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;inbounds&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;tun&amp;quot;,&lt;br /&gt;
      &amp;quot;tag&amp;quot;: &amp;quot;tun-in&amp;quot;,&lt;br /&gt;
      &amp;quot;interface_name&amp;quot;: &amp;quot;singtun&amp;quot;,&lt;br /&gt;
      &amp;quot;address&amp;quot;: [&amp;quot;198.18.0.1/30&amp;quot;],&lt;br /&gt;
      &amp;quot;mtu&amp;quot;: 1500,&lt;br /&gt;
      &amp;quot;auto_route&amp;quot;: false,&lt;br /&gt;
      &amp;quot;strict_route&amp;quot;: false,&lt;br /&gt;
      &amp;quot;stack&amp;quot;: &amp;quot;gvisor&amp;quot;,&lt;br /&gt;
      &amp;quot;sniff&amp;quot;: true&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;mixed&amp;quot;,&lt;br /&gt;
      &amp;quot;tag&amp;quot;: &amp;quot;test-proxy&amp;quot;,&lt;br /&gt;
      &amp;quot;listen&amp;quot;: &amp;quot;192.168.10.1&amp;quot;,&lt;br /&gt;
      &amp;quot;listen_port&amp;quot;: 7891&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;outbounds&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;hysteria2&amp;quot;,&lt;br /&gt;
      &amp;quot;tag&amp;quot;: &amp;quot;hy2&amp;quot;,&lt;br /&gt;
      &amp;quot;server&amp;quot;: &amp;quot;ВАШ_СЕРВЕР&amp;quot;,&lt;br /&gt;
      &amp;quot;server_port&amp;quot;: ПОРТ,&lt;br /&gt;
      &amp;quot;password&amp;quot;: &amp;quot;ПАРОЛЬ&amp;quot;,&lt;br /&gt;
      &amp;quot;tls&amp;quot;: {&lt;br /&gt;
        &amp;quot;enabled&amp;quot;: true,&lt;br /&gt;
        &amp;quot;server_name&amp;quot;: &amp;quot;ВАШ_СЕРВЕР&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    },&lt;br /&gt;
    { &amp;quot;type&amp;quot;: &amp;quot;direct&amp;quot;, &amp;quot;tag&amp;quot;: &amp;quot;direct&amp;quot; }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;route&amp;quot;: {&lt;br /&gt;
    &amp;quot;final&amp;quot;: &amp;quot;hy2&amp;quot;,&lt;br /&gt;
    &amp;quot;rules&amp;quot;: [&lt;br /&gt;
      { &amp;quot;action&amp;quot;: &amp;quot;sniff&amp;quot; },&lt;br /&gt;
      { &amp;quot;protocol&amp;quot;: &amp;quot;dns&amp;quot;, &amp;quot;action&amp;quot;: &amp;quot;hijack-dns&amp;quot; }&lt;br /&gt;
    ]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;experimental&amp;quot;: {&lt;br /&gt;
    &amp;quot;clash_api&amp;quot;: {&lt;br /&gt;
      &amp;quot;external_controller&amp;quot;: &amp;quot;0.0.0.0:9090&amp;quot;,&lt;br /&gt;
      &amp;quot;external_ui&amp;quot;: &amp;quot;/opt/share/dashboard&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Замените &amp;lt;code&amp;gt;ВАШ_СЕРВЕР&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ПОРТ&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ПАРОЛЬ&amp;lt;/code&amp;gt; на реальные значения.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — про подсеть TUN:&#039;&#039;&#039; Значение &amp;lt;code&amp;gt;&amp;quot;address&amp;quot;: [&amp;quot;198.18.0.1/30&amp;quot;]&amp;lt;/code&amp;gt; — это подсеть TUN-интерфейса (внутренний адрес виртуального сетевого устройства). Диапазон &amp;lt;code&amp;gt;198.18.0.0/15&amp;lt;/code&amp;gt; зарезервирован RFC 2544 и не используется в реальном интернете — он не конфликтует ни с вашей LAN, ни с публичными адресами.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — про IP роутера:&#039;&#039;&#039; В строке &amp;lt;code&amp;gt;&amp;quot;listen&amp;quot;: &amp;quot;192.168.10.1&amp;quot;&amp;lt;/code&amp;gt; подставьте &#039;&#039;&#039;LAN-адрес вашего роутера&#039;&#039;&#039; (увидеть его можно в веб-интерфейсе Keenetic в карточке &amp;quot;Домашняя сеть&amp;quot;). Этот mixed-inbound — служебный, мы используем его для тестов; для боевой работы он не нужен, но не мешает.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что делает каждая секция ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Секция&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;log&amp;lt;/code&amp;gt;&lt;br /&gt;
|Уровень логирования. &amp;lt;code&amp;gt;info&amp;lt;/code&amp;gt; достаточно; для отладки можно поставить &amp;lt;code&amp;gt;debug&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;dns&amp;lt;/code&amp;gt;&lt;br /&gt;
|Какие DNS-серверы использует сам sing-box для резолва имён узлов (например, сервера Hysteria2).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;inbounds → tun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается трафик. Этот интерфейс будет использовать &amp;lt;code&amp;gt;keen-pbr&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;inbounds → mixed&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный HTTP/SOCKS5-прокси на порту &amp;lt;code&amp;gt;7891&amp;lt;/code&amp;gt;. Удобен для проверки туннеля.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;outbounds → hysteria2&amp;lt;/code&amp;gt;&lt;br /&gt;
|Описание узла на удалённой стороне — куда идёт инкапсулированный трафик.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;outbounds → direct&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;quot;Прямой&amp;quot; выход — используется для трафика, который не нужно туннелировать.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;route.final = hy2&amp;lt;/code&amp;gt;&lt;br /&gt;
|По умолчанию весь трафик, попавший в sing-box, отправляется через outbound с тегом &amp;lt;code&amp;gt;hy2&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;experimental.clash_api&amp;lt;/code&amp;gt;&lt;br /&gt;
|REST API на порту &amp;lt;code&amp;gt;9090&amp;lt;/code&amp;gt;. Через него к sing-box подключаются дашборды (Yacd, Zashboard, metacubexd).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Проверка конфига ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sing-box check -c /opt/etc/sing-box/config.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если конфиг корректен — команда отработает молча. Если ошибка — sing-box подскажет, какая.&lt;br /&gt;
&lt;br /&gt;
== 2.3. Запуск ==&lt;br /&gt;
Запустить через init-скрипт Entware:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S99sing-box start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В норме скрипт автоматически прописывает sing-box в автозагрузку — после перезагрузки роутера он стартует сам.&lt;br /&gt;
&lt;br /&gt;
=== Проверка процесса и интерфейса ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Процесс&lt;br /&gt;
pgrep -af sing-box&lt;br /&gt;
&lt;br /&gt;
# Создался ли TUN-интерфейс&lt;br /&gt;
awk &#039;/:/{print $1}&#039; /proc/net/dev | grep singtun&lt;br /&gt;
&lt;br /&gt;
# Порты, которые слушает&lt;br /&gt;
netstat -tlnup | grep sing-box&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемые результаты:&#039;&#039;&#039;&lt;br /&gt;
* Процесс &amp;lt;code&amp;gt;sing-box run -C /opt/etc/sing-box&amp;lt;/code&amp;gt; существует.&lt;br /&gt;
* Интерфейс &amp;lt;code&amp;gt;singtun:&amp;lt;/code&amp;gt; есть в списке.&lt;br /&gt;
* Слушаются как минимум: &amp;lt;code&amp;gt;0.0.0.0:7891&amp;lt;/code&amp;gt; (mixed proxy), &amp;lt;code&amp;gt;0.0.0.0:9090&amp;lt;/code&amp;gt; (clash-api).&lt;br /&gt;
&lt;br /&gt;
== 2.4. Проверка туннеля ==&lt;br /&gt;
Сделайте запрос через локальный mixed-proxy и сравните с прямым:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Прямой запрос (через ваш WAN)&lt;br /&gt;
curl -sS https://api.ipify.org&lt;br /&gt;
echo&lt;br /&gt;
&lt;br /&gt;
# Тот же запрос, но через туннель&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
echo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039; два разных IP — первый ваш домашний, второй — IP туннеля.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают или второй запрос не отвечает — туннель не работает. Проверьте логи sing-box и параметры конфига.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория и установка ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG и установите пакет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt; (выбрать OS = &#039;&#039;&#039;Keenetic / NetCraze&#039;&#039;&#039;, version = &#039;&#039;&#039;current&#039;&#039;&#039;, архитектуру — свою). Узнать архитектуру роутера можно командой &amp;lt;code&amp;gt;opkg print-architecture&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
=== Интерактивный диалог при установке ===&lt;br /&gt;
В процессе установки появится вопрос:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring keen-pbr.&lt;br /&gt;
keen-pbr installation&lt;br /&gt;
------------------------&lt;br /&gt;
Tip: set KEEN_PBR_REPLACE_DNSMASQ_DEFAULTS=Y or N to automate keen-pbr installation.&lt;br /&gt;
Replace /opt/etc/dnsmasq.conf with recommended keen-pbr dnsmasq defaults? [y/n]:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ответьте &#039;&#039;&#039;&amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; и нажмите Enter. Это критически важно — keen-pbr заменит дефолтный &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на свой шаблон, который позволяет keen-pbr динамически наполнять ipset-списки доменами. Без этого ничего работать не будет.&lt;br /&gt;
&lt;br /&gt;
Ожидаемый ответ после ввода &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Backing up existing /opt/etc/dnsmasq.conf to /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
Installing recommended keen-pbr dnsmasq base config to /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
keen-pbr: Disabling HW NAT...&lt;br /&gt;
net.netfilter.nf_conntrack_fastnat = 0&lt;br /&gt;
[local_list] Skipped (no URL)&lt;br /&gt;
 Starting keen-pbr...              done.&lt;br /&gt;
&lt;br /&gt;
Installation complete!&lt;br /&gt;
Config path: /opt/etc/keen-pbr/config.json&lt;br /&gt;
Web API: http://my.keenetic.net:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого к Keenetic:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.1.1:12121&amp;lt;/code&amp;gt;, или &amp;lt;code&amp;gt;http://my.keenetic.net:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 3.3. Базовая настройка через веб-интерфейс ==&lt;br /&gt;
Все пять шагов ниже делаются в UI keen-pbr. После них трафик пойдёт в туннель и DNS будет давать реальные IP, а не подменённые.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить outbound&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;Исправен&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Outbounds (выходы)&amp;quot; с тремя строками: wan, block, vpn.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить список&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Имя&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Тип&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Домены&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Источник&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка с textarea)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;+ Добавить правило маршрутизации&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (созданный на шаге 1)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Убрать встроенный keenetic_dns ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;DNS-серверы&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
В таблице вы увидите две строки: &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Удалите &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt;&#039;&#039;&#039; (иконка корзины в столбце «Действия»).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем это нужно:&#039;&#039;&#039; Сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; идёт через встроенный DNS-резолвер прошивки KeeneticOS. На некоторых конфигурациях (включённые «защитные» сервисы, community-порты) этот резолвер подменяет ответы для конкретных доменов на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;. Эти fake-IP попадают в ipset keen-pbr → маршрутизация формально срабатывает → но трафик улетает на несуществующий адрес и клиент получает таймаут.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Назначить основной DNS-сервер ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;DNS-правила&#039;&#039;&#039; → блок &#039;&#039;&#039;«Основные DNS сервера»&#039;&#039;&#039; (вверху страницы).&lt;br /&gt;
&lt;br /&gt;
Нажмите &#039;&#039;&#039;+ Добавить основной DNS сервер&#039;&#039;&#039; и выберите из списка &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Что это такое:&#039;&#039;&#039; «Основные DNS сервера» — это fallback dnsmasq, то есть сервер, который используется, когда ни одно DNS-правило не подходит. После удаления &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; на шаге 4 он стал пустым — назначаем &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; (9.9.9.9), чтобы все запросы шли на публичный DNS, а не на DNS прошивки.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Применить изменения ===&lt;br /&gt;
В правом нижнем углу горит оранжевый баннер &#039;&#039;&#039;«Несохранённые изменения»&#039;&#039;&#039;. Нажмите &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; — keen-pbr перестроит конфигурацию dnsmasq и применит правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Правила маршрутизации&amp;quot; с активным правилом #2 bypass → vpn.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== 3.4. Скрипт правил NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Зачем нужен этот шаг:&#039;&#039;&#039; keen-pbr настраивает маркировку пакетов, ip-rule и таблицу маршрутизации, но &#039;&#039;&#039;не трогает&#039;&#039;&#039; таблицы NAT и FORWARD. Для интерфейсов, которые KeeneticOS знает (например, штатный WireGuard &amp;lt;code&amp;gt;nwg0&amp;lt;/code&amp;gt;), правила NAT/FORWARD добавляет сам ndm. Но &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt; от sing-box — userspace-интерфейс, ndm о нём не знает. Без MASQUERADE и FORWARD ACCEPT трафик клиентов LAN до туннеля не доходит. Создадим один маленький скрипт, который добавляет эти правила автоматически.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключитесь по SSH к роутеру и выполните одну команду: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
ls -la /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя строка покажет файл — должно быть &amp;lt;code&amp;gt;-rwxr-xr-x ... 40-singtun-nat.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Почему именно &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt; ===&lt;br /&gt;
KeeneticOS-овский ndm периодически перестраивает таблицы iptables «с нуля» (при изменении сети, новых клиентах, реконфигурации). Всё, что добавлено обычным &amp;lt;code&amp;gt;init.d&amp;lt;/code&amp;gt;-скриптом, при этом стирается. А скрипты в &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; ndm &#039;&#039;&#039;сам дёргает&#039;&#039;&#039; после каждого перестроения. Так что наш хук переживает любые события сети без вмешательства пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Переменные в скрипте ===&lt;br /&gt;
В скрипте всего два места, которые &#039;&#039;&#039;теоретически&#039;&#039;&#039; могут отличаться у разных пользователей:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Переменная&lt;br /&gt;
!Значение по умолчанию&lt;br /&gt;
!Что подставить, если у вас иначе&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;TUN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|То имя, которое вы прописали в поле &amp;lt;code&amp;gt;interface_name&amp;lt;/code&amp;gt; своего &amp;lt;code&amp;gt;sing-box/config.json&amp;lt;/code&amp;gt; (Этап 2.2). В этом гайде — &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, и менять не нужно.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя LAN-bridge KeeneticOS. &#039;&#039;&#039;На всех Keenetic-роутерах&#039;&#039;&#039; (включая community-порты на Xiaomi/TP-Link/Mercusys) это &amp;lt;code&amp;gt;br0&amp;lt;/code&amp;gt;. Проверить: &amp;lt;code&amp;gt;ip link show \| grep &amp;quot;state UP&amp;quot;&amp;lt;/code&amp;gt; на роутере или раздел &amp;quot;Домашняя сеть&amp;quot; в веб-UI Keenetic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Архитектура (mipsel/aarch64) на этот скрипт &#039;&#039;&#039;не влияет&#039;&#039;&#039; — пути &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;/opt/sbin/iptables&amp;lt;/code&amp;gt; одинаковы для всех Entware-сборок.&lt;br /&gt;
&lt;br /&gt;
== 3.5. Тестирование ==&lt;br /&gt;
На клиентском устройстве, подключённом к Keenetic:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Очистите кеш DNS&#039;&#039;&#039; (важно — без этого старые ответы остаются):&lt;br /&gt;
#* Windows: &amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; в PowerShell.&lt;br /&gt;
#* Android / iOS: переподключиться к Wi-Fi (off → on).&lt;br /&gt;
#* macOS: &amp;lt;code&amp;gt;sudo dscacheutil -flushcache&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Перезапустите браузер (у него свой DNS-кеш).&lt;br /&gt;
# Откройте сайт из списка bypass.&lt;br /&gt;
# Параллельно откройте &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; в браузере. Адрес должен быть тот же, который вы видели в проверке туннеля sing-box (т.е. IP вашего VPN-провайдера, а не домашний WAN-IP).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница api.ipify.org с подменённым IP.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Установка ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.2. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Замечание про «failed» в конце установки:&#039;&#039;&#039; В выводе установщика вы можете увидеть строку:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Starting /opt/sbin/lighttpd...              failed.&lt;br /&gt;
NFQWS2 Web Interface installed: http://192.168.10.1:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Это &#039;&#039;&#039;не ошибка&#039;&#039;&#039;. lighttpd пытается стартануть до того, как все его модули (php8-mod-curl, php8-mod-session, mod-rewrite, mod-redirect) полностью зарегистрировались. Через несколько секунд стартовый скрипт &amp;lt;code&amp;gt;S80lighttpd&amp;lt;/code&amp;gt; успешно поднимает сервис. Достаточно проверить:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pgrep -af lighttpd&lt;br /&gt;
netstat -tlnup | grep :90&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Оба должны показать запущенный процесс на порту 90. Если веб-интерфейс открывается на &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt; — всё в порядке.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, &amp;lt;code&amp;gt;http://192.168.10.1:90&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для доступа из другой подсети — открыть порт &amp;lt;code&amp;gt;90&amp;lt;/code&amp;gt; в фаерволе Keenetic (по аналогии с keen-pbr WebUI).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;dnsmasq&#039;&#039;&#039;&lt;br /&gt;
|UDP/TCP :53 на LAN-адресе роутера&lt;br /&gt;
|Принимает DNS-запросы от LAN и наполняет ipset keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                  K E E N E T I C   Р О У Т Е Р&lt;br /&gt;
   ┌───────────────────────────────────────────────────────────────────────────┐&lt;br /&gt;
   │                                                                           │&lt;br /&gt;
   │   ┌──────────────┐                                                        │&lt;br /&gt;
LAN│   │  DNS-запрос  │                                                        │&lt;br /&gt;
───┼──►│  от клиента  │                                                        │&lt;br /&gt;
   │   └──────┬───────┘                                                        │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │          ▼                                                                │&lt;br /&gt;
   │   ┌──────────────┐  upstream  ┌────────────────┐                          │&lt;br /&gt;
   │   │  keen-pbr    │  через     │  Quad9 9.9.9.9 │                          │&lt;br /&gt;
   │   │  dnsmasq     │ ─────────► │                │                          │&lt;br /&gt;
   │   │  на :53      │            │                │                          │&lt;br /&gt;
   │   └──────┬───────┘            └────────────────┘                          │&lt;br /&gt;
   │          │ IP → ipset                                                     │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │   ┌──────▼──────────────────────────────────────────────┐                 │&lt;br /&gt;
LAN│   │  iptables / маршрутизация                           │                 │&lt;br /&gt;
───┼──►│  ├ если dst-IP в ipset bypass:                      │                 │&lt;br /&gt;
TCP│   │  │   fwmark → ip rule → table 151 → singtun         │                 │&lt;br /&gt;
   │   │  │                                                  │                 │&lt;br /&gt;
   │   │  └ иначе:                                           │                 │&lt;br /&gt;
   │   │      обычный WAN-маршрут                            │                 │&lt;br /&gt;
   │   │      └ nfqws2 ловит первые пакеты                   │                 │&lt;br /&gt;
   │   │        и модифицирует для обхода DPI                │                 │&lt;br /&gt;
   │   └────┬──────────────────────────────────────────┬─────┘                 │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          ▼                       │&lt;br /&gt;
   │   ┌─────────┐                            ┌────────────────┐               │&lt;br /&gt;
   │   │ singtun │                            │ WAN-интерфейс  │               │&lt;br /&gt;
   │   │ (TUN)   │                            │ (ваш провайдер)│               │&lt;br /&gt;
   │   └────┬────┘                            └────────┬───────┘               │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          │                       │&lt;br /&gt;
   │   ┌─────────────┐                                 │                       │&lt;br /&gt;
   │   │  sing-box   │                                 │                       │&lt;br /&gt;
   │   │  outbound:  │                                 │                       │&lt;br /&gt;
   │   │  hysteria2  │                                 │                       │&lt;br /&gt;
   │   └──────┬──────┘                                 │                       │&lt;br /&gt;
   │          │                                        │                       │&lt;br /&gt;
   └──────────┼────────────────────────────────────────┼───────────────────────┘&lt;br /&gt;
              │                                        │&lt;br /&gt;
              ▼                                        ▼&lt;br /&gt;
        ┌───────────┐                            ┌───────────┐&lt;br /&gt;
        │ VPN-узел  │                            │ Любой     │&lt;br /&gt;
        │ провайдера│                            │ интернет  │&lt;br /&gt;
        └───────────┘                            └───────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Здесь можно перерисовать в Mermaid/Excalidraw для финальной картинки.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После обновления может потребоваться перезапуск сервисов или роутера.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|&amp;lt;code&amp;gt;logread \| grep keen-pbr&amp;lt;/code&amp;gt; + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S99sing-box status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr status&lt;br /&gt;
/opt/etc/init.d/S56dnsmasq status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
keen-pbr --config /opt/etc/keen-pbr/config.json status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В выводе должно быть &#039;&#039;&#039;&amp;lt;code&amp;gt;Overall: OK&amp;lt;/code&amp;gt;&#039;&#039;&#039;, а у outbound &amp;lt;code&amp;gt;vpn [interface] iface=singtun&amp;lt;/code&amp;gt; — все строки со статусом &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оба должны вернуть IP вашего VPN-узла.&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Должен вернуться реальный публичный IP (НЕ из 198.18.x.x)&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# Self-test keen-pbr — должен вернуть 127.0.0.88&lt;br /&gt;
nslookup check.keen.pbr 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список (должны быть реальные публичные)&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица для помеченного трафика&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&lt;br /&gt;
# NAT и FORWARD для singtun (наш хук)&lt;br /&gt;
iptables -t nat -S POSTROUTING | grep singtun&lt;br /&gt;
iptables -S FORWARD | grep singtun&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;: &amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы — сервер &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; не удалён в UI keen-pbr&lt;br /&gt;
|Проверьте Шаги 4 и 5 раздела &#039;&#039;&#039;3.3&#039;&#039;&#039; — должен быть удалён &amp;lt;code&amp;gt;keenetic_dns&amp;lt;/code&amp;gt; и добавлен &amp;lt;code&amp;gt;quad9&amp;lt;/code&amp;gt; в &amp;quot;Основные DNS сервера&amp;quot;. После — &#039;&#039;&#039;Применить и перезапустить&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr (вы ответили &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на вопрос при установке)&lt;br /&gt;
|Восстановить шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf &amp;amp;&amp;amp; /opt/etc/init.d/S56dnsmasq restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут с клиента)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun (хук не создан или не выполняется)&lt;br /&gt;
|Проверить &amp;lt;code&amp;gt;ls /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;. Если нет — пересоздать (раздел &#039;&#039;&#039;3.4&#039;&#039;&#039;). Если есть — выполнить вручную: &amp;lt;code&amp;gt;/opt/etc/ndm/netfilter.d/40-singtun-nat.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|После установки nfqws-keenetic-web видна строка &amp;quot;Starting lighttpd... failed&amp;quot;&lt;br /&gt;
|Не ошибка — lighttpd стартует до полной регистрации модулей и поднимается на следующей попытке&lt;br /&gt;
|Проверить, что lighttpd сейчас запущен: &amp;lt;code&amp;gt;pgrep -af lighttpd&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;netstat -tlnup \| grep :90&amp;lt;/code&amp;gt;. Если процесс есть и порт слушается — всё в порядке.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (в командной строке Keenetic /a) ===&lt;br /&gt;
show media                                                # узнать UUID&lt;br /&gt;
opkg dns-override                                          # сразу включаем DNS-override&lt;br /&gt;
system configuration save&lt;br /&gt;
opkg disk ВАШ_UUID_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
system reboot&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 (пароль keenetic) ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box ===&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install sing-box-go curl nano wget-ssl&lt;br /&gt;
# Поместить рабочий config.json в /opt/etc/sing-box/ (см. Этап 2.2)&lt;br /&gt;
sing-box check -c /opt/etc/sing-box/config.json&lt;br /&gt;
/opt/etc/init.d/S99sing-box start&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr                                      # на вопрос про dnsmasq.conf — ответить y&lt;br /&gt;
&lt;br /&gt;
# Дальше — UI на http://my.keenetic.net:12121:&lt;br /&gt;
#   * Outbounds: создать vpn (type=Interface, interface=singtun)&lt;br /&gt;
#   * Списки: создать bypass с доменами&lt;br /&gt;
#   * Правила маршрутизации: bypass → vpn&lt;br /&gt;
#   * DNS-серверы: удалить keenetic_dns&lt;br /&gt;
#   * DNS-правила → Основные DNS сервера: добавить quad9&lt;br /&gt;
#   * Применить и перезапустить&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD для singtun:&lt;br /&gt;
cat &amp;gt; /opt/etc/ndm/netfilter.d/40-singtun-nat.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/opt/bin/sh&lt;br /&gt;
[ &amp;quot;$table&amp;quot; = &amp;quot;nat&amp;quot; ] || [ &amp;quot;$table&amp;quot; = &amp;quot;filter&amp;quot; ] || [ -z &amp;quot;$table&amp;quot; ] || exit 0&lt;br /&gt;
TUN=singtun&lt;br /&gt;
LAN=br0&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:$PATH&lt;br /&gt;
ip link show &amp;quot;$TUN&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || exit 0&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN -o $TUN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN -o $TUN -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN -o $LAN -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN -o $LAN -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/ndm/netfilter.d/40-singtun-nat.sh&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic                               # стартует автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web                            # &amp;quot;failed&amp;quot; в конце — нормально, см. 4.2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Приложение А. OpenSSH с ключом (опционально) =&lt;br /&gt;
Этот раздел описывает &#039;&#039;&#039;продвинутую&#039;&#039;&#039; настройку SSH-доступа: установку полноценного OpenSSH-сервера в Entware и настройку входа по публичному ключу вместо пароля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Для всего, что описано в Этапах 1–4 (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю через встроенный SSH-сервер Entware (dropbear) на порту &#039;&#039;&#039;222&#039;&#039;&#039; — настроенный в разделе 1.4. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Когда этот раздел действительно полезен ==&lt;br /&gt;
* Вы заходите на роутер часто и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время.&lt;br /&gt;
&lt;br /&gt;
== Что мы получим ==&lt;br /&gt;
* Дополнительный SSH-сервер OpenSSH на порту &#039;&#039;&#039;2022&#039;&#039;&#039; (рядом с dropbear на 222, не вместо).&lt;br /&gt;
* Вход по публичному ключу без ввода пароля.&lt;br /&gt;
* Удобный алиас на ПК — подключение одной командой &amp;lt;code&amp;gt;ssh keen&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Встроенный dropbear на 222 остаётся работать — это «запасной» канал на случай, если что-то сломается в настройках OpenSSH.&lt;br /&gt;
&lt;br /&gt;
== А.1. Установка OpenSSH-сервера ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.2. Создание пользователя для privsep ==&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.3. Генерация host-ключей ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.4. Конфигурация sshd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание про StrictModes:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt;. Это нормально для прошивки, но OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывает в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== А.5. Скрипт пересоздания /var/empty при загрузке ==&lt;br /&gt;
Каталог &amp;lt;code&amp;gt;/var&amp;lt;/code&amp;gt; на роутере — это tmpfs (RAM-диск), он очищается при каждой загрузке. Создадим стартовый скрипт, который воссоздаёт &amp;lt;code&amp;gt;/var/empty&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/init.d/S39sshd-prep &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
chown root:root /var/empty&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.6. Добавление публичного ключа ==&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставьте строку публичного ключа (правой кнопкой мыши в PuTTY), сохраните файл, дайте права:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.7. Запуск ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.8. Открытие порта в фаерволе (если нужен внешний доступ) ==&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== А.9. Удобный алиас на ПК ==&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставьте свой LAN-адрес роутера в &amp;lt;code&amp;gt;HostName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь подключение — одной командой:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== А.10. Откат ==&lt;br /&gt;
Если что-то пошло не так — встроенный dropbear на :222 продолжает работать, через него зайдите и удалите OpenSSH:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd stop&lt;br /&gt;
opkg remove openssh-server&lt;br /&gt;
rm -f /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A1%D1%83%D0%B2%D0%B5%D1%80%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82&amp;diff=978</id>
		<title>Суверенный интернет</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A1%D1%83%D0%B2%D0%B5%D1%80%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82&amp;diff=978"/>
		<updated>2026-05-12T08:04:15Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Эта страница посвящается всему что связано с ограничим доступа в интернет.&lt;br /&gt;
&lt;br /&gt;
На данный момент 20.04.26 мы имеем полную блокировку по белыми IP у операторов мобильной связи. И предпосылки к блокировкам на уровне провайдеров домашнего интернета.&lt;br /&gt;
&lt;br /&gt;
* [[Обход НКР|Установка и настройка связки Zapret + Podkop на OpenWRT]]&lt;br /&gt;
* [[Hysteria 2 каскад]]&lt;br /&gt;
* [[Whitelist-bypass: VK Creator (headless на сервере) + Joiner (Android)]]&lt;br /&gt;
* [[Установка MTProto Proxy (mtg) на Linux-сервере]]&lt;br /&gt;
* [[VK Turn Proxy + FreeTurn + VLESS]]&lt;br /&gt;
* [[NaïveProxy: установка полной каскадной цепочки]]&lt;br /&gt;
* [[OlcRTC: туннель через WebRTC-сервисы|olcRTC: туннель через легальные WebRTC-сервисы]]&lt;br /&gt;
* [[mieru: каскадный шифрованный SOCKS5-туннель]]&lt;br /&gt;
* [[Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)]]&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=977</id>
		<title>Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%93%D0%B8%D0%B1%D0%BA%D0%B0%D1%8F_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B8_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_DPI_%D0%BD%D0%B0_Keenetic_(sing-box_%2B_keen-pbr_%2B_nfqws2)&amp;diff=977"/>
		<updated>2026-05-12T07:32:46Z</updated>

		<summary type="html">&lt;p&gt;Владимир: Новая страница: «= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic = Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &amp;#039;&amp;#039;&amp;#039;Xiaomi Mi Router 3G&amp;#039;&amp;#039;&amp;#039; с KeeneticOS &amp;#039;&amp;#039;&amp;#039;5.0.7&amp;#039;&amp;#039;&amp;#039; (порт сообщес...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка стека: гибкая маршрутизация и обход DPI на роутере Keenetic =&lt;br /&gt;
Подробная пошаговая инструкция для пользователя, который умеет работать в терминале, но не знаком с устройством роутерных систем. Проверено на &#039;&#039;&#039;Xiaomi Mi Router 3G&#039;&#039;&#039; с KeeneticOS &#039;&#039;&#039;5.0.7&#039;&#039;&#039; (порт сообщества). Подходит для любого Keenetic-устройства с поддержкой OPKG/Entware.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что мы построим ==&lt;br /&gt;
Связка из четырёх компонентов, каждый из которых решает свою задачу:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware&#039;&#039;&#039;&lt;br /&gt;
|Менеджер пакетов на роутере. Позволяет ставить любой Linux-софт через &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|Универсальный туннельный движок. Поддерживает VLESS, Hysteria2, Trojan, Shadowsocks, WireGuard и др. Создаёт виртуальный сетевой интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который можно завернуть выборочный трафик.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Маршрутизатор по доменам. Решает, какой трафик отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какой пускать напрямую. Имеет полноценный веб-интерфейс.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039; (zapret v2)&lt;br /&gt;
|Утилита модификации сетевых пакетов. Обходит DPI-фильтрацию для сервисов, которые &#039;&#039;&#039;не нужно&#039;&#039;&#039; заворачивать в туннель (например, потоковое видео — чтобы не нагружать тоннель и не терять скорость).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Общая архитектура ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                          KEENETIC РОУТЕР&lt;br /&gt;
&lt;br /&gt;
  ┌──────────────────────────────────────────────────────────────┐&lt;br /&gt;
  │                                                              │&lt;br /&gt;
  │  ┌────────────────┐                                          │&lt;br /&gt;
  │  │   keen-pbr     │  --- адрес домена в списке? ---          │&lt;br /&gt;
  │  │   (по доменам) │            │           │                 │&lt;br /&gt;
  │  └────────────────┘            │ ДА        │ НЕТ             │&lt;br /&gt;
  │                                ▼           ▼                 │&lt;br /&gt;
  │                       ┌────────────┐  ┌────────────┐         │&lt;br /&gt;
  │                       │  singtun   │  │   nfqws2   │         │&lt;br /&gt;
  │                       │ (sing-box) │  │  DPI fix   │         │&lt;br /&gt;
  │                       └────────────┘  └────────────┘         │&lt;br /&gt;
  │                            │                │                │&lt;br /&gt;
  └────────────────────────────┼────────────────┼────────────────┘&lt;br /&gt;
                               │                │&lt;br /&gt;
                          ┌────▼────┐      ┌────▼────┐&lt;br /&gt;
                          │  VPN-   │      │  Прямой │&lt;br /&gt;
                          │  сервер │      │  WAN    │&lt;br /&gt;
                          └─────────┘      └─────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&#039;&#039;(Здесь схему можно перерисовать в Mermaid или Excalidraw и заменить блок.)&#039;&#039;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Требование&lt;br /&gt;
!Описание&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Роутер&#039;&#039;&#039;&lt;br /&gt;
|Keenetic с поддержкой Entware/OPKG (KeeneticOS 3.7 и новее) и хотя бы одним свободным USB-портом.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USB-накопитель&#039;&#039;&#039;&lt;br /&gt;
|Любая флешка от &#039;&#039;&#039;8 ГБ&#039;&#039;&#039;. Будет отформатирована в EXT4. Без флешки не получится — встроенной памяти роутера не хватит.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Доступ к веб-интерфейсу&#039;&#039;&#039;&lt;br /&gt;
|Адрес роутера в браузере (обычно &amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my.keenetic.net&amp;lt;/code&amp;gt;), логин администратора.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SSH-клиент&#039;&#039;&#039;&lt;br /&gt;
|PuTTY, Windows Terminal с OpenSSH, или любой другой.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VPN-узел&#039;&#039;&#039;&lt;br /&gt;
|Любой провайдер с протоколами VLESS, Hysteria2, Trojan и т.п. (необходим только для туннеля; обход DPI работает без него).&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Полный стек (sing-box + keen-pbr + nfqws2 + зависимости) занимает &#039;&#039;&#039;около 110 МБ&#039;&#039;&#039; распакованного места. На встроенной флэш-памяти большинства роутеров этого нет — поэтому USB-накопитель &#039;&#039;&#039;обязателен&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Установка Entware =&lt;br /&gt;
Entware — это система пакетов на основе OpenWrt-репозитория. После установки на роутере появится Linux-окружение в каталоге &amp;lt;code&amp;gt;/opt&amp;lt;/code&amp;gt;, в которое можно ставить пакеты командой &amp;lt;code&amp;gt;opkg install&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Подготовка USB-накопителя ==&lt;br /&gt;
&lt;br /&gt;
=== Подключение и форматирование ===&lt;br /&gt;
&lt;br /&gt;
# Воткните флешку в USB-порт роутера.&lt;br /&gt;
# Откройте веб-интерфейс Keenetic: &#039;&#039;&#039;Приложения&#039;&#039;&#039; → &#039;&#039;&#039;USB-диски и принтеры&#039;&#039;&#039;.&lt;br /&gt;
# В списке появится диск. Откройте его параметры.&lt;br /&gt;
# Если файловая система не &amp;lt;code&amp;gt;ext4&amp;lt;/code&amp;gt; — нажмите &#039;&#039;&#039;Форматировать&#039;&#039;&#039; и выберите &#039;&#039;&#039;EXT4&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;USB-диски&amp;quot; в веб-интерфейсе Keenetic с подключённым диском и кнопкой &amp;quot;Форматировать&amp;quot;.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Запомните идентификатор диска ===&lt;br /&gt;
После форматирования у диска есть уникальный &#039;&#039;&#039;идентификатор&#039;&#039;&#039; (UUID или метка). Он понадобится в следующем шаге. Идентификатор виден на той же странице — обычно это длинная строка вида:&amp;lt;pre&amp;gt;&lt;br /&gt;
d5f39712-7ae1-dc01-00f3-97127ae1dc01&lt;br /&gt;
&amp;lt;/pre&amp;gt;&#039;&#039;(Скриншот: страница диска с подсвеченным UUID/идентификатором.)&#039;&#039;&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Скопируйте идентификатор в блокнот — впереди он пригодится несколько раз.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Компоненты KeeneticOS ==&lt;br /&gt;
&lt;br /&gt;
=== Какая у вас прошивка? ===&lt;br /&gt;
KeeneticOS существует в двух вариантах, и от этого зависит, нужно ли вам что-то включать на этом этапе:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Вариант прошивки&lt;br /&gt;
!Нужно ли включать компоненты?&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Оригинальный Keenetic&#039;&#039;&#039; (роутер, который продавался как Keenetic с завода: KN-..., Hero, Ultra, Giga, Viva, Hopper, Peak и т.п.)&lt;br /&gt;
|&#039;&#039;&#039;Да&#039;&#039;&#039;, через веб-интерфейс — см. ниже&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Порт сообщества&#039;&#039;&#039; (например, [https://keeneticported.dev keeneticported.dev]) на роутере другой марки (Xiaomi Mi Router 3G/3/Pro, TP-Link, Mercusys и др.)&lt;br /&gt;
|&#039;&#039;&#039;Нет&#039;&#039;&#039;, все нужные пакеты уже включены в образ прошивки этого порта — переходите к разделу 1.3&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — как понять, какая у вас прошивка:&#039;&#039;&#039; На странице &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; (главная страница веб-интерфейса) видна модель устройства. Если рядом с моделью стоит знакомое маркетинговое имя Keenetic (например, &amp;quot;Keenetic Hero&amp;quot;) и модель начинается с &amp;quot;KN-&amp;quot; — это оригинальный Keenetic. Если вы видите название роутера другого производителя (например, &amp;quot;Xiaomi R3G&amp;quot;) и при этом отображается KeeneticOS — у вас порт сообщества.&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Признак порта сообщества:&#039;&#039;&#039; На странице с компонентами окно &amp;quot;Компоненты операционной системы&amp;quot; может показывать сообщение &amp;quot;Не удалось получить список компонентов от сервера&amp;quot; — это нормально для портированных сборок, у которых нет своего сервера обновлений. В этом случае шаг с компонентами &#039;&#039;&#039;не нужен&#039;&#039;&#039; — переходите к разделу 1.3.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Только для оригинального Keenetic ===&lt;br /&gt;
В веб-интерфейсе: &#039;&#039;&#039;Управление → Общие настройки&#039;&#039;&#039; → блок &#039;&#039;&#039;Обновления и компоненты&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Показать компоненты&#039;&#039;&#039; (в более старых версиях UI — &#039;&#039;&#039;Изменить набор компонентов&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Включите следующие компоненты:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Компонент (точное название в UI)&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Поддержка открытых пакетов&#039;&#039;&#039; (OPKG)&lt;br /&gt;
|Базовая инфраструктура Entware — без этого нельзя ставить пакеты на USB&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Файловая система Ext&#039;&#039;&#039;&lt;br /&gt;
|Чтобы роутер мог монтировать ext4-диск&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Сервер SSH&#039;&#039;&#039;&lt;br /&gt;
|Доступ к командной строке роутера&lt;br /&gt;
|}&lt;br /&gt;
Кроме того, &#039;&#039;&#039;желательно&#039;&#039;&#039; проверить наличие следующих компонентов (точные названия в интерфейсе могут отличаться от версии к версии — ищите по словам):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Что искать в списке&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Netfilter&amp;quot; / &amp;quot;Модули ядра Netfilter&amp;quot;&lt;br /&gt;
|Базовые модули iptables для работы фаервола Entware&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Расширенные модули Netfilter&amp;quot; / &amp;quot;Netfilter addons&amp;quot;&lt;br /&gt;
|Дополнительные модули (xt_set, xt_multiport, conntrack-extra) — &#039;&#039;&#039;критично&#039;&#039;&#039; для работы keen-pbr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Конструктор Access Policy&amp;quot; / &amp;quot;IntelliQoS&amp;quot;&lt;br /&gt;
|Для тонкой настройки nfqws2 по устройствам (опционально)&lt;br /&gt;
|}&lt;br /&gt;
После выбора нажмите &#039;&#039;&#039;Установить обновление&#039;&#039;&#039; и подождите 2–5 минут. Роутер перезагрузится самостоятельно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Обновления и компоненты&amp;quot; с открытым окном &amp;quot;Показать компоненты&amp;quot; и отмеченными нужными пунктами.)&#039;&#039;&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В KeeneticOS 5 и новее компонент &#039;&#039;&#039;Протокол IPv6&#039;&#039;&#039; включён по умолчанию и не может быть отключён — это нормально.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Установка Entware через командную строку ==&lt;br /&gt;
&lt;br /&gt;
=== Открытие командной строки роутера ===&lt;br /&gt;
Веб-интерфейс Keenetic имеет встроенную консоль. Откройте её одним из способов:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Способ A:&#039;&#039;&#039; Перейдите по адресу &amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt; в браузере.&lt;br /&gt;
* &#039;&#039;&#039;Способ B:&#039;&#039;&#039; &#039;&#039;&#039;Диагностика&#039;&#039;&#039; → &#039;&#039;&#039;Командная строка&#039;&#039;&#039; (в новых прошивках).&lt;br /&gt;
&lt;br /&gt;
Должно появиться приглашение вида:&amp;lt;pre&amp;gt;&lt;br /&gt;
(config)&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&#039;&#039;(Скриншот: окно командной строки с приглашением &amp;lt;code&amp;gt;(config)&amp;gt;&amp;lt;/code&amp;gt;.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Запуск установки Entware ===&lt;br /&gt;
Команда состоит из &#039;&#039;&#039;двух частей, которые вы должны подставить сами&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Идентификатор вашего USB-диска&#039;&#039;&#039; — тот UUID, который вы запомнили на шаге &#039;&#039;&#039;1.1&#039;&#039;&#039; (длинная строка вида &amp;lt;code&amp;gt;d5f39712-7ae1-...&amp;lt;/code&amp;gt;).&lt;br /&gt;
# &#039;&#039;&#039;URL установщика&#039;&#039;&#039; — выбирается по архитектуре вашего роутера (см. таблицу ниже).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — не копируйте команду как есть!&#039;&#039;&#039; В шаблоне ниже фигурные скобки &amp;lt;code&amp;gt;&amp;lt;...&amp;gt;&amp;lt;/code&amp;gt; — это места, куда нужно подставить &#039;&#039;&#039;ваши&#039;&#039;&#039; значения. Если оставить шаблон с угловыми скобками или скопировать чужой UUID — установка не сработает.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Шаблон команды ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg disk &amp;lt;ВАШ_UUID_ДИСКА&amp;gt;:/ &amp;lt;URL_УСТАНОВЩИКА_ДЛЯ_ВАШЕЙ_АРХИТЕКТУРЫ&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Где взять каждую часть ====&lt;br /&gt;
&#039;&#039;&#039;(1) UUID диска&#039;&#039;&#039; — со страницы &#039;&#039;&#039;Приложения → Диски и принтеры&#039;&#039;&#039; (раздел 1.1 этого гайда). Скопируйте длинную строку, которая отображается как имя диска.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;(2) URL установщика&#039;&#039;&#039; — выберите по архитектуре вашего роутера:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Архитектура роутера&lt;br /&gt;
!URL установщика (целиком)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MIPS little-endian (mipsel)&#039;&#039;&#039; — большинство моделей Keenetic и портов на Xiaomi/TP-Link/Mercusys (Mi 3G, Mi 3, Mi 4A, Hero, Ultra, Giga, Viva, Air и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ARM 64-bit (aarch64)&#039;&#039;&#039; — современные Keenetic (Hopper KN-3810, Peak KN-2710 и др.)&lt;br /&gt;
|&amp;lt;code&amp;gt;https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — как узнать архитектуру:&#039;&#039;&#039; Откройте &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; в веб-интерфейсе → видно модель устройства и процессор. Для большинства бытовых моделей это MIPS — берите верхнюю строку таблицы. Если сомневаетесь — пишите команду с &amp;lt;code&amp;gt;mipsel&amp;lt;/code&amp;gt;: если архитектура не подходит, установка скажет об этом ошибкой, и вы не сломаете роутер.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Пример с подставленными значениями ====&lt;br /&gt;
Допустим, ваш UUID — &amp;lt;code&amp;gt;d5f39712-7ae1-dc01-00f3-97127ae1dc01&amp;lt;/code&amp;gt;, архитектура — mipsel. Тогда команда полностью выглядит так:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Это &#039;&#039;&#039;пример&#039;&#039;&#039; — UUID &amp;lt;code&amp;gt;d5f39712-...&amp;lt;/code&amp;gt; здесь приведён только для иллюстрации. У &#039;&#039;&#039;вашего&#039;&#039;&#039; диска UUID будет &#039;&#039;&#039;другой&#039;&#039;&#039;. Подставьте именно свой со страницы &amp;quot;Диски и принтеры&amp;quot;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Проверочный чек-лист перед нажатием Enter ====&lt;br /&gt;
&lt;br /&gt;
* Двоеточие и слэш &amp;lt;code&amp;gt;:/&amp;lt;/code&amp;gt; сразу после UUID — &#039;&#039;&#039;обязательны&#039;&#039;&#039;.&lt;br /&gt;
* URL — &#039;&#039;&#039;одной строкой&#039;&#039;&#039;, без пробелов и переносов.&lt;br /&gt;
* После UUID и перед URL — &#039;&#039;&#039;ровно один пробел&#039;&#039;&#039;.&lt;br /&gt;
* Угловых скобок &amp;lt;code&amp;gt;&amp;lt;&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; в финальной команде &#039;&#039;&#039;не должно остаться&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Сохранение конфигурации ===&lt;br /&gt;
После того как установка прошла без ошибок, сохраните конфигурацию:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — если установщик &amp;quot;молчит&amp;quot;:&#039;&#039;&#039; В некоторых сборках команда &amp;lt;code&amp;gt;opkg disk ... URL&amp;lt;/code&amp;gt; не работает, если OPKG-диск уже был назначен раньше. Если в логе вы не видите строк про загрузку &amp;lt;code&amp;gt;mipsel-installer.tar.gz&amp;lt;/code&amp;gt; — сбросьте диск и повторите:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
no opkg disk&lt;br /&gt;
opkg disk d5f39712-7ae1-dc01-00f3-97127ae1dc01:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Проверка установки ===&lt;br /&gt;
Откройте журнал: &#039;&#039;&#039;Диагностика&#039;&#039;&#039; → &#039;&#039;&#039;Системный журнал&#039;&#039;&#039;. Должны появиться строки примерно такого содержания:&amp;lt;pre&amp;gt;&lt;br /&gt;
Opkg::Manager: downloading installer...&lt;br /&gt;
Opkg::Manager: extracting to /opt...&lt;br /&gt;
Opkg::Manager: ...&lt;br /&gt;
Entware installed.&lt;br /&gt;
&amp;lt;/pre&amp;gt;После завершения установки на роутере поднимется встроенный SSH-сервер Entware на порту &#039;&#039;&#039;222&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Первое подключение по SSH ==&lt;br /&gt;
Подключитесь к роутеру с компьютера. На Windows — через PuTTY или через стандартный &amp;lt;code&amp;gt;ssh.exe&amp;lt;/code&amp;gt;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Хост&lt;br /&gt;
|&amp;lt;code&amp;gt;192.168.1.1&amp;lt;/code&amp;gt; (LAN-адрес роутера)&lt;br /&gt;
|-&lt;br /&gt;
|Порт&lt;br /&gt;
|&#039;&#039;&#039;222&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Логин&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Пароль&lt;br /&gt;
|&amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Из PowerShell это одна строка:&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 222 root@192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;При первом подключении ssh попросит подтвердить fingerprint — ответьте &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Смена пароля (обязательно!) ===&lt;br /&gt;
Сразу после входа смените пароль:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
passwd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Введите новый пароль дважды.&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Дефолтный пароль &amp;lt;code&amp;gt;keenetic&amp;lt;/code&amp;gt; известен всем — если SSH будет проброшен наружу, роутер взломают за минуты.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.5. (опционально) Доступ по SSH-ключу через OpenSSH ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — этот раздел не нужен для обычной установки.&#039;&#039;&#039; Здесь описана продвинутая настройка: замена встроенного SSH-сервера (dropbear на порту 222) на полноценный OpenSSH с поддержкой ключей. Делайте, только если вы &#039;&#039;&#039;понимаете, зачем это нужно&#039;&#039;&#039; лично вам. Для всего, что описано в гайде дальше (sing-box, keen-pbr, nfqws2), хватает стандартного входа по паролю из раздела &#039;&#039;&#039;1.4&#039;&#039;&#039; — можете спокойно его пропустить и перейти к &#039;&#039;&#039;Этапу 2&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Когда этот раздел действительно полезен ===&lt;br /&gt;
&lt;br /&gt;
* Вы заходите на роутер часто, и каждый раз вводить пароль раздражает.&lt;br /&gt;
* На том же ПК уже есть SSH-ключ, которым вы пользуетесь для других серверов, и хочется единообразия.&lt;br /&gt;
* Вы планируете давать роутеру доступ автоматизированным инструментам (скрипты, агенты, CI), которые не умеют вводить пароль.&lt;br /&gt;
* Хочется иметь возможность &#039;&#039;&#039;выключить парольную аутентификацию&#039;&#039;&#039; и оставить только ключ — это сильно повышает безопасность, если SSH будет проброшен наружу.&lt;br /&gt;
&lt;br /&gt;
Если ни один пункт не про вас — не тратьте время, переходите к &#039;&#039;&#039;Этапу 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Установка OpenSSH-сервера ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install openssh-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание пользователя для privsep ===&lt;br /&gt;
OpenSSH требует системного пользователя &amp;lt;code&amp;gt;sshd&amp;lt;/code&amp;gt; для изоляции привилегий. В Entware его по умолчанию нет:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;sshd:*:22:22:sshd:/var/empty:/bin/false&#039; &amp;gt;&amp;gt; /opt/etc/passwd&lt;br /&gt;
echo &#039;sshd:*:22:&#039; &amp;gt;&amp;gt; /opt/etc/group&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Генерация host-ключей ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Конфигурация sshd ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Найдите и отредактируйте следующие параметры (раскомментируйте, если стоит &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;):&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Port 2022&lt;br /&gt;
PermitRootLogin yes&lt;br /&gt;
PubkeyAuthentication yes&lt;br /&gt;
PasswordAuthentication yes&lt;br /&gt;
StrictModes no&lt;br /&gt;
AuthorizedKeysFile /opt/root/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; На Keenetic корневой каталог &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; смонтирован с правами &amp;lt;code&amp;gt;777&amp;lt;/code&amp;gt; (write для всех). Это нормально для прошивки, но dropbear и OpenSSH &#039;&#039;&#039;по умолчанию&#039;&#039;&#039; отказывают в pubkey-аутентификации, если хоть один каталог в пути до &amp;lt;code&amp;gt;authorized_keys&amp;lt;/code&amp;gt; доступен на запись группе или всем. Параметр &amp;lt;code&amp;gt;StrictModes no&amp;lt;/code&amp;gt; отключает эту проверку.&lt;br /&gt;
&amp;lt;/div&amp;gt;Сохраните файл (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Скрипт пересоздания /var/empty при загрузке ===&lt;br /&gt;
Каталог &amp;lt;code&amp;gt;/var&amp;lt;/code&amp;gt; на роутере — это tmpfs (RAM-диск), он очищается при каждой загрузке. Создадим стартовый скрипт, который воссоздаёт &amp;lt;code&amp;gt;/var/empty&amp;lt;/code&amp;gt;:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/init.d/S39sshd-prep &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
mkdir -p /var/empty&lt;br /&gt;
chmod 755 /var/empty&lt;br /&gt;
chown root:root /var/empty&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/init.d/S39sshd-prep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление публичного ключа ===&lt;br /&gt;
На вашем компьютере получите содержимое публичного ключа (Windows, PowerShell):&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если ключа нет — создайте: &amp;lt;code&amp;gt;ssh-keygen -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На роутере:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh&lt;br /&gt;
nano ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте строку публичного ключа (правой кнопкой в PuTTY), сохраните файл, дайте права:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Запуск ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S40sshd start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Открытие порта в фаерволе ===&lt;br /&gt;
Если планируете заходить с другой сети — добавьте правило в &#039;&#039;&#039;Сетевые правила → Межсетевой экран → Ethernet-подключение → Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;SSH OpenSSH&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;2022&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Удобный алиас на ПК ===&lt;br /&gt;
Создайте/откройте файл &amp;lt;code&amp;gt;C:\Users\ВашИмя\.ssh\config&amp;lt;/code&amp;gt; и добавьте:&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Host keen&lt;br /&gt;
    HostName 192.168.1.1&lt;br /&gt;
    User root&lt;br /&gt;
    Port 2022&lt;br /&gt;
    IdentityFile ~/.ssh/id_ed25519&lt;br /&gt;
    IdentitiesOnly yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Теперь подключение — одной командой:&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
ssh keen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка sing-box =&lt;br /&gt;
sing-box — это движок туннеля. Он умеет «слушать» виртуальный TUN-интерфейс и пересылать всё, что туда прилетит, через выбранный протокол (VLESS, Hysteria2, и др.) на удалённый сервер.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Установка пакета ==&lt;br /&gt;
Подключитесь к роутеру по SSH и выполните:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install sing-box-go&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание:&#039;&#039;&#039; Пакет занимает &#039;&#039;&#039;около 62 МБ&#039;&#039;&#039; в распакованном виде. Установка во встроенную память роутера (без USB) почти всегда невозможна — поэтому Entware должен быть на USB.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sing-box version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Ожидаемый вывод:&#039;&#039;&#039;&amp;lt;pre&amp;gt;&lt;br /&gt;
sing-box version 1.13.3&lt;br /&gt;
&lt;br /&gt;
Environment: go1.26.1 linux/mipsle&lt;br /&gt;
Tags: ... with_quic ... with_clash_api ... with_gvisor ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Обратите внимание на флаги в выводе. &amp;lt;code&amp;gt;with_quic&amp;lt;/code&amp;gt; означает поддержку Hysteria/Hysteria2/TUIC. &amp;lt;code&amp;gt;with_clash_api&amp;lt;/code&amp;gt; — встроенный API для подключения веб-дашбордов. Если этих флагов нет — версия урезана, нужна другая сборка.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2. Создание конфига ==&lt;br /&gt;
sing-box читает конфиг из &amp;lt;code&amp;gt;/opt/etc/sing-box/config.json&amp;lt;/code&amp;gt;. Заводской пример нам не подойдёт — там настроен серверный режим Shadowsocks. Создадим клиентский конфиг.&lt;br /&gt;
&lt;br /&gt;
=== Пример: Hysteria2-узел в туннеле ===&lt;br /&gt;
Предположим, ваш провайдер выдал ссылку вида:&amp;lt;pre&amp;gt;&lt;br /&gt;
hysteria2://ПАРОЛЬ@ВАШ_СЕРВЕР:ПОРТ&lt;br /&gt;
&amp;lt;/pre&amp;gt;Запишите рабочий конфиг:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/sing-box/config.json &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;log&amp;quot;: { &amp;quot;level&amp;quot;: &amp;quot;info&amp;quot;, &amp;quot;timestamp&amp;quot;: true },&lt;br /&gt;
  &amp;quot;dns&amp;quot;: {&lt;br /&gt;
    &amp;quot;servers&amp;quot;: [&lt;br /&gt;
      { &amp;quot;type&amp;quot;: &amp;quot;udp&amp;quot;, &amp;quot;tag&amp;quot;: &amp;quot;dns-direct&amp;quot;, &amp;quot;server&amp;quot;: &amp;quot;1.1.1.1&amp;quot; }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;strategy&amp;quot;: &amp;quot;ipv4_only&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;inbounds&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;tun&amp;quot;,&lt;br /&gt;
      &amp;quot;tag&amp;quot;: &amp;quot;tun-in&amp;quot;,&lt;br /&gt;
      &amp;quot;interface_name&amp;quot;: &amp;quot;singtun&amp;quot;,&lt;br /&gt;
      &amp;quot;address&amp;quot;: [&amp;quot;198.18.0.1/30&amp;quot;],&lt;br /&gt;
      &amp;quot;mtu&amp;quot;: 1500,&lt;br /&gt;
      &amp;quot;auto_route&amp;quot;: false,&lt;br /&gt;
      &amp;quot;strict_route&amp;quot;: false,&lt;br /&gt;
      &amp;quot;stack&amp;quot;: &amp;quot;gvisor&amp;quot;,&lt;br /&gt;
      &amp;quot;sniff&amp;quot;: true&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;mixed&amp;quot;,&lt;br /&gt;
      &amp;quot;tag&amp;quot;: &amp;quot;test-proxy&amp;quot;,&lt;br /&gt;
      &amp;quot;listen&amp;quot;: &amp;quot;192.168.10.1&amp;quot;,&lt;br /&gt;
      &amp;quot;listen_port&amp;quot;: 7891&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;outbounds&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;hysteria2&amp;quot;,&lt;br /&gt;
      &amp;quot;tag&amp;quot;: &amp;quot;hy2&amp;quot;,&lt;br /&gt;
      &amp;quot;server&amp;quot;: &amp;quot;ВАШ_СЕРВЕР&amp;quot;,&lt;br /&gt;
      &amp;quot;server_port&amp;quot;: ПОРТ,&lt;br /&gt;
      &amp;quot;password&amp;quot;: &amp;quot;ПАРОЛЬ&amp;quot;,&lt;br /&gt;
      &amp;quot;tls&amp;quot;: {&lt;br /&gt;
        &amp;quot;enabled&amp;quot;: true,&lt;br /&gt;
        &amp;quot;server_name&amp;quot;: &amp;quot;ВАШ_СЕРВЕР&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    },&lt;br /&gt;
    { &amp;quot;type&amp;quot;: &amp;quot;direct&amp;quot;, &amp;quot;tag&amp;quot;: &amp;quot;direct&amp;quot; }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;route&amp;quot;: {&lt;br /&gt;
    &amp;quot;final&amp;quot;: &amp;quot;hy2&amp;quot;,&lt;br /&gt;
    &amp;quot;rules&amp;quot;: [&lt;br /&gt;
      { &amp;quot;action&amp;quot;: &amp;quot;sniff&amp;quot; },&lt;br /&gt;
      { &amp;quot;protocol&amp;quot;: &amp;quot;dns&amp;quot;, &amp;quot;action&amp;quot;: &amp;quot;hijack-dns&amp;quot; }&lt;br /&gt;
    ]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;experimental&amp;quot;: {&lt;br /&gt;
    &amp;quot;clash_api&amp;quot;: {&lt;br /&gt;
      &amp;quot;external_controller&amp;quot;: &amp;quot;0.0.0.0:9090&amp;quot;,&lt;br /&gt;
      &amp;quot;external_ui&amp;quot;: &amp;quot;/opt/share/dashboard&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Замените &amp;lt;code&amp;gt;ВАШ_СЕРВЕР&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ПОРТ&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ПАРОЛЬ&amp;lt;/code&amp;gt; на реальные значения.&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — про подсеть TUN:&#039;&#039;&#039; Значение &amp;lt;code&amp;gt;&amp;quot;address&amp;quot;: [&amp;quot;198.18.0.1/30&amp;quot;]&amp;lt;/code&amp;gt; — это подсеть TUN-интерфейса (внутренний адрес виртуального сетевого устройства). Диапазон &amp;lt;code&amp;gt;198.18.0.0/15&amp;lt;/code&amp;gt; зарезервирован RFC 2544 и не используется в реальном интернете — он не конфликтует ни с вашей LAN, ни с публичными адресами.&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет — про IP роутера:&#039;&#039;&#039; В строке &amp;lt;code&amp;gt;&amp;quot;listen&amp;quot;: &amp;quot;192.168.10.1&amp;quot;&amp;lt;/code&amp;gt; подставьте &#039;&#039;&#039;LAN-адрес вашего роутера&#039;&#039;&#039; (увидеть его можно в веб-интерфейсе Keenetic в карточке &amp;quot;Домашняя сеть&amp;quot;). Этот mixed-inbound — служебный, мы используем его для тестов; для боевой работы он не нужен, но не мешает.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что делает каждая секция ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Секция&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;log&amp;lt;/code&amp;gt;&lt;br /&gt;
|Уровень логирования. &amp;lt;code&amp;gt;info&amp;lt;/code&amp;gt; достаточно; для отладки можно поставить &amp;lt;code&amp;gt;debug&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;dns&amp;lt;/code&amp;gt;&lt;br /&gt;
|Какие DNS-серверы использует сам sing-box для резолва имён узлов (например, сервера Hysteria2).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;inbounds → tun&amp;lt;/code&amp;gt;&lt;br /&gt;
|Создаёт виртуальный интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, в который заворачивается трафик. Этот интерфейс будет использовать &amp;lt;code&amp;gt;keen-pbr&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;inbounds → mixed&amp;lt;/code&amp;gt;&lt;br /&gt;
|Локальный HTTP/SOCKS5-прокси на порту &amp;lt;code&amp;gt;7891&amp;lt;/code&amp;gt;. Удобен для проверки туннеля.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;outbounds → hysteria2&amp;lt;/code&amp;gt;&lt;br /&gt;
|Описание узла на удалённой стороне — куда идёт инкапсулированный трафик.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;outbounds → direct&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;quot;Прямой&amp;quot; выход — используется для трафика, который не нужно туннелировать.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;route.final = hy2&amp;lt;/code&amp;gt;&lt;br /&gt;
|По умолчанию весь трафик, попавший в sing-box, отправляется через outbound с тегом &amp;lt;code&amp;gt;hy2&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;experimental.clash_api&amp;lt;/code&amp;gt;&lt;br /&gt;
|REST API на порту &amp;lt;code&amp;gt;9090&amp;lt;/code&amp;gt;. Через него к sing-box подключаются дашборды (Yacd, Zashboard, metacubexd).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Проверка конфига ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sing-box check -c /opt/etc/sing-box/config.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если конфиг корректен — команда отработает молча. Если ошибка — sing-box подскажет, какая.&lt;br /&gt;
&lt;br /&gt;
== 2.3. Запуск ==&lt;br /&gt;
Запустить через init-скрипт Entware:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S99sing-box start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В норме скрипт автоматически прописывает sing-box в автозагрузку — после перезагрузки роутера он стартует сам.&lt;br /&gt;
&lt;br /&gt;
=== Проверка процесса и интерфейса ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Процесс&lt;br /&gt;
pgrep -af sing-box&lt;br /&gt;
&lt;br /&gt;
# Создался ли TUN-интерфейс&lt;br /&gt;
awk &#039;/:/{print $1}&#039; /proc/net/dev | grep singtun&lt;br /&gt;
&lt;br /&gt;
# Порты, которые слушает&lt;br /&gt;
netstat -tlnup | grep sing-box&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Ожидаемые результаты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Процесс &amp;lt;code&amp;gt;sing-box run -C /opt/etc/sing-box&amp;lt;/code&amp;gt; существует.&lt;br /&gt;
* Интерфейс &amp;lt;code&amp;gt;singtun:&amp;lt;/code&amp;gt; есть в списке.&lt;br /&gt;
* Слушаются как минимум: &amp;lt;code&amp;gt;0.0.0.0:7891&amp;lt;/code&amp;gt; (mixed proxy), &amp;lt;code&amp;gt;0.0.0.0:9090&amp;lt;/code&amp;gt; (clash-api).&lt;br /&gt;
&lt;br /&gt;
== 2.4. Проверка туннеля ==&lt;br /&gt;
Сделайте запрос через локальный mixed-proxy и сравните с прямым:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Поставим curl, если ещё не стоит&lt;br /&gt;
opkg install curl&lt;br /&gt;
&lt;br /&gt;
# Прямой запрос (через ваш WAN)&lt;br /&gt;
curl -sS https://api.ipify.org&lt;br /&gt;
echo&lt;br /&gt;
&lt;br /&gt;
# Тот же запрос, но через туннель&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
echo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039; два разных IP — первый ваш домашний, второй — IP туннеля.&lt;br /&gt;
&lt;br /&gt;
Если IP совпадают или второй запрос не отвечает — туннель не работает. Проверьте логи sing-box и параметры конфига.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Установка keen-pbr =&lt;br /&gt;
keen-pbr решает &#039;&#039;&#039;одну задачу&#039;&#039;&#039;: какие домены отправлять в туннель &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;, а какие пускать напрямую. Имеет современный веб-интерфейс на отдельном порту.&lt;br /&gt;
&lt;br /&gt;
== 3.1. Подключение репозитория ==&lt;br /&gt;
Добавьте feed keen-pbr к конфигу OPKG:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; Для других архитектур URL feed-а отличается. Список архитектур и URL — на странице репозитория проекта: &amp;lt;code&amp;gt;https://repo.keen-pbr.fyi/repository/stable/&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.2. Установка пакета ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Пакет потянет за собой зависимости: &amp;lt;code&amp;gt;dnsmasq-full&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ipset&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;libnl-*&amp;lt;/code&amp;gt; и др. — это нормально.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: вывод команды &amp;lt;code&amp;gt;opkg install keen-pbr&amp;lt;/code&amp;gt; с перечислением устанавливаемых зависимостей.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== 3.3. Замена dnsmasq.conf ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — это критичный шаг:&#039;&#039;&#039; При установке через SSH postinst-скрипт keen-pbr ждёт интерактивного ответа («заменить ли &amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; на шаблон keen-pbr?»). В неинтерактивном режиме скрипт ничего не делает — и dnsmasq стартует без интеграции с keen-pbr. Сделаем замену вручную.&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Сохраним заводской конфиг про запас&lt;br /&gt;
cp /opt/etc/dnsmasq.conf /opt/etc/dnsmasq.conf.backup-pre-keen-pbr&lt;br /&gt;
&lt;br /&gt;
# Установим шаблон keen-pbr&lt;br /&gt;
cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3.4. Включение DNS Override ==&lt;br /&gt;
Чтобы прошивка KeeneticOS отдавала перехваченный 53-й порт нашему dnsmasq, нужно включить опцию &#039;&#039;&#039;opkg dns-override&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Выполните в командной строке роутера (&amp;lt;code&amp;gt;http://192.168.1.1/a&amp;lt;/code&amp;gt;):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg dns-override&lt;br /&gt;
system configuration save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;(Скриншот: окно &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt; с введённой командой и ответом &amp;lt;code&amp;gt;DNS override enabled.&amp;lt;/code&amp;gt;)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== 3.5. Перезагрузка роутера ==&lt;br /&gt;
Опция &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; применяется только после полной перезагрузки. Выполните:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
system reboot&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Или через веб-интерфейс: &#039;&#039;&#039;Системный монитор&#039;&#039;&#039; → &#039;&#039;&#039;Перезагрузить&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Ожидайте 1–2 минуты, пока роутер поднимется обратно.&lt;br /&gt;
&lt;br /&gt;
== 3.6. Workaround: правила NAT и FORWARD ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — известный нюанс keen-pbr 3.x:&#039;&#039;&#039; Для outbound типа &amp;lt;code&amp;gt;interface&amp;lt;/code&amp;gt; (т.е. для отправки трафика в TUN-интерфейс sing-box) keen-pbr 3.x &#039;&#039;&#039;не добавляет&#039;&#039;&#039; необходимые правила NAT MASQUERADE и FORWARD ACCEPT. Без них трафик клиентов LAN не доходит до туннеля. Создадим стартовый скрипт, который добавит их.&lt;br /&gt;
&amp;lt;/div&amp;gt;Подключитесь по SSH и создайте файл:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/etc/init.d/S81keen-pbr-fixup &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# Workaround для keen-pbr 3.x + sing-box TUN.&lt;br /&gt;
# Добавляет MASQUERADE на singtun и FORWARD ACCEPT br0 &amp;lt;-&amp;gt; singtun.&lt;br /&gt;
&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:/opt/bin:/opt/usr/bin:$PATH&lt;br /&gt;
TUN_IFACE=singtun&lt;br /&gt;
LAN_IFACE=br0&lt;br /&gt;
&lt;br /&gt;
# Подождать пока интерфейс появится после старта sing-box&lt;br /&gt;
for i in 1 2 3 4 5 6 7 8 9 10; do&lt;br /&gt;
  ip link show $TUN_IFACE &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 &amp;amp;&amp;amp; break&lt;br /&gt;
  sleep 1&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN_IFACE -j MASQUERADE 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -t nat -A POSTROUTING -o $TUN_IFACE -j MASQUERADE&lt;br /&gt;
&lt;br /&gt;
iptables -C FORWARD -i $LAN_IFACE -o $TUN_IFACE -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $LAN_IFACE -o $TUN_IFACE -j ACCEPT&lt;br /&gt;
&lt;br /&gt;
iptables -C FORWARD -i $TUN_IFACE -o $LAN_IFACE -j ACCEPT 2&amp;gt;/dev/null || \&lt;br /&gt;
  iptables -I FORWARD 1 -i $TUN_IFACE -o $LAN_IFACE -j ACCEPT&lt;br /&gt;
&lt;br /&gt;
logger -t keen-pbr-fixup &amp;quot;NAT/FORWARD rules applied for $TUN_IFACE&amp;quot;&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/init.d/S81keen-pbr-fixup&lt;br /&gt;
&lt;br /&gt;
# Запустим прямо сейчас&lt;br /&gt;
/opt/etc/init.d/S81keen-pbr-fixup&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Скрипт стартует автоматически с Entware (имя начинается с &amp;lt;code&amp;gt;S81&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== 3.7. Замена upstream DNS на публичные серверы ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Внимание — обязательный шаг:&#039;&#039;&#039; По умолчанию keen-pbr использует встроенный DNS-сервер KeeneticOS в качестве upstream. Этот сервер может подменять ответы на fake-IP из диапазона &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt; для некоторых доменов (это поведение зависит от настроек прошивки и подключённых &amp;quot;защитных&amp;quot; сервисов). В итоге keen-pbr получает поддельные IP, кладёт их в свой ipset, а трафик клиента уходит &amp;quot;в никуда&amp;quot;.&lt;br /&gt;
&amp;lt;/div&amp;gt;Откройте конфиг keen-pbr:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/etc/keen-pbr/config.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Найдите блок &amp;lt;code&amp;gt;&amp;quot;dns&amp;quot;&amp;lt;/code&amp;gt; и замените его на:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;dns&amp;quot;: {&lt;br /&gt;
  &amp;quot;system_resolver&amp;quot;: {&lt;br /&gt;
    &amp;quot;address&amp;quot;: &amp;quot;127.0.0.1&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;dns_test_server&amp;quot;: {&lt;br /&gt;
    &amp;quot;listen&amp;quot;: &amp;quot;127.0.0.88:12153&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;servers&amp;quot;: [&lt;br /&gt;
    { &amp;quot;tag&amp;quot;: &amp;quot;cloudflare&amp;quot;, &amp;quot;address&amp;quot;: &amp;quot;1.1.1.1&amp;quot; },&lt;br /&gt;
    { &amp;quot;tag&amp;quot;: &amp;quot;quad9&amp;quot;, &amp;quot;address&amp;quot;: &amp;quot;9.9.9.9&amp;quot; }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;rules&amp;quot;: [],&lt;br /&gt;
  &amp;quot;fallback&amp;quot;: [&amp;quot;cloudflare&amp;quot;, &amp;quot;quad9&amp;quot;]&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните файл и перезапустите сервис:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Резолв через локальный сервер должен вернуть реальный IP&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Хороший результат:&#039;&#039;&#039; нормальный публичный IP. &#039;&#039;&#039;Плохой результат:&#039;&#039;&#039; что-то из &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt; — DNS не сменился, проверьте конфиг ещё раз.&lt;br /&gt;
&lt;br /&gt;
== 3.8. Доступ к веб-интерфейсу ==&lt;br /&gt;
keen-pbr слушает на порту &#039;&#039;&#039;12121&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Изнутри LAN роутера ===&lt;br /&gt;
В браузере устройства, подключённого по Wi-Fi/Ethernet к Keenetic:&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:12121&lt;br /&gt;
&amp;lt;/pre&amp;gt;Например, &amp;lt;code&amp;gt;http://192.168.10.1:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Снаружи (если хочется заходить из другой подсети) ===&lt;br /&gt;
В веб-интерфейсе Keenetic: &#039;&#039;&#039;Сетевые правила&#039;&#039;&#039; → &#039;&#039;&#039;Межсетевой экран&#039;&#039;&#039; → &#039;&#039;&#039;Ethernet-подключение&#039;&#039;&#039; → &#039;&#039;&#039;Добавить правило&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Имя&lt;br /&gt;
|&amp;lt;code&amp;gt;keen-pbr WebUI&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Действие&lt;br /&gt;
|Разрешить&lt;br /&gt;
|-&lt;br /&gt;
|Протокол&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Порт назначения&lt;br /&gt;
|Один порт → &amp;lt;code&amp;gt;12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|IP-адрес источника&lt;br /&gt;
|подсеть, из которой будете заходить (например, &amp;lt;code&amp;gt;192.168.1.0/24&amp;lt;/code&amp;gt;)&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;(Скриншот: страница межсетевого экрана с добавленным правилом.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
После этого UI доступен по адресу &amp;lt;code&amp;gt;http://WAN-IP-РОУТЕРА:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 3.9. Настройка через веб-интерфейс ==&lt;br /&gt;
Откройте UI keen-pbr и убедитесь, что баннер про &#039;&#039;&#039;dnsmasq&#039;&#039;&#039; зелёный.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: главная страница UI keen-pbr с зелёным статусом &amp;quot;dnsmasq исправен&amp;quot;.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1: Создать outbound (точку выхода в туннель) ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Интернет&#039;&#039;&#039; → &#039;&#039;&#039;Outbounds (выходы)&#039;&#039;&#039; → кнопка &#039;&#039;&#039;Создать&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Заполните:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Tag&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (или любое короткое имя)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Interface&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Interface&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gateway IPv6&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;оставить пустым&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
Сохранить. В списке outbounds появится строка &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; со статусом &#039;&#039;&#039;healthy&#039;&#039;&#039; и активным интерфейсом.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: форма создания outbound с заполненными полями.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2: Создать список доменов ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → &#039;&#039;&#039;Создать&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Заполните:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Source&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;Inline&amp;lt;/code&amp;gt; (вкладка)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Domains&#039;&#039;&#039;&lt;br /&gt;
|вставьте список доменов, &#039;&#039;&#039;по одному на строку&#039;&#039;&#039;. Например:&amp;lt;pre&amp;gt;&lt;br /&gt;
example.com&lt;br /&gt;
streaming-service.net&lt;br /&gt;
another-site.org&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d1ecf1; border-left: 4px solid #17a2b8; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Совет:&#039;&#039;&#039; В режиме Inline можно вставить тысячи строк сразу — поддержка большого списка предусмотрена. Один домен покрывает и сам сайт, и все его поддомены. Если вместо Inline хочется автоматическую подписку — выберите вариант &#039;&#039;&#039;URL&#039;&#039;&#039; и укажите адрес внешнего списка; keen-pbr будет обновлять его по расписанию.&lt;br /&gt;
&amp;lt;/div&amp;gt;Сохранить.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: форма создания списка с textarea, в которую вставлены домены.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3: Создать правило маршрутизации ===&lt;br /&gt;
В меню слева: &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Правила маршрутизации&#039;&#039;&#039; → &#039;&#039;&#039;Создать&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Заполните:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;List(s)&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; (выбрать из выпадающего)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Outbound&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (наш только что созданный)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Enabled&#039;&#039;&#039;&lt;br /&gt;
|включить&lt;br /&gt;
|}&lt;br /&gt;
Сохранить.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4: Применить изменения ===&lt;br /&gt;
Внизу страницы появится кнопка &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039;. Нажмите её — keen-pbr перестроит конфигурацию dnsmasq и применит новые правила маршрутизации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница &amp;quot;Правила маршрутизации&amp;quot; с активным правилом и кнопкой &amp;quot;Применить&amp;quot;.)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== 3.10. Тестирование ==&lt;br /&gt;
На клиентском устройстве, подключённом к Keenetic:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Очистите кеш DNS&#039;&#039;&#039; (важно — без этого старые ответы остаются):&lt;br /&gt;
#* Windows: &amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; в PowerShell.&lt;br /&gt;
#* Android / iOS: переподключиться к Wi-Fi (off → on).&lt;br /&gt;
#* macOS: &amp;lt;code&amp;gt;sudo dscacheutil -flushcache&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Перезапустите браузер (у него свой DNS-кеш).&lt;br /&gt;
# Откройте сайт из списка.&lt;br /&gt;
# Параллельно откройте &amp;lt;code&amp;gt;https://api.ipify.org&amp;lt;/code&amp;gt; в браузере. Адрес должен быть тот же, который вы видели в проверке туннеля sing-box (т.е. IP вашего VPN-провайдера, а не домашний WAN-IP).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: страница api.ipify.org с подменённым IP.)&#039;&#039;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Установка nfqws2 =&lt;br /&gt;
nfqws2 — это userspace-демон, который через очередь NFQUEUE перехватывает первые пакеты соединений и модифицирует их так, чтобы DPI-фильтры не распознали трафик. Используется для обхода замедления сервисов потокового видео, голосовой связи и т.п. — &#039;&#039;&#039;без необходимости заворачивать их в туннель&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 4.1. Подключение репозитория ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Установка пакета ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После установки сервис стартует автоматически — вмешательства не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Ожидаемый результат:&#039;&#039;&#039;&amp;lt;pre&amp;gt;&lt;br /&gt;
Service NFQWS2 is running&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Что обрабатывается по умолчанию ===&lt;br /&gt;
В заводском конфиге работает режим &amp;lt;code&amp;gt;MODE_AUTO&amp;lt;/code&amp;gt; — комбинация:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Список&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/user.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, для которых &#039;&#039;&#039;всегда&#039;&#039;&#039; применяется обход (по умолчанию ~280 строк: Google/YouTube/CDN сервисы).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/auto.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые nfqws2 &#039;&#039;&#039;сам обнаружил&#039;&#039;&#039; как замедленные/блокируемые. Заполняется автоматически.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/nfqws2/lists/exclude.list&amp;lt;/code&amp;gt;&lt;br /&gt;
|Домены, которые &#039;&#039;&#039;нельзя&#039;&#039;&#039; трогать (по умолчанию: домены KeeneticOS, чтобы не сломать облачные сервисы прошивки).&lt;br /&gt;
|}&lt;br /&gt;
Покрываемые протоколы: HTTPS (TCP/443), HTTP (TCP/80), QUIC (UDP/443), Discord voice, WireGuard handshake, STUN/TURN, Telegram MTProto.&lt;br /&gt;
&lt;br /&gt;
== 4.3. (опционально) Веб-интерфейс ==&lt;br /&gt;
Для удобной работы со списками и стратегиями есть отдельный пакет с веб-UI.&lt;br /&gt;
&lt;br /&gt;
=== Подключение repo ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Установка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg install nfqws-keenetic-web&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Пакет потянет lighttpd + PHP 8 — общий размер около &#039;&#039;&#039;10 МБ&#039;&#039;&#039;. После установки лёгкий веб-сервер запустится автоматически.&lt;br /&gt;
&lt;br /&gt;
=== Доступ ===&lt;br /&gt;
Веб-морда слушает на порту &#039;&#039;&#039;90&#039;&#039;&#039;:&amp;lt;pre&amp;gt;&lt;br /&gt;
http://LAN-АДРЕС-РОУТЕРА:90&lt;br /&gt;
&amp;lt;/pre&amp;gt;Для доступа из другой подсети — открыть порт &amp;lt;code&amp;gt;90&amp;lt;/code&amp;gt; в фаерволе Keenetic (по аналогии с keen-pbr).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Скриншот: главная страница UI nfqws-keenetic-web.)&#039;&#039;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Финальная архитектура =&lt;br /&gt;
После завершения всех этапов на роутере работают четыре сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Порт / Управление&lt;br /&gt;
!Что делает&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;sing-box&#039;&#039;&#039;&lt;br /&gt;
|TUN-интерфейс &amp;lt;code&amp;gt;singtun&amp;lt;/code&amp;gt;; Clash API на &amp;lt;code&amp;gt;:9090&amp;lt;/code&amp;gt;&lt;br /&gt;
|Шифрует и пересылает трафик в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;keen-pbr&#039;&#039;&#039;&lt;br /&gt;
|Web UI на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;&lt;br /&gt;
|Решает, какой трафик отправить в туннель&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;nfqws2&#039;&#039;&#039;&lt;br /&gt;
|Демон, без отдельного порта (управление через файлы или nfqws-keenetic-web на &amp;lt;code&amp;gt;:90&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Обходит DPI-фильтры для прямого трафика&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Entware OpenSSH&#039;&#039;&#039;&lt;br /&gt;
|TCP &amp;lt;code&amp;gt;:2022&amp;lt;/code&amp;gt; (если настраивали) / &amp;lt;code&amp;gt;:222&amp;lt;/code&amp;gt; dropbear&lt;br /&gt;
|Удалённое управление&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                  K E E N E T I C   Р О У Т Е Р&lt;br /&gt;
   ┌───────────────────────────────────────────────────────────────────────────┐&lt;br /&gt;
   │                                                                           │&lt;br /&gt;
   │   ┌──────────────┐                                                        │&lt;br /&gt;
LAN│   │  DNS-запрос  │                                                        │&lt;br /&gt;
───┼──►│  от клиента  │                                                        │&lt;br /&gt;
   │   └──────┬───────┘                                                        │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │          ▼                                                                │&lt;br /&gt;
   │   ┌──────────────┐  upstream  ┌────────────────┐                          │&lt;br /&gt;
   │   │  keen-pbr    │  через     │  Cloudflare    │                          │&lt;br /&gt;
   │   │  dnsmasq     │ ─────────► │  / Quad9       │                          │&lt;br /&gt;
   │   │  на :53      │            │                │                          │&lt;br /&gt;
   │   └──────┬───────┘            └────────────────┘                          │&lt;br /&gt;
   │          │ IP → ipset                                                     │&lt;br /&gt;
   │          │                                                                │&lt;br /&gt;
   │   ┌──────▼──────────────────────────────────────────────┐                 │&lt;br /&gt;
LAN│   │  iptables / маршрутизация                           │                 │&lt;br /&gt;
───┼──►│  ├ если dst-IP в ipset bypass:                      │                 │&lt;br /&gt;
TCP│   │  │   fwmark → ip rule → table 151 → singtun         │                 │&lt;br /&gt;
   │   │  │                                                  │                 │&lt;br /&gt;
   │   │  └ иначе:                                           │                 │&lt;br /&gt;
   │   │      обычный WAN-маршрут                            │                 │&lt;br /&gt;
   │   │      └ nfqws2 ловит первые пакеты                   │                 │&lt;br /&gt;
   │   │        и модифицирует для обхода DPI                │                 │&lt;br /&gt;
   │   └────┬──────────────────────────────────────────┬─────┘                 │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          ▼                       │&lt;br /&gt;
   │   ┌─────────┐                            ┌────────────────┐               │&lt;br /&gt;
   │   │ singtun │                            │ WAN-интерфейс  │               │&lt;br /&gt;
   │   │ (TUN)   │                            │ (ваш провайдер)│               │&lt;br /&gt;
   │   └────┬────┘                            └────────┬───────┘               │&lt;br /&gt;
   │        │                                          │                       │&lt;br /&gt;
   │        ▼                                          │                       │&lt;br /&gt;
   │   ┌─────────────┐                                 │                       │&lt;br /&gt;
   │   │  sing-box   │                                 │                       │&lt;br /&gt;
   │   │  outbound:  │                                 │                       │&lt;br /&gt;
   │   │  hysteria2  │                                 │                       │&lt;br /&gt;
   │   └──────┬──────┘                                 │                       │&lt;br /&gt;
   │          │                                        │                       │&lt;br /&gt;
   └──────────┼────────────────────────────────────────┼───────────────────────┘&lt;br /&gt;
              │                                        │&lt;br /&gt;
              ▼                                        ▼&lt;br /&gt;
        ┌───────────┐                            ┌───────────┐&lt;br /&gt;
        │ VPN-узел  │                            │ Любой     │&lt;br /&gt;
        │ провайдера│                            │ интернет  │&lt;br /&gt;
        └───────────┘                            └───────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&#039;&#039;(Здесь можно перерисовать в Mermaid/Excalidraw для финальной картинки.)&#039;&#039;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Эксплуатация =&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список keen-pbr ==&lt;br /&gt;
&lt;br /&gt;
# Открыть UI keen-pbr на &amp;lt;code&amp;gt;:12121&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Правила трафика&#039;&#039;&#039; → &#039;&#039;&#039;Списки&#039;&#039;&#039; → выбрать список &amp;lt;code&amp;gt;bypass&amp;lt;/code&amp;gt; → &#039;&#039;&#039;Изменить&#039;&#039;&#039;.&lt;br /&gt;
# Добавить новые домены в textarea, &#039;&#039;&#039;Сохранить&#039;&#039;&#039;.&lt;br /&gt;
# Нажать &#039;&#039;&#039;«Применить и перезапустить»&#039;&#039;&#039; внизу страницы.&lt;br /&gt;
&lt;br /&gt;
== Добавление новых доменов в список nfqws2 ==&lt;br /&gt;
&lt;br /&gt;
=== Через файл ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;new-site.com&#039; &amp;gt;&amp;gt; /opt/etc/nfqws2/lists/user.list&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Через веб-UI ===&lt;br /&gt;
Открыть &amp;lt;code&amp;gt;http://LAN-АДРЕС-РОУТЕРА:90&amp;lt;/code&amp;gt;, секция работы со списками.&lt;br /&gt;
&lt;br /&gt;
== Обновление компонентов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
opkg update&lt;br /&gt;
opkg upgrade sing-box-go keen-pbr nfqws2-keenetic&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После обновления может потребоваться перезапуск сервисов или роутера.&lt;br /&gt;
&lt;br /&gt;
== Просмотр логов ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сервис&lt;br /&gt;
!Команда&lt;br /&gt;
|-&lt;br /&gt;
|sing-box&lt;br /&gt;
|grep sing-box&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr&lt;br /&gt;
|grep keen-pbr + системный журнал в веб-UI Keenetic&lt;br /&gt;
|-&lt;br /&gt;
|nfqws2&lt;br /&gt;
|&amp;lt;code&amp;gt;tail -f /opt/var/log/nfqws2.log&amp;lt;/code&amp;gt; (если включено логирование в конфиге)&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Диагностика =&lt;br /&gt;
&lt;br /&gt;
== Проверка статусов всех сервисов ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/etc/init.d/S99sing-box status&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr status&lt;br /&gt;
/opt/etc/init.d/S51nfqws2 status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка туннеля ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Через локальный mixed-proxy sing-box&lt;br /&gt;
curl -sS --socks5-hostname 192.168.10.1:7891 https://api.ipify.org&lt;br /&gt;
&lt;br /&gt;
# Прямо через TUN (если интерфейс на роутере)&lt;br /&gt;
curl -sS --interface singtun https://api.ipify.org&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Проверка DNS keen-pbr ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nslookup example.com 127.0.0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если получаете адрес из &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt; — значит DNS-фильтр прошивки подменяет ответ. Замените upstream-DNS на публичные (см. этап 3.7).&lt;br /&gt;
&lt;br /&gt;
== Проверка ipset и маршрутизации ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Какие IP уложены в bypass-список&lt;br /&gt;
ipset list kpbr4d_bypass | tail -20&lt;br /&gt;
&lt;br /&gt;
# Маршрутная таблица куда идёт помеченный трафик&lt;br /&gt;
ip route show table 151&lt;br /&gt;
# Должна быть строка вида: default dev singtun scope link&lt;br /&gt;
&lt;br /&gt;
# Помечает ли iptables пакеты&lt;br /&gt;
iptables -t mangle -L KeenPbrTable -n -v&lt;br /&gt;
# Счётчики MARK должны увеличиваться при тестовом запросе&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Частые проблемы ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Симптом&lt;br /&gt;
!Причина&lt;br /&gt;
!Решение&lt;br /&gt;
|-&lt;br /&gt;
|У клиентов нет интернета совсем&lt;br /&gt;
|dnsmasq keen-pbr остановлен или поломан&lt;br /&gt;
|Откатить &amp;lt;code&amp;gt;opkg dns-override&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;192.168.1.1/a&amp;lt;/code&amp;gt;:&amp;lt;pre&amp;gt;no opkg dns-override&lt;br /&gt;
system configuration save&amp;lt;/pre&amp;gt;и перезагрузить роутер&lt;br /&gt;
|-&lt;br /&gt;
|Сайт из списка не открывается, но другие работают&lt;br /&gt;
|Старый DNS-кеш на клиенте&lt;br /&gt;
|&amp;lt;code&amp;gt;ipconfig /flushdns&amp;lt;/code&amp;gt; + перезапуск браузера&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nslookup site.com 127.0.0.1&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;198.18.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|DNS прошивки подменяет ответы&lt;br /&gt;
|Заменить upstream на &amp;lt;code&amp;gt;1.1.1.1&amp;lt;/code&amp;gt; в &amp;lt;code&amp;gt;/opt/etc/keen-pbr/config.json&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|keen-pbr UI показывает &amp;quot;dnsmasq недоступен&amp;quot;&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt; не содержит секцию &amp;lt;code&amp;gt;conf-script=...&amp;lt;/code&amp;gt; keen-pbr&lt;br /&gt;
|Скопировать шаблон: &amp;lt;code&amp;gt;cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Домены в списке резолвятся в реальный IP, но не открываются (таймаут)&lt;br /&gt;
|Нет NAT/FORWARD-правил для singtun&lt;br /&gt;
|Проверить наличие скрипта &amp;lt;code&amp;gt;/opt/etc/init.d/S81keen-pbr-fixup&amp;lt;/code&amp;gt; и запустить его вручную&lt;br /&gt;
|-&lt;br /&gt;
|sing-box не стартует, в логе &amp;quot;no firewall backend&amp;quot;&lt;br /&gt;
|В PATH процесса нет &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запускать только через init-скрипт &amp;lt;code&amp;gt;/opt/etc/init.d/S99sing-box&amp;lt;/code&amp;gt; (он сам задаёт PATH)&lt;br /&gt;
|-&lt;br /&gt;
|YouTube/Discord работают медленно или не работают&lt;br /&gt;
|nfqws2 не запущен или его правила не применены&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/etc/init.d/S51nfqws2 status&amp;lt;/code&amp;gt; и при необходимости &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Шпаргалка (все команды на одной странице) =&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# === 1. ENTWARE (выполняется в командной строке Keenetic) ===&lt;br /&gt;
opkg disk ВАШ_ID_USB_ДИСКА:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz&lt;br /&gt;
system configuration save&lt;br /&gt;
&lt;br /&gt;
# === 2. После SSH-входа на :222 ===&lt;br /&gt;
passwd  # сменить пароль root&lt;br /&gt;
&lt;br /&gt;
# === 3. sing-box ===&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install sing-box-go&lt;br /&gt;
# Поместить рабочий config.json в /opt/etc/sing-box/&lt;br /&gt;
sing-box check -c /opt/etc/sing-box/config.json&lt;br /&gt;
/opt/etc/init.d/S99sing-box start&lt;br /&gt;
&lt;br /&gt;
# === 4. keen-pbr ===&lt;br /&gt;
echo &#039;src/gz keen-pbr https://repo.keen-pbr.fyi/repository/stable/keenetic/current/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install keen-pbr&lt;br /&gt;
cp /opt/usr/lib/keen-pbr/dnsmasq.conf.template /opt/etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
# Через 192.168.1.1/a:&lt;br /&gt;
#   opkg dns-override&lt;br /&gt;
#   system configuration save&lt;br /&gt;
#   system reboot&lt;br /&gt;
&lt;br /&gt;
# Скрипт NAT/FORWARD:&lt;br /&gt;
cat &amp;gt; /opt/etc/init.d/S81keen-pbr-fixup &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
PATH=/opt/sbin:/opt/usr/sbin:/opt/bin:/opt/usr/bin:$PATH&lt;br /&gt;
TUN_IFACE=singtun&lt;br /&gt;
LAN_IFACE=br0&lt;br /&gt;
for i in 1 2 3 4 5 6 7 8 9 10; do&lt;br /&gt;
  ip link show $TUN_IFACE &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 &amp;amp;&amp;amp; break&lt;br /&gt;
  sleep 1&lt;br /&gt;
done&lt;br /&gt;
iptables -t nat -C POSTROUTING -o $TUN_IFACE -j MASQUERADE 2&amp;gt;/dev/null || iptables -t nat -A POSTROUTING -o $TUN_IFACE -j MASQUERADE&lt;br /&gt;
iptables -C FORWARD -i $LAN_IFACE -o $TUN_IFACE -j ACCEPT 2&amp;gt;/dev/null || iptables -I FORWARD 1 -i $LAN_IFACE -o $TUN_IFACE -j ACCEPT&lt;br /&gt;
iptables -C FORWARD -i $TUN_IFACE -o $LAN_IFACE -j ACCEPT 2&amp;gt;/dev/null || iptables -I FORWARD 1 -i $TUN_IFACE -o $LAN_IFACE -j ACCEPT&lt;br /&gt;
EOF&lt;br /&gt;
chmod +x /opt/etc/init.d/S81keen-pbr-fixup&lt;br /&gt;
/opt/etc/init.d/S81keen-pbr-fixup&lt;br /&gt;
&lt;br /&gt;
# Замена DNS на 1.1.1.1/9.9.9.9 в /opt/etc/keen-pbr/config.json (см. этап 3.7)&lt;br /&gt;
/opt/etc/init.d/S80keen-pbr restart&lt;br /&gt;
&lt;br /&gt;
# === 5. nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws2-keenetic https://nfqws.github.io/nfqws2-keenetic/mipsel&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws2-keenetic&lt;br /&gt;
# Уже запущен автоматически&lt;br /&gt;
&lt;br /&gt;
# === 6. (опц) Веб-UI для nfqws2 ===&lt;br /&gt;
echo &#039;src/gz nfqws-keenetic-web https://nfqws.github.io/nfqws-keenetic-web/all&#039; &amp;gt;&amp;gt; /opt/etc/opkg.conf&lt;br /&gt;
opkg update&lt;br /&gt;
opkg install nfqws-keenetic-web&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
----&amp;lt;div style=&amp;quot;padding: 10px 15px; margin: 10px 0; background-color: #d4edda; border-left: 4px solid #28a745; border-radius: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ссылки на проекты:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Entware: &amp;lt;code&amp;gt;https://github.com/Entware/Entware&amp;lt;/code&amp;gt;&lt;br /&gt;
* sing-box: &amp;lt;code&amp;gt;https://sing-box.sagernet.org&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/SagerNet/sing-box&amp;lt;/code&amp;gt;&lt;br /&gt;
* keen-pbr: &amp;lt;code&amp;gt;https://keen-pbr.fyi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;https://github.com/maksimkurb/keen-pbr&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws2-keenetic: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws2-keenetic&amp;lt;/code&amp;gt;&lt;br /&gt;
* nfqws-keenetic-web: &amp;lt;code&amp;gt;https://github.com/nfqws/nfqws-keenetic-web&amp;lt;/code&amp;gt;&lt;br /&gt;
* zapret (upstream): &amp;lt;code&amp;gt;https://github.com/bol-van/zapret&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A1%D1%83%D0%B2%D0%B5%D1%80%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82&amp;diff=976</id>
		<title>Суверенный интернет</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A1%D1%83%D0%B2%D0%B5%D1%80%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82&amp;diff=976"/>
		<updated>2026-05-12T07:04:25Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Эта страница посвящается всему что связано с ограничим доступа в интернет.&lt;br /&gt;
&lt;br /&gt;
На данный момент 20.04.26 мы имеем полную блокировку по белыми IP у операторов мобильной связи. И предпосылки к блокировкам на уровне провайдеров домашнего интернета.&lt;br /&gt;
&lt;br /&gt;
* [[Обход НКР|Установка и настройка связки Zapret + Podkop на OpenWRT]]&lt;br /&gt;
* [[Hysteria 2 каскад]]&lt;br /&gt;
* [[Whitelist-bypass: VK Creator (headless на сервере) + Joiner (Android)]]&lt;br /&gt;
* [[Установка MTProto Proxy (mtg) на Linux-сервере]]&lt;br /&gt;
* [[VK Turn Proxy + FreeTurn + VLESS]]&lt;br /&gt;
* [[NaïveProxy: установка полной каскадной цепочки]]&lt;br /&gt;
* [[OlcRTC: туннель через WebRTC-сервисы|olcRTC: туннель через легальные WebRTC-сервисы]]&lt;br /&gt;
* [[mieru: каскадный шифрованный SOCKS5-туннель]]&lt;br /&gt;
* Гибкая маршрутизация и обход DPI на Keenetic (sing-box + keen-pbr + nfqws2)&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=Mieru:_%D0%BA%D0%B0%D1%81%D0%BA%D0%B0%D0%B4%D0%BD%D1%8B%D0%B9_%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9_SOCKS5-%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D1%8C&amp;diff=975</id>
		<title>Mieru: каскадный шифрованный SOCKS5-туннель</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=Mieru:_%D0%BA%D0%B0%D1%81%D0%BA%D0%B0%D0%B4%D0%BD%D1%8B%D0%B9_%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9_SOCKS5-%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D1%8C&amp;diff=975"/>
		<updated>2026-05-10T20:22:09Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* Поток данных в одиночном режиме */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= mieru: каскадный шифрованный SOCKS5-туннель с устойчивостью к классификации трафика =&lt;br /&gt;
&lt;br /&gt;
== Введение ==&lt;br /&gt;
&lt;br /&gt;
=== Что такое mieru ===&lt;br /&gt;
&#039;&#039;&#039;mieru&#039;&#039;&#039; (見える, «видимый») — это криптографически защищённый прокси-протокол, ориентированный на работу в средах с активным DPI и статистическим анализом сетевого трафика. В отличие от большинства современных туннелей, mieru &#039;&#039;&#039;не использует TLS&#039;&#039;&#039; и &#039;&#039;&#039;не маскируется под легитимный сайт&#039;&#039;&#039;. Вместо этого он подаёт на провод поток, который при пассивном анализе выглядит как случайные байты или произвольный текстовый протокол — без узнаваемых заголовков, фиксированных длин и характерных handshake-паттернов.&lt;br /&gt;
&lt;br /&gt;
Программный пакет состоит из двух самостоятельных бинарников:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Бинарник&lt;br /&gt;
!Роль&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mita&amp;lt;/code&amp;gt;&lt;br /&gt;
|Серверная часть. Принимает зашифрованные соединения, аутентифицирует пользователей, переправляет полезную нагрузку наружу&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mieru&amp;lt;/code&amp;gt;&lt;br /&gt;
|Клиентская часть. Поднимает локальный SOCKS5-прокси на машине пользователя; всё, что в него пришло, шифруется и отправляется на &amp;lt;code&amp;gt;mita&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Когда применяется ===&lt;br /&gt;
&lt;br /&gt;
* Канал между клиентом и обычными VPN-серверами проходит через инфраструктуру с DPI или ML-классификацией протоколов.&lt;br /&gt;
* Нужен альтернативный канал, не зависящий от валидного TLS-сертификата и собственного домена (mieru вообще не требует доменного имени).&lt;br /&gt;
* Нужна устойчивость к активному зондированию: сервер mieru, в отличие от REALITY-/Trojan-серверов, при попытке зондирования просто &#039;&#039;&#039;молчит&#039;&#039;&#039;, не имитируя ни сайта-донора, ни TLS-handshake — нечего фингерпринтить.&lt;br /&gt;
&lt;br /&gt;
=== Сравнение с другими методами туннелирования ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Метод&lt;br /&gt;
!Транспорт&lt;br /&gt;
!Маскировка&lt;br /&gt;
!Требует домен и TLS&lt;br /&gt;
!Устойчивость к ML-классификации&lt;br /&gt;
|-&lt;br /&gt;
|WireGuard&lt;br /&gt;
|UDP&lt;br /&gt;
|нет (явный WG)&lt;br /&gt;
|нет&lt;br /&gt;
|низкая&lt;br /&gt;
|-&lt;br /&gt;
|OpenVPN&lt;br /&gt;
|UDP/TCP&lt;br /&gt;
|нет&lt;br /&gt;
|опционально&lt;br /&gt;
|низкая&lt;br /&gt;
|-&lt;br /&gt;
|Shadowsocks-AEAD-2022&lt;br /&gt;
|TCP&lt;br /&gt;
|случайный шум&lt;br /&gt;
|нет&lt;br /&gt;
|средняя&lt;br /&gt;
|-&lt;br /&gt;
|VLESS + REALITY&lt;br /&gt;
|TCP (TLS)&lt;br /&gt;
|TLS-handshake чужого сайта&lt;br /&gt;
|да&lt;br /&gt;
|высокая (внутри пула TLS)&lt;br /&gt;
|-&lt;br /&gt;
|NaiveProxy&lt;br /&gt;
|TCP (HTTP/2)&lt;br /&gt;
|Chromium-стек, неотличим от HTTPS&lt;br /&gt;
|да&lt;br /&gt;
|высокая (внутри пула HTTPS)&lt;br /&gt;
|-&lt;br /&gt;
|Hysteria2&lt;br /&gt;
|UDP (QUIC)&lt;br /&gt;
|QUIC поверх UDP с маскировкой под HTTPS&lt;br /&gt;
|да&lt;br /&gt;
|высокая (внутри пула QUIC)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;mieru&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;TCP / UDP, без TLS&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;случайный шум либо текстоподобный поток (через traffic pattern)&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;нет — только пара логин/пароль&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;высокая (специальная подгонка энтропии и ASCII)&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Принципы работы ==&lt;br /&gt;
&lt;br /&gt;
=== Поток данных в одиночном режиме ===&lt;br /&gt;
[[Файл:Mieru-single-flow.png|центр|685x685px|Поток данных одиночного mieru: клиент → SOCKS5 → mieru → шифр → mita → интернет]]&lt;br /&gt;
=== Каскадный режим (двухзвенный) ===&lt;br /&gt;
В каскаде роль обычного «сервера» выполняют два узла. Первый принимает клиентов и не выходит в интернет напрямую; вместо этого он переправляет уже расшифрованный трафик во второй узел через тот же протокол mieru. Второй узел осуществляет финальный egress.&lt;br /&gt;
[[Файл:Mieru-cascade-flow.png|центр|1010x1010px|Поток данных каскадного mieru: Сервер A (frontend) → Сервер B (backend) → egress]]&lt;br /&gt;
=== Зачем разделять frontend и backend ===&lt;br /&gt;
&lt;br /&gt;
* Адрес backend-сервера никогда не виден клиентскому ПО. Если frontend замечен и заблокирован — backend остаётся неизвестным наблюдателям и переиспользуется со следующим frontend.&lt;br /&gt;
* Frontend хранит &#039;&#039;&#039;только&#039;&#039;&#039; учётки клиентов и не имеет финального egress. Компрометация его конфига не раскрывает финальный IP.&lt;br /&gt;
* Двойное шифрование mieru на каждом плече: каждый сегмент дважды проходит AEAD с разными ключами, что усложняет статистический анализ.&lt;br /&gt;
&lt;br /&gt;
=== Шифрование и аутентификация ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Алгоритм&lt;br /&gt;
|XChaCha20-Poly1305 (AEAD) с 24-байтным nonce&lt;br /&gt;
|-&lt;br /&gt;
|Длина ключа&lt;br /&gt;
|32 байта&lt;br /&gt;
|-&lt;br /&gt;
|Метод выработки ключа&lt;br /&gt;
|PBKDF2-SHA256, 64 итерации, соль = SHA-256 от текущего времени, округлённого до 2 минут&lt;br /&gt;
|-&lt;br /&gt;
|Идентификатор пользователя в пакете&lt;br /&gt;
|Последние 4 байта nonce заменены на префикс SHA-256 от &amp;lt;code&amp;gt;username + nonce[0:16]&amp;lt;/code&amp;gt;; имя пользователя на провод не передаётся&lt;br /&gt;
|-&lt;br /&gt;
|Защита от reuse&lt;br /&gt;
|Проверка nonce-кэша на серверной стороне; повторный пакет отбрасывается&lt;br /&gt;
|}&lt;br /&gt;
Ключ шифрования &#039;&#039;&#039;не передаётся&#039;&#039;&#039; через канал и нигде не хранится в виде сериализованной строки: он каждый раз генерируется на лету из пары логин+пароль и текущего времени. Из этого следует одно практическое требование, которое легко не заметить.&lt;br /&gt;
&lt;br /&gt;
==== Требование к синхронизации часов ====&lt;br /&gt;
Расхождение системного времени клиента и сервера &#039;&#039;&#039;не должно превышать 4 минуты&#039;&#039;&#039;. При большем расхождении ключ, выработанный клиентом, не сойдётся с ключом сервера, и подключения будут &#039;&#039;&#039;молча&#039;&#039;&#039; падать (без явной ошибки в логах). На обоих серверах и на клиентском устройстве должен работать NTP-демон.&lt;br /&gt;
&lt;br /&gt;
=== Формат сегмента ===&lt;br /&gt;
[[Файл:Mieru-segment-format.png|центр|984x984px|Формат сегмента mieru: padding, nonce, шифр-метаданные, шифр-полезная нагрузка]]Ключевое отличие от других протоколов: &#039;&#039;&#039;ВСЕ&#039;&#039;&#039; структурные поля сегмента (тип, размер, sequence number, ID сессии и пр.) находятся внутри поля &amp;lt;code&amp;gt;enc-meta&amp;lt;/code&amp;gt; — то есть зашифрованы. Снаружи невозможно даже определить, что это за пакет, какой длины полезная нагрузка, в начале или в середине сессии находится клиент. Видны только три зоны паддинга и зашифрованные блобы.&lt;br /&gt;
&lt;br /&gt;
=== Traffic pattern (опциональная подгонка маскировки) ===&lt;br /&gt;
mieru предоставляет два независимых механизма для подмены статистических признаков шифр-трафика на «обычные»:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Опция&lt;br /&gt;
!Что делает&lt;br /&gt;
!Накладные расходы&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;tcpFragment&amp;lt;/code&amp;gt;&lt;br /&gt;
|Дробит TCP-пакеты на мелкие куски и вставляет случайную задержку между ними. Цель — сломать узнаваемость «один большой шифр-стрим»&lt;br /&gt;
| +латентность до &amp;lt;code&amp;gt;maxSleepMs&amp;lt;/code&amp;gt; мс на каждый фрагмент&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nonce.NONCE_TYPE_PRINTABLE&amp;lt;/code&amp;gt;&lt;br /&gt;
|Подменяет первые N байт nonce печатными ASCII-символами. Цель — увести классификатор «высокая энтропия от нулевого байта» в ложное «это текстовый протокол»&lt;br /&gt;
|почти ноль (только подмена байтов)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nonce.NONCE_TYPE_FIXED&amp;lt;/code&amp;gt;&lt;br /&gt;
|Подменяет первые байты nonce фиксированными hex-строками из списка. Цель — имитировать конкретный фиксированный заголовок&lt;br /&gt;
|ноль&lt;br /&gt;
|}&lt;br /&gt;
Включение traffic pattern имеет смысл &#039;&#039;&#039;только&#039;&#039;&#039; на видимом анализатором плече (клиент → frontend). На внутреннем плече каскада (frontend → backend) это лишний overhead.&lt;br /&gt;
&lt;br /&gt;
=== Многопользовательский режим ===&lt;br /&gt;
Один сервер mita может обслуживать неограниченное число учёток одновременно. Каждый user — это пара &amp;lt;code&amp;gt;(name, password)&amp;lt;/code&amp;gt;; лимит по числу одновременных сессий внутри одной учётки &#039;&#039;&#039;не задан в протоколе&#039;&#039;&#039; (можно опционально настраивать квоты по объёму трафика).&lt;br /&gt;
[[Файл:Mieru-multi-user.png|центр|958x958px|Многопользовательский режим: один сервер mita обслуживает несколько учёток одновременно]]Такая модель радикально отличается от mash-/torch-протоколов с архитектурой «один сервер — один пользователь»: вам &#039;&#039;&#039;не нужно&#039;&#039;&#039; создавать отдельный контейнер на каждого пользователя.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что должно быть на серверах перед установкой ==&lt;br /&gt;
&lt;br /&gt;
=== Минимальная конфигурация каждого сервера ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!№&lt;br /&gt;
!Требование&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Linux дистрибутив (Ubuntu 22.04+, Debian 12+, Fedora 38+ или сравнимый)&lt;br /&gt;
|Среда выполнения Docker&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|SSH-доступ с правами &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; либо аккаунт с &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; без пароля&lt;br /&gt;
|Установка пакетов и управление контейнерами&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Docker Engine 24.0+ и плагин Docker Compose v2.20+&lt;br /&gt;
|Запуск контейнеров mita и mieru&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|NTP-демон активен (&amp;lt;code&amp;gt;chrony&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;systemd-timesyncd&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Синхронизация часов в пределах 4 минут (см. раздел «Шифрование»)&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Открытый наружу TCP-диапазон (для нашей статьи — &amp;lt;code&amp;gt;2012-2022&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Принимающий порт mita&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Опциональная конфигурация: egress через сторонний прокси ===&lt;br /&gt;
По умолчанию backend-сервер выходит в интернет напрямую с публичного IP виртуальной машины. В качестве промежуточной цепочки часто используется выделенный SOCKS5-прокси, обслуживаемый сторонней панелью (например, &#039;&#039;&#039;3x-ui&#039;&#039;&#039; над xray-core).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!№&lt;br /&gt;
!Параметр&lt;br /&gt;
!Пример&lt;br /&gt;
!Комментарий&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|SOCKS5-inbound, слушающий &#039;&#039;&#039;только на &amp;lt;code&amp;gt;172.17.0.1&amp;lt;/code&amp;gt;&#039;&#039;&#039; (docker0-bridge gateway)&lt;br /&gt;
|порт &amp;lt;code&amp;gt;24366&amp;lt;/code&amp;gt;&lt;br /&gt;
|Слушать на &amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt; &#039;&#039;&#039;не подойдёт&#039;&#039;&#039;: контейнер mita с &amp;lt;code&amp;gt;network_mode: host&amp;lt;/code&amp;gt; увидит нужный адрес именно как &amp;lt;code&amp;gt;172.17.0.1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Аутентификация на этом inbound отключена&lt;br /&gt;
|—&lt;br /&gt;
|Можно включить и прописать креды в &amp;lt;code&amp;gt;egress.proxies&amp;lt;/code&amp;gt; mita, но без авторизации проще&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Routing-rule: трафик с этого inbound → нужный outbound (например, WireGuard-к-WARP, наружный VPN, сторонний прокси)&lt;br /&gt;
|—&lt;br /&gt;
|Зависит от вашей панели; в 3x-ui — раздел «Маршрутизация»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Проверка egress-цепочки ====&lt;br /&gt;
Команда выполняется на самом backend-сервере. Заменить &amp;lt;code&amp;gt;24366&amp;lt;/code&amp;gt; на ваш порт.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run --rm curlimages/curl:latest --max-time 12 --socks5 172.17.0.1:24366 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидание: IP вашего egress-узла (например, IP Cloudflare WARP или IP стороннего VPN). Если возвращается публичный IP вашей VM — egress не работает, проверьте routing панели.&lt;br /&gt;
&lt;br /&gt;
Если egress через сторонний прокси не нужен (готовы выходить с публичного IP backend-сервера) — пропустите этот раздел; в дальнейших шагах указания «без egress» помечены явно.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Параметры, которые нужно подготовить заранее ==&lt;br /&gt;
Перед началом установки заполните таблицу собственными значениями. На каждом шаге, где встретится плейсхолдер, мы будем ссылаться на эту таблицу.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Плейсхолдер&lt;br /&gt;
!Что это&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_FRONTEND_HOST&amp;lt;/code&amp;gt;&lt;br /&gt;
|Адрес frontend-сервера для SSH (IP, имя из &amp;lt;code&amp;gt;~/.ssh/config&amp;lt;/code&amp;gt; либо домен)&lt;br /&gt;
|&amp;lt;code&amp;gt;198.51.100.10&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_BACKEND_HOST&amp;lt;/code&amp;gt;&lt;br /&gt;
|Адрес backend-сервера для SSH&lt;br /&gt;
|&amp;lt;code&amp;gt;203.0.113.20&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_BACKEND_PUBLIC_IP&amp;lt;/code&amp;gt;&lt;br /&gt;
|Публичный IP backend-сервера, к которому будет коннектиться mieru-client с frontend&lt;br /&gt;
|&amp;lt;code&amp;gt;203.0.113.20&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_FRONTEND_PUBLIC_IP&amp;lt;/code&amp;gt;&lt;br /&gt;
|Публичный IP frontend-сервера, к которому будут коннектиться клиенты&lt;br /&gt;
|&amp;lt;code&amp;gt;198.51.100.10&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_BRIDGE_PASSWORD&amp;lt;/code&amp;gt;&lt;br /&gt;
|Пароль учётки mieru, которой mieru-client на frontend подключается к mita на backend. Один на оба узла&lt;br /&gt;
|длинная случайная строка, сгенерированная &amp;lt;code&amp;gt;openssl rand&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_CLIENT_PASSWORD&amp;lt;/code&amp;gt;&lt;br /&gt;
|Пароль первой клиентской учётки &amp;lt;code&amp;gt;client01&amp;lt;/code&amp;gt; на frontend&lt;br /&gt;
|длинная случайная строка&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_EGRESS_HOST&amp;lt;/code&amp;gt;&lt;br /&gt;
|Адрес SOCKS5-egress на backend (если используете)&lt;br /&gt;
|&amp;lt;code&amp;gt;172.17.0.1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_EGRESS_PORT&amp;lt;/code&amp;gt;&lt;br /&gt;
|Порт SOCKS5-egress&lt;br /&gt;
|&amp;lt;code&amp;gt;24366&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Сохраните таблицу в надёжное место — особенно пароли. Без них восстановить рабочее состояние нельзя.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Установка backend-сервера (точка выхода) ==&lt;br /&gt;
Все команды этого раздела выполняются на backend-сервере по SSH. Каждое пояснение — одна команда.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Подключение по SSH ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh root@YOUR_BACKEND_HOST&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Проверка Docker ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker --version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если выведено &amp;lt;code&amp;gt;Docker version 24.0.x&amp;lt;/code&amp;gt; или новее — переходите к шагу 3. Если &amp;lt;code&amp;gt;command not found&amp;lt;/code&amp;gt; — установите Docker по официальной инструкции для вашей ОС: &amp;lt;code&amp;gt;https://docs.docker.com/engine/install/&amp;lt;/code&amp;gt;. После установки вернитесь сюда.&lt;br /&gt;
&lt;br /&gt;
Дополнительно проверьте плагин Compose.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создание рабочего каталога ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/mieru-backend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/mieru-backend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Создание Dockerfile ===&lt;br /&gt;
Откройте файл для редактирования.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-backend/Dockerfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте следующее содержимое полностью.&amp;lt;syntaxhighlight lang=&amp;quot;dockerfile&amp;quot;&amp;gt;&lt;br /&gt;
ARG MIERU_VERSION=3.32.0&lt;br /&gt;
ARG TARGETARCH=amd64&lt;br /&gt;
&lt;br /&gt;
FROM alpine:3.19 AS downloader&lt;br /&gt;
ARG MIERU_VERSION&lt;br /&gt;
ARG TARGETARCH&lt;br /&gt;
RUN apk add --no-cache ca-certificates wget&lt;br /&gt;
WORKDIR /tmp/mita&lt;br /&gt;
RUN wget -qO- &amp;quot;https://github.com/enfein/mieru/releases/download/v${MIERU_VERSION}/mita_${MIERU_VERSION}_linux_${TARGETARCH}.tar.gz&amp;quot; | tar xz&lt;br /&gt;
WORKDIR /tmp/mieru&lt;br /&gt;
RUN wget -qO- &amp;quot;https://github.com/enfein/mieru/releases/download/v${MIERU_VERSION}/mieru_${MIERU_VERSION}_linux_${TARGETARCH}.tar.gz&amp;quot; | tar xz&lt;br /&gt;
&lt;br /&gt;
FROM alpine:3.19&lt;br /&gt;
RUN apk add --no-cache ca-certificates tini &amp;amp;&amp;amp; \&lt;br /&gt;
    adduser -H -D -g &amp;quot;&amp;quot; mita &amp;amp;&amp;amp; \&lt;br /&gt;
    adduser -H -D -g &amp;quot;&amp;quot; mieru&lt;br /&gt;
COPY --from=downloader /tmp/mita/mita /usr/local/bin/mita&lt;br /&gt;
COPY --from=downloader /tmp/mieru/mieru /usr/local/bin/mieru&lt;br /&gt;
RUN chmod +x /usr/local/bin/mita /usr/local/bin/mieru &amp;amp;&amp;amp; \&lt;br /&gt;
    mkdir -p /etc/mita /var/lib/mita /var/run/mita \&lt;br /&gt;
             /etc/mieru /var/lib/mieru /var/run/mieru /srv &amp;amp;&amp;amp; \&lt;br /&gt;
    chown -R mita:mita /etc/mita /var/lib/mita /var/run/mita &amp;amp;&amp;amp; \&lt;br /&gt;
    chown -R mieru:mieru /etc/mieru /var/lib/mieru /var/run/mieru&lt;br /&gt;
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh&lt;br /&gt;
RUN chmod +x /usr/local/bin/docker-entrypoint.sh&lt;br /&gt;
ENTRYPOINT [&amp;quot;/sbin/tini&amp;quot;,&amp;quot;--&amp;quot;,&amp;quot;/usr/local/bin/docker-entrypoint.sh&amp;quot;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Создание скрипта-entrypoint ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-backend/docker-entrypoint.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте полное содержимое.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
set -eu&lt;br /&gt;
&lt;br /&gt;
MODE=&amp;quot;${MIERU_MODE:-mita}&amp;quot;&lt;br /&gt;
CONFIG_FILE=&amp;quot;${MIERU_CONFIG:-/srv/config.json}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$MODE&amp;quot; in&lt;br /&gt;
    mita)  BIN=mita ;;&lt;br /&gt;
    mieru) BIN=mieru ;;&lt;br /&gt;
    *) echo &amp;quot;[entrypoint] FATAL: MIERU_MODE=&#039;$MODE&#039; (mita или mieru)&amp;quot;; exit 1 ;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
if [ ! -f &amp;quot;$CONFIG_FILE&amp;quot; ]; then&lt;br /&gt;
    echo &amp;quot;[entrypoint] WARN: $CONFIG_FILE не найден&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$MODE&amp;quot; = &amp;quot;mieru&amp;quot; ]; then&lt;br /&gt;
    if [ -f &amp;quot;$CONFIG_FILE&amp;quot; ]; then&lt;br /&gt;
        mieru apply config &amp;quot;$CONFIG_FILE&amp;quot; 2&amp;gt;&amp;amp;1&lt;br /&gt;
    fi&lt;br /&gt;
    exec mieru run&lt;br /&gt;
else&lt;br /&gt;
    apply_via_rpc() {&lt;br /&gt;
        i=0&lt;br /&gt;
        while [ &amp;quot;$i&amp;quot; -lt 30 ]; do&lt;br /&gt;
            i=$((i+1)); sleep 1&lt;br /&gt;
            if [ -f &amp;quot;$CONFIG_FILE&amp;quot; ] &amp;amp;&amp;amp; mita apply config &amp;quot;$CONFIG_FILE&amp;quot; &amp;gt;/tmp/apply.out 2&amp;gt;&amp;amp;1; then&lt;br /&gt;
                mita start &amp;gt;/tmp/start.out 2&amp;gt;&amp;amp;1&lt;br /&gt;
                return 0&lt;br /&gt;
            fi&lt;br /&gt;
        done&lt;br /&gt;
    }&lt;br /&gt;
    apply_via_rpc &amp;amp;&lt;br /&gt;
    exec mita run&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дайте файлу права на исполнение.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x /opt/mieru-backend/docker-entrypoint.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 6. Генерация пароля для bridge-учётки ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl rand -base64 24 | tr -d &#039;=/+&#039; | head -c 31&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Команда выведет одну строку из 31 символа. Скопируйте её и впишите в подготовленную таблицу как &amp;lt;code&amp;gt;YOUR_BRIDGE_PASSWORD&amp;lt;/code&amp;gt;. Этот же пароль понадобится на frontend-сервере (шаг ниже).&lt;br /&gt;
&lt;br /&gt;
=== Шаг 7. Создание серверного конфига ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-backend/server.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте содержимое и замените &amp;lt;code&amp;gt;YOUR_BRIDGE_PASSWORD&amp;lt;/code&amp;gt; на скопированное значение из шага 6.&lt;br /&gt;
&lt;br /&gt;
Если вы &#039;&#039;&#039;используете&#039;&#039;&#039; egress через сторонний SOCKS5-прокси — оставьте секцию &amp;lt;code&amp;gt;egress&amp;lt;/code&amp;gt; как есть и при необходимости подправьте &amp;lt;code&amp;gt;host&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;port&amp;lt;/code&amp;gt;. Если &#039;&#039;&#039;не используете&#039;&#039;&#039; — удалите всю секцию &amp;lt;code&amp;gt;egress&amp;lt;/code&amp;gt; от открывающей до закрывающей фигурной скобки.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;portBindings&amp;quot;: [&lt;br /&gt;
        {&amp;quot;portRange&amp;quot;: &amp;quot;2012-2022&amp;quot;, &amp;quot;protocol&amp;quot;: &amp;quot;TCP&amp;quot;}&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;users&amp;quot;: [&lt;br /&gt;
        {&amp;quot;name&amp;quot;: &amp;quot;frontend-bridge&amp;quot;, &amp;quot;password&amp;quot;: &amp;quot;YOUR_BRIDGE_PASSWORD&amp;quot;}&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;loggingLevel&amp;quot;: &amp;quot;INFO&amp;quot;,&lt;br /&gt;
    &amp;quot;mtu&amp;quot;: 1380,&lt;br /&gt;
    &amp;quot;egress&amp;quot;: {&lt;br /&gt;
        &amp;quot;proxies&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;external-egress&amp;quot;,&lt;br /&gt;
                &amp;quot;protocol&amp;quot;: &amp;quot;SOCKS5_PROXY_PROTOCOL&amp;quot;,&lt;br /&gt;
                &amp;quot;host&amp;quot;: &amp;quot;172.17.0.1&amp;quot;,&lt;br /&gt;
                &amp;quot;port&amp;quot;: 24366&lt;br /&gt;
            }&lt;br /&gt;
        ],&lt;br /&gt;
        &amp;quot;rules&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;ipRanges&amp;quot;: [&amp;quot;*&amp;quot;],&lt;br /&gt;
                &amp;quot;domainNames&amp;quot;: [&amp;quot;*&amp;quot;],&lt;br /&gt;
                &amp;quot;action&amp;quot;: &amp;quot;PROXY&amp;quot;,&lt;br /&gt;
                &amp;quot;proxyNames&amp;quot;: [&amp;quot;external-egress&amp;quot;]&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Защитите файл (содержит пароль).&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /opt/mieru-backend/server.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 8. Создание docker-compose.yml ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-backend/docker-compose.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте.&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  mita:&lt;br /&gt;
    build:&lt;br /&gt;
      context: .&lt;br /&gt;
      args:&lt;br /&gt;
        MIERU_VERSION: &amp;quot;3.32.0&amp;quot;&lt;br /&gt;
    image: mieru-bundle:3.32.0&lt;br /&gt;
    container_name: mita-backend&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    environment:&lt;br /&gt;
      MIERU_MODE: mita&lt;br /&gt;
      MIERU_CONFIG: /srv/server.json&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./server.json:/srv/server.json:ro&lt;br /&gt;
      - mita-state:/etc/mita&lt;br /&gt;
      - mita-runtime:/var/run/mita&lt;br /&gt;
      - mita-data:/var/lib/mita&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: json-file&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;10m&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  mita-state:&lt;br /&gt;
  mita-runtime:&lt;br /&gt;
  mita-data:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 9. Сборка образа ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-backend/docker-compose.yml build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сборка длится 1–3 минуты. По завершении выводится &amp;lt;code&amp;gt;Image mieru-bundle:3.32.0 Built&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 10. Запуск ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-backend/docker-compose.yml up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подождите 10 секунд.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sleep 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Проверьте логи.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs mita-backend --tail 25&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидаемые строки:&lt;br /&gt;
 [entrypoint] config применён (/srv/server.json)&lt;br /&gt;
 [entrypoint] mita start: OK&lt;br /&gt;
 mita server status is &amp;quot;RUNNING&amp;quot;&lt;br /&gt;
Проверьте, что сервер слушает порты &amp;lt;code&amp;gt;2012-2022&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -tlnp | grep -E &#039;:20(1[2-9]|2[012]) &#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должны появиться 11 строк со статусом &amp;lt;code&amp;gt;LISTEN&amp;lt;/code&amp;gt; и пользователем &amp;lt;code&amp;gt;mita&amp;lt;/code&amp;gt;. Если их нет — обратитесь к разделу «Поиск проблем».&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Установка frontend-сервера (точка входа) ==&lt;br /&gt;
Все команды этого раздела выполняются на frontend-сервере по SSH.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Подключение и подготовка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh root@YOUR_FRONTEND_HOST&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/mieru-frontend &amp;amp;&amp;amp; cd /opt/mieru-frontend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Dockerfile и entrypoint (одинаковые с backend) ===&lt;br /&gt;
Создайте оба файла так же, как на backend-сервере (см. шаги 4–5 раздела «Установка backend-сервера»). Содержимое идентично — образ универсальный, режим работы выбирается переменной окружения.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-frontend/Dockerfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;(вставьте тот же Dockerfile, что на backend)&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-frontend/docker-entrypoint.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;(вставьте тот же entrypoint)&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x /opt/mieru-frontend/docker-entrypoint.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Генерация пароля первой клиентской учётки ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl rand -base64 24 | tr -d &#039;=/+&#039; | head -c 31&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Скопируйте результат и впишите в таблицу как &amp;lt;code&amp;gt;YOUR_CLIENT_PASSWORD&amp;lt;/code&amp;gt;. Это пароль учётки &amp;lt;code&amp;gt;client01&amp;lt;/code&amp;gt;, который вы потом отдадите своему первому клиентскому устройству.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Серверный конфиг (mita-frontend) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-frontend/server.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Замените &amp;lt;code&amp;gt;YOUR_CLIENT_PASSWORD&amp;lt;/code&amp;gt; на значение из шага 3.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;portBindings&amp;quot;: [&lt;br /&gt;
        {&amp;quot;portRange&amp;quot;: &amp;quot;2012-2022&amp;quot;, &amp;quot;protocol&amp;quot;: &amp;quot;TCP&amp;quot;}&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;users&amp;quot;: [&lt;br /&gt;
        {&amp;quot;name&amp;quot;: &amp;quot;client01&amp;quot;, &amp;quot;password&amp;quot;: &amp;quot;YOUR_CLIENT_PASSWORD&amp;quot;}&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;loggingLevel&amp;quot;: &amp;quot;INFO&amp;quot;,&lt;br /&gt;
    &amp;quot;mtu&amp;quot;: 1380,&lt;br /&gt;
    &amp;quot;trafficPattern&amp;quot;: {&lt;br /&gt;
        &amp;quot;unlockAll&amp;quot;: false,&lt;br /&gt;
        &amp;quot;tcpFragment&amp;quot;: {&amp;quot;enable&amp;quot;: true, &amp;quot;maxSleepMs&amp;quot;: 10},&lt;br /&gt;
        &amp;quot;nonce&amp;quot;: {&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;NONCE_TYPE_PRINTABLE&amp;quot;,&lt;br /&gt;
            &amp;quot;minLen&amp;quot;: 6,&lt;br /&gt;
            &amp;quot;maxLen&amp;quot;: 8&lt;br /&gt;
        }&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;egress&amp;quot;: {&lt;br /&gt;
        &amp;quot;proxies&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;to-backend&amp;quot;,&lt;br /&gt;
                &amp;quot;protocol&amp;quot;: &amp;quot;SOCKS5_PROXY_PROTOCOL&amp;quot;,&lt;br /&gt;
                &amp;quot;host&amp;quot;: &amp;quot;127.0.0.1&amp;quot;,&lt;br /&gt;
                &amp;quot;port&amp;quot;: 1080&lt;br /&gt;
            }&lt;br /&gt;
        ],&lt;br /&gt;
        &amp;quot;rules&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;ipRanges&amp;quot;: [&amp;quot;*&amp;quot;],&lt;br /&gt;
                &amp;quot;domainNames&amp;quot;: [&amp;quot;*&amp;quot;],&lt;br /&gt;
                &amp;quot;action&amp;quot;: &amp;quot;PROXY&amp;quot;,&lt;br /&gt;
                &amp;quot;proxyNames&amp;quot;: [&amp;quot;to-backend&amp;quot;]&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните и защитите файл.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /opt/mieru-frontend/server.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Клиентский конфиг (mieru-client) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-frontend/client.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Замените &amp;lt;code&amp;gt;YOUR_BACKEND_PUBLIC_IP&amp;lt;/code&amp;gt; на публичный IP backend-сервера, &amp;lt;code&amp;gt;YOUR_BRIDGE_PASSWORD&amp;lt;/code&amp;gt; — на пароль bridge-учётки, который вы создавали на backend в шаге 6.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;profiles&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;profileName&amp;quot;: &amp;quot;default&amp;quot;,&lt;br /&gt;
            &amp;quot;user&amp;quot;: {&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;frontend-bridge&amp;quot;,&lt;br /&gt;
                &amp;quot;password&amp;quot;: &amp;quot;YOUR_BRIDGE_PASSWORD&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;servers&amp;quot;: [&lt;br /&gt;
                {&lt;br /&gt;
                    &amp;quot;ipAddress&amp;quot;: &amp;quot;YOUR_BACKEND_PUBLIC_IP&amp;quot;,&lt;br /&gt;
                    &amp;quot;portBindings&amp;quot;: [&lt;br /&gt;
                        {&amp;quot;portRange&amp;quot;: &amp;quot;2012-2022&amp;quot;, &amp;quot;protocol&amp;quot;: &amp;quot;TCP&amp;quot;}&lt;br /&gt;
                    ]&lt;br /&gt;
                }&lt;br /&gt;
            ],&lt;br /&gt;
            &amp;quot;mtu&amp;quot;: 1380,&lt;br /&gt;
            &amp;quot;multiplexing&amp;quot;: {&amp;quot;level&amp;quot;: &amp;quot;MULTIPLEXING_HIGH&amp;quot;},&lt;br /&gt;
            &amp;quot;handshakeMode&amp;quot;: &amp;quot;HANDSHAKE_NO_WAIT&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;activeProfile&amp;quot;: &amp;quot;default&amp;quot;,&lt;br /&gt;
    &amp;quot;rpcPort&amp;quot;: 8964,&lt;br /&gt;
    &amp;quot;socks5Port&amp;quot;: 1080,&lt;br /&gt;
    &amp;quot;loggingLevel&amp;quot;: &amp;quot;INFO&amp;quot;,&lt;br /&gt;
    &amp;quot;socks5ListenLAN&amp;quot;: false,&lt;br /&gt;
    &amp;quot;httpProxyListenLAN&amp;quot;: false&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните и защитите файл.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /opt/mieru-frontend/client.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 6. docker-compose.yml на frontend ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-frontend/docker-compose.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте.&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  mieru-client:&lt;br /&gt;
    build:&lt;br /&gt;
      context: .&lt;br /&gt;
      args:&lt;br /&gt;
        MIERU_VERSION: &amp;quot;3.32.0&amp;quot;&lt;br /&gt;
    image: mieru-bundle:3.32.0&lt;br /&gt;
    container_name: mieru-client&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    environment:&lt;br /&gt;
      MIERU_MODE: mieru&lt;br /&gt;
      MIERU_CONFIG: /srv/client.json&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./client.json:/srv/client.json:ro&lt;br /&gt;
      - mieru-client-state:/etc/mieru&lt;br /&gt;
      - mieru-client-runtime:/var/run/mieru&lt;br /&gt;
      - mieru-client-data:/var/lib/mieru&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: json-file&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;10m&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  mita:&lt;br /&gt;
    image: mieru-bundle:3.32.0&lt;br /&gt;
    container_name: mita-frontend&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    depends_on:&lt;br /&gt;
      - mieru-client&lt;br /&gt;
    environment:&lt;br /&gt;
      MIERU_MODE: mita&lt;br /&gt;
      MIERU_CONFIG: /srv/server.json&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./server.json:/srv/server.json:ro&lt;br /&gt;
      - mita-state:/etc/mita&lt;br /&gt;
      - mita-runtime:/var/run/mita&lt;br /&gt;
      - mita-data:/var/lib/mita&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: json-file&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;10m&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  mieru-client-state:&lt;br /&gt;
  mieru-client-runtime:&lt;br /&gt;
  mieru-client-data:&lt;br /&gt;
  mita-state:&lt;br /&gt;
  mita-runtime:&lt;br /&gt;
  mita-data:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 7. Сборка и запуск ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-frontend/docker-compose.yml build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-frontend/docker-compose.yml up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sleep 12&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 8. Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs mieru-client --tail 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должна быть строка &amp;lt;code&amp;gt;mieru: config применён&amp;lt;/code&amp;gt; и затем &amp;lt;code&amp;gt;запуск mieru run&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs mita-frontend --tail 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должно быть &amp;lt;code&amp;gt;RUNNING&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;mita start: OK&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mieru-client mieru status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидание: &amp;lt;code&amp;gt;mieru client is running&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-frontend mita status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидание: &amp;lt;code&amp;gt;mita server status is &amp;quot;RUNNING&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 9. Сквозной тест каскада ===&lt;br /&gt;
С frontend-сервера обратитесь во внешний интернет через локальный SOCKS5 mieru-client. Это эквивалент того, как пойдёт реальный клиентский запрос.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS --max-time 30 --proxy socks5h://127.0.0.1:1080 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидание: IP вашего egress-узла. Например, IP Cloudflare WARP, если на backend настроен такой outbound. Команда &#039;&#039;&#039;не должна&#039;&#039;&#039; возвращать публичный IP frontend-сервера.&lt;br /&gt;
&lt;br /&gt;
Контрольный замер прямого IP frontend для сравнения.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS --max-time 5 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если первый IP отличается от второго — каскад работает.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Подключение клиентов ==&lt;br /&gt;
mieru имеет два равнозначных формата отдачи параметров клиенту: &#039;&#039;&#039;Clash/Mihomo YAML&#039;&#039;&#039; и &#039;&#039;&#039;&amp;lt;code&amp;gt;mierus://&amp;lt;/code&amp;gt; URI&#039;&#039;&#039;. На практике YAML более переносим — его понимает большинство клиентов в одном виде, тогда как URI разбирается каждым приложением по-своему.&lt;br /&gt;
&lt;br /&gt;
=== Десктоп: Clash Verge Rev / Mihomo Party / NekoBox ===&lt;br /&gt;
Создайте новый профиль (или отредактируйте существующий) и добавьте блок &amp;lt;code&amp;gt;proxies&amp;lt;/code&amp;gt;:&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
proxies:&lt;br /&gt;
  - name: mieru-frontend&lt;br /&gt;
    type: mieru&lt;br /&gt;
    server: YOUR_FRONTEND_PUBLIC_IP&lt;br /&gt;
    port: 2022&lt;br /&gt;
    username: client01&lt;br /&gt;
    password: YOUR_CLIENT_PASSWORD&lt;br /&gt;
    multiplexing: MULTIPLEXING_HIGH&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Параметр &amp;lt;code&amp;gt;port: 2022&amp;lt;/code&amp;gt; — это один из портов из диапазона &amp;lt;code&amp;gt;2012-2022&amp;lt;/code&amp;gt;; mita слушает все 11 параллельно, клиент использует один (мультиплексор).&lt;br /&gt;
&lt;br /&gt;
=== Мобильные: Karing / ClashMi / NekoBox+plugin / husi ===&lt;br /&gt;
Подключение через тот же YAML-блок выше — большинство клиентов поддерживают вставку YAML вручную в раздел «Серверы» или «Outbounds». Сценарий импорта URI в Karing 1.2.x работает плохо (поле порта обнуляется), поэтому YAML предпочтительнее.&lt;br /&gt;
&lt;br /&gt;
=== Универсальный URI-формат ===&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
mierus://client01:YOUR_CLIENT_PASSWORD@YOUR_FRONTEND_PUBLIC_IP?port=2022&amp;amp;protocol=TCP&amp;amp;mtu=1380&amp;amp;multiplexing=MULTIPLEXING_HIGH&amp;amp;handshake-mode=HANDSHAKE_NO_WAIT&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подходит для нативного &amp;lt;code&amp;gt;mieru&amp;lt;/code&amp;gt; CLI, husi с mieru-плагином, Exclave.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Подключение клиента на OpenWrt-роутере ==&lt;br /&gt;
Если на роутере уже стоит трафик-менеджер (например, podkop), и вы хотите, чтобы он отправлял трафик через mieru — поставьте на роутер standalone mieru-клиент с локальным SOCKS5, и подкоп цепляйте к этому SOCKS5.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Подключение к роутеру ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh root@YOUR_ROUTER_HOST&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Скачивание бинаря ===&lt;br /&gt;
Архитектура роутера большинства современных моделей — &amp;lt;code&amp;gt;aarch64&amp;lt;/code&amp;gt;. Если ваш роутер — другой (например, &amp;lt;code&amp;gt;mips&amp;lt;/code&amp;gt;), проверьте список релизов &amp;lt;code&amp;gt;https://github.com/enfein/mieru/releases/latest&amp;lt;/code&amp;gt; и подставьте нужный артефакт в команду.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /tmp &amp;amp;&amp;amp; wget -q https://github.com/enfein/mieru/releases/download/v3.32.0/mieru_3.32.0_linux_arm64.tar.gz -O mieru.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar xzf mieru.tar.gz &amp;amp;&amp;amp; mv mieru /usr/bin/mieru &amp;amp;&amp;amp; chmod +x /usr/bin/mieru &amp;amp;&amp;amp; rm -f /tmp/mieru.tar.gz /tmp/LICENSE /tmp/README.md&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/usr/bin/mieru version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должно вывести &amp;lt;code&amp;gt;3.32.0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Клиентский конфиг ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /etc/mieru_client_config.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте, заменив плейсхолдеры:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;profiles&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;profileName&amp;quot;: &amp;quot;default&amp;quot;,&lt;br /&gt;
            &amp;quot;user&amp;quot;: {&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;client01&amp;quot;,&lt;br /&gt;
                &amp;quot;password&amp;quot;: &amp;quot;YOUR_CLIENT_PASSWORD&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;servers&amp;quot;: [&lt;br /&gt;
                {&lt;br /&gt;
                    &amp;quot;ipAddress&amp;quot;: &amp;quot;YOUR_FRONTEND_PUBLIC_IP&amp;quot;,&lt;br /&gt;
                    &amp;quot;portBindings&amp;quot;: [&lt;br /&gt;
                        {&amp;quot;portRange&amp;quot;: &amp;quot;2012-2022&amp;quot;, &amp;quot;protocol&amp;quot;: &amp;quot;TCP&amp;quot;}&lt;br /&gt;
                    ]&lt;br /&gt;
                }&lt;br /&gt;
            ],&lt;br /&gt;
            &amp;quot;mtu&amp;quot;: 1380,&lt;br /&gt;
            &amp;quot;multiplexing&amp;quot;: {&amp;quot;level&amp;quot;: &amp;quot;MULTIPLEXING_HIGH&amp;quot;},&lt;br /&gt;
            &amp;quot;handshakeMode&amp;quot;: &amp;quot;HANDSHAKE_NO_WAIT&amp;quot;,&lt;br /&gt;
            &amp;quot;trafficPattern&amp;quot;: {&lt;br /&gt;
                &amp;quot;unlockAll&amp;quot;: false,&lt;br /&gt;
                &amp;quot;tcpFragment&amp;quot;: {&amp;quot;enable&amp;quot;: true, &amp;quot;maxSleepMs&amp;quot;: 10},&lt;br /&gt;
                &amp;quot;nonce&amp;quot;: {&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;NONCE_TYPE_PRINTABLE&amp;quot;,&lt;br /&gt;
                    &amp;quot;minLen&amp;quot;: 6,&lt;br /&gt;
                    &amp;quot;maxLen&amp;quot;: 8&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;activeProfile&amp;quot;: &amp;quot;default&amp;quot;,&lt;br /&gt;
    &amp;quot;rpcPort&amp;quot;: 8964,&lt;br /&gt;
    &amp;quot;socks5Port&amp;quot;: 1090,&lt;br /&gt;
    &amp;quot;loggingLevel&amp;quot;: &amp;quot;ERROR&amp;quot;,&lt;br /&gt;
    &amp;quot;socks5ListenLAN&amp;quot;: false,&lt;br /&gt;
    &amp;quot;httpProxyListenLAN&amp;quot;: false&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните и защитите файл.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /etc/mieru_client_config.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ключевые отличия конфига для роутера от десктопного клиента:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;socks5Port: 1090&amp;lt;/code&amp;gt; — порт &amp;lt;code&amp;gt;1080&amp;lt;/code&amp;gt; часто занят другими прокси (например, naive); 1090 свободен.&lt;br /&gt;
* &amp;lt;code&amp;gt;loggingLevel: &amp;quot;ERROR&amp;quot;&amp;lt;/code&amp;gt; — overlay на роутерах маленький, ограничение логов защищает от заполнения диска.&lt;br /&gt;
* &amp;lt;code&amp;gt;trafficPattern&amp;lt;/code&amp;gt; включён полностью — на пути «роутер → frontend» классификатор смотрит, маскировка нужна.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Init.d-скрипт ===&lt;br /&gt;
OpenWrt использует procd; в отличие от mita, на OpenWrt mieru читает JSON-конфиг напрямую через переменную &amp;lt;code&amp;gt;MIERU_CONFIG_JSON_FILE&amp;lt;/code&amp;gt;, и команды &amp;lt;code&amp;gt;mieru apply config&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;mieru describe config&amp;lt;/code&amp;gt; &#039;&#039;&#039;не используются&#039;&#039;&#039;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /etc/init.d/mieru&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh /etc/rc.common&lt;br /&gt;
&lt;br /&gt;
START=99&lt;br /&gt;
STOP=01&lt;br /&gt;
&lt;br /&gt;
MIERU_BIN=&amp;quot;/usr/bin/mieru&amp;quot;&lt;br /&gt;
MIERU_CONFIG=&amp;quot;/etc/mieru_client_config.json&amp;quot;&lt;br /&gt;
PID_FILE=&amp;quot;/var/run/mieru.pid&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start() {&lt;br /&gt;
    echo &amp;quot;Starting mieru client...&amp;quot;&lt;br /&gt;
    export MIERU_CONFIG_JSON_FILE=$MIERU_CONFIG&lt;br /&gt;
    start-stop-daemon -S -b -m -p &amp;quot;$PID_FILE&amp;quot; -x &amp;quot;$MIERU_BIN&amp;quot; -- run&lt;br /&gt;
    RC=$?&lt;br /&gt;
    if [ $RC -eq 0 ]; then&lt;br /&gt;
        echo &amp;quot;mieru client is started&amp;quot;&lt;br /&gt;
        exit 0&lt;br /&gt;
    else&lt;br /&gt;
        echo &amp;quot;failed to start mieru client&amp;quot;&lt;br /&gt;
        exit $RC&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
stop() {&lt;br /&gt;
    echo &amp;quot;Stopping mieru client...&amp;quot;&lt;br /&gt;
    start-stop-daemon -K -p &amp;quot;$PID_FILE&amp;quot;&lt;br /&gt;
    RC=$?&lt;br /&gt;
    if [ $RC -eq 0 ]; then&lt;br /&gt;
        echo &amp;quot;mieru client is stopped&amp;quot;&lt;br /&gt;
        rm -f &amp;quot;$PID_FILE&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        echo &amp;quot;failed to stop mieru client&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните и сделайте исполняемым.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x /etc/init.d/mieru&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Запуск и автозапуск ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/etc/init.d/mieru enable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/etc/init.d/mieru start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 6. Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps | grep mieru | grep -v grep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должна быть одна строка с процессом &amp;lt;code&amp;gt;/usr/bin/mieru run&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
netstat -tlnp 2&amp;gt;/dev/null | grep 1090&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должна быть строка &amp;lt;code&amp;gt;127.0.0.1:1090 ... LISTEN ... mieru&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS --max-time 30 -x socks5h://127.0.0.1:1090 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должен вернуть IP egress-узла каскада.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 7. Подключение podkop к локальному mieru ===&lt;br /&gt;
В LuCI откройте подкоп. Создайте новую секцию или измените существующую:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Тип конфига&lt;br /&gt;
|URL&lt;br /&gt;
|-&lt;br /&gt;
|Proxy string&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1090&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Эквивалент через &amp;lt;code&amp;gt;uci&amp;lt;/code&amp;gt;:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
uci set podkop.10=section&lt;br /&gt;
uci set podkop.10.connection_type=&#039;proxy&#039;&lt;br /&gt;
uci set podkop.10.proxy_config_type=&#039;url&#039;&lt;br /&gt;
uci set podkop.10.proxy_string=&#039;socks5://127.0.0.1:1090&#039;&lt;br /&gt;
uci commit podkop&lt;br /&gt;
service podkop restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подкоп отправляет mieru-серверу обычный SOCKS5-запрос на &amp;lt;code&amp;gt;127.0.0.1:1090&amp;lt;/code&amp;gt;; mieru шифрует его и отправляет через каскад.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Управление пользователями: скрипт &amp;lt;code&amp;gt;mieru-users.sh&amp;lt;/code&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
=== Зачем он нужен ===&lt;br /&gt;
mita-сервер хранит список учёток в файле &amp;lt;code&amp;gt;server.json&amp;lt;/code&amp;gt;. Чтобы добавлять/удалять/смотреть пользователей вручную каждый раз — много шагов: jq-правка JSON, вызов &amp;lt;code&amp;gt;mita apply config&amp;lt;/code&amp;gt;, генерация ссылки клиенту, опционально &amp;lt;code&amp;gt;mita delete user&amp;lt;/code&amp;gt; для разрыва активных сессий. Скрипт &amp;lt;code&amp;gt;mieru-users.sh&amp;lt;/code&amp;gt; автоматизирует это всё.&lt;br /&gt;
&lt;br /&gt;
=== Что делает скрипт ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Пункт меню&lt;br /&gt;
!Действие&lt;br /&gt;
|-&lt;br /&gt;
|1. Список пользователей&lt;br /&gt;
|Чтение &amp;lt;code&amp;gt;server.json&amp;lt;/code&amp;gt; + опрос &amp;lt;code&amp;gt;mita get connections&amp;lt;/code&amp;gt; для активных сессий&lt;br /&gt;
|-&lt;br /&gt;
|2. Добавить пользователя&lt;br /&gt;
|Запрос имени, генерация пароля через &amp;lt;code&amp;gt;openssl rand&amp;lt;/code&amp;gt;, бэкап JSON, &amp;lt;code&amp;gt;jq&amp;lt;/code&amp;gt;-вставка, &amp;lt;code&amp;gt;mita apply config&amp;lt;/code&amp;gt;, выдача готовых YAML и URI клиенту&lt;br /&gt;
|-&lt;br /&gt;
|3. Удалить пользователя&lt;br /&gt;
|&amp;lt;code&amp;gt;mita delete user&amp;lt;/code&amp;gt; для разрыва сессий → &amp;lt;code&amp;gt;jq&amp;lt;/code&amp;gt;-удаление из JSON → &amp;lt;code&amp;gt;apply config&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|4. Показать URI клиента&lt;br /&gt;
|Сборка YAML и URI по выбранному имени&lt;br /&gt;
|-&lt;br /&gt;
|5. Статус сервера&lt;br /&gt;
|&amp;lt;code&amp;gt;mita status&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;get connections&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;get metrics&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Установка скрипта ===&lt;br /&gt;
Все команды выполняются на frontend-сервере по SSH.&lt;br /&gt;
&lt;br /&gt;
==== Шаг 1. Загрузка скрипта ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /usr/local/bin/mieru-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте полное содержимое скрипта (исходный код в спойлере «Исходный код &amp;lt;code&amp;gt;mieru-users.sh&amp;lt;/code&amp;gt;» в конце статьи).&lt;br /&gt;
&lt;br /&gt;
Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Шаг 2. Подстановка реального адреса ====&lt;br /&gt;
В начале скрипта есть строка &amp;lt;code&amp;gt;SERVER_IP=&amp;quot;YOUR_FRONTEND_PUBLIC_IP&amp;quot;&amp;lt;/code&amp;gt;. Замените её на реальный IP frontend-сервера.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sed -i &#039;s/YOUR_FRONTEND_PUBLIC_IP/198.51.100.10/&#039; /usr/local/bin/mieru-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;(подставьте свой IP вместо &amp;lt;code&amp;gt;198.51.100.10&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==== Шаг 3. Права на исполнение ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x /usr/local/bin/mieru-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Шаг 4. Проверка ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
bash -n /usr/local/bin/mieru-users.sh &amp;amp;&amp;amp; echo OK&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если выводит &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt; — скрипт установлен корректно.&lt;br /&gt;
&lt;br /&gt;
=== Использование ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo bash /usr/local/bin/mieru-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Появится меню:&amp;lt;pre&amp;gt;&lt;br /&gt;
╔══════════════════════════════════════╗&lt;br /&gt;
║   mieru User Manager                 ║&lt;br /&gt;
║   IP: 198.51.100.10                  ║&lt;br /&gt;
╚══════════════════════════════════════╝&lt;br /&gt;
&lt;br /&gt;
  Пользователей в конфиге: 1&lt;br /&gt;
&lt;br /&gt;
  1. Список пользователей и активных сессий&lt;br /&gt;
  2. Добавить пользователя&lt;br /&gt;
  3. Удалить пользователя&lt;br /&gt;
  4. Показать URI клиента&lt;br /&gt;
  5. Статус сервера&lt;br /&gt;
  0. Выход&lt;br /&gt;
&amp;lt;/pre&amp;gt;После добавления пользователя скрипт выводит готовые конфиги:&amp;lt;pre&amp;gt;&lt;br /&gt;
=== Вариант 1: Clash / Mihomo YAML (рекомендую) ===&lt;br /&gt;
proxies:&lt;br /&gt;
  - name: mieru-RU-alice&lt;br /&gt;
    type: mieru&lt;br /&gt;
    server: 198.51.100.10&lt;br /&gt;
    port: 2022&lt;br /&gt;
    username: alice&lt;br /&gt;
    password: &amp;lt;автогенерированный&amp;gt;&lt;br /&gt;
    multiplexing: MULTIPLEXING_HIGH&lt;br /&gt;
&lt;br /&gt;
=== Вариант 2: mierus:// URI ===&lt;br /&gt;
mierus://alice:&amp;lt;пароль&amp;gt;@198.51.100.10?port=2022&amp;amp;protocol=TCP&amp;amp;mtu=1380&amp;amp;multiplexing=MULTIPLEXING_HIGH&amp;amp;handshake-mode=HANDSHAKE_NO_WAIT&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Команды управления ==&lt;br /&gt;
&lt;br /&gt;
=== На обоих серверах ===&lt;br /&gt;
Посмотреть логи в реальном времени.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f mita-backend       # на backend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f mita-frontend mieru-client       # на frontend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Перезапустить.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-backend/docker-compose.yml restart    # на backend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-frontend/docker-compose.yml restart   # на frontend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Остановить.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-backend/docker-compose.yml down       # на backend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-frontend/docker-compose.yml down      # на frontend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Обновить версию mita/mieru. Поменяйте &amp;lt;code&amp;gt;3.32.0&amp;lt;/code&amp;gt; на нужную в &amp;lt;code&amp;gt;docker-compose.yml&amp;lt;/code&amp;gt; и пересоберите.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-backend/docker-compose.yml build &amp;amp;&amp;amp; docker compose -f /opt/mieru-backend/docker-compose.yml up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Команды mita через CLI (внутри контейнера) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita status              # IDLE / RUNNING&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita get users           # список user&#039;ов и их статистика&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita get connections     # активные сессии&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita get metrics         # метрики&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita describe config     # текущий применённый конфиг&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== На OpenWrt-роутере ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/etc/init.d/mieru start | stop | restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps | grep mieru | grep -v grep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
logread | grep mieru&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Поиск проблем ==&lt;br /&gt;
&lt;br /&gt;
=== Симптом: сервер показывает &amp;lt;code&amp;gt;IDLE&amp;lt;/code&amp;gt;, порты не слушаются ===&lt;br /&gt;
mita после &amp;lt;code&amp;gt;apply config&amp;lt;/code&amp;gt; остаётся в &amp;lt;code&amp;gt;IDLE&amp;lt;/code&amp;gt; до явной команды &amp;lt;code&amp;gt;mita start&amp;lt;/code&amp;gt;. В нашем entrypoint это происходит автоматически, но если что-то пошло не так, выполните вручную внутри контейнера:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Симптом: &amp;lt;code&amp;gt;FATAL: getUid(&amp;quot;mita&amp;quot;) failed&amp;lt;/code&amp;gt; ===&lt;br /&gt;
В образ не добавлен системный пользователь &amp;lt;code&amp;gt;mita&amp;lt;/code&amp;gt;. Проверьте, что Dockerfile содержит строки &amp;lt;code&amp;gt;adduser -H -D -g &amp;quot;&amp;quot; mita&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;adduser -H -D -g &amp;quot;&amp;quot; mieru&amp;lt;/code&amp;gt;, пересоберите образ.&lt;br /&gt;
&lt;br /&gt;
=== Симптом: клиент подключается, но трафик не идёт ===&lt;br /&gt;
Проверьте на клиенте время системы. Расхождение более 4 минут с сервером приведёт к молчаливому отказу. Команда на Linux/macOS:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
date -u&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если время существенно расходится — настройте NTP.&lt;br /&gt;
&lt;br /&gt;
=== Симптом: на frontend curl возвращает не egress-IP, а frontend-IP ===&lt;br /&gt;
Trafic идёт мимо mieru-client. Возможные причины:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;egress.action&amp;lt;/code&amp;gt; в frontend-конфиге — &amp;lt;code&amp;gt;DIRECT&amp;lt;/code&amp;gt; вместо &amp;lt;code&amp;gt;PROXY&amp;lt;/code&amp;gt;.&lt;br /&gt;
* mieru-client не запущен либо упал. Проверьте: &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Backend не доступен. Проверьте на frontend: &amp;lt;code&amp;gt;nc -vz YOUR_BACKEND_PUBLIC_IP 2022&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Симптом: на frontend curl возвращает frontend-IP, а должен — backend-IP ===&lt;br /&gt;
То же самое, что выше: трафик не доходит до backend. Дополнительно посмотрите логи:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs mieru-client --tail 50&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ошибки &amp;lt;code&amp;gt;TLS handshake&amp;lt;/code&amp;gt; здесь невозможны — mieru не использует TLS. Ищите &amp;lt;code&amp;gt;auth failed&amp;lt;/code&amp;gt; (неверная пара логин/пароль на mita-backend) и &amp;lt;code&amp;gt;connection refused&amp;lt;/code&amp;gt; (backend не слушает).&lt;br /&gt;
&lt;br /&gt;
=== Симптом: на роутере Karing/Clash подключается, но трафик не идёт ===&lt;br /&gt;
В первую очередь проверить YAML-конфиг: тип &amp;lt;code&amp;gt;type: mieru&amp;lt;/code&amp;gt; (не &amp;lt;code&amp;gt;type: socks5&amp;lt;/code&amp;gt;!), порт &amp;lt;code&amp;gt;port: 2022&amp;lt;/code&amp;gt; (одиночное число, не диапазон). Многие mihomo-форки не парсят диапазон портов корректно.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Исходный код &amp;lt;code&amp;gt;mieru-users.sh&amp;lt;/code&amp;gt; ==&lt;br /&gt;
Полный текст скрипта приведён ниже. Скопируйте его целиком в &amp;lt;code&amp;gt;/usr/local/bin/mieru-users.sh&amp;lt;/code&amp;gt; на frontend-сервере по инструкции выше.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# mieru-users — управление пользователями mita&lt;br /&gt;
# Источник истины: /opt/mieru-frontend/server.json&lt;br /&gt;
# Применение через mita apply config (RPC к работающему daemon).&lt;br /&gt;
&lt;br /&gt;
CONFIG_FILE=&amp;quot;/opt/mieru-frontend/server.json&amp;quot;&lt;br /&gt;
COMPOSE_DIR=&amp;quot;/opt/mieru-frontend&amp;quot;&lt;br /&gt;
COMPOSE_SVC=&amp;quot;mita&amp;quot;&lt;br /&gt;
BACKUP_DIR=&amp;quot;/opt/mieru-frontend/backups&amp;quot;&lt;br /&gt;
BACKUP_KEEP=10&lt;br /&gt;
SERVER_IP=&amp;quot;YOUR_FRONTEND_PUBLIC_IP&amp;quot;&lt;br /&gt;
&lt;br /&gt;
RED=&#039;\033[0;31m&#039;; GREEN=&#039;\033[0;32m&#039;; YELLOW=&#039;\033[1;33m&#039;&lt;br /&gt;
CYAN=&#039;\033[0;36m&#039;; BOLD=&#039;\033[1m&#039;; NC=&#039;\033[0m&#039;&lt;br /&gt;
&lt;br /&gt;
check_root() {&lt;br /&gt;
    if [[ $EUID -ne 0 ]]; then&lt;br /&gt;
        echo -e &amp;quot;${RED}Запусти от root: sudo bash mieru-users.sh${NC}&amp;quot;; exit 1&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
check_deps() {&lt;br /&gt;
    for c in jq docker openssl; do&lt;br /&gt;
        if ! command -v &amp;quot;$c&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then&lt;br /&gt;
            echo -e &amp;quot;${RED}Не найдено: $c${NC}&amp;quot;; exit 1&lt;br /&gt;
        fi&lt;br /&gt;
    done&lt;br /&gt;
    if [[ ! -f &amp;quot;$CONFIG_FILE&amp;quot; ]]; then&lt;br /&gt;
        echo -e &amp;quot;${RED}Не найден $CONFIG_FILE${NC}&amp;quot;; exit 1&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
mita_cli() {&lt;br /&gt;
    docker compose -f &amp;quot;$COMPOSE_DIR/docker-compose.yml&amp;quot; exec -T &amp;quot;$COMPOSE_SVC&amp;quot; mita &amp;quot;$@&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
backup_config() {&lt;br /&gt;
    mkdir -p &amp;quot;$BACKUP_DIR&amp;quot;&lt;br /&gt;
    local stamp; stamp=$(date +%Y%m%d-%H%M%S)&lt;br /&gt;
    cp &amp;quot;$CONFIG_FILE&amp;quot; &amp;quot;$BACKUP_DIR/server-$stamp.json&amp;quot;&lt;br /&gt;
    ls -1t &amp;quot;$BACKUP_DIR&amp;quot;/server-*.json 2&amp;gt;/dev/null | tail -n +$((BACKUP_KEEP+1)) | xargs -r rm -f&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
apply_config() {&lt;br /&gt;
    if ! mita_cli apply config /srv/server.json 2&amp;gt;&amp;amp;1; then&lt;br /&gt;
        echo -e &amp;quot;${RED}mita apply config упал. Откатываюсь к последнему бэкапу.${NC}&amp;quot;&lt;br /&gt;
        local last; last=$(ls -1t &amp;quot;$BACKUP_DIR&amp;quot;/server-*.json 2&amp;gt;/dev/null | head -1)&lt;br /&gt;
        if [[ -n &amp;quot;$last&amp;quot; ]]; then&lt;br /&gt;
            cp &amp;quot;$last&amp;quot; &amp;quot;$CONFIG_FILE&amp;quot;&lt;br /&gt;
            mita_cli apply config /srv/server.json &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || true&lt;br /&gt;
        fi&lt;br /&gt;
        return 1&lt;br /&gt;
    fi&lt;br /&gt;
    return 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
press_enter() { echo &amp;quot;&amp;quot;; read -rp &amp;quot;Enter для возврата...&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
generate_password() {&lt;br /&gt;
    openssl rand -base64 24 | tr -d &#039;=/+&#039; | head -c 31&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
generate_uri() {&lt;br /&gt;
    echo &amp;quot;mierus://${1}:${2}@${SERVER_IP}?port=2022&amp;amp;protocol=TCP&amp;amp;mtu=1380&amp;amp;multiplexing=MULTIPLEXING_HIGH&amp;amp;handshake-mode=HANDSHAKE_NO_WAIT&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
generate_yaml() {&lt;br /&gt;
    cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
proxies:&lt;br /&gt;
  - name: mieru-${1}&lt;br /&gt;
    type: mieru&lt;br /&gt;
    server: ${SERVER_IP}&lt;br /&gt;
    port: 2022&lt;br /&gt;
    username: ${1}&lt;br /&gt;
    password: ${2}&lt;br /&gt;
    multiplexing: MULTIPLEXING_HIGH&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
print_uri_for() {&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${CYAN}=== Вариант 1: Clash / Mihomo YAML ===${NC}&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}$(generate_yaml &amp;quot;$1&amp;quot; &amp;quot;$2&amp;quot;)${NC}&amp;quot;&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${CYAN}=== Вариант 2: mierus:// URI ===${NC}&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}  $(generate_uri &amp;quot;$1&amp;quot; &amp;quot;$2&amp;quot;)${NC}&amp;quot;&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${CYAN}user=${BOLD}${1}${NC}, pwd=${BOLD}${2}${NC}, host=${BOLD}${SERVER_IP}${NC}, port=${BOLD}2022${NC}&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list_users() {&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    local n; n=$(jq &#039;.users | length&#039; &amp;quot;$CONFIG_FILE&amp;quot;)&lt;br /&gt;
    echo -e &amp;quot;${BOLD}${CYAN}=== Пользователей: $n ===${NC}&amp;quot;&lt;br /&gt;
    jq -r &#039;.users[] | &amp;quot;  \(.name)\t\(.password[0:6])…&amp;quot;&#039; &amp;quot;$CONFIG_FILE&amp;quot; | nl -w2 -s&#039;. &#039;&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}${CYAN}=== Активные сессии ===${NC}&amp;quot;&lt;br /&gt;
    mita_cli get connections 2&amp;gt;&amp;amp;1 | head -20&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
add_user() {&lt;br /&gt;
    echo &amp;quot;&amp;quot;; read -rp &amp;quot;Имя пользователя: &amp;quot; name&lt;br /&gt;
    name=$(echo &amp;quot;$name&amp;quot; | tr -d &#039; &#039;)&lt;br /&gt;
    [[ -z &amp;quot;$name&amp;quot; ]] &amp;amp;&amp;amp; { echo &amp;quot;Пусто.&amp;quot;; press_enter; return; }&lt;br /&gt;
    if jq -e --arg n &amp;quot;$name&amp;quot; &#039;.users[] | select(.name == $n)&#039; &amp;quot;$CONFIG_FILE&amp;quot; &amp;gt;/dev/null; then&lt;br /&gt;
        echo &amp;quot;Уже есть.&amp;quot;; press_enter; return&lt;br /&gt;
    fi&lt;br /&gt;
    read -rp &amp;quot;Пароль (Enter — сгенерировать): &amp;quot; pwd&lt;br /&gt;
    [[ -z &amp;quot;$pwd&amp;quot; ]] &amp;amp;&amp;amp; pwd=$(generate_password)&lt;br /&gt;
&lt;br /&gt;
    backup_config&lt;br /&gt;
    local tmp; tmp=$(mktemp)&lt;br /&gt;
    jq --arg n &amp;quot;$name&amp;quot; --arg p &amp;quot;$pwd&amp;quot; &#039;.users += [{&amp;quot;name&amp;quot;:$n,&amp;quot;password&amp;quot;:$p}]&#039; &amp;quot;$CONFIG_FILE&amp;quot; &amp;gt; &amp;quot;$tmp&amp;quot; &amp;amp;&amp;amp; mv &amp;quot;$tmp&amp;quot; &amp;quot;$CONFIG_FILE&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    if apply_config; then&lt;br /&gt;
        echo -e &amp;quot;${GREEN}Пользователь $name добавлен.${NC}&amp;quot;&lt;br /&gt;
        print_uri_for &amp;quot;$name&amp;quot; &amp;quot;$pwd&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
delete_user() {&lt;br /&gt;
    mapfile -t users &amp;lt; &amp;lt;(jq -r &#039;.users[].name&#039; &amp;quot;$CONFIG_FILE&amp;quot;)&lt;br /&gt;
    [[ ${#users[@]} -eq 0 ]] &amp;amp;&amp;amp; { echo &amp;quot;Пусто.&amp;quot;; press_enter; return; }&lt;br /&gt;
    for i in &amp;quot;${!users[@]}&amp;quot;; do echo &amp;quot;  $((i+1))) ${users[$i]}&amp;quot;; done&lt;br /&gt;
    echo &amp;quot;  0) Отмена&amp;quot;; read -rp &amp;quot;Номер: &amp;quot; n&lt;br /&gt;
    [[ &amp;quot;$n&amp;quot; == &amp;quot;0&amp;quot; || -z &amp;quot;$n&amp;quot; ]] &amp;amp;&amp;amp; return&lt;br /&gt;
    local target=&amp;quot;${users[$((n-1))]}&amp;quot;&lt;br /&gt;
    read -rp &amp;quot;Удалить &#039;$target&#039;? (y/N): &amp;quot; yn&lt;br /&gt;
    [[ ! &amp;quot;$yn&amp;quot; =~ ^[Yy]$ ]] &amp;amp;&amp;amp; return&lt;br /&gt;
&lt;br /&gt;
    mita_cli delete user &amp;quot;$target&amp;quot; 2&amp;gt;&amp;amp;1&lt;br /&gt;
    backup_config&lt;br /&gt;
    local tmp; tmp=$(mktemp)&lt;br /&gt;
    jq --arg n &amp;quot;$target&amp;quot; &#039;del(.users[] | select(.name == $n))&#039; &amp;quot;$CONFIG_FILE&amp;quot; &amp;gt; &amp;quot;$tmp&amp;quot; &amp;amp;&amp;amp; mv &amp;quot;$tmp&amp;quot; &amp;quot;$CONFIG_FILE&amp;quot;&lt;br /&gt;
    apply_config &amp;amp;&amp;amp; echo -e &amp;quot;${GREEN}Удалён.${NC}&amp;quot;&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
show_uri() {&lt;br /&gt;
    mapfile -t users &amp;lt; &amp;lt;(jq -r &#039;.users[].name&#039; &amp;quot;$CONFIG_FILE&amp;quot;)&lt;br /&gt;
    [[ ${#users[@]} -eq 0 ]] &amp;amp;&amp;amp; { echo &amp;quot;Пусто.&amp;quot;; press_enter; return; }&lt;br /&gt;
    for i in &amp;quot;${!users[@]}&amp;quot;; do echo &amp;quot;  $((i+1))) ${users[$i]}&amp;quot;; done&lt;br /&gt;
    read -rp &amp;quot;Номер: &amp;quot; n&lt;br /&gt;
    [[ -z &amp;quot;$n&amp;quot; ]] &amp;amp;&amp;amp; return&lt;br /&gt;
    local user=&amp;quot;${users[$((n-1))]}&amp;quot;&lt;br /&gt;
    local pwd; pwd=$(jq -r --arg n &amp;quot;$user&amp;quot; &#039;.users[] | select(.name == $n) | .password&#039; &amp;quot;$CONFIG_FILE&amp;quot;)&lt;br /&gt;
    print_uri_for &amp;quot;$user&amp;quot; &amp;quot;$pwd&amp;quot;&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
server_status() {&lt;br /&gt;
    mita_cli status 2&amp;gt;&amp;amp;1&lt;br /&gt;
    echo&lt;br /&gt;
    mita_cli get connections 2&amp;gt;&amp;amp;1&lt;br /&gt;
    echo&lt;br /&gt;
    mita_cli get metrics 2&amp;gt;&amp;amp;1 | head -30&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
main_menu() {&lt;br /&gt;
    check_root; check_deps&lt;br /&gt;
    while true; do&lt;br /&gt;
        clear&lt;br /&gt;
        echo &amp;quot;╔══════════════════════════════════════╗&amp;quot;&lt;br /&gt;
        echo &amp;quot;║   mieru User Manager                 ║&amp;quot;&lt;br /&gt;
        echo &amp;quot;║   IP: $SERVER_IP&amp;quot;&lt;br /&gt;
        echo &amp;quot;╚══════════════════════════════════════╝&amp;quot;&lt;br /&gt;
        echo&lt;br /&gt;
        echo &amp;quot;  1) Список пользователей&amp;quot;&lt;br /&gt;
        echo &amp;quot;  2) Добавить&amp;quot;&lt;br /&gt;
        echo &amp;quot;  3) Удалить&amp;quot;&lt;br /&gt;
        echo &amp;quot;  4) URI клиента&amp;quot;&lt;br /&gt;
        echo &amp;quot;  5) Статус сервера&amp;quot;&lt;br /&gt;
        echo &amp;quot;  0) Выход&amp;quot;&lt;br /&gt;
        read -rp &amp;quot;Выбор: &amp;quot; opt&lt;br /&gt;
        case &amp;quot;$opt&amp;quot; in&lt;br /&gt;
            1) list_users ;; 2) add_user ;;&lt;br /&gt;
            3) delete_user ;; 4) show_uri ;;&lt;br /&gt;
            5) server_status ;; 0) exit 0 ;;&lt;br /&gt;
        esac&lt;br /&gt;
    done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
main_menu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/enfein/mieru Официальный репозиторий mieru]&lt;br /&gt;
* [https://github.com/enfein/mieru/blob/master/docs/protocol.md Спецификация протокола mieru]&lt;br /&gt;
* [https://github.com/enfein/mieru/blob/master/docs/traffic-pattern.md Документация по traffic pattern]&lt;br /&gt;
* [https://github.com/enfein/mieru/blob/master/docs/security.md Руководство по безопасности]&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Mieru-multi-user.png&amp;diff=974</id>
		<title>Файл:Mieru-multi-user.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Mieru-multi-user.png&amp;diff=974"/>
		<updated>2026-05-10T20:20:15Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Mieru-segment-format.png&amp;diff=973</id>
		<title>Файл:Mieru-segment-format.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Mieru-segment-format.png&amp;diff=973"/>
		<updated>2026-05-10T20:20:01Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Mieru-cascade-flow.png&amp;diff=972</id>
		<title>Файл:Mieru-cascade-flow.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Mieru-cascade-flow.png&amp;diff=972"/>
		<updated>2026-05-10T20:19:47Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=Mieru:_%D0%BA%D0%B0%D1%81%D0%BA%D0%B0%D0%B4%D0%BD%D1%8B%D0%B9_%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9_SOCKS5-%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D1%8C&amp;diff=971</id>
		<title>Mieru: каскадный шифрованный SOCKS5-туннель</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=Mieru:_%D0%BA%D0%B0%D1%81%D0%BA%D0%B0%D0%B4%D0%BD%D1%8B%D0%B9_%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9_SOCKS5-%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D1%8C&amp;diff=971"/>
		<updated>2026-05-10T20:17:45Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* Поток данных в одиночном режиме */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= mieru: каскадный шифрованный SOCKS5-туннель с устойчивостью к классификации трафика =&lt;br /&gt;
&lt;br /&gt;
== Введение ==&lt;br /&gt;
&lt;br /&gt;
=== Что такое mieru ===&lt;br /&gt;
&#039;&#039;&#039;mieru&#039;&#039;&#039; (見える, «видимый») — это криптографически защищённый прокси-протокол, ориентированный на работу в средах с активным DPI и статистическим анализом сетевого трафика. В отличие от большинства современных туннелей, mieru &#039;&#039;&#039;не использует TLS&#039;&#039;&#039; и &#039;&#039;&#039;не маскируется под легитимный сайт&#039;&#039;&#039;. Вместо этого он подаёт на провод поток, который при пассивном анализе выглядит как случайные байты или произвольный текстовый протокол — без узнаваемых заголовков, фиксированных длин и характерных handshake-паттернов.&lt;br /&gt;
&lt;br /&gt;
Программный пакет состоит из двух самостоятельных бинарников:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Бинарник&lt;br /&gt;
!Роль&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mita&amp;lt;/code&amp;gt;&lt;br /&gt;
|Серверная часть. Принимает зашифрованные соединения, аутентифицирует пользователей, переправляет полезную нагрузку наружу&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mieru&amp;lt;/code&amp;gt;&lt;br /&gt;
|Клиентская часть. Поднимает локальный SOCKS5-прокси на машине пользователя; всё, что в него пришло, шифруется и отправляется на &amp;lt;code&amp;gt;mita&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Когда применяется ===&lt;br /&gt;
&lt;br /&gt;
* Канал между клиентом и обычными VPN-серверами проходит через инфраструктуру с DPI или ML-классификацией протоколов.&lt;br /&gt;
* Нужен альтернативный канал, не зависящий от валидного TLS-сертификата и собственного домена (mieru вообще не требует доменного имени).&lt;br /&gt;
* Нужна устойчивость к активному зондированию: сервер mieru, в отличие от REALITY-/Trojan-серверов, при попытке зондирования просто &#039;&#039;&#039;молчит&#039;&#039;&#039;, не имитируя ни сайта-донора, ни TLS-handshake — нечего фингерпринтить.&lt;br /&gt;
&lt;br /&gt;
=== Сравнение с другими методами туннелирования ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Метод&lt;br /&gt;
!Транспорт&lt;br /&gt;
!Маскировка&lt;br /&gt;
!Требует домен и TLS&lt;br /&gt;
!Устойчивость к ML-классификации&lt;br /&gt;
|-&lt;br /&gt;
|WireGuard&lt;br /&gt;
|UDP&lt;br /&gt;
|нет (явный WG)&lt;br /&gt;
|нет&lt;br /&gt;
|низкая&lt;br /&gt;
|-&lt;br /&gt;
|OpenVPN&lt;br /&gt;
|UDP/TCP&lt;br /&gt;
|нет&lt;br /&gt;
|опционально&lt;br /&gt;
|низкая&lt;br /&gt;
|-&lt;br /&gt;
|Shadowsocks-AEAD-2022&lt;br /&gt;
|TCP&lt;br /&gt;
|случайный шум&lt;br /&gt;
|нет&lt;br /&gt;
|средняя&lt;br /&gt;
|-&lt;br /&gt;
|VLESS + REALITY&lt;br /&gt;
|TCP (TLS)&lt;br /&gt;
|TLS-handshake чужого сайта&lt;br /&gt;
|да&lt;br /&gt;
|высокая (внутри пула TLS)&lt;br /&gt;
|-&lt;br /&gt;
|NaiveProxy&lt;br /&gt;
|TCP (HTTP/2)&lt;br /&gt;
|Chromium-стек, неотличим от HTTPS&lt;br /&gt;
|да&lt;br /&gt;
|высокая (внутри пула HTTPS)&lt;br /&gt;
|-&lt;br /&gt;
|Hysteria2&lt;br /&gt;
|UDP (QUIC)&lt;br /&gt;
|QUIC поверх UDP с маскировкой под HTTPS&lt;br /&gt;
|да&lt;br /&gt;
|высокая (внутри пула QUIC)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;mieru&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;TCP / UDP, без TLS&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;случайный шум либо текстоподобный поток (через traffic pattern)&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;нет — только пара логин/пароль&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;высокая (специальная подгонка энтропии и ASCII)&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Принципы работы ==&lt;br /&gt;
&lt;br /&gt;
=== Поток данных в одиночном режиме ===&lt;br /&gt;
[[Файл:Mieru-single-flow.png|центр|517x517px|Поток данных одиночного mieru: клиент → SOCKS5 → mieru → шифр → mita → интернет]]&lt;br /&gt;
=== Каскадный режим (двухзвенный) ===&lt;br /&gt;
В каскаде роль обычного «сервера» выполняют два узла. Первый принимает клиентов и не выходит в интернет напрямую; вместо этого он переправляет уже расшифрованный трафик во второй узел через тот же протокол mieru. Второй узел осуществляет финальный egress.&lt;br /&gt;
[[Файл:Mieru-cascade-flow.png|центр|600x600пкс|Поток данных каскадного mieru: Сервер A (frontend) → Сервер B (backend) → egress]]&lt;br /&gt;
=== Зачем разделять frontend и backend ===&lt;br /&gt;
&lt;br /&gt;
* Адрес backend-сервера никогда не виден клиентскому ПО. Если frontend замечен и заблокирован — backend остаётся неизвестным наблюдателям и переиспользуется со следующим frontend.&lt;br /&gt;
* Frontend хранит &#039;&#039;&#039;только&#039;&#039;&#039; учётки клиентов и не имеет финального egress. Компрометация его конфига не раскрывает финальный IP.&lt;br /&gt;
* Двойное шифрование mieru на каждом плече: каждый сегмент дважды проходит AEAD с разными ключами, что усложняет статистический анализ.&lt;br /&gt;
&lt;br /&gt;
=== Шифрование и аутентификация ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Алгоритм&lt;br /&gt;
|XChaCha20-Poly1305 (AEAD) с 24-байтным nonce&lt;br /&gt;
|-&lt;br /&gt;
|Длина ключа&lt;br /&gt;
|32 байта&lt;br /&gt;
|-&lt;br /&gt;
|Метод выработки ключа&lt;br /&gt;
|PBKDF2-SHA256, 64 итерации, соль = SHA-256 от текущего времени, округлённого до 2 минут&lt;br /&gt;
|-&lt;br /&gt;
|Идентификатор пользователя в пакете&lt;br /&gt;
|Последние 4 байта nonce заменены на префикс SHA-256 от &amp;lt;code&amp;gt;username + nonce[0:16]&amp;lt;/code&amp;gt;; имя пользователя на провод не передаётся&lt;br /&gt;
|-&lt;br /&gt;
|Защита от reuse&lt;br /&gt;
|Проверка nonce-кэша на серверной стороне; повторный пакет отбрасывается&lt;br /&gt;
|}&lt;br /&gt;
Ключ шифрования &#039;&#039;&#039;не передаётся&#039;&#039;&#039; через канал и нигде не хранится в виде сериализованной строки: он каждый раз генерируется на лету из пары логин+пароль и текущего времени. Из этого следует одно практическое требование, которое легко не заметить.&lt;br /&gt;
&lt;br /&gt;
==== Требование к синхронизации часов ====&lt;br /&gt;
Расхождение системного времени клиента и сервера &#039;&#039;&#039;не должно превышать 4 минуты&#039;&#039;&#039;. При большем расхождении ключ, выработанный клиентом, не сойдётся с ключом сервера, и подключения будут &#039;&#039;&#039;молча&#039;&#039;&#039; падать (без явной ошибки в логах). На обоих серверах и на клиентском устройстве должен работать NTP-демон.&lt;br /&gt;
&lt;br /&gt;
=== Формат сегмента ===&lt;br /&gt;
[[Файл:Mieru-segment-format.png|центр|500x500пкс|Формат сегмента mieru: padding, nonce, шифр-метаданные, шифр-полезная нагрузка]]Ключевое отличие от других протоколов: &#039;&#039;&#039;ВСЕ&#039;&#039;&#039; структурные поля сегмента (тип, размер, sequence number, ID сессии и пр.) находятся внутри поля &amp;lt;code&amp;gt;enc-meta&amp;lt;/code&amp;gt; — то есть зашифрованы. Снаружи невозможно даже определить, что это за пакет, какой длины полезная нагрузка, в начале или в середине сессии находится клиент. Видны только три зоны паддинга и зашифрованные блобы.&lt;br /&gt;
&lt;br /&gt;
=== Traffic pattern (опциональная подгонка маскировки) ===&lt;br /&gt;
mieru предоставляет два независимых механизма для подмены статистических признаков шифр-трафика на «обычные»:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Опция&lt;br /&gt;
!Что делает&lt;br /&gt;
!Накладные расходы&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;tcpFragment&amp;lt;/code&amp;gt;&lt;br /&gt;
|Дробит TCP-пакеты на мелкие куски и вставляет случайную задержку между ними. Цель — сломать узнаваемость «один большой шифр-стрим»&lt;br /&gt;
| +латентность до &amp;lt;code&amp;gt;maxSleepMs&amp;lt;/code&amp;gt; мс на каждый фрагмент&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nonce.NONCE_TYPE_PRINTABLE&amp;lt;/code&amp;gt;&lt;br /&gt;
|Подменяет первые N байт nonce печатными ASCII-символами. Цель — увести классификатор «высокая энтропия от нулевого байта» в ложное «это текстовый протокол»&lt;br /&gt;
|почти ноль (только подмена байтов)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nonce.NONCE_TYPE_FIXED&amp;lt;/code&amp;gt;&lt;br /&gt;
|Подменяет первые байты nonce фиксированными hex-строками из списка. Цель — имитировать конкретный фиксированный заголовок&lt;br /&gt;
|ноль&lt;br /&gt;
|}&lt;br /&gt;
Включение traffic pattern имеет смысл &#039;&#039;&#039;только&#039;&#039;&#039; на видимом анализатором плече (клиент → frontend). На внутреннем плече каскада (frontend → backend) это лишний overhead.&lt;br /&gt;
&lt;br /&gt;
=== Многопользовательский режим ===&lt;br /&gt;
Один сервер mita может обслуживать неограниченное число учёток одновременно. Каждый user — это пара &amp;lt;code&amp;gt;(name, password)&amp;lt;/code&amp;gt;; лимит по числу одновременных сессий внутри одной учётки &#039;&#039;&#039;не задан в протоколе&#039;&#039;&#039; (можно опционально настраивать квоты по объёму трафика).&lt;br /&gt;
[[Файл:Mieru-multi-user.png|центр|450x450пкс|Многопользовательский режим: один сервер mita обслуживает несколько учёток одновременно]]Такая модель радикально отличается от mash-/torch-протоколов с архитектурой «один сервер — один пользователь»: вам &#039;&#039;&#039;не нужно&#039;&#039;&#039; создавать отдельный контейнер на каждого пользователя.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что должно быть на серверах перед установкой ==&lt;br /&gt;
&lt;br /&gt;
=== Минимальная конфигурация каждого сервера ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!№&lt;br /&gt;
!Требование&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Linux дистрибутив (Ubuntu 22.04+, Debian 12+, Fedora 38+ или сравнимый)&lt;br /&gt;
|Среда выполнения Docker&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|SSH-доступ с правами &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; либо аккаунт с &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; без пароля&lt;br /&gt;
|Установка пакетов и управление контейнерами&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Docker Engine 24.0+ и плагин Docker Compose v2.20+&lt;br /&gt;
|Запуск контейнеров mita и mieru&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|NTP-демон активен (&amp;lt;code&amp;gt;chrony&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;systemd-timesyncd&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Синхронизация часов в пределах 4 минут (см. раздел «Шифрование»)&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Открытый наружу TCP-диапазон (для нашей статьи — &amp;lt;code&amp;gt;2012-2022&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Принимающий порт mita&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Опциональная конфигурация: egress через сторонний прокси ===&lt;br /&gt;
По умолчанию backend-сервер выходит в интернет напрямую с публичного IP виртуальной машины. В качестве промежуточной цепочки часто используется выделенный SOCKS5-прокси, обслуживаемый сторонней панелью (например, &#039;&#039;&#039;3x-ui&#039;&#039;&#039; над xray-core).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!№&lt;br /&gt;
!Параметр&lt;br /&gt;
!Пример&lt;br /&gt;
!Комментарий&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|SOCKS5-inbound, слушающий &#039;&#039;&#039;только на &amp;lt;code&amp;gt;172.17.0.1&amp;lt;/code&amp;gt;&#039;&#039;&#039; (docker0-bridge gateway)&lt;br /&gt;
|порт &amp;lt;code&amp;gt;24366&amp;lt;/code&amp;gt;&lt;br /&gt;
|Слушать на &amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt; &#039;&#039;&#039;не подойдёт&#039;&#039;&#039;: контейнер mita с &amp;lt;code&amp;gt;network_mode: host&amp;lt;/code&amp;gt; увидит нужный адрес именно как &amp;lt;code&amp;gt;172.17.0.1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Аутентификация на этом inbound отключена&lt;br /&gt;
|—&lt;br /&gt;
|Можно включить и прописать креды в &amp;lt;code&amp;gt;egress.proxies&amp;lt;/code&amp;gt; mita, но без авторизации проще&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Routing-rule: трафик с этого inbound → нужный outbound (например, WireGuard-к-WARP, наружный VPN, сторонний прокси)&lt;br /&gt;
|—&lt;br /&gt;
|Зависит от вашей панели; в 3x-ui — раздел «Маршрутизация»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Проверка egress-цепочки ====&lt;br /&gt;
Команда выполняется на самом backend-сервере. Заменить &amp;lt;code&amp;gt;24366&amp;lt;/code&amp;gt; на ваш порт.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run --rm curlimages/curl:latest --max-time 12 --socks5 172.17.0.1:24366 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидание: IP вашего egress-узла (например, IP Cloudflare WARP или IP стороннего VPN). Если возвращается публичный IP вашей VM — egress не работает, проверьте routing панели.&lt;br /&gt;
&lt;br /&gt;
Если egress через сторонний прокси не нужен (готовы выходить с публичного IP backend-сервера) — пропустите этот раздел; в дальнейших шагах указания «без egress» помечены явно.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Параметры, которые нужно подготовить заранее ==&lt;br /&gt;
Перед началом установки заполните таблицу собственными значениями. На каждом шаге, где встретится плейсхолдер, мы будем ссылаться на эту таблицу.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Плейсхолдер&lt;br /&gt;
!Что это&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_FRONTEND_HOST&amp;lt;/code&amp;gt;&lt;br /&gt;
|Адрес frontend-сервера для SSH (IP, имя из &amp;lt;code&amp;gt;~/.ssh/config&amp;lt;/code&amp;gt; либо домен)&lt;br /&gt;
|&amp;lt;code&amp;gt;198.51.100.10&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_BACKEND_HOST&amp;lt;/code&amp;gt;&lt;br /&gt;
|Адрес backend-сервера для SSH&lt;br /&gt;
|&amp;lt;code&amp;gt;203.0.113.20&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_BACKEND_PUBLIC_IP&amp;lt;/code&amp;gt;&lt;br /&gt;
|Публичный IP backend-сервера, к которому будет коннектиться mieru-client с frontend&lt;br /&gt;
|&amp;lt;code&amp;gt;203.0.113.20&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_FRONTEND_PUBLIC_IP&amp;lt;/code&amp;gt;&lt;br /&gt;
|Публичный IP frontend-сервера, к которому будут коннектиться клиенты&lt;br /&gt;
|&amp;lt;code&amp;gt;198.51.100.10&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_BRIDGE_PASSWORD&amp;lt;/code&amp;gt;&lt;br /&gt;
|Пароль учётки mieru, которой mieru-client на frontend подключается к mita на backend. Один на оба узла&lt;br /&gt;
|длинная случайная строка, сгенерированная &amp;lt;code&amp;gt;openssl rand&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_CLIENT_PASSWORD&amp;lt;/code&amp;gt;&lt;br /&gt;
|Пароль первой клиентской учётки &amp;lt;code&amp;gt;client01&amp;lt;/code&amp;gt; на frontend&lt;br /&gt;
|длинная случайная строка&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_EGRESS_HOST&amp;lt;/code&amp;gt;&lt;br /&gt;
|Адрес SOCKS5-egress на backend (если используете)&lt;br /&gt;
|&amp;lt;code&amp;gt;172.17.0.1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_EGRESS_PORT&amp;lt;/code&amp;gt;&lt;br /&gt;
|Порт SOCKS5-egress&lt;br /&gt;
|&amp;lt;code&amp;gt;24366&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Сохраните таблицу в надёжное место — особенно пароли. Без них восстановить рабочее состояние нельзя.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Установка backend-сервера (точка выхода) ==&lt;br /&gt;
Все команды этого раздела выполняются на backend-сервере по SSH. Каждое пояснение — одна команда.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Подключение по SSH ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh root@YOUR_BACKEND_HOST&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Проверка Docker ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker --version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если выведено &amp;lt;code&amp;gt;Docker version 24.0.x&amp;lt;/code&amp;gt; или новее — переходите к шагу 3. Если &amp;lt;code&amp;gt;command not found&amp;lt;/code&amp;gt; — установите Docker по официальной инструкции для вашей ОС: &amp;lt;code&amp;gt;https://docs.docker.com/engine/install/&amp;lt;/code&amp;gt;. После установки вернитесь сюда.&lt;br /&gt;
&lt;br /&gt;
Дополнительно проверьте плагин Compose.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создание рабочего каталога ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/mieru-backend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/mieru-backend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Создание Dockerfile ===&lt;br /&gt;
Откройте файл для редактирования.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-backend/Dockerfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте следующее содержимое полностью.&amp;lt;syntaxhighlight lang=&amp;quot;dockerfile&amp;quot;&amp;gt;&lt;br /&gt;
ARG MIERU_VERSION=3.32.0&lt;br /&gt;
ARG TARGETARCH=amd64&lt;br /&gt;
&lt;br /&gt;
FROM alpine:3.19 AS downloader&lt;br /&gt;
ARG MIERU_VERSION&lt;br /&gt;
ARG TARGETARCH&lt;br /&gt;
RUN apk add --no-cache ca-certificates wget&lt;br /&gt;
WORKDIR /tmp/mita&lt;br /&gt;
RUN wget -qO- &amp;quot;https://github.com/enfein/mieru/releases/download/v${MIERU_VERSION}/mita_${MIERU_VERSION}_linux_${TARGETARCH}.tar.gz&amp;quot; | tar xz&lt;br /&gt;
WORKDIR /tmp/mieru&lt;br /&gt;
RUN wget -qO- &amp;quot;https://github.com/enfein/mieru/releases/download/v${MIERU_VERSION}/mieru_${MIERU_VERSION}_linux_${TARGETARCH}.tar.gz&amp;quot; | tar xz&lt;br /&gt;
&lt;br /&gt;
FROM alpine:3.19&lt;br /&gt;
RUN apk add --no-cache ca-certificates tini &amp;amp;&amp;amp; \&lt;br /&gt;
    adduser -H -D -g &amp;quot;&amp;quot; mita &amp;amp;&amp;amp; \&lt;br /&gt;
    adduser -H -D -g &amp;quot;&amp;quot; mieru&lt;br /&gt;
COPY --from=downloader /tmp/mita/mita /usr/local/bin/mita&lt;br /&gt;
COPY --from=downloader /tmp/mieru/mieru /usr/local/bin/mieru&lt;br /&gt;
RUN chmod +x /usr/local/bin/mita /usr/local/bin/mieru &amp;amp;&amp;amp; \&lt;br /&gt;
    mkdir -p /etc/mita /var/lib/mita /var/run/mita \&lt;br /&gt;
             /etc/mieru /var/lib/mieru /var/run/mieru /srv &amp;amp;&amp;amp; \&lt;br /&gt;
    chown -R mita:mita /etc/mita /var/lib/mita /var/run/mita &amp;amp;&amp;amp; \&lt;br /&gt;
    chown -R mieru:mieru /etc/mieru /var/lib/mieru /var/run/mieru&lt;br /&gt;
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh&lt;br /&gt;
RUN chmod +x /usr/local/bin/docker-entrypoint.sh&lt;br /&gt;
ENTRYPOINT [&amp;quot;/sbin/tini&amp;quot;,&amp;quot;--&amp;quot;,&amp;quot;/usr/local/bin/docker-entrypoint.sh&amp;quot;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Создание скрипта-entrypoint ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-backend/docker-entrypoint.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте полное содержимое.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
set -eu&lt;br /&gt;
&lt;br /&gt;
MODE=&amp;quot;${MIERU_MODE:-mita}&amp;quot;&lt;br /&gt;
CONFIG_FILE=&amp;quot;${MIERU_CONFIG:-/srv/config.json}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$MODE&amp;quot; in&lt;br /&gt;
    mita)  BIN=mita ;;&lt;br /&gt;
    mieru) BIN=mieru ;;&lt;br /&gt;
    *) echo &amp;quot;[entrypoint] FATAL: MIERU_MODE=&#039;$MODE&#039; (mita или mieru)&amp;quot;; exit 1 ;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
if [ ! -f &amp;quot;$CONFIG_FILE&amp;quot; ]; then&lt;br /&gt;
    echo &amp;quot;[entrypoint] WARN: $CONFIG_FILE не найден&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$MODE&amp;quot; = &amp;quot;mieru&amp;quot; ]; then&lt;br /&gt;
    if [ -f &amp;quot;$CONFIG_FILE&amp;quot; ]; then&lt;br /&gt;
        mieru apply config &amp;quot;$CONFIG_FILE&amp;quot; 2&amp;gt;&amp;amp;1&lt;br /&gt;
    fi&lt;br /&gt;
    exec mieru run&lt;br /&gt;
else&lt;br /&gt;
    apply_via_rpc() {&lt;br /&gt;
        i=0&lt;br /&gt;
        while [ &amp;quot;$i&amp;quot; -lt 30 ]; do&lt;br /&gt;
            i=$((i+1)); sleep 1&lt;br /&gt;
            if [ -f &amp;quot;$CONFIG_FILE&amp;quot; ] &amp;amp;&amp;amp; mita apply config &amp;quot;$CONFIG_FILE&amp;quot; &amp;gt;/tmp/apply.out 2&amp;gt;&amp;amp;1; then&lt;br /&gt;
                mita start &amp;gt;/tmp/start.out 2&amp;gt;&amp;amp;1&lt;br /&gt;
                return 0&lt;br /&gt;
            fi&lt;br /&gt;
        done&lt;br /&gt;
    }&lt;br /&gt;
    apply_via_rpc &amp;amp;&lt;br /&gt;
    exec mita run&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дайте файлу права на исполнение.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x /opt/mieru-backend/docker-entrypoint.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 6. Генерация пароля для bridge-учётки ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl rand -base64 24 | tr -d &#039;=/+&#039; | head -c 31&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Команда выведет одну строку из 31 символа. Скопируйте её и впишите в подготовленную таблицу как &amp;lt;code&amp;gt;YOUR_BRIDGE_PASSWORD&amp;lt;/code&amp;gt;. Этот же пароль понадобится на frontend-сервере (шаг ниже).&lt;br /&gt;
&lt;br /&gt;
=== Шаг 7. Создание серверного конфига ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-backend/server.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте содержимое и замените &amp;lt;code&amp;gt;YOUR_BRIDGE_PASSWORD&amp;lt;/code&amp;gt; на скопированное значение из шага 6.&lt;br /&gt;
&lt;br /&gt;
Если вы &#039;&#039;&#039;используете&#039;&#039;&#039; egress через сторонний SOCKS5-прокси — оставьте секцию &amp;lt;code&amp;gt;egress&amp;lt;/code&amp;gt; как есть и при необходимости подправьте &amp;lt;code&amp;gt;host&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;port&amp;lt;/code&amp;gt;. Если &#039;&#039;&#039;не используете&#039;&#039;&#039; — удалите всю секцию &amp;lt;code&amp;gt;egress&amp;lt;/code&amp;gt; от открывающей до закрывающей фигурной скобки.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;portBindings&amp;quot;: [&lt;br /&gt;
        {&amp;quot;portRange&amp;quot;: &amp;quot;2012-2022&amp;quot;, &amp;quot;protocol&amp;quot;: &amp;quot;TCP&amp;quot;}&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;users&amp;quot;: [&lt;br /&gt;
        {&amp;quot;name&amp;quot;: &amp;quot;frontend-bridge&amp;quot;, &amp;quot;password&amp;quot;: &amp;quot;YOUR_BRIDGE_PASSWORD&amp;quot;}&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;loggingLevel&amp;quot;: &amp;quot;INFO&amp;quot;,&lt;br /&gt;
    &amp;quot;mtu&amp;quot;: 1380,&lt;br /&gt;
    &amp;quot;egress&amp;quot;: {&lt;br /&gt;
        &amp;quot;proxies&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;external-egress&amp;quot;,&lt;br /&gt;
                &amp;quot;protocol&amp;quot;: &amp;quot;SOCKS5_PROXY_PROTOCOL&amp;quot;,&lt;br /&gt;
                &amp;quot;host&amp;quot;: &amp;quot;172.17.0.1&amp;quot;,&lt;br /&gt;
                &amp;quot;port&amp;quot;: 24366&lt;br /&gt;
            }&lt;br /&gt;
        ],&lt;br /&gt;
        &amp;quot;rules&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;ipRanges&amp;quot;: [&amp;quot;*&amp;quot;],&lt;br /&gt;
                &amp;quot;domainNames&amp;quot;: [&amp;quot;*&amp;quot;],&lt;br /&gt;
                &amp;quot;action&amp;quot;: &amp;quot;PROXY&amp;quot;,&lt;br /&gt;
                &amp;quot;proxyNames&amp;quot;: [&amp;quot;external-egress&amp;quot;]&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Защитите файл (содержит пароль).&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /opt/mieru-backend/server.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 8. Создание docker-compose.yml ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-backend/docker-compose.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте.&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  mita:&lt;br /&gt;
    build:&lt;br /&gt;
      context: .&lt;br /&gt;
      args:&lt;br /&gt;
        MIERU_VERSION: &amp;quot;3.32.0&amp;quot;&lt;br /&gt;
    image: mieru-bundle:3.32.0&lt;br /&gt;
    container_name: mita-backend&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    environment:&lt;br /&gt;
      MIERU_MODE: mita&lt;br /&gt;
      MIERU_CONFIG: /srv/server.json&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./server.json:/srv/server.json:ro&lt;br /&gt;
      - mita-state:/etc/mita&lt;br /&gt;
      - mita-runtime:/var/run/mita&lt;br /&gt;
      - mita-data:/var/lib/mita&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: json-file&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;10m&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  mita-state:&lt;br /&gt;
  mita-runtime:&lt;br /&gt;
  mita-data:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 9. Сборка образа ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-backend/docker-compose.yml build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сборка длится 1–3 минуты. По завершении выводится &amp;lt;code&amp;gt;Image mieru-bundle:3.32.0 Built&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 10. Запуск ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-backend/docker-compose.yml up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подождите 10 секунд.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sleep 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Проверьте логи.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs mita-backend --tail 25&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидаемые строки:&lt;br /&gt;
 [entrypoint] config применён (/srv/server.json)&lt;br /&gt;
 [entrypoint] mita start: OK&lt;br /&gt;
 mita server status is &amp;quot;RUNNING&amp;quot;&lt;br /&gt;
Проверьте, что сервер слушает порты &amp;lt;code&amp;gt;2012-2022&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -tlnp | grep -E &#039;:20(1[2-9]|2[012]) &#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должны появиться 11 строк со статусом &amp;lt;code&amp;gt;LISTEN&amp;lt;/code&amp;gt; и пользователем &amp;lt;code&amp;gt;mita&amp;lt;/code&amp;gt;. Если их нет — обратитесь к разделу «Поиск проблем».&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Установка frontend-сервера (точка входа) ==&lt;br /&gt;
Все команды этого раздела выполняются на frontend-сервере по SSH.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Подключение и подготовка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh root@YOUR_FRONTEND_HOST&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/mieru-frontend &amp;amp;&amp;amp; cd /opt/mieru-frontend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Dockerfile и entrypoint (одинаковые с backend) ===&lt;br /&gt;
Создайте оба файла так же, как на backend-сервере (см. шаги 4–5 раздела «Установка backend-сервера»). Содержимое идентично — образ универсальный, режим работы выбирается переменной окружения.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-frontend/Dockerfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;(вставьте тот же Dockerfile, что на backend)&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-frontend/docker-entrypoint.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;(вставьте тот же entrypoint)&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x /opt/mieru-frontend/docker-entrypoint.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Генерация пароля первой клиентской учётки ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl rand -base64 24 | tr -d &#039;=/+&#039; | head -c 31&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Скопируйте результат и впишите в таблицу как &amp;lt;code&amp;gt;YOUR_CLIENT_PASSWORD&amp;lt;/code&amp;gt;. Это пароль учётки &amp;lt;code&amp;gt;client01&amp;lt;/code&amp;gt;, который вы потом отдадите своему первому клиентскому устройству.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Серверный конфиг (mita-frontend) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-frontend/server.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Замените &amp;lt;code&amp;gt;YOUR_CLIENT_PASSWORD&amp;lt;/code&amp;gt; на значение из шага 3.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;portBindings&amp;quot;: [&lt;br /&gt;
        {&amp;quot;portRange&amp;quot;: &amp;quot;2012-2022&amp;quot;, &amp;quot;protocol&amp;quot;: &amp;quot;TCP&amp;quot;}&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;users&amp;quot;: [&lt;br /&gt;
        {&amp;quot;name&amp;quot;: &amp;quot;client01&amp;quot;, &amp;quot;password&amp;quot;: &amp;quot;YOUR_CLIENT_PASSWORD&amp;quot;}&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;loggingLevel&amp;quot;: &amp;quot;INFO&amp;quot;,&lt;br /&gt;
    &amp;quot;mtu&amp;quot;: 1380,&lt;br /&gt;
    &amp;quot;trafficPattern&amp;quot;: {&lt;br /&gt;
        &amp;quot;unlockAll&amp;quot;: false,&lt;br /&gt;
        &amp;quot;tcpFragment&amp;quot;: {&amp;quot;enable&amp;quot;: true, &amp;quot;maxSleepMs&amp;quot;: 10},&lt;br /&gt;
        &amp;quot;nonce&amp;quot;: {&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;NONCE_TYPE_PRINTABLE&amp;quot;,&lt;br /&gt;
            &amp;quot;minLen&amp;quot;: 6,&lt;br /&gt;
            &amp;quot;maxLen&amp;quot;: 8&lt;br /&gt;
        }&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;egress&amp;quot;: {&lt;br /&gt;
        &amp;quot;proxies&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;to-backend&amp;quot;,&lt;br /&gt;
                &amp;quot;protocol&amp;quot;: &amp;quot;SOCKS5_PROXY_PROTOCOL&amp;quot;,&lt;br /&gt;
                &amp;quot;host&amp;quot;: &amp;quot;127.0.0.1&amp;quot;,&lt;br /&gt;
                &amp;quot;port&amp;quot;: 1080&lt;br /&gt;
            }&lt;br /&gt;
        ],&lt;br /&gt;
        &amp;quot;rules&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;ipRanges&amp;quot;: [&amp;quot;*&amp;quot;],&lt;br /&gt;
                &amp;quot;domainNames&amp;quot;: [&amp;quot;*&amp;quot;],&lt;br /&gt;
                &amp;quot;action&amp;quot;: &amp;quot;PROXY&amp;quot;,&lt;br /&gt;
                &amp;quot;proxyNames&amp;quot;: [&amp;quot;to-backend&amp;quot;]&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните и защитите файл.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /opt/mieru-frontend/server.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Клиентский конфиг (mieru-client) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-frontend/client.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Замените &amp;lt;code&amp;gt;YOUR_BACKEND_PUBLIC_IP&amp;lt;/code&amp;gt; на публичный IP backend-сервера, &amp;lt;code&amp;gt;YOUR_BRIDGE_PASSWORD&amp;lt;/code&amp;gt; — на пароль bridge-учётки, который вы создавали на backend в шаге 6.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;profiles&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;profileName&amp;quot;: &amp;quot;default&amp;quot;,&lt;br /&gt;
            &amp;quot;user&amp;quot;: {&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;frontend-bridge&amp;quot;,&lt;br /&gt;
                &amp;quot;password&amp;quot;: &amp;quot;YOUR_BRIDGE_PASSWORD&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;servers&amp;quot;: [&lt;br /&gt;
                {&lt;br /&gt;
                    &amp;quot;ipAddress&amp;quot;: &amp;quot;YOUR_BACKEND_PUBLIC_IP&amp;quot;,&lt;br /&gt;
                    &amp;quot;portBindings&amp;quot;: [&lt;br /&gt;
                        {&amp;quot;portRange&amp;quot;: &amp;quot;2012-2022&amp;quot;, &amp;quot;protocol&amp;quot;: &amp;quot;TCP&amp;quot;}&lt;br /&gt;
                    ]&lt;br /&gt;
                }&lt;br /&gt;
            ],&lt;br /&gt;
            &amp;quot;mtu&amp;quot;: 1380,&lt;br /&gt;
            &amp;quot;multiplexing&amp;quot;: {&amp;quot;level&amp;quot;: &amp;quot;MULTIPLEXING_HIGH&amp;quot;},&lt;br /&gt;
            &amp;quot;handshakeMode&amp;quot;: &amp;quot;HANDSHAKE_NO_WAIT&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;activeProfile&amp;quot;: &amp;quot;default&amp;quot;,&lt;br /&gt;
    &amp;quot;rpcPort&amp;quot;: 8964,&lt;br /&gt;
    &amp;quot;socks5Port&amp;quot;: 1080,&lt;br /&gt;
    &amp;quot;loggingLevel&amp;quot;: &amp;quot;INFO&amp;quot;,&lt;br /&gt;
    &amp;quot;socks5ListenLAN&amp;quot;: false,&lt;br /&gt;
    &amp;quot;httpProxyListenLAN&amp;quot;: false&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните и защитите файл.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /opt/mieru-frontend/client.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 6. docker-compose.yml на frontend ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-frontend/docker-compose.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте.&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  mieru-client:&lt;br /&gt;
    build:&lt;br /&gt;
      context: .&lt;br /&gt;
      args:&lt;br /&gt;
        MIERU_VERSION: &amp;quot;3.32.0&amp;quot;&lt;br /&gt;
    image: mieru-bundle:3.32.0&lt;br /&gt;
    container_name: mieru-client&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    environment:&lt;br /&gt;
      MIERU_MODE: mieru&lt;br /&gt;
      MIERU_CONFIG: /srv/client.json&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./client.json:/srv/client.json:ro&lt;br /&gt;
      - mieru-client-state:/etc/mieru&lt;br /&gt;
      - mieru-client-runtime:/var/run/mieru&lt;br /&gt;
      - mieru-client-data:/var/lib/mieru&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: json-file&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;10m&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  mita:&lt;br /&gt;
    image: mieru-bundle:3.32.0&lt;br /&gt;
    container_name: mita-frontend&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    depends_on:&lt;br /&gt;
      - mieru-client&lt;br /&gt;
    environment:&lt;br /&gt;
      MIERU_MODE: mita&lt;br /&gt;
      MIERU_CONFIG: /srv/server.json&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./server.json:/srv/server.json:ro&lt;br /&gt;
      - mita-state:/etc/mita&lt;br /&gt;
      - mita-runtime:/var/run/mita&lt;br /&gt;
      - mita-data:/var/lib/mita&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: json-file&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;10m&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  mieru-client-state:&lt;br /&gt;
  mieru-client-runtime:&lt;br /&gt;
  mieru-client-data:&lt;br /&gt;
  mita-state:&lt;br /&gt;
  mita-runtime:&lt;br /&gt;
  mita-data:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 7. Сборка и запуск ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-frontend/docker-compose.yml build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-frontend/docker-compose.yml up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sleep 12&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 8. Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs mieru-client --tail 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должна быть строка &amp;lt;code&amp;gt;mieru: config применён&amp;lt;/code&amp;gt; и затем &amp;lt;code&amp;gt;запуск mieru run&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs mita-frontend --tail 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должно быть &amp;lt;code&amp;gt;RUNNING&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;mita start: OK&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mieru-client mieru status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидание: &amp;lt;code&amp;gt;mieru client is running&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-frontend mita status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидание: &amp;lt;code&amp;gt;mita server status is &amp;quot;RUNNING&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 9. Сквозной тест каскада ===&lt;br /&gt;
С frontend-сервера обратитесь во внешний интернет через локальный SOCKS5 mieru-client. Это эквивалент того, как пойдёт реальный клиентский запрос.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS --max-time 30 --proxy socks5h://127.0.0.1:1080 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидание: IP вашего egress-узла. Например, IP Cloudflare WARP, если на backend настроен такой outbound. Команда &#039;&#039;&#039;не должна&#039;&#039;&#039; возвращать публичный IP frontend-сервера.&lt;br /&gt;
&lt;br /&gt;
Контрольный замер прямого IP frontend для сравнения.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS --max-time 5 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если первый IP отличается от второго — каскад работает.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Подключение клиентов ==&lt;br /&gt;
mieru имеет два равнозначных формата отдачи параметров клиенту: &#039;&#039;&#039;Clash/Mihomo YAML&#039;&#039;&#039; и &#039;&#039;&#039;&amp;lt;code&amp;gt;mierus://&amp;lt;/code&amp;gt; URI&#039;&#039;&#039;. На практике YAML более переносим — его понимает большинство клиентов в одном виде, тогда как URI разбирается каждым приложением по-своему.&lt;br /&gt;
&lt;br /&gt;
=== Десктоп: Clash Verge Rev / Mihomo Party / NekoBox ===&lt;br /&gt;
Создайте новый профиль (или отредактируйте существующий) и добавьте блок &amp;lt;code&amp;gt;proxies&amp;lt;/code&amp;gt;:&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
proxies:&lt;br /&gt;
  - name: mieru-frontend&lt;br /&gt;
    type: mieru&lt;br /&gt;
    server: YOUR_FRONTEND_PUBLIC_IP&lt;br /&gt;
    port: 2022&lt;br /&gt;
    username: client01&lt;br /&gt;
    password: YOUR_CLIENT_PASSWORD&lt;br /&gt;
    multiplexing: MULTIPLEXING_HIGH&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Параметр &amp;lt;code&amp;gt;port: 2022&amp;lt;/code&amp;gt; — это один из портов из диапазона &amp;lt;code&amp;gt;2012-2022&amp;lt;/code&amp;gt;; mita слушает все 11 параллельно, клиент использует один (мультиплексор).&lt;br /&gt;
&lt;br /&gt;
=== Мобильные: Karing / ClashMi / NekoBox+plugin / husi ===&lt;br /&gt;
Подключение через тот же YAML-блок выше — большинство клиентов поддерживают вставку YAML вручную в раздел «Серверы» или «Outbounds». Сценарий импорта URI в Karing 1.2.x работает плохо (поле порта обнуляется), поэтому YAML предпочтительнее.&lt;br /&gt;
&lt;br /&gt;
=== Универсальный URI-формат ===&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
mierus://client01:YOUR_CLIENT_PASSWORD@YOUR_FRONTEND_PUBLIC_IP?port=2022&amp;amp;protocol=TCP&amp;amp;mtu=1380&amp;amp;multiplexing=MULTIPLEXING_HIGH&amp;amp;handshake-mode=HANDSHAKE_NO_WAIT&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подходит для нативного &amp;lt;code&amp;gt;mieru&amp;lt;/code&amp;gt; CLI, husi с mieru-плагином, Exclave.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Подключение клиента на OpenWrt-роутере ==&lt;br /&gt;
Если на роутере уже стоит трафик-менеджер (например, podkop), и вы хотите, чтобы он отправлял трафик через mieru — поставьте на роутер standalone mieru-клиент с локальным SOCKS5, и подкоп цепляйте к этому SOCKS5.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Подключение к роутеру ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh root@YOUR_ROUTER_HOST&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Скачивание бинаря ===&lt;br /&gt;
Архитектура роутера большинства современных моделей — &amp;lt;code&amp;gt;aarch64&amp;lt;/code&amp;gt;. Если ваш роутер — другой (например, &amp;lt;code&amp;gt;mips&amp;lt;/code&amp;gt;), проверьте список релизов &amp;lt;code&amp;gt;https://github.com/enfein/mieru/releases/latest&amp;lt;/code&amp;gt; и подставьте нужный артефакт в команду.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /tmp &amp;amp;&amp;amp; wget -q https://github.com/enfein/mieru/releases/download/v3.32.0/mieru_3.32.0_linux_arm64.tar.gz -O mieru.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar xzf mieru.tar.gz &amp;amp;&amp;amp; mv mieru /usr/bin/mieru &amp;amp;&amp;amp; chmod +x /usr/bin/mieru &amp;amp;&amp;amp; rm -f /tmp/mieru.tar.gz /tmp/LICENSE /tmp/README.md&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/usr/bin/mieru version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должно вывести &amp;lt;code&amp;gt;3.32.0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Клиентский конфиг ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /etc/mieru_client_config.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте, заменив плейсхолдеры:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;profiles&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;profileName&amp;quot;: &amp;quot;default&amp;quot;,&lt;br /&gt;
            &amp;quot;user&amp;quot;: {&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;client01&amp;quot;,&lt;br /&gt;
                &amp;quot;password&amp;quot;: &amp;quot;YOUR_CLIENT_PASSWORD&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;servers&amp;quot;: [&lt;br /&gt;
                {&lt;br /&gt;
                    &amp;quot;ipAddress&amp;quot;: &amp;quot;YOUR_FRONTEND_PUBLIC_IP&amp;quot;,&lt;br /&gt;
                    &amp;quot;portBindings&amp;quot;: [&lt;br /&gt;
                        {&amp;quot;portRange&amp;quot;: &amp;quot;2012-2022&amp;quot;, &amp;quot;protocol&amp;quot;: &amp;quot;TCP&amp;quot;}&lt;br /&gt;
                    ]&lt;br /&gt;
                }&lt;br /&gt;
            ],&lt;br /&gt;
            &amp;quot;mtu&amp;quot;: 1380,&lt;br /&gt;
            &amp;quot;multiplexing&amp;quot;: {&amp;quot;level&amp;quot;: &amp;quot;MULTIPLEXING_HIGH&amp;quot;},&lt;br /&gt;
            &amp;quot;handshakeMode&amp;quot;: &amp;quot;HANDSHAKE_NO_WAIT&amp;quot;,&lt;br /&gt;
            &amp;quot;trafficPattern&amp;quot;: {&lt;br /&gt;
                &amp;quot;unlockAll&amp;quot;: false,&lt;br /&gt;
                &amp;quot;tcpFragment&amp;quot;: {&amp;quot;enable&amp;quot;: true, &amp;quot;maxSleepMs&amp;quot;: 10},&lt;br /&gt;
                &amp;quot;nonce&amp;quot;: {&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;NONCE_TYPE_PRINTABLE&amp;quot;,&lt;br /&gt;
                    &amp;quot;minLen&amp;quot;: 6,&lt;br /&gt;
                    &amp;quot;maxLen&amp;quot;: 8&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;activeProfile&amp;quot;: &amp;quot;default&amp;quot;,&lt;br /&gt;
    &amp;quot;rpcPort&amp;quot;: 8964,&lt;br /&gt;
    &amp;quot;socks5Port&amp;quot;: 1090,&lt;br /&gt;
    &amp;quot;loggingLevel&amp;quot;: &amp;quot;ERROR&amp;quot;,&lt;br /&gt;
    &amp;quot;socks5ListenLAN&amp;quot;: false,&lt;br /&gt;
    &amp;quot;httpProxyListenLAN&amp;quot;: false&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните и защитите файл.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /etc/mieru_client_config.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ключевые отличия конфига для роутера от десктопного клиента:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;socks5Port: 1090&amp;lt;/code&amp;gt; — порт &amp;lt;code&amp;gt;1080&amp;lt;/code&amp;gt; часто занят другими прокси (например, naive); 1090 свободен.&lt;br /&gt;
* &amp;lt;code&amp;gt;loggingLevel: &amp;quot;ERROR&amp;quot;&amp;lt;/code&amp;gt; — overlay на роутерах маленький, ограничение логов защищает от заполнения диска.&lt;br /&gt;
* &amp;lt;code&amp;gt;trafficPattern&amp;lt;/code&amp;gt; включён полностью — на пути «роутер → frontend» классификатор смотрит, маскировка нужна.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Init.d-скрипт ===&lt;br /&gt;
OpenWrt использует procd; в отличие от mita, на OpenWrt mieru читает JSON-конфиг напрямую через переменную &amp;lt;code&amp;gt;MIERU_CONFIG_JSON_FILE&amp;lt;/code&amp;gt;, и команды &amp;lt;code&amp;gt;mieru apply config&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;mieru describe config&amp;lt;/code&amp;gt; &#039;&#039;&#039;не используются&#039;&#039;&#039;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /etc/init.d/mieru&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh /etc/rc.common&lt;br /&gt;
&lt;br /&gt;
START=99&lt;br /&gt;
STOP=01&lt;br /&gt;
&lt;br /&gt;
MIERU_BIN=&amp;quot;/usr/bin/mieru&amp;quot;&lt;br /&gt;
MIERU_CONFIG=&amp;quot;/etc/mieru_client_config.json&amp;quot;&lt;br /&gt;
PID_FILE=&amp;quot;/var/run/mieru.pid&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start() {&lt;br /&gt;
    echo &amp;quot;Starting mieru client...&amp;quot;&lt;br /&gt;
    export MIERU_CONFIG_JSON_FILE=$MIERU_CONFIG&lt;br /&gt;
    start-stop-daemon -S -b -m -p &amp;quot;$PID_FILE&amp;quot; -x &amp;quot;$MIERU_BIN&amp;quot; -- run&lt;br /&gt;
    RC=$?&lt;br /&gt;
    if [ $RC -eq 0 ]; then&lt;br /&gt;
        echo &amp;quot;mieru client is started&amp;quot;&lt;br /&gt;
        exit 0&lt;br /&gt;
    else&lt;br /&gt;
        echo &amp;quot;failed to start mieru client&amp;quot;&lt;br /&gt;
        exit $RC&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
stop() {&lt;br /&gt;
    echo &amp;quot;Stopping mieru client...&amp;quot;&lt;br /&gt;
    start-stop-daemon -K -p &amp;quot;$PID_FILE&amp;quot;&lt;br /&gt;
    RC=$?&lt;br /&gt;
    if [ $RC -eq 0 ]; then&lt;br /&gt;
        echo &amp;quot;mieru client is stopped&amp;quot;&lt;br /&gt;
        rm -f &amp;quot;$PID_FILE&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        echo &amp;quot;failed to stop mieru client&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните и сделайте исполняемым.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x /etc/init.d/mieru&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Запуск и автозапуск ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/etc/init.d/mieru enable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/etc/init.d/mieru start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 6. Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps | grep mieru | grep -v grep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должна быть одна строка с процессом &amp;lt;code&amp;gt;/usr/bin/mieru run&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
netstat -tlnp 2&amp;gt;/dev/null | grep 1090&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должна быть строка &amp;lt;code&amp;gt;127.0.0.1:1090 ... LISTEN ... mieru&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS --max-time 30 -x socks5h://127.0.0.1:1090 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должен вернуть IP egress-узла каскада.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 7. Подключение podkop к локальному mieru ===&lt;br /&gt;
В LuCI откройте подкоп. Создайте новую секцию или измените существующую:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Тип конфига&lt;br /&gt;
|URL&lt;br /&gt;
|-&lt;br /&gt;
|Proxy string&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1090&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Эквивалент через &amp;lt;code&amp;gt;uci&amp;lt;/code&amp;gt;:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
uci set podkop.10=section&lt;br /&gt;
uci set podkop.10.connection_type=&#039;proxy&#039;&lt;br /&gt;
uci set podkop.10.proxy_config_type=&#039;url&#039;&lt;br /&gt;
uci set podkop.10.proxy_string=&#039;socks5://127.0.0.1:1090&#039;&lt;br /&gt;
uci commit podkop&lt;br /&gt;
service podkop restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подкоп отправляет mieru-серверу обычный SOCKS5-запрос на &amp;lt;code&amp;gt;127.0.0.1:1090&amp;lt;/code&amp;gt;; mieru шифрует его и отправляет через каскад.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Управление пользователями: скрипт &amp;lt;code&amp;gt;mieru-users.sh&amp;lt;/code&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
=== Зачем он нужен ===&lt;br /&gt;
mita-сервер хранит список учёток в файле &amp;lt;code&amp;gt;server.json&amp;lt;/code&amp;gt;. Чтобы добавлять/удалять/смотреть пользователей вручную каждый раз — много шагов: jq-правка JSON, вызов &amp;lt;code&amp;gt;mita apply config&amp;lt;/code&amp;gt;, генерация ссылки клиенту, опционально &amp;lt;code&amp;gt;mita delete user&amp;lt;/code&amp;gt; для разрыва активных сессий. Скрипт &amp;lt;code&amp;gt;mieru-users.sh&amp;lt;/code&amp;gt; автоматизирует это всё.&lt;br /&gt;
&lt;br /&gt;
=== Что делает скрипт ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Пункт меню&lt;br /&gt;
!Действие&lt;br /&gt;
|-&lt;br /&gt;
|1. Список пользователей&lt;br /&gt;
|Чтение &amp;lt;code&amp;gt;server.json&amp;lt;/code&amp;gt; + опрос &amp;lt;code&amp;gt;mita get connections&amp;lt;/code&amp;gt; для активных сессий&lt;br /&gt;
|-&lt;br /&gt;
|2. Добавить пользователя&lt;br /&gt;
|Запрос имени, генерация пароля через &amp;lt;code&amp;gt;openssl rand&amp;lt;/code&amp;gt;, бэкап JSON, &amp;lt;code&amp;gt;jq&amp;lt;/code&amp;gt;-вставка, &amp;lt;code&amp;gt;mita apply config&amp;lt;/code&amp;gt;, выдача готовых YAML и URI клиенту&lt;br /&gt;
|-&lt;br /&gt;
|3. Удалить пользователя&lt;br /&gt;
|&amp;lt;code&amp;gt;mita delete user&amp;lt;/code&amp;gt; для разрыва сессий → &amp;lt;code&amp;gt;jq&amp;lt;/code&amp;gt;-удаление из JSON → &amp;lt;code&amp;gt;apply config&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|4. Показать URI клиента&lt;br /&gt;
|Сборка YAML и URI по выбранному имени&lt;br /&gt;
|-&lt;br /&gt;
|5. Статус сервера&lt;br /&gt;
|&amp;lt;code&amp;gt;mita status&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;get connections&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;get metrics&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Установка скрипта ===&lt;br /&gt;
Все команды выполняются на frontend-сервере по SSH.&lt;br /&gt;
&lt;br /&gt;
==== Шаг 1. Загрузка скрипта ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /usr/local/bin/mieru-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте полное содержимое скрипта (исходный код в спойлере «Исходный код &amp;lt;code&amp;gt;mieru-users.sh&amp;lt;/code&amp;gt;» в конце статьи).&lt;br /&gt;
&lt;br /&gt;
Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Шаг 2. Подстановка реального адреса ====&lt;br /&gt;
В начале скрипта есть строка &amp;lt;code&amp;gt;SERVER_IP=&amp;quot;YOUR_FRONTEND_PUBLIC_IP&amp;quot;&amp;lt;/code&amp;gt;. Замените её на реальный IP frontend-сервера.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sed -i &#039;s/YOUR_FRONTEND_PUBLIC_IP/198.51.100.10/&#039; /usr/local/bin/mieru-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;(подставьте свой IP вместо &amp;lt;code&amp;gt;198.51.100.10&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==== Шаг 3. Права на исполнение ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x /usr/local/bin/mieru-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Шаг 4. Проверка ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
bash -n /usr/local/bin/mieru-users.sh &amp;amp;&amp;amp; echo OK&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если выводит &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt; — скрипт установлен корректно.&lt;br /&gt;
&lt;br /&gt;
=== Использование ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo bash /usr/local/bin/mieru-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Появится меню:&amp;lt;pre&amp;gt;&lt;br /&gt;
╔══════════════════════════════════════╗&lt;br /&gt;
║   mieru User Manager                 ║&lt;br /&gt;
║   IP: 198.51.100.10                  ║&lt;br /&gt;
╚══════════════════════════════════════╝&lt;br /&gt;
&lt;br /&gt;
  Пользователей в конфиге: 1&lt;br /&gt;
&lt;br /&gt;
  1. Список пользователей и активных сессий&lt;br /&gt;
  2. Добавить пользователя&lt;br /&gt;
  3. Удалить пользователя&lt;br /&gt;
  4. Показать URI клиента&lt;br /&gt;
  5. Статус сервера&lt;br /&gt;
  0. Выход&lt;br /&gt;
&amp;lt;/pre&amp;gt;После добавления пользователя скрипт выводит готовые конфиги:&amp;lt;pre&amp;gt;&lt;br /&gt;
=== Вариант 1: Clash / Mihomo YAML (рекомендую) ===&lt;br /&gt;
proxies:&lt;br /&gt;
  - name: mieru-RU-alice&lt;br /&gt;
    type: mieru&lt;br /&gt;
    server: 198.51.100.10&lt;br /&gt;
    port: 2022&lt;br /&gt;
    username: alice&lt;br /&gt;
    password: &amp;lt;автогенерированный&amp;gt;&lt;br /&gt;
    multiplexing: MULTIPLEXING_HIGH&lt;br /&gt;
&lt;br /&gt;
=== Вариант 2: mierus:// URI ===&lt;br /&gt;
mierus://alice:&amp;lt;пароль&amp;gt;@198.51.100.10?port=2022&amp;amp;protocol=TCP&amp;amp;mtu=1380&amp;amp;multiplexing=MULTIPLEXING_HIGH&amp;amp;handshake-mode=HANDSHAKE_NO_WAIT&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Команды управления ==&lt;br /&gt;
&lt;br /&gt;
=== На обоих серверах ===&lt;br /&gt;
Посмотреть логи в реальном времени.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f mita-backend       # на backend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f mita-frontend mieru-client       # на frontend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Перезапустить.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-backend/docker-compose.yml restart    # на backend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-frontend/docker-compose.yml restart   # на frontend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Остановить.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-backend/docker-compose.yml down       # на backend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-frontend/docker-compose.yml down      # на frontend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Обновить версию mita/mieru. Поменяйте &amp;lt;code&amp;gt;3.32.0&amp;lt;/code&amp;gt; на нужную в &amp;lt;code&amp;gt;docker-compose.yml&amp;lt;/code&amp;gt; и пересоберите.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-backend/docker-compose.yml build &amp;amp;&amp;amp; docker compose -f /opt/mieru-backend/docker-compose.yml up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Команды mita через CLI (внутри контейнера) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita status              # IDLE / RUNNING&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita get users           # список user&#039;ов и их статистика&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita get connections     # активные сессии&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita get metrics         # метрики&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita describe config     # текущий применённый конфиг&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== На OpenWrt-роутере ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/etc/init.d/mieru start | stop | restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps | grep mieru | grep -v grep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
logread | grep mieru&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Поиск проблем ==&lt;br /&gt;
&lt;br /&gt;
=== Симптом: сервер показывает &amp;lt;code&amp;gt;IDLE&amp;lt;/code&amp;gt;, порты не слушаются ===&lt;br /&gt;
mita после &amp;lt;code&amp;gt;apply config&amp;lt;/code&amp;gt; остаётся в &amp;lt;code&amp;gt;IDLE&amp;lt;/code&amp;gt; до явной команды &amp;lt;code&amp;gt;mita start&amp;lt;/code&amp;gt;. В нашем entrypoint это происходит автоматически, но если что-то пошло не так, выполните вручную внутри контейнера:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Симптом: &amp;lt;code&amp;gt;FATAL: getUid(&amp;quot;mita&amp;quot;) failed&amp;lt;/code&amp;gt; ===&lt;br /&gt;
В образ не добавлен системный пользователь &amp;lt;code&amp;gt;mita&amp;lt;/code&amp;gt;. Проверьте, что Dockerfile содержит строки &amp;lt;code&amp;gt;adduser -H -D -g &amp;quot;&amp;quot; mita&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;adduser -H -D -g &amp;quot;&amp;quot; mieru&amp;lt;/code&amp;gt;, пересоберите образ.&lt;br /&gt;
&lt;br /&gt;
=== Симптом: клиент подключается, но трафик не идёт ===&lt;br /&gt;
Проверьте на клиенте время системы. Расхождение более 4 минут с сервером приведёт к молчаливому отказу. Команда на Linux/macOS:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
date -u&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если время существенно расходится — настройте NTP.&lt;br /&gt;
&lt;br /&gt;
=== Симптом: на frontend curl возвращает не egress-IP, а frontend-IP ===&lt;br /&gt;
Trafic идёт мимо mieru-client. Возможные причины:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;egress.action&amp;lt;/code&amp;gt; в frontend-конфиге — &amp;lt;code&amp;gt;DIRECT&amp;lt;/code&amp;gt; вместо &amp;lt;code&amp;gt;PROXY&amp;lt;/code&amp;gt;.&lt;br /&gt;
* mieru-client не запущен либо упал. Проверьте: &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Backend не доступен. Проверьте на frontend: &amp;lt;code&amp;gt;nc -vz YOUR_BACKEND_PUBLIC_IP 2022&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Симптом: на frontend curl возвращает frontend-IP, а должен — backend-IP ===&lt;br /&gt;
То же самое, что выше: трафик не доходит до backend. Дополнительно посмотрите логи:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs mieru-client --tail 50&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ошибки &amp;lt;code&amp;gt;TLS handshake&amp;lt;/code&amp;gt; здесь невозможны — mieru не использует TLS. Ищите &amp;lt;code&amp;gt;auth failed&amp;lt;/code&amp;gt; (неверная пара логин/пароль на mita-backend) и &amp;lt;code&amp;gt;connection refused&amp;lt;/code&amp;gt; (backend не слушает).&lt;br /&gt;
&lt;br /&gt;
=== Симптом: на роутере Karing/Clash подключается, но трафик не идёт ===&lt;br /&gt;
В первую очередь проверить YAML-конфиг: тип &amp;lt;code&amp;gt;type: mieru&amp;lt;/code&amp;gt; (не &amp;lt;code&amp;gt;type: socks5&amp;lt;/code&amp;gt;!), порт &amp;lt;code&amp;gt;port: 2022&amp;lt;/code&amp;gt; (одиночное число, не диапазон). Многие mihomo-форки не парсят диапазон портов корректно.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Исходный код &amp;lt;code&amp;gt;mieru-users.sh&amp;lt;/code&amp;gt; ==&lt;br /&gt;
Полный текст скрипта приведён ниже. Скопируйте его целиком в &amp;lt;code&amp;gt;/usr/local/bin/mieru-users.sh&amp;lt;/code&amp;gt; на frontend-сервере по инструкции выше.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# mieru-users — управление пользователями mita&lt;br /&gt;
# Источник истины: /opt/mieru-frontend/server.json&lt;br /&gt;
# Применение через mita apply config (RPC к работающему daemon).&lt;br /&gt;
&lt;br /&gt;
CONFIG_FILE=&amp;quot;/opt/mieru-frontend/server.json&amp;quot;&lt;br /&gt;
COMPOSE_DIR=&amp;quot;/opt/mieru-frontend&amp;quot;&lt;br /&gt;
COMPOSE_SVC=&amp;quot;mita&amp;quot;&lt;br /&gt;
BACKUP_DIR=&amp;quot;/opt/mieru-frontend/backups&amp;quot;&lt;br /&gt;
BACKUP_KEEP=10&lt;br /&gt;
SERVER_IP=&amp;quot;YOUR_FRONTEND_PUBLIC_IP&amp;quot;&lt;br /&gt;
&lt;br /&gt;
RED=&#039;\033[0;31m&#039;; GREEN=&#039;\033[0;32m&#039;; YELLOW=&#039;\033[1;33m&#039;&lt;br /&gt;
CYAN=&#039;\033[0;36m&#039;; BOLD=&#039;\033[1m&#039;; NC=&#039;\033[0m&#039;&lt;br /&gt;
&lt;br /&gt;
check_root() {&lt;br /&gt;
    if [[ $EUID -ne 0 ]]; then&lt;br /&gt;
        echo -e &amp;quot;${RED}Запусти от root: sudo bash mieru-users.sh${NC}&amp;quot;; exit 1&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
check_deps() {&lt;br /&gt;
    for c in jq docker openssl; do&lt;br /&gt;
        if ! command -v &amp;quot;$c&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then&lt;br /&gt;
            echo -e &amp;quot;${RED}Не найдено: $c${NC}&amp;quot;; exit 1&lt;br /&gt;
        fi&lt;br /&gt;
    done&lt;br /&gt;
    if [[ ! -f &amp;quot;$CONFIG_FILE&amp;quot; ]]; then&lt;br /&gt;
        echo -e &amp;quot;${RED}Не найден $CONFIG_FILE${NC}&amp;quot;; exit 1&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
mita_cli() {&lt;br /&gt;
    docker compose -f &amp;quot;$COMPOSE_DIR/docker-compose.yml&amp;quot; exec -T &amp;quot;$COMPOSE_SVC&amp;quot; mita &amp;quot;$@&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
backup_config() {&lt;br /&gt;
    mkdir -p &amp;quot;$BACKUP_DIR&amp;quot;&lt;br /&gt;
    local stamp; stamp=$(date +%Y%m%d-%H%M%S)&lt;br /&gt;
    cp &amp;quot;$CONFIG_FILE&amp;quot; &amp;quot;$BACKUP_DIR/server-$stamp.json&amp;quot;&lt;br /&gt;
    ls -1t &amp;quot;$BACKUP_DIR&amp;quot;/server-*.json 2&amp;gt;/dev/null | tail -n +$((BACKUP_KEEP+1)) | xargs -r rm -f&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
apply_config() {&lt;br /&gt;
    if ! mita_cli apply config /srv/server.json 2&amp;gt;&amp;amp;1; then&lt;br /&gt;
        echo -e &amp;quot;${RED}mita apply config упал. Откатываюсь к последнему бэкапу.${NC}&amp;quot;&lt;br /&gt;
        local last; last=$(ls -1t &amp;quot;$BACKUP_DIR&amp;quot;/server-*.json 2&amp;gt;/dev/null | head -1)&lt;br /&gt;
        if [[ -n &amp;quot;$last&amp;quot; ]]; then&lt;br /&gt;
            cp &amp;quot;$last&amp;quot; &amp;quot;$CONFIG_FILE&amp;quot;&lt;br /&gt;
            mita_cli apply config /srv/server.json &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || true&lt;br /&gt;
        fi&lt;br /&gt;
        return 1&lt;br /&gt;
    fi&lt;br /&gt;
    return 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
press_enter() { echo &amp;quot;&amp;quot;; read -rp &amp;quot;Enter для возврата...&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
generate_password() {&lt;br /&gt;
    openssl rand -base64 24 | tr -d &#039;=/+&#039; | head -c 31&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
generate_uri() {&lt;br /&gt;
    echo &amp;quot;mierus://${1}:${2}@${SERVER_IP}?port=2022&amp;amp;protocol=TCP&amp;amp;mtu=1380&amp;amp;multiplexing=MULTIPLEXING_HIGH&amp;amp;handshake-mode=HANDSHAKE_NO_WAIT&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
generate_yaml() {&lt;br /&gt;
    cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
proxies:&lt;br /&gt;
  - name: mieru-${1}&lt;br /&gt;
    type: mieru&lt;br /&gt;
    server: ${SERVER_IP}&lt;br /&gt;
    port: 2022&lt;br /&gt;
    username: ${1}&lt;br /&gt;
    password: ${2}&lt;br /&gt;
    multiplexing: MULTIPLEXING_HIGH&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
print_uri_for() {&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${CYAN}=== Вариант 1: Clash / Mihomo YAML ===${NC}&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}$(generate_yaml &amp;quot;$1&amp;quot; &amp;quot;$2&amp;quot;)${NC}&amp;quot;&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${CYAN}=== Вариант 2: mierus:// URI ===${NC}&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}  $(generate_uri &amp;quot;$1&amp;quot; &amp;quot;$2&amp;quot;)${NC}&amp;quot;&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${CYAN}user=${BOLD}${1}${NC}, pwd=${BOLD}${2}${NC}, host=${BOLD}${SERVER_IP}${NC}, port=${BOLD}2022${NC}&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list_users() {&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    local n; n=$(jq &#039;.users | length&#039; &amp;quot;$CONFIG_FILE&amp;quot;)&lt;br /&gt;
    echo -e &amp;quot;${BOLD}${CYAN}=== Пользователей: $n ===${NC}&amp;quot;&lt;br /&gt;
    jq -r &#039;.users[] | &amp;quot;  \(.name)\t\(.password[0:6])…&amp;quot;&#039; &amp;quot;$CONFIG_FILE&amp;quot; | nl -w2 -s&#039;. &#039;&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}${CYAN}=== Активные сессии ===${NC}&amp;quot;&lt;br /&gt;
    mita_cli get connections 2&amp;gt;&amp;amp;1 | head -20&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
add_user() {&lt;br /&gt;
    echo &amp;quot;&amp;quot;; read -rp &amp;quot;Имя пользователя: &amp;quot; name&lt;br /&gt;
    name=$(echo &amp;quot;$name&amp;quot; | tr -d &#039; &#039;)&lt;br /&gt;
    [[ -z &amp;quot;$name&amp;quot; ]] &amp;amp;&amp;amp; { echo &amp;quot;Пусто.&amp;quot;; press_enter; return; }&lt;br /&gt;
    if jq -e --arg n &amp;quot;$name&amp;quot; &#039;.users[] | select(.name == $n)&#039; &amp;quot;$CONFIG_FILE&amp;quot; &amp;gt;/dev/null; then&lt;br /&gt;
        echo &amp;quot;Уже есть.&amp;quot;; press_enter; return&lt;br /&gt;
    fi&lt;br /&gt;
    read -rp &amp;quot;Пароль (Enter — сгенерировать): &amp;quot; pwd&lt;br /&gt;
    [[ -z &amp;quot;$pwd&amp;quot; ]] &amp;amp;&amp;amp; pwd=$(generate_password)&lt;br /&gt;
&lt;br /&gt;
    backup_config&lt;br /&gt;
    local tmp; tmp=$(mktemp)&lt;br /&gt;
    jq --arg n &amp;quot;$name&amp;quot; --arg p &amp;quot;$pwd&amp;quot; &#039;.users += [{&amp;quot;name&amp;quot;:$n,&amp;quot;password&amp;quot;:$p}]&#039; &amp;quot;$CONFIG_FILE&amp;quot; &amp;gt; &amp;quot;$tmp&amp;quot; &amp;amp;&amp;amp; mv &amp;quot;$tmp&amp;quot; &amp;quot;$CONFIG_FILE&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    if apply_config; then&lt;br /&gt;
        echo -e &amp;quot;${GREEN}Пользователь $name добавлен.${NC}&amp;quot;&lt;br /&gt;
        print_uri_for &amp;quot;$name&amp;quot; &amp;quot;$pwd&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
delete_user() {&lt;br /&gt;
    mapfile -t users &amp;lt; &amp;lt;(jq -r &#039;.users[].name&#039; &amp;quot;$CONFIG_FILE&amp;quot;)&lt;br /&gt;
    [[ ${#users[@]} -eq 0 ]] &amp;amp;&amp;amp; { echo &amp;quot;Пусто.&amp;quot;; press_enter; return; }&lt;br /&gt;
    for i in &amp;quot;${!users[@]}&amp;quot;; do echo &amp;quot;  $((i+1))) ${users[$i]}&amp;quot;; done&lt;br /&gt;
    echo &amp;quot;  0) Отмена&amp;quot;; read -rp &amp;quot;Номер: &amp;quot; n&lt;br /&gt;
    [[ &amp;quot;$n&amp;quot; == &amp;quot;0&amp;quot; || -z &amp;quot;$n&amp;quot; ]] &amp;amp;&amp;amp; return&lt;br /&gt;
    local target=&amp;quot;${users[$((n-1))]}&amp;quot;&lt;br /&gt;
    read -rp &amp;quot;Удалить &#039;$target&#039;? (y/N): &amp;quot; yn&lt;br /&gt;
    [[ ! &amp;quot;$yn&amp;quot; =~ ^[Yy]$ ]] &amp;amp;&amp;amp; return&lt;br /&gt;
&lt;br /&gt;
    mita_cli delete user &amp;quot;$target&amp;quot; 2&amp;gt;&amp;amp;1&lt;br /&gt;
    backup_config&lt;br /&gt;
    local tmp; tmp=$(mktemp)&lt;br /&gt;
    jq --arg n &amp;quot;$target&amp;quot; &#039;del(.users[] | select(.name == $n))&#039; &amp;quot;$CONFIG_FILE&amp;quot; &amp;gt; &amp;quot;$tmp&amp;quot; &amp;amp;&amp;amp; mv &amp;quot;$tmp&amp;quot; &amp;quot;$CONFIG_FILE&amp;quot;&lt;br /&gt;
    apply_config &amp;amp;&amp;amp; echo -e &amp;quot;${GREEN}Удалён.${NC}&amp;quot;&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
show_uri() {&lt;br /&gt;
    mapfile -t users &amp;lt; &amp;lt;(jq -r &#039;.users[].name&#039; &amp;quot;$CONFIG_FILE&amp;quot;)&lt;br /&gt;
    [[ ${#users[@]} -eq 0 ]] &amp;amp;&amp;amp; { echo &amp;quot;Пусто.&amp;quot;; press_enter; return; }&lt;br /&gt;
    for i in &amp;quot;${!users[@]}&amp;quot;; do echo &amp;quot;  $((i+1))) ${users[$i]}&amp;quot;; done&lt;br /&gt;
    read -rp &amp;quot;Номер: &amp;quot; n&lt;br /&gt;
    [[ -z &amp;quot;$n&amp;quot; ]] &amp;amp;&amp;amp; return&lt;br /&gt;
    local user=&amp;quot;${users[$((n-1))]}&amp;quot;&lt;br /&gt;
    local pwd; pwd=$(jq -r --arg n &amp;quot;$user&amp;quot; &#039;.users[] | select(.name == $n) | .password&#039; &amp;quot;$CONFIG_FILE&amp;quot;)&lt;br /&gt;
    print_uri_for &amp;quot;$user&amp;quot; &amp;quot;$pwd&amp;quot;&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
server_status() {&lt;br /&gt;
    mita_cli status 2&amp;gt;&amp;amp;1&lt;br /&gt;
    echo&lt;br /&gt;
    mita_cli get connections 2&amp;gt;&amp;amp;1&lt;br /&gt;
    echo&lt;br /&gt;
    mita_cli get metrics 2&amp;gt;&amp;amp;1 | head -30&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
main_menu() {&lt;br /&gt;
    check_root; check_deps&lt;br /&gt;
    while true; do&lt;br /&gt;
        clear&lt;br /&gt;
        echo &amp;quot;╔══════════════════════════════════════╗&amp;quot;&lt;br /&gt;
        echo &amp;quot;║   mieru User Manager                 ║&amp;quot;&lt;br /&gt;
        echo &amp;quot;║   IP: $SERVER_IP&amp;quot;&lt;br /&gt;
        echo &amp;quot;╚══════════════════════════════════════╝&amp;quot;&lt;br /&gt;
        echo&lt;br /&gt;
        echo &amp;quot;  1) Список пользователей&amp;quot;&lt;br /&gt;
        echo &amp;quot;  2) Добавить&amp;quot;&lt;br /&gt;
        echo &amp;quot;  3) Удалить&amp;quot;&lt;br /&gt;
        echo &amp;quot;  4) URI клиента&amp;quot;&lt;br /&gt;
        echo &amp;quot;  5) Статус сервера&amp;quot;&lt;br /&gt;
        echo &amp;quot;  0) Выход&amp;quot;&lt;br /&gt;
        read -rp &amp;quot;Выбор: &amp;quot; opt&lt;br /&gt;
        case &amp;quot;$opt&amp;quot; in&lt;br /&gt;
            1) list_users ;; 2) add_user ;;&lt;br /&gt;
            3) delete_user ;; 4) show_uri ;;&lt;br /&gt;
            5) server_status ;; 0) exit 0 ;;&lt;br /&gt;
        esac&lt;br /&gt;
    done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
main_menu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/enfein/mieru Официальный репозиторий mieru]&lt;br /&gt;
* [https://github.com/enfein/mieru/blob/master/docs/protocol.md Спецификация протокола mieru]&lt;br /&gt;
* [https://github.com/enfein/mieru/blob/master/docs/traffic-pattern.md Документация по traffic pattern]&lt;br /&gt;
* [https://github.com/enfein/mieru/blob/master/docs/security.md Руководство по безопасности]&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Mieru-single-flow.png&amp;diff=970</id>
		<title>Файл:Mieru-single-flow.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Mieru-single-flow.png&amp;diff=970"/>
		<updated>2026-05-10T20:15:17Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A1%D1%83%D0%B2%D0%B5%D1%80%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82&amp;diff=969</id>
		<title>Суверенный интернет</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A1%D1%83%D0%B2%D0%B5%D1%80%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82&amp;diff=969"/>
		<updated>2026-05-10T20:15:01Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Эта страница посвящается всему что связано с ограничим доступа в интернет.&lt;br /&gt;
&lt;br /&gt;
На данный момент 20.04.26 мы имеем полную блокировку по белыми IP у операторов мобильной связи. И предпосылки к блокировкам на уровне провайдеров домашнего интернета.&lt;br /&gt;
&lt;br /&gt;
* [[Обход НКР|Установка и настройка связки Zapret + Podkop на OpenWRT]]&lt;br /&gt;
* [[Hysteria 2 каскад]]&lt;br /&gt;
* [[Whitelist-bypass: VK Creator (headless на сервере) + Joiner (Android)]]&lt;br /&gt;
* [[Установка MTProto Proxy (mtg) на Linux-сервере]]&lt;br /&gt;
* [[VK Turn Proxy + FreeTurn + VLESS]]&lt;br /&gt;
* [[NaïveProxy: установка полной каскадной цепочки]]&lt;br /&gt;
* [[OlcRTC: туннель через WebRTC-сервисы|olcRTC: туннель через легальные WebRTC-сервисы]]&lt;br /&gt;
* [[mieru: каскадный шифрованный SOCKS5-туннель]]&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=Mieru:_%D0%BA%D0%B0%D1%81%D0%BA%D0%B0%D0%B4%D0%BD%D1%8B%D0%B9_%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9_SOCKS5-%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D1%8C&amp;diff=968</id>
		<title>Mieru: каскадный шифрованный SOCKS5-туннель</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=Mieru:_%D0%BA%D0%B0%D1%81%D0%BA%D0%B0%D0%B4%D0%BD%D1%8B%D0%B9_%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9_SOCKS5-%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D1%8C&amp;diff=968"/>
		<updated>2026-05-10T18:44:09Z</updated>

		<summary type="html">&lt;p&gt;Владимир: Новая страница: «= mieru: каскадный шифрованный SOCKS5-туннель с устойчивостью к классификации трафика =  == Введение ==  === Что такое mieru === &amp;#039;&amp;#039;&amp;#039;mieru&amp;#039;&amp;#039;&amp;#039; (見える, «видимый») — это криптографически защищённый прокси-протокол, ориентированный на работу в средах с активным DPI и статистичес...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= mieru: каскадный шифрованный SOCKS5-туннель с устойчивостью к классификации трафика =&lt;br /&gt;
&lt;br /&gt;
== Введение ==&lt;br /&gt;
&lt;br /&gt;
=== Что такое mieru ===&lt;br /&gt;
&#039;&#039;&#039;mieru&#039;&#039;&#039; (見える, «видимый») — это криптографически защищённый прокси-протокол, ориентированный на работу в средах с активным DPI и статистическим анализом сетевого трафика. В отличие от большинства современных туннелей, mieru &#039;&#039;&#039;не использует TLS&#039;&#039;&#039; и &#039;&#039;&#039;не маскируется под легитимный сайт&#039;&#039;&#039;. Вместо этого он подаёт на провод поток, который при пассивном анализе выглядит как случайные байты или произвольный текстовый протокол — без узнаваемых заголовков, фиксированных длин и характерных handshake-паттернов.&lt;br /&gt;
&lt;br /&gt;
Программный пакет состоит из двух самостоятельных бинарников:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Бинарник&lt;br /&gt;
!Роль&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mita&amp;lt;/code&amp;gt;&lt;br /&gt;
|Серверная часть. Принимает зашифрованные соединения, аутентифицирует пользователей, переправляет полезную нагрузку наружу&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mieru&amp;lt;/code&amp;gt;&lt;br /&gt;
|Клиентская часть. Поднимает локальный SOCKS5-прокси на машине пользователя; всё, что в него пришло, шифруется и отправляется на &amp;lt;code&amp;gt;mita&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Когда применяется ===&lt;br /&gt;
&lt;br /&gt;
* Канал между клиентом и обычными VPN-серверами проходит через инфраструктуру с DPI или ML-классификацией протоколов.&lt;br /&gt;
* Нужен альтернативный канал, не зависящий от валидного TLS-сертификата и собственного домена (mieru вообще не требует доменного имени).&lt;br /&gt;
* Нужна устойчивость к активному зондированию: сервер mieru, в отличие от REALITY-/Trojan-серверов, при попытке зондирования просто &#039;&#039;&#039;молчит&#039;&#039;&#039;, не имитируя ни сайта-донора, ни TLS-handshake — нечего фингерпринтить.&lt;br /&gt;
&lt;br /&gt;
=== Сравнение с другими методами туннелирования ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Метод&lt;br /&gt;
!Транспорт&lt;br /&gt;
!Маскировка&lt;br /&gt;
!Требует домен и TLS&lt;br /&gt;
!Устойчивость к ML-классификации&lt;br /&gt;
|-&lt;br /&gt;
|WireGuard&lt;br /&gt;
|UDP&lt;br /&gt;
|нет (явный WG)&lt;br /&gt;
|нет&lt;br /&gt;
|низкая&lt;br /&gt;
|-&lt;br /&gt;
|OpenVPN&lt;br /&gt;
|UDP/TCP&lt;br /&gt;
|нет&lt;br /&gt;
|опционально&lt;br /&gt;
|низкая&lt;br /&gt;
|-&lt;br /&gt;
|Shadowsocks-AEAD-2022&lt;br /&gt;
|TCP&lt;br /&gt;
|случайный шум&lt;br /&gt;
|нет&lt;br /&gt;
|средняя&lt;br /&gt;
|-&lt;br /&gt;
|VLESS + REALITY&lt;br /&gt;
|TCP (TLS)&lt;br /&gt;
|TLS-handshake чужого сайта&lt;br /&gt;
|да&lt;br /&gt;
|высокая (внутри пула TLS)&lt;br /&gt;
|-&lt;br /&gt;
|NaiveProxy&lt;br /&gt;
|TCP (HTTP/2)&lt;br /&gt;
|Chromium-стек, неотличим от HTTPS&lt;br /&gt;
|да&lt;br /&gt;
|высокая (внутри пула HTTPS)&lt;br /&gt;
|-&lt;br /&gt;
|Hysteria2&lt;br /&gt;
|UDP (QUIC)&lt;br /&gt;
|QUIC поверх UDP с маскировкой под HTTPS&lt;br /&gt;
|да&lt;br /&gt;
|высокая (внутри пула QUIC)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;mieru&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;TCP / UDP, без TLS&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;случайный шум либо текстоподобный поток (через traffic pattern)&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;нет — только пара логин/пароль&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;высокая (специальная подгонка энтропии и ASCII)&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Принципы работы ==&lt;br /&gt;
&lt;br /&gt;
=== Поток данных в одиночном режиме ===&lt;br /&gt;
[[Файл:Mieru-single-flow.png|центр|450x450пкс|Поток данных одиночного mieru: клиент → SOCKS5 → mieru → шифр → mita → интернет]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   клиентское                 локальный          шифрованный            сервер             интернет&lt;br /&gt;
   приложение                 прокси-демон       туннель                              (опц. через&lt;br /&gt;
   (браузер,                                     mieru protocol                       другой прокси&lt;br /&gt;
   мессенджер)                                   (TCP или UDP)                        для egress)&lt;br /&gt;
   ┌────────┐ SOCKS5  ┌─────────────┐  AEAD    ┌──────────┐  открытый    ┌──────────┐&lt;br /&gt;
   │ app    │────────►│ mieru       │ ───────► │ mita     │  TCP/UDP    │ целевой  │&lt;br /&gt;
   │        │ :1080   │ (клиент)    │          │ (сервер) │ ──────────► │ сайт/IP  │&lt;br /&gt;
   └────────┘         └─────────────┘          └──────────┘             └──────────┘&lt;br /&gt;
                          ▲&lt;br /&gt;
                          │ конфиг с user/password&lt;br /&gt;
                          │ → AEAD-ключ детерминированно&lt;br /&gt;
                          │   из (user, password, time)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Каскадный режим (двухзвенный) ===&lt;br /&gt;
В каскаде роль обычного «сервера» выполняют два узла. Первый принимает клиентов и не выходит в интернет напрямую; вместо этого он переправляет уже расшифрованный трафик во второй узел через тот же протокол mieru. Второй узел осуществляет финальный egress.&lt;br /&gt;
[[Файл:Mieru-cascade-flow.png|центр|600x600пкс|Поток данных каскадного mieru: Сервер A (frontend) → Сервер B (backend) → egress]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                       Сервер A (frontend)                          Сервер B (backend)&lt;br /&gt;
                  ┌─────────────────────────┐                  ┌─────────────────────────┐&lt;br /&gt;
                  │                          │                  │                          │&lt;br /&gt;
   ┌────────┐    │  ┌──────────────────┐    │  mieru protocol  │  ┌──────────────────┐    │&lt;br /&gt;
   │клиент  │    │  │ mita server      │    │      (TCP)       │  │ mita server      │    │&lt;br /&gt;
   │mieru-  │ ─► │  │ :2012-2022       │    │                  │  │ :2012-2022       │    │&lt;br /&gt;
   │capable │    │  │  users[] = N     │    │                  │  │  users[] = 1     │    │&lt;br /&gt;
   └────────┘    │  └──────────┬───────┘    │                  │  └──────────┬───────┘    │&lt;br /&gt;
                  │             │            │                  │             │             │&lt;br /&gt;
                  │             ▼ socks5     │                  │             ▼ socks5      │&lt;br /&gt;
                  │  ┌──────────────────┐    │                  │  ┌──────────────────┐    │&lt;br /&gt;
                  │  │ mieru client     │ ───┼──────────────────┼─►│ (один user:      │    │&lt;br /&gt;
                  │  │ :1080 localhost  │    │ зашифрованный    │  │  &amp;quot;frontend-      │    │&lt;br /&gt;
                  │  │ user=&amp;quot;frontend-  │    │ туннель          │  │   bridge&amp;quot;)       │    │&lt;br /&gt;
                  │  │  bridge&amp;quot;         │    │                  │  └──────────┬───────┘    │&lt;br /&gt;
                  │  └──────────────────┘    │                  │             │             │&lt;br /&gt;
                  └─────────────────────────┘                  │             ▼             │&lt;br /&gt;
                                                                │  ┌──────────────────┐    │&lt;br /&gt;
                                                                │  │ egress (любой    │    │&lt;br /&gt;
                                                                │  │ SOCKS5 / TUN /   │    │&lt;br /&gt;
                                                                │  │ прямой выход)    │    │&lt;br /&gt;
                                                                │  └──────────┬───────┘    │&lt;br /&gt;
                                                                └─────────────┼────────────┘&lt;br /&gt;
                                                                              ▼&lt;br /&gt;
                                                                          интернет&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Зачем разделять frontend и backend ===&lt;br /&gt;
&lt;br /&gt;
* Адрес backend-сервера никогда не виден клиентскому ПО. Если frontend замечен и заблокирован — backend остаётся неизвестным наблюдателям и переиспользуется со следующим frontend.&lt;br /&gt;
* Frontend хранит &#039;&#039;&#039;только&#039;&#039;&#039; учётки клиентов и не имеет финального egress. Компрометация его конфига не раскрывает финальный IP.&lt;br /&gt;
* Двойное шифрование mieru на каждом плече: каждый сегмент дважды проходит AEAD с разными ключами, что усложняет статистический анализ.&lt;br /&gt;
&lt;br /&gt;
=== Шифрование и аутентификация ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Алгоритм&lt;br /&gt;
|XChaCha20-Poly1305 (AEAD) с 24-байтным nonce&lt;br /&gt;
|-&lt;br /&gt;
|Длина ключа&lt;br /&gt;
|32 байта&lt;br /&gt;
|-&lt;br /&gt;
|Метод выработки ключа&lt;br /&gt;
|PBKDF2-SHA256, 64 итерации, соль = SHA-256 от текущего времени, округлённого до 2 минут&lt;br /&gt;
|-&lt;br /&gt;
|Идентификатор пользователя в пакете&lt;br /&gt;
|Последние 4 байта nonce заменены на префикс SHA-256 от &amp;lt;code&amp;gt;username + nonce[0:16]&amp;lt;/code&amp;gt;; имя пользователя на провод не передаётся&lt;br /&gt;
|-&lt;br /&gt;
|Защита от reuse&lt;br /&gt;
|Проверка nonce-кэша на серверной стороне; повторный пакет отбрасывается&lt;br /&gt;
|}&lt;br /&gt;
Ключ шифрования &#039;&#039;&#039;не передаётся&#039;&#039;&#039; через канал и нигде не хранится в виде сериализованной строки: он каждый раз генерируется на лету из пары логин+пароль и текущего времени. Из этого следует одно практическое требование, которое легко не заметить.&lt;br /&gt;
&lt;br /&gt;
==== Требование к синхронизации часов ====&lt;br /&gt;
Расхождение системного времени клиента и сервера &#039;&#039;&#039;не должно превышать 4 минуты&#039;&#039;&#039;. При большем расхождении ключ, выработанный клиентом, не сойдётся с ключом сервера, и подключения будут &#039;&#039;&#039;молча&#039;&#039;&#039; падать (без явной ошибки в логах). На обоих серверах и на клиентском устройстве должен работать NTP-демон.&lt;br /&gt;
&lt;br /&gt;
=== Формат сегмента ===&lt;br /&gt;
[[Файл:Mieru-segment-format.png|центр|500x500пкс|Формат сегмента mieru: padding, nonce, шифр-метаданные, шифр-полезная нагрузка]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
| pad0 |  nonce  | enc-meta | tag | pad1 | enc-payload | tag | pad2 |&lt;br /&gt;
|  ?   | 0 или 24|    32    | 16  |  ?   |   до 32 КБ  | 16  |  ?   |&lt;br /&gt;
   ▲                                  ▲                            ▲&lt;br /&gt;
   │                                  │                            │&lt;br /&gt;
   │                                  │                            └── произвольный мусор&lt;br /&gt;
   │                                  └── случайной длины разрыв       (тоже шифр-нейтральный)&lt;br /&gt;
   │&lt;br /&gt;
   └── динамическая «прелюдия»: либо случайные байты,&lt;br /&gt;
       либо ASCII-строка (см. traffic pattern)&lt;br /&gt;
&amp;lt;/pre&amp;gt;Ключевое отличие от других протоколов: &#039;&#039;&#039;ВСЕ&#039;&#039;&#039; структурные поля сегмента (тип, размер, sequence number, ID сессии и пр.) находятся внутри поля &amp;lt;code&amp;gt;enc-meta&amp;lt;/code&amp;gt; — то есть зашифрованы. Снаружи невозможно даже определить, что это за пакет, какой длины полезная нагрузка, в начале или в середине сессии находится клиент. Видны только три зоны паддинга и зашифрованные блобы.&lt;br /&gt;
&lt;br /&gt;
=== Traffic pattern (опциональная подгонка маскировки) ===&lt;br /&gt;
mieru предоставляет два независимых механизма для подмены статистических признаков шифр-трафика на «обычные»:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Опция&lt;br /&gt;
!Что делает&lt;br /&gt;
!Накладные расходы&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;tcpFragment&amp;lt;/code&amp;gt;&lt;br /&gt;
|Дробит TCP-пакеты на мелкие куски и вставляет случайную задержку между ними. Цель — сломать узнаваемость «один большой шифр-стрим»&lt;br /&gt;
| +латентность до &amp;lt;code&amp;gt;maxSleepMs&amp;lt;/code&amp;gt; мс на каждый фрагмент&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nonce.NONCE_TYPE_PRINTABLE&amp;lt;/code&amp;gt;&lt;br /&gt;
|Подменяет первые N байт nonce печатными ASCII-символами. Цель — увести классификатор «высокая энтропия от нулевого байта» в ложное «это текстовый протокол»&lt;br /&gt;
|почти ноль (только подмена байтов)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;nonce.NONCE_TYPE_FIXED&amp;lt;/code&amp;gt;&lt;br /&gt;
|Подменяет первые байты nonce фиксированными hex-строками из списка. Цель — имитировать конкретный фиксированный заголовок&lt;br /&gt;
|ноль&lt;br /&gt;
|}&lt;br /&gt;
Включение traffic pattern имеет смысл &#039;&#039;&#039;только&#039;&#039;&#039; на видимом анализатором плече (клиент → frontend). На внутреннем плече каскада (frontend → backend) это лишний overhead.&lt;br /&gt;
&lt;br /&gt;
=== Многопользовательский режим ===&lt;br /&gt;
Один сервер mita может обслуживать неограниченное число учёток одновременно. Каждый user — это пара &amp;lt;code&amp;gt;(name, password)&amp;lt;/code&amp;gt;; лимит по числу одновременных сессий внутри одной учётки &#039;&#039;&#039;не задан в протоколе&#039;&#039;&#039; (можно опционально настраивать квоты по объёму трафика).&lt;br /&gt;
[[Файл:Mieru-multi-user.png|центр|450x450пкс|Многопользовательский режим: один сервер mita обслуживает несколько учёток одновременно]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                        Сервер A (frontend)&lt;br /&gt;
        ┌──────────────────────────────────────────────┐&lt;br /&gt;
        │  mita server                                  │&lt;br /&gt;
        │  слушает :2012-2022                           │&lt;br /&gt;
        │                                                │&lt;br /&gt;
        │  users[]:                                      │&lt;br /&gt;
        │   ┌────────────┬────────────┬────────────┐     │&lt;br /&gt;
        │   │ alice      │ bob        │ carol      │     │&lt;br /&gt;
        │   │ pwd_alice  │ pwd_bob    │ pwd_carol  │     │&lt;br /&gt;
        │   └─────┬──────┴─────┬──────┴─────┬──────┘     │&lt;br /&gt;
        │         │            │            │            │&lt;br /&gt;
        │         └────────────┼────────────┘            │&lt;br /&gt;
        │                      ▼                         │&lt;br /&gt;
        │            один общий outbound                 │&lt;br /&gt;
        │            (egress на следующий узел)          │&lt;br /&gt;
        └──────────────────────────────────────────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;Такая модель радикально отличается от mash-/torch-протоколов с архитектурой «один сервер — один пользователь»: вам &#039;&#039;&#039;не нужно&#039;&#039;&#039; создавать отдельный контейнер на каждого пользователя.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что должно быть на серверах перед установкой ==&lt;br /&gt;
&lt;br /&gt;
=== Минимальная конфигурация каждого сервера ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!№&lt;br /&gt;
!Требование&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Linux дистрибутив (Ubuntu 22.04+, Debian 12+, Fedora 38+ или сравнимый)&lt;br /&gt;
|Среда выполнения Docker&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|SSH-доступ с правами &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; либо аккаунт с &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; без пароля&lt;br /&gt;
|Установка пакетов и управление контейнерами&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Docker Engine 24.0+ и плагин Docker Compose v2.20+&lt;br /&gt;
|Запуск контейнеров mita и mieru&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|NTP-демон активен (&amp;lt;code&amp;gt;chrony&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;systemd-timesyncd&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Синхронизация часов в пределах 4 минут (см. раздел «Шифрование»)&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Открытый наружу TCP-диапазон (для нашей статьи — &amp;lt;code&amp;gt;2012-2022&amp;lt;/code&amp;gt;)&lt;br /&gt;
|Принимающий порт mita&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Опциональная конфигурация: egress через сторонний прокси ===&lt;br /&gt;
По умолчанию backend-сервер выходит в интернет напрямую с публичного IP виртуальной машины. В качестве промежуточной цепочки часто используется выделенный SOCKS5-прокси, обслуживаемый сторонней панелью (например, &#039;&#039;&#039;3x-ui&#039;&#039;&#039; над xray-core).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!№&lt;br /&gt;
!Параметр&lt;br /&gt;
!Пример&lt;br /&gt;
!Комментарий&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|SOCKS5-inbound, слушающий &#039;&#039;&#039;только на &amp;lt;code&amp;gt;172.17.0.1&amp;lt;/code&amp;gt;&#039;&#039;&#039; (docker0-bridge gateway)&lt;br /&gt;
|порт &amp;lt;code&amp;gt;24366&amp;lt;/code&amp;gt;&lt;br /&gt;
|Слушать на &amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt; &#039;&#039;&#039;не подойдёт&#039;&#039;&#039;: контейнер mita с &amp;lt;code&amp;gt;network_mode: host&amp;lt;/code&amp;gt; увидит нужный адрес именно как &amp;lt;code&amp;gt;172.17.0.1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Аутентификация на этом inbound отключена&lt;br /&gt;
|—&lt;br /&gt;
|Можно включить и прописать креды в &amp;lt;code&amp;gt;egress.proxies&amp;lt;/code&amp;gt; mita, но без авторизации проще&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Routing-rule: трафик с этого inbound → нужный outbound (например, WireGuard-к-WARP, наружный VPN, сторонний прокси)&lt;br /&gt;
|—&lt;br /&gt;
|Зависит от вашей панели; в 3x-ui — раздел «Маршрутизация»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Проверка egress-цепочки ====&lt;br /&gt;
Команда выполняется на самом backend-сервере. Заменить &amp;lt;code&amp;gt;24366&amp;lt;/code&amp;gt; на ваш порт.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run --rm curlimages/curl:latest --max-time 12 --socks5 172.17.0.1:24366 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидание: IP вашего egress-узла (например, IP Cloudflare WARP или IP стороннего VPN). Если возвращается публичный IP вашей VM — egress не работает, проверьте routing панели.&lt;br /&gt;
&lt;br /&gt;
Если egress через сторонний прокси не нужен (готовы выходить с публичного IP backend-сервера) — пропустите этот раздел; в дальнейших шагах указания «без egress» помечены явно.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Параметры, которые нужно подготовить заранее ==&lt;br /&gt;
Перед началом установки заполните таблицу собственными значениями. На каждом шаге, где встретится плейсхолдер, мы будем ссылаться на эту таблицу.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Плейсхолдер&lt;br /&gt;
!Что это&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_FRONTEND_HOST&amp;lt;/code&amp;gt;&lt;br /&gt;
|Адрес frontend-сервера для SSH (IP, имя из &amp;lt;code&amp;gt;~/.ssh/config&amp;lt;/code&amp;gt; либо домен)&lt;br /&gt;
|&amp;lt;code&amp;gt;198.51.100.10&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_BACKEND_HOST&amp;lt;/code&amp;gt;&lt;br /&gt;
|Адрес backend-сервера для SSH&lt;br /&gt;
|&amp;lt;code&amp;gt;203.0.113.20&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_BACKEND_PUBLIC_IP&amp;lt;/code&amp;gt;&lt;br /&gt;
|Публичный IP backend-сервера, к которому будет коннектиться mieru-client с frontend&lt;br /&gt;
|&amp;lt;code&amp;gt;203.0.113.20&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_FRONTEND_PUBLIC_IP&amp;lt;/code&amp;gt;&lt;br /&gt;
|Публичный IP frontend-сервера, к которому будут коннектиться клиенты&lt;br /&gt;
|&amp;lt;code&amp;gt;198.51.100.10&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_BRIDGE_PASSWORD&amp;lt;/code&amp;gt;&lt;br /&gt;
|Пароль учётки mieru, которой mieru-client на frontend подключается к mita на backend. Один на оба узла&lt;br /&gt;
|длинная случайная строка, сгенерированная &amp;lt;code&amp;gt;openssl rand&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_CLIENT_PASSWORD&amp;lt;/code&amp;gt;&lt;br /&gt;
|Пароль первой клиентской учётки &amp;lt;code&amp;gt;client01&amp;lt;/code&amp;gt; на frontend&lt;br /&gt;
|длинная случайная строка&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_EGRESS_HOST&amp;lt;/code&amp;gt;&lt;br /&gt;
|Адрес SOCKS5-egress на backend (если используете)&lt;br /&gt;
|&amp;lt;code&amp;gt;172.17.0.1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_EGRESS_PORT&amp;lt;/code&amp;gt;&lt;br /&gt;
|Порт SOCKS5-egress&lt;br /&gt;
|&amp;lt;code&amp;gt;24366&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Сохраните таблицу в надёжное место — особенно пароли. Без них восстановить рабочее состояние нельзя.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Установка backend-сервера (точка выхода) ==&lt;br /&gt;
Все команды этого раздела выполняются на backend-сервере по SSH. Каждое пояснение — одна команда.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Подключение по SSH ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh root@YOUR_BACKEND_HOST&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Проверка Docker ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker --version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если выведено &amp;lt;code&amp;gt;Docker version 24.0.x&amp;lt;/code&amp;gt; или новее — переходите к шагу 3. Если &amp;lt;code&amp;gt;command not found&amp;lt;/code&amp;gt; — установите Docker по официальной инструкции для вашей ОС: &amp;lt;code&amp;gt;https://docs.docker.com/engine/install/&amp;lt;/code&amp;gt;. После установки вернитесь сюда.&lt;br /&gt;
&lt;br /&gt;
Дополнительно проверьте плагин Compose.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создание рабочего каталога ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/mieru-backend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/mieru-backend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Создание Dockerfile ===&lt;br /&gt;
Откройте файл для редактирования.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-backend/Dockerfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте следующее содержимое полностью.&amp;lt;syntaxhighlight lang=&amp;quot;dockerfile&amp;quot;&amp;gt;&lt;br /&gt;
ARG MIERU_VERSION=3.32.0&lt;br /&gt;
ARG TARGETARCH=amd64&lt;br /&gt;
&lt;br /&gt;
FROM alpine:3.19 AS downloader&lt;br /&gt;
ARG MIERU_VERSION&lt;br /&gt;
ARG TARGETARCH&lt;br /&gt;
RUN apk add --no-cache ca-certificates wget&lt;br /&gt;
WORKDIR /tmp/mita&lt;br /&gt;
RUN wget -qO- &amp;quot;https://github.com/enfein/mieru/releases/download/v${MIERU_VERSION}/mita_${MIERU_VERSION}_linux_${TARGETARCH}.tar.gz&amp;quot; | tar xz&lt;br /&gt;
WORKDIR /tmp/mieru&lt;br /&gt;
RUN wget -qO- &amp;quot;https://github.com/enfein/mieru/releases/download/v${MIERU_VERSION}/mieru_${MIERU_VERSION}_linux_${TARGETARCH}.tar.gz&amp;quot; | tar xz&lt;br /&gt;
&lt;br /&gt;
FROM alpine:3.19&lt;br /&gt;
RUN apk add --no-cache ca-certificates tini &amp;amp;&amp;amp; \&lt;br /&gt;
    adduser -H -D -g &amp;quot;&amp;quot; mita &amp;amp;&amp;amp; \&lt;br /&gt;
    adduser -H -D -g &amp;quot;&amp;quot; mieru&lt;br /&gt;
COPY --from=downloader /tmp/mita/mita /usr/local/bin/mita&lt;br /&gt;
COPY --from=downloader /tmp/mieru/mieru /usr/local/bin/mieru&lt;br /&gt;
RUN chmod +x /usr/local/bin/mita /usr/local/bin/mieru &amp;amp;&amp;amp; \&lt;br /&gt;
    mkdir -p /etc/mita /var/lib/mita /var/run/mita \&lt;br /&gt;
             /etc/mieru /var/lib/mieru /var/run/mieru /srv &amp;amp;&amp;amp; \&lt;br /&gt;
    chown -R mita:mita /etc/mita /var/lib/mita /var/run/mita &amp;amp;&amp;amp; \&lt;br /&gt;
    chown -R mieru:mieru /etc/mieru /var/lib/mieru /var/run/mieru&lt;br /&gt;
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh&lt;br /&gt;
RUN chmod +x /usr/local/bin/docker-entrypoint.sh&lt;br /&gt;
ENTRYPOINT [&amp;quot;/sbin/tini&amp;quot;,&amp;quot;--&amp;quot;,&amp;quot;/usr/local/bin/docker-entrypoint.sh&amp;quot;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Создание скрипта-entrypoint ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-backend/docker-entrypoint.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте полное содержимое.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
set -eu&lt;br /&gt;
&lt;br /&gt;
MODE=&amp;quot;${MIERU_MODE:-mita}&amp;quot;&lt;br /&gt;
CONFIG_FILE=&amp;quot;${MIERU_CONFIG:-/srv/config.json}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$MODE&amp;quot; in&lt;br /&gt;
    mita)  BIN=mita ;;&lt;br /&gt;
    mieru) BIN=mieru ;;&lt;br /&gt;
    *) echo &amp;quot;[entrypoint] FATAL: MIERU_MODE=&#039;$MODE&#039; (mita или mieru)&amp;quot;; exit 1 ;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
if [ ! -f &amp;quot;$CONFIG_FILE&amp;quot; ]; then&lt;br /&gt;
    echo &amp;quot;[entrypoint] WARN: $CONFIG_FILE не найден&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$MODE&amp;quot; = &amp;quot;mieru&amp;quot; ]; then&lt;br /&gt;
    if [ -f &amp;quot;$CONFIG_FILE&amp;quot; ]; then&lt;br /&gt;
        mieru apply config &amp;quot;$CONFIG_FILE&amp;quot; 2&amp;gt;&amp;amp;1&lt;br /&gt;
    fi&lt;br /&gt;
    exec mieru run&lt;br /&gt;
else&lt;br /&gt;
    apply_via_rpc() {&lt;br /&gt;
        i=0&lt;br /&gt;
        while [ &amp;quot;$i&amp;quot; -lt 30 ]; do&lt;br /&gt;
            i=$((i+1)); sleep 1&lt;br /&gt;
            if [ -f &amp;quot;$CONFIG_FILE&amp;quot; ] &amp;amp;&amp;amp; mita apply config &amp;quot;$CONFIG_FILE&amp;quot; &amp;gt;/tmp/apply.out 2&amp;gt;&amp;amp;1; then&lt;br /&gt;
                mita start &amp;gt;/tmp/start.out 2&amp;gt;&amp;amp;1&lt;br /&gt;
                return 0&lt;br /&gt;
            fi&lt;br /&gt;
        done&lt;br /&gt;
    }&lt;br /&gt;
    apply_via_rpc &amp;amp;&lt;br /&gt;
    exec mita run&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дайте файлу права на исполнение.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x /opt/mieru-backend/docker-entrypoint.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 6. Генерация пароля для bridge-учётки ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl rand -base64 24 | tr -d &#039;=/+&#039; | head -c 31&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Команда выведет одну строку из 31 символа. Скопируйте её и впишите в подготовленную таблицу как &amp;lt;code&amp;gt;YOUR_BRIDGE_PASSWORD&amp;lt;/code&amp;gt;. Этот же пароль понадобится на frontend-сервере (шаг ниже).&lt;br /&gt;
&lt;br /&gt;
=== Шаг 7. Создание серверного конфига ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-backend/server.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте содержимое и замените &amp;lt;code&amp;gt;YOUR_BRIDGE_PASSWORD&amp;lt;/code&amp;gt; на скопированное значение из шага 6.&lt;br /&gt;
&lt;br /&gt;
Если вы &#039;&#039;&#039;используете&#039;&#039;&#039; egress через сторонний SOCKS5-прокси — оставьте секцию &amp;lt;code&amp;gt;egress&amp;lt;/code&amp;gt; как есть и при необходимости подправьте &amp;lt;code&amp;gt;host&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;port&amp;lt;/code&amp;gt;. Если &#039;&#039;&#039;не используете&#039;&#039;&#039; — удалите всю секцию &amp;lt;code&amp;gt;egress&amp;lt;/code&amp;gt; от открывающей до закрывающей фигурной скобки.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;portBindings&amp;quot;: [&lt;br /&gt;
        {&amp;quot;portRange&amp;quot;: &amp;quot;2012-2022&amp;quot;, &amp;quot;protocol&amp;quot;: &amp;quot;TCP&amp;quot;}&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;users&amp;quot;: [&lt;br /&gt;
        {&amp;quot;name&amp;quot;: &amp;quot;frontend-bridge&amp;quot;, &amp;quot;password&amp;quot;: &amp;quot;YOUR_BRIDGE_PASSWORD&amp;quot;}&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;loggingLevel&amp;quot;: &amp;quot;INFO&amp;quot;,&lt;br /&gt;
    &amp;quot;mtu&amp;quot;: 1380,&lt;br /&gt;
    &amp;quot;egress&amp;quot;: {&lt;br /&gt;
        &amp;quot;proxies&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;external-egress&amp;quot;,&lt;br /&gt;
                &amp;quot;protocol&amp;quot;: &amp;quot;SOCKS5_PROXY_PROTOCOL&amp;quot;,&lt;br /&gt;
                &amp;quot;host&amp;quot;: &amp;quot;172.17.0.1&amp;quot;,&lt;br /&gt;
                &amp;quot;port&amp;quot;: 24366&lt;br /&gt;
            }&lt;br /&gt;
        ],&lt;br /&gt;
        &amp;quot;rules&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;ipRanges&amp;quot;: [&amp;quot;*&amp;quot;],&lt;br /&gt;
                &amp;quot;domainNames&amp;quot;: [&amp;quot;*&amp;quot;],&lt;br /&gt;
                &amp;quot;action&amp;quot;: &amp;quot;PROXY&amp;quot;,&lt;br /&gt;
                &amp;quot;proxyNames&amp;quot;: [&amp;quot;external-egress&amp;quot;]&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Защитите файл (содержит пароль).&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /opt/mieru-backend/server.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 8. Создание docker-compose.yml ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-backend/docker-compose.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте.&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  mita:&lt;br /&gt;
    build:&lt;br /&gt;
      context: .&lt;br /&gt;
      args:&lt;br /&gt;
        MIERU_VERSION: &amp;quot;3.32.0&amp;quot;&lt;br /&gt;
    image: mieru-bundle:3.32.0&lt;br /&gt;
    container_name: mita-backend&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    environment:&lt;br /&gt;
      MIERU_MODE: mita&lt;br /&gt;
      MIERU_CONFIG: /srv/server.json&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./server.json:/srv/server.json:ro&lt;br /&gt;
      - mita-state:/etc/mita&lt;br /&gt;
      - mita-runtime:/var/run/mita&lt;br /&gt;
      - mita-data:/var/lib/mita&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: json-file&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;10m&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  mita-state:&lt;br /&gt;
  mita-runtime:&lt;br /&gt;
  mita-data:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 9. Сборка образа ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-backend/docker-compose.yml build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сборка длится 1–3 минуты. По завершении выводится &amp;lt;code&amp;gt;Image mieru-bundle:3.32.0 Built&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 10. Запуск ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-backend/docker-compose.yml up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подождите 10 секунд.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sleep 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Проверьте логи.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs mita-backend --tail 25&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидаемые строки:&lt;br /&gt;
 [entrypoint] config применён (/srv/server.json)&lt;br /&gt;
 [entrypoint] mita start: OK&lt;br /&gt;
 mita server status is &amp;quot;RUNNING&amp;quot;&lt;br /&gt;
Проверьте, что сервер слушает порты &amp;lt;code&amp;gt;2012-2022&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -tlnp | grep -E &#039;:20(1[2-9]|2[012]) &#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должны появиться 11 строк со статусом &amp;lt;code&amp;gt;LISTEN&amp;lt;/code&amp;gt; и пользователем &amp;lt;code&amp;gt;mita&amp;lt;/code&amp;gt;. Если их нет — обратитесь к разделу «Поиск проблем».&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Установка frontend-сервера (точка входа) ==&lt;br /&gt;
Все команды этого раздела выполняются на frontend-сервере по SSH.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Подключение и подготовка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh root@YOUR_FRONTEND_HOST&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/mieru-frontend &amp;amp;&amp;amp; cd /opt/mieru-frontend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Dockerfile и entrypoint (одинаковые с backend) ===&lt;br /&gt;
Создайте оба файла так же, как на backend-сервере (см. шаги 4–5 раздела «Установка backend-сервера»). Содержимое идентично — образ универсальный, режим работы выбирается переменной окружения.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-frontend/Dockerfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;(вставьте тот же Dockerfile, что на backend)&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-frontend/docker-entrypoint.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;(вставьте тот же entrypoint)&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x /opt/mieru-frontend/docker-entrypoint.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Генерация пароля первой клиентской учётки ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl rand -base64 24 | tr -d &#039;=/+&#039; | head -c 31&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Скопируйте результат и впишите в таблицу как &amp;lt;code&amp;gt;YOUR_CLIENT_PASSWORD&amp;lt;/code&amp;gt;. Это пароль учётки &amp;lt;code&amp;gt;client01&amp;lt;/code&amp;gt;, который вы потом отдадите своему первому клиентскому устройству.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Серверный конфиг (mita-frontend) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-frontend/server.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Замените &amp;lt;code&amp;gt;YOUR_CLIENT_PASSWORD&amp;lt;/code&amp;gt; на значение из шага 3.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;portBindings&amp;quot;: [&lt;br /&gt;
        {&amp;quot;portRange&amp;quot;: &amp;quot;2012-2022&amp;quot;, &amp;quot;protocol&amp;quot;: &amp;quot;TCP&amp;quot;}&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;users&amp;quot;: [&lt;br /&gt;
        {&amp;quot;name&amp;quot;: &amp;quot;client01&amp;quot;, &amp;quot;password&amp;quot;: &amp;quot;YOUR_CLIENT_PASSWORD&amp;quot;}&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;loggingLevel&amp;quot;: &amp;quot;INFO&amp;quot;,&lt;br /&gt;
    &amp;quot;mtu&amp;quot;: 1380,&lt;br /&gt;
    &amp;quot;trafficPattern&amp;quot;: {&lt;br /&gt;
        &amp;quot;unlockAll&amp;quot;: false,&lt;br /&gt;
        &amp;quot;tcpFragment&amp;quot;: {&amp;quot;enable&amp;quot;: true, &amp;quot;maxSleepMs&amp;quot;: 10},&lt;br /&gt;
        &amp;quot;nonce&amp;quot;: {&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;NONCE_TYPE_PRINTABLE&amp;quot;,&lt;br /&gt;
            &amp;quot;minLen&amp;quot;: 6,&lt;br /&gt;
            &amp;quot;maxLen&amp;quot;: 8&lt;br /&gt;
        }&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;egress&amp;quot;: {&lt;br /&gt;
        &amp;quot;proxies&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;to-backend&amp;quot;,&lt;br /&gt;
                &amp;quot;protocol&amp;quot;: &amp;quot;SOCKS5_PROXY_PROTOCOL&amp;quot;,&lt;br /&gt;
                &amp;quot;host&amp;quot;: &amp;quot;127.0.0.1&amp;quot;,&lt;br /&gt;
                &amp;quot;port&amp;quot;: 1080&lt;br /&gt;
            }&lt;br /&gt;
        ],&lt;br /&gt;
        &amp;quot;rules&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;ipRanges&amp;quot;: [&amp;quot;*&amp;quot;],&lt;br /&gt;
                &amp;quot;domainNames&amp;quot;: [&amp;quot;*&amp;quot;],&lt;br /&gt;
                &amp;quot;action&amp;quot;: &amp;quot;PROXY&amp;quot;,&lt;br /&gt;
                &amp;quot;proxyNames&amp;quot;: [&amp;quot;to-backend&amp;quot;]&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните и защитите файл.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /opt/mieru-frontend/server.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Клиентский конфиг (mieru-client) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-frontend/client.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Замените &amp;lt;code&amp;gt;YOUR_BACKEND_PUBLIC_IP&amp;lt;/code&amp;gt; на публичный IP backend-сервера, &amp;lt;code&amp;gt;YOUR_BRIDGE_PASSWORD&amp;lt;/code&amp;gt; — на пароль bridge-учётки, который вы создавали на backend в шаге 6.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;profiles&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;profileName&amp;quot;: &amp;quot;default&amp;quot;,&lt;br /&gt;
            &amp;quot;user&amp;quot;: {&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;frontend-bridge&amp;quot;,&lt;br /&gt;
                &amp;quot;password&amp;quot;: &amp;quot;YOUR_BRIDGE_PASSWORD&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;servers&amp;quot;: [&lt;br /&gt;
                {&lt;br /&gt;
                    &amp;quot;ipAddress&amp;quot;: &amp;quot;YOUR_BACKEND_PUBLIC_IP&amp;quot;,&lt;br /&gt;
                    &amp;quot;portBindings&amp;quot;: [&lt;br /&gt;
                        {&amp;quot;portRange&amp;quot;: &amp;quot;2012-2022&amp;quot;, &amp;quot;protocol&amp;quot;: &amp;quot;TCP&amp;quot;}&lt;br /&gt;
                    ]&lt;br /&gt;
                }&lt;br /&gt;
            ],&lt;br /&gt;
            &amp;quot;mtu&amp;quot;: 1380,&lt;br /&gt;
            &amp;quot;multiplexing&amp;quot;: {&amp;quot;level&amp;quot;: &amp;quot;MULTIPLEXING_HIGH&amp;quot;},&lt;br /&gt;
            &amp;quot;handshakeMode&amp;quot;: &amp;quot;HANDSHAKE_NO_WAIT&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;activeProfile&amp;quot;: &amp;quot;default&amp;quot;,&lt;br /&gt;
    &amp;quot;rpcPort&amp;quot;: 8964,&lt;br /&gt;
    &amp;quot;socks5Port&amp;quot;: 1080,&lt;br /&gt;
    &amp;quot;loggingLevel&amp;quot;: &amp;quot;INFO&amp;quot;,&lt;br /&gt;
    &amp;quot;socks5ListenLAN&amp;quot;: false,&lt;br /&gt;
    &amp;quot;httpProxyListenLAN&amp;quot;: false&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните и защитите файл.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /opt/mieru-frontend/client.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 6. docker-compose.yml на frontend ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mieru-frontend/docker-compose.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте.&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  mieru-client:&lt;br /&gt;
    build:&lt;br /&gt;
      context: .&lt;br /&gt;
      args:&lt;br /&gt;
        MIERU_VERSION: &amp;quot;3.32.0&amp;quot;&lt;br /&gt;
    image: mieru-bundle:3.32.0&lt;br /&gt;
    container_name: mieru-client&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    environment:&lt;br /&gt;
      MIERU_MODE: mieru&lt;br /&gt;
      MIERU_CONFIG: /srv/client.json&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./client.json:/srv/client.json:ro&lt;br /&gt;
      - mieru-client-state:/etc/mieru&lt;br /&gt;
      - mieru-client-runtime:/var/run/mieru&lt;br /&gt;
      - mieru-client-data:/var/lib/mieru&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: json-file&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;10m&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  mita:&lt;br /&gt;
    image: mieru-bundle:3.32.0&lt;br /&gt;
    container_name: mita-frontend&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    depends_on:&lt;br /&gt;
      - mieru-client&lt;br /&gt;
    environment:&lt;br /&gt;
      MIERU_MODE: mita&lt;br /&gt;
      MIERU_CONFIG: /srv/server.json&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./server.json:/srv/server.json:ro&lt;br /&gt;
      - mita-state:/etc/mita&lt;br /&gt;
      - mita-runtime:/var/run/mita&lt;br /&gt;
      - mita-data:/var/lib/mita&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: json-file&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;10m&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  mieru-client-state:&lt;br /&gt;
  mieru-client-runtime:&lt;br /&gt;
  mieru-client-data:&lt;br /&gt;
  mita-state:&lt;br /&gt;
  mita-runtime:&lt;br /&gt;
  mita-data:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 7. Сборка и запуск ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-frontend/docker-compose.yml build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-frontend/docker-compose.yml up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sleep 12&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 8. Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs mieru-client --tail 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должна быть строка &amp;lt;code&amp;gt;mieru: config применён&amp;lt;/code&amp;gt; и затем &amp;lt;code&amp;gt;запуск mieru run&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs mita-frontend --tail 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должно быть &amp;lt;code&amp;gt;RUNNING&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;mita start: OK&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mieru-client mieru status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидание: &amp;lt;code&amp;gt;mieru client is running&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-frontend mita status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидание: &amp;lt;code&amp;gt;mita server status is &amp;quot;RUNNING&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 9. Сквозной тест каскада ===&lt;br /&gt;
С frontend-сервера обратитесь во внешний интернет через локальный SOCKS5 mieru-client. Это эквивалент того, как пойдёт реальный клиентский запрос.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS --max-time 30 --proxy socks5h://127.0.0.1:1080 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидание: IP вашего egress-узла. Например, IP Cloudflare WARP, если на backend настроен такой outbound. Команда &#039;&#039;&#039;не должна&#039;&#039;&#039; возвращать публичный IP frontend-сервера.&lt;br /&gt;
&lt;br /&gt;
Контрольный замер прямого IP frontend для сравнения.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS --max-time 5 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если первый IP отличается от второго — каскад работает.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Подключение клиентов ==&lt;br /&gt;
mieru имеет два равнозначных формата отдачи параметров клиенту: &#039;&#039;&#039;Clash/Mihomo YAML&#039;&#039;&#039; и &#039;&#039;&#039;&amp;lt;code&amp;gt;mierus://&amp;lt;/code&amp;gt; URI&#039;&#039;&#039;. На практике YAML более переносим — его понимает большинство клиентов в одном виде, тогда как URI разбирается каждым приложением по-своему.&lt;br /&gt;
&lt;br /&gt;
=== Десктоп: Clash Verge Rev / Mihomo Party / NekoBox ===&lt;br /&gt;
Создайте новый профиль (или отредактируйте существующий) и добавьте блок &amp;lt;code&amp;gt;proxies&amp;lt;/code&amp;gt;:&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
proxies:&lt;br /&gt;
  - name: mieru-frontend&lt;br /&gt;
    type: mieru&lt;br /&gt;
    server: YOUR_FRONTEND_PUBLIC_IP&lt;br /&gt;
    port: 2022&lt;br /&gt;
    username: client01&lt;br /&gt;
    password: YOUR_CLIENT_PASSWORD&lt;br /&gt;
    multiplexing: MULTIPLEXING_HIGH&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Параметр &amp;lt;code&amp;gt;port: 2022&amp;lt;/code&amp;gt; — это один из портов из диапазона &amp;lt;code&amp;gt;2012-2022&amp;lt;/code&amp;gt;; mita слушает все 11 параллельно, клиент использует один (мультиплексор).&lt;br /&gt;
&lt;br /&gt;
=== Мобильные: Karing / ClashMi / NekoBox+plugin / husi ===&lt;br /&gt;
Подключение через тот же YAML-блок выше — большинство клиентов поддерживают вставку YAML вручную в раздел «Серверы» или «Outbounds». Сценарий импорта URI в Karing 1.2.x работает плохо (поле порта обнуляется), поэтому YAML предпочтительнее.&lt;br /&gt;
&lt;br /&gt;
=== Универсальный URI-формат ===&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
mierus://client01:YOUR_CLIENT_PASSWORD@YOUR_FRONTEND_PUBLIC_IP?port=2022&amp;amp;protocol=TCP&amp;amp;mtu=1380&amp;amp;multiplexing=MULTIPLEXING_HIGH&amp;amp;handshake-mode=HANDSHAKE_NO_WAIT&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подходит для нативного &amp;lt;code&amp;gt;mieru&amp;lt;/code&amp;gt; CLI, husi с mieru-плагином, Exclave.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Подключение клиента на OpenWrt-роутере ==&lt;br /&gt;
Если на роутере уже стоит трафик-менеджер (например, podkop), и вы хотите, чтобы он отправлял трафик через mieru — поставьте на роутер standalone mieru-клиент с локальным SOCKS5, и подкоп цепляйте к этому SOCKS5.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Подключение к роутеру ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh root@YOUR_ROUTER_HOST&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Скачивание бинаря ===&lt;br /&gt;
Архитектура роутера большинства современных моделей — &amp;lt;code&amp;gt;aarch64&amp;lt;/code&amp;gt;. Если ваш роутер — другой (например, &amp;lt;code&amp;gt;mips&amp;lt;/code&amp;gt;), проверьте список релизов &amp;lt;code&amp;gt;https://github.com/enfein/mieru/releases/latest&amp;lt;/code&amp;gt; и подставьте нужный артефакт в команду.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /tmp &amp;amp;&amp;amp; wget -q https://github.com/enfein/mieru/releases/download/v3.32.0/mieru_3.32.0_linux_arm64.tar.gz -O mieru.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar xzf mieru.tar.gz &amp;amp;&amp;amp; mv mieru /usr/bin/mieru &amp;amp;&amp;amp; chmod +x /usr/bin/mieru &amp;amp;&amp;amp; rm -f /tmp/mieru.tar.gz /tmp/LICENSE /tmp/README.md&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/usr/bin/mieru version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должно вывести &amp;lt;code&amp;gt;3.32.0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Клиентский конфиг ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /etc/mieru_client_config.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте, заменив плейсхолдеры:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;profiles&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;profileName&amp;quot;: &amp;quot;default&amp;quot;,&lt;br /&gt;
            &amp;quot;user&amp;quot;: {&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;client01&amp;quot;,&lt;br /&gt;
                &amp;quot;password&amp;quot;: &amp;quot;YOUR_CLIENT_PASSWORD&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;servers&amp;quot;: [&lt;br /&gt;
                {&lt;br /&gt;
                    &amp;quot;ipAddress&amp;quot;: &amp;quot;YOUR_FRONTEND_PUBLIC_IP&amp;quot;,&lt;br /&gt;
                    &amp;quot;portBindings&amp;quot;: [&lt;br /&gt;
                        {&amp;quot;portRange&amp;quot;: &amp;quot;2012-2022&amp;quot;, &amp;quot;protocol&amp;quot;: &amp;quot;TCP&amp;quot;}&lt;br /&gt;
                    ]&lt;br /&gt;
                }&lt;br /&gt;
            ],&lt;br /&gt;
            &amp;quot;mtu&amp;quot;: 1380,&lt;br /&gt;
            &amp;quot;multiplexing&amp;quot;: {&amp;quot;level&amp;quot;: &amp;quot;MULTIPLEXING_HIGH&amp;quot;},&lt;br /&gt;
            &amp;quot;handshakeMode&amp;quot;: &amp;quot;HANDSHAKE_NO_WAIT&amp;quot;,&lt;br /&gt;
            &amp;quot;trafficPattern&amp;quot;: {&lt;br /&gt;
                &amp;quot;unlockAll&amp;quot;: false,&lt;br /&gt;
                &amp;quot;tcpFragment&amp;quot;: {&amp;quot;enable&amp;quot;: true, &amp;quot;maxSleepMs&amp;quot;: 10},&lt;br /&gt;
                &amp;quot;nonce&amp;quot;: {&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;NONCE_TYPE_PRINTABLE&amp;quot;,&lt;br /&gt;
                    &amp;quot;minLen&amp;quot;: 6,&lt;br /&gt;
                    &amp;quot;maxLen&amp;quot;: 8&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;activeProfile&amp;quot;: &amp;quot;default&amp;quot;,&lt;br /&gt;
    &amp;quot;rpcPort&amp;quot;: 8964,&lt;br /&gt;
    &amp;quot;socks5Port&amp;quot;: 1090,&lt;br /&gt;
    &amp;quot;loggingLevel&amp;quot;: &amp;quot;ERROR&amp;quot;,&lt;br /&gt;
    &amp;quot;socks5ListenLAN&amp;quot;: false,&lt;br /&gt;
    &amp;quot;httpProxyListenLAN&amp;quot;: false&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните и защитите файл.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /etc/mieru_client_config.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ключевые отличия конфига для роутера от десктопного клиента:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;socks5Port: 1090&amp;lt;/code&amp;gt; — порт &amp;lt;code&amp;gt;1080&amp;lt;/code&amp;gt; часто занят другими прокси (например, naive); 1090 свободен.&lt;br /&gt;
* &amp;lt;code&amp;gt;loggingLevel: &amp;quot;ERROR&amp;quot;&amp;lt;/code&amp;gt; — overlay на роутерах маленький, ограничение логов защищает от заполнения диска.&lt;br /&gt;
* &amp;lt;code&amp;gt;trafficPattern&amp;lt;/code&amp;gt; включён полностью — на пути «роутер → frontend» классификатор смотрит, маскировка нужна.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Init.d-скрипт ===&lt;br /&gt;
OpenWrt использует procd; в отличие от mita, на OpenWrt mieru читает JSON-конфиг напрямую через переменную &amp;lt;code&amp;gt;MIERU_CONFIG_JSON_FILE&amp;lt;/code&amp;gt;, и команды &amp;lt;code&amp;gt;mieru apply config&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;mieru describe config&amp;lt;/code&amp;gt; &#039;&#039;&#039;не используются&#039;&#039;&#039;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /etc/init.d/mieru&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh /etc/rc.common&lt;br /&gt;
&lt;br /&gt;
START=99&lt;br /&gt;
STOP=01&lt;br /&gt;
&lt;br /&gt;
MIERU_BIN=&amp;quot;/usr/bin/mieru&amp;quot;&lt;br /&gt;
MIERU_CONFIG=&amp;quot;/etc/mieru_client_config.json&amp;quot;&lt;br /&gt;
PID_FILE=&amp;quot;/var/run/mieru.pid&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start() {&lt;br /&gt;
    echo &amp;quot;Starting mieru client...&amp;quot;&lt;br /&gt;
    export MIERU_CONFIG_JSON_FILE=$MIERU_CONFIG&lt;br /&gt;
    start-stop-daemon -S -b -m -p &amp;quot;$PID_FILE&amp;quot; -x &amp;quot;$MIERU_BIN&amp;quot; -- run&lt;br /&gt;
    RC=$?&lt;br /&gt;
    if [ $RC -eq 0 ]; then&lt;br /&gt;
        echo &amp;quot;mieru client is started&amp;quot;&lt;br /&gt;
        exit 0&lt;br /&gt;
    else&lt;br /&gt;
        echo &amp;quot;failed to start mieru client&amp;quot;&lt;br /&gt;
        exit $RC&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
stop() {&lt;br /&gt;
    echo &amp;quot;Stopping mieru client...&amp;quot;&lt;br /&gt;
    start-stop-daemon -K -p &amp;quot;$PID_FILE&amp;quot;&lt;br /&gt;
    RC=$?&lt;br /&gt;
    if [ $RC -eq 0 ]; then&lt;br /&gt;
        echo &amp;quot;mieru client is stopped&amp;quot;&lt;br /&gt;
        rm -f &amp;quot;$PID_FILE&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        echo &amp;quot;failed to stop mieru client&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните и сделайте исполняемым.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x /etc/init.d/mieru&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Запуск и автозапуск ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/etc/init.d/mieru enable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/etc/init.d/mieru start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 6. Проверка ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps | grep mieru | grep -v grep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должна быть одна строка с процессом &amp;lt;code&amp;gt;/usr/bin/mieru run&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
netstat -tlnp 2&amp;gt;/dev/null | grep 1090&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должна быть строка &amp;lt;code&amp;gt;127.0.0.1:1090 ... LISTEN ... mieru&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS --max-time 30 -x socks5h://127.0.0.1:1090 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должен вернуть IP egress-узла каскада.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 7. Подключение podkop к локальному mieru ===&lt;br /&gt;
В LuCI откройте подкоп. Создайте новую секцию или измените существующую:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Поле&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Тип конфига&lt;br /&gt;
|URL&lt;br /&gt;
|-&lt;br /&gt;
|Proxy string&lt;br /&gt;
|&amp;lt;code&amp;gt;socks5://127.0.0.1:1090&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Эквивалент через &amp;lt;code&amp;gt;uci&amp;lt;/code&amp;gt;:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
uci set podkop.10=section&lt;br /&gt;
uci set podkop.10.connection_type=&#039;proxy&#039;&lt;br /&gt;
uci set podkop.10.proxy_config_type=&#039;url&#039;&lt;br /&gt;
uci set podkop.10.proxy_string=&#039;socks5://127.0.0.1:1090&#039;&lt;br /&gt;
uci commit podkop&lt;br /&gt;
service podkop restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подкоп отправляет mieru-серверу обычный SOCKS5-запрос на &amp;lt;code&amp;gt;127.0.0.1:1090&amp;lt;/code&amp;gt;; mieru шифрует его и отправляет через каскад.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Управление пользователями: скрипт &amp;lt;code&amp;gt;mieru-users.sh&amp;lt;/code&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
=== Зачем он нужен ===&lt;br /&gt;
mita-сервер хранит список учёток в файле &amp;lt;code&amp;gt;server.json&amp;lt;/code&amp;gt;. Чтобы добавлять/удалять/смотреть пользователей вручную каждый раз — много шагов: jq-правка JSON, вызов &amp;lt;code&amp;gt;mita apply config&amp;lt;/code&amp;gt;, генерация ссылки клиенту, опционально &amp;lt;code&amp;gt;mita delete user&amp;lt;/code&amp;gt; для разрыва активных сессий. Скрипт &amp;lt;code&amp;gt;mieru-users.sh&amp;lt;/code&amp;gt; автоматизирует это всё.&lt;br /&gt;
&lt;br /&gt;
=== Что делает скрипт ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Пункт меню&lt;br /&gt;
!Действие&lt;br /&gt;
|-&lt;br /&gt;
|1. Список пользователей&lt;br /&gt;
|Чтение &amp;lt;code&amp;gt;server.json&amp;lt;/code&amp;gt; + опрос &amp;lt;code&amp;gt;mita get connections&amp;lt;/code&amp;gt; для активных сессий&lt;br /&gt;
|-&lt;br /&gt;
|2. Добавить пользователя&lt;br /&gt;
|Запрос имени, генерация пароля через &amp;lt;code&amp;gt;openssl rand&amp;lt;/code&amp;gt;, бэкап JSON, &amp;lt;code&amp;gt;jq&amp;lt;/code&amp;gt;-вставка, &amp;lt;code&amp;gt;mita apply config&amp;lt;/code&amp;gt;, выдача готовых YAML и URI клиенту&lt;br /&gt;
|-&lt;br /&gt;
|3. Удалить пользователя&lt;br /&gt;
|&amp;lt;code&amp;gt;mita delete user&amp;lt;/code&amp;gt; для разрыва сессий → &amp;lt;code&amp;gt;jq&amp;lt;/code&amp;gt;-удаление из JSON → &amp;lt;code&amp;gt;apply config&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|4. Показать URI клиента&lt;br /&gt;
|Сборка YAML и URI по выбранному имени&lt;br /&gt;
|-&lt;br /&gt;
|5. Статус сервера&lt;br /&gt;
|&amp;lt;code&amp;gt;mita status&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;get connections&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;get metrics&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Установка скрипта ===&lt;br /&gt;
Все команды выполняются на frontend-сервере по SSH.&lt;br /&gt;
&lt;br /&gt;
==== Шаг 1. Загрузка скрипта ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /usr/local/bin/mieru-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте полное содержимое скрипта (исходный код в спойлере «Исходный код &amp;lt;code&amp;gt;mieru-users.sh&amp;lt;/code&amp;gt;» в конце статьи).&lt;br /&gt;
&lt;br /&gt;
Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Шаг 2. Подстановка реального адреса ====&lt;br /&gt;
В начале скрипта есть строка &amp;lt;code&amp;gt;SERVER_IP=&amp;quot;YOUR_FRONTEND_PUBLIC_IP&amp;quot;&amp;lt;/code&amp;gt;. Замените её на реальный IP frontend-сервера.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sed -i &#039;s/YOUR_FRONTEND_PUBLIC_IP/198.51.100.10/&#039; /usr/local/bin/mieru-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;(подставьте свой IP вместо &amp;lt;code&amp;gt;198.51.100.10&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==== Шаг 3. Права на исполнение ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x /usr/local/bin/mieru-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Шаг 4. Проверка ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
bash -n /usr/local/bin/mieru-users.sh &amp;amp;&amp;amp; echo OK&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если выводит &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt; — скрипт установлен корректно.&lt;br /&gt;
&lt;br /&gt;
=== Использование ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo bash /usr/local/bin/mieru-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Появится меню:&amp;lt;pre&amp;gt;&lt;br /&gt;
╔══════════════════════════════════════╗&lt;br /&gt;
║   mieru User Manager                 ║&lt;br /&gt;
║   IP: 198.51.100.10                  ║&lt;br /&gt;
╚══════════════════════════════════════╝&lt;br /&gt;
&lt;br /&gt;
  Пользователей в конфиге: 1&lt;br /&gt;
&lt;br /&gt;
  1. Список пользователей и активных сессий&lt;br /&gt;
  2. Добавить пользователя&lt;br /&gt;
  3. Удалить пользователя&lt;br /&gt;
  4. Показать URI клиента&lt;br /&gt;
  5. Статус сервера&lt;br /&gt;
  0. Выход&lt;br /&gt;
&amp;lt;/pre&amp;gt;После добавления пользователя скрипт выводит готовые конфиги:&amp;lt;pre&amp;gt;&lt;br /&gt;
=== Вариант 1: Clash / Mihomo YAML (рекомендую) ===&lt;br /&gt;
proxies:&lt;br /&gt;
  - name: mieru-RU-alice&lt;br /&gt;
    type: mieru&lt;br /&gt;
    server: 198.51.100.10&lt;br /&gt;
    port: 2022&lt;br /&gt;
    username: alice&lt;br /&gt;
    password: &amp;lt;автогенерированный&amp;gt;&lt;br /&gt;
    multiplexing: MULTIPLEXING_HIGH&lt;br /&gt;
&lt;br /&gt;
=== Вариант 2: mierus:// URI ===&lt;br /&gt;
mierus://alice:&amp;lt;пароль&amp;gt;@198.51.100.10?port=2022&amp;amp;protocol=TCP&amp;amp;mtu=1380&amp;amp;multiplexing=MULTIPLEXING_HIGH&amp;amp;handshake-mode=HANDSHAKE_NO_WAIT&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Команды управления ==&lt;br /&gt;
&lt;br /&gt;
=== На обоих серверах ===&lt;br /&gt;
Посмотреть логи в реальном времени.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f mita-backend       # на backend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f mita-frontend mieru-client       # на frontend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Перезапустить.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-backend/docker-compose.yml restart    # на backend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-frontend/docker-compose.yml restart   # на frontend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Остановить.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-backend/docker-compose.yml down       # на backend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-frontend/docker-compose.yml down      # на frontend&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Обновить версию mita/mieru. Поменяйте &amp;lt;code&amp;gt;3.32.0&amp;lt;/code&amp;gt; на нужную в &amp;lt;code&amp;gt;docker-compose.yml&amp;lt;/code&amp;gt; и пересоберите.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/mieru-backend/docker-compose.yml build &amp;amp;&amp;amp; docker compose -f /opt/mieru-backend/docker-compose.yml up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Команды mita через CLI (внутри контейнера) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita status              # IDLE / RUNNING&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita get users           # список user&#039;ов и их статистика&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita get connections     # активные сессии&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita get metrics         # метрики&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita describe config     # текущий применённый конфиг&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== На OpenWrt-роутере ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/etc/init.d/mieru start | stop | restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ps | grep mieru | grep -v grep&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
logread | grep mieru&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Поиск проблем ==&lt;br /&gt;
&lt;br /&gt;
=== Симптом: сервер показывает &amp;lt;code&amp;gt;IDLE&amp;lt;/code&amp;gt;, порты не слушаются ===&lt;br /&gt;
mita после &amp;lt;code&amp;gt;apply config&amp;lt;/code&amp;gt; остаётся в &amp;lt;code&amp;gt;IDLE&amp;lt;/code&amp;gt; до явной команды &amp;lt;code&amp;gt;mita start&amp;lt;/code&amp;gt;. В нашем entrypoint это происходит автоматически, но если что-то пошло не так, выполните вручную внутри контейнера:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mita-backend mita start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Симптом: &amp;lt;code&amp;gt;FATAL: getUid(&amp;quot;mita&amp;quot;) failed&amp;lt;/code&amp;gt; ===&lt;br /&gt;
В образ не добавлен системный пользователь &amp;lt;code&amp;gt;mita&amp;lt;/code&amp;gt;. Проверьте, что Dockerfile содержит строки &amp;lt;code&amp;gt;adduser -H -D -g &amp;quot;&amp;quot; mita&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;adduser -H -D -g &amp;quot;&amp;quot; mieru&amp;lt;/code&amp;gt;, пересоберите образ.&lt;br /&gt;
&lt;br /&gt;
=== Симптом: клиент подключается, но трафик не идёт ===&lt;br /&gt;
Проверьте на клиенте время системы. Расхождение более 4 минут с сервером приведёт к молчаливому отказу. Команда на Linux/macOS:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
date -u&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если время существенно расходится — настройте NTP.&lt;br /&gt;
&lt;br /&gt;
=== Симптом: на frontend curl возвращает не egress-IP, а frontend-IP ===&lt;br /&gt;
Trafic идёт мимо mieru-client. Возможные причины:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;egress.action&amp;lt;/code&amp;gt; в frontend-конфиге — &amp;lt;code&amp;gt;DIRECT&amp;lt;/code&amp;gt; вместо &amp;lt;code&amp;gt;PROXY&amp;lt;/code&amp;gt;.&lt;br /&gt;
* mieru-client не запущен либо упал. Проверьте: &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Backend не доступен. Проверьте на frontend: &amp;lt;code&amp;gt;nc -vz YOUR_BACKEND_PUBLIC_IP 2022&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Симптом: на frontend curl возвращает frontend-IP, а должен — backend-IP ===&lt;br /&gt;
То же самое, что выше: трафик не доходит до backend. Дополнительно посмотрите логи:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs mieru-client --tail 50&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ошибки &amp;lt;code&amp;gt;TLS handshake&amp;lt;/code&amp;gt; здесь невозможны — mieru не использует TLS. Ищите &amp;lt;code&amp;gt;auth failed&amp;lt;/code&amp;gt; (неверная пара логин/пароль на mita-backend) и &amp;lt;code&amp;gt;connection refused&amp;lt;/code&amp;gt; (backend не слушает).&lt;br /&gt;
&lt;br /&gt;
=== Симптом: на роутере Karing/Clash подключается, но трафик не идёт ===&lt;br /&gt;
В первую очередь проверить YAML-конфиг: тип &amp;lt;code&amp;gt;type: mieru&amp;lt;/code&amp;gt; (не &amp;lt;code&amp;gt;type: socks5&amp;lt;/code&amp;gt;!), порт &amp;lt;code&amp;gt;port: 2022&amp;lt;/code&amp;gt; (одиночное число, не диапазон). Многие mihomo-форки не парсят диапазон портов корректно.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Исходный код &amp;lt;code&amp;gt;mieru-users.sh&amp;lt;/code&amp;gt; ==&lt;br /&gt;
Полный текст скрипта приведён ниже. Скопируйте его целиком в &amp;lt;code&amp;gt;/usr/local/bin/mieru-users.sh&amp;lt;/code&amp;gt; на frontend-сервере по инструкции выше.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# mieru-users — управление пользователями mita&lt;br /&gt;
# Источник истины: /opt/mieru-frontend/server.json&lt;br /&gt;
# Применение через mita apply config (RPC к работающему daemon).&lt;br /&gt;
&lt;br /&gt;
CONFIG_FILE=&amp;quot;/opt/mieru-frontend/server.json&amp;quot;&lt;br /&gt;
COMPOSE_DIR=&amp;quot;/opt/mieru-frontend&amp;quot;&lt;br /&gt;
COMPOSE_SVC=&amp;quot;mita&amp;quot;&lt;br /&gt;
BACKUP_DIR=&amp;quot;/opt/mieru-frontend/backups&amp;quot;&lt;br /&gt;
BACKUP_KEEP=10&lt;br /&gt;
SERVER_IP=&amp;quot;YOUR_FRONTEND_PUBLIC_IP&amp;quot;&lt;br /&gt;
&lt;br /&gt;
RED=&#039;\033[0;31m&#039;; GREEN=&#039;\033[0;32m&#039;; YELLOW=&#039;\033[1;33m&#039;&lt;br /&gt;
CYAN=&#039;\033[0;36m&#039;; BOLD=&#039;\033[1m&#039;; NC=&#039;\033[0m&#039;&lt;br /&gt;
&lt;br /&gt;
check_root() {&lt;br /&gt;
    if [[ $EUID -ne 0 ]]; then&lt;br /&gt;
        echo -e &amp;quot;${RED}Запусти от root: sudo bash mieru-users.sh${NC}&amp;quot;; exit 1&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
check_deps() {&lt;br /&gt;
    for c in jq docker openssl; do&lt;br /&gt;
        if ! command -v &amp;quot;$c&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then&lt;br /&gt;
            echo -e &amp;quot;${RED}Не найдено: $c${NC}&amp;quot;; exit 1&lt;br /&gt;
        fi&lt;br /&gt;
    done&lt;br /&gt;
    if [[ ! -f &amp;quot;$CONFIG_FILE&amp;quot; ]]; then&lt;br /&gt;
        echo -e &amp;quot;${RED}Не найден $CONFIG_FILE${NC}&amp;quot;; exit 1&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
mita_cli() {&lt;br /&gt;
    docker compose -f &amp;quot;$COMPOSE_DIR/docker-compose.yml&amp;quot; exec -T &amp;quot;$COMPOSE_SVC&amp;quot; mita &amp;quot;$@&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
backup_config() {&lt;br /&gt;
    mkdir -p &amp;quot;$BACKUP_DIR&amp;quot;&lt;br /&gt;
    local stamp; stamp=$(date +%Y%m%d-%H%M%S)&lt;br /&gt;
    cp &amp;quot;$CONFIG_FILE&amp;quot; &amp;quot;$BACKUP_DIR/server-$stamp.json&amp;quot;&lt;br /&gt;
    ls -1t &amp;quot;$BACKUP_DIR&amp;quot;/server-*.json 2&amp;gt;/dev/null | tail -n +$((BACKUP_KEEP+1)) | xargs -r rm -f&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
apply_config() {&lt;br /&gt;
    if ! mita_cli apply config /srv/server.json 2&amp;gt;&amp;amp;1; then&lt;br /&gt;
        echo -e &amp;quot;${RED}mita apply config упал. Откатываюсь к последнему бэкапу.${NC}&amp;quot;&lt;br /&gt;
        local last; last=$(ls -1t &amp;quot;$BACKUP_DIR&amp;quot;/server-*.json 2&amp;gt;/dev/null | head -1)&lt;br /&gt;
        if [[ -n &amp;quot;$last&amp;quot; ]]; then&lt;br /&gt;
            cp &amp;quot;$last&amp;quot; &amp;quot;$CONFIG_FILE&amp;quot;&lt;br /&gt;
            mita_cli apply config /srv/server.json &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || true&lt;br /&gt;
        fi&lt;br /&gt;
        return 1&lt;br /&gt;
    fi&lt;br /&gt;
    return 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
press_enter() { echo &amp;quot;&amp;quot;; read -rp &amp;quot;Enter для возврата...&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
generate_password() {&lt;br /&gt;
    openssl rand -base64 24 | tr -d &#039;=/+&#039; | head -c 31&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
generate_uri() {&lt;br /&gt;
    echo &amp;quot;mierus://${1}:${2}@${SERVER_IP}?port=2022&amp;amp;protocol=TCP&amp;amp;mtu=1380&amp;amp;multiplexing=MULTIPLEXING_HIGH&amp;amp;handshake-mode=HANDSHAKE_NO_WAIT&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
generate_yaml() {&lt;br /&gt;
    cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
proxies:&lt;br /&gt;
  - name: mieru-${1}&lt;br /&gt;
    type: mieru&lt;br /&gt;
    server: ${SERVER_IP}&lt;br /&gt;
    port: 2022&lt;br /&gt;
    username: ${1}&lt;br /&gt;
    password: ${2}&lt;br /&gt;
    multiplexing: MULTIPLEXING_HIGH&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
print_uri_for() {&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${CYAN}=== Вариант 1: Clash / Mihomo YAML ===${NC}&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}$(generate_yaml &amp;quot;$1&amp;quot; &amp;quot;$2&amp;quot;)${NC}&amp;quot;&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${CYAN}=== Вариант 2: mierus:// URI ===${NC}&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}  $(generate_uri &amp;quot;$1&amp;quot; &amp;quot;$2&amp;quot;)${NC}&amp;quot;&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${CYAN}user=${BOLD}${1}${NC}, pwd=${BOLD}${2}${NC}, host=${BOLD}${SERVER_IP}${NC}, port=${BOLD}2022${NC}&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list_users() {&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    local n; n=$(jq &#039;.users | length&#039; &amp;quot;$CONFIG_FILE&amp;quot;)&lt;br /&gt;
    echo -e &amp;quot;${BOLD}${CYAN}=== Пользователей: $n ===${NC}&amp;quot;&lt;br /&gt;
    jq -r &#039;.users[] | &amp;quot;  \(.name)\t\(.password[0:6])…&amp;quot;&#039; &amp;quot;$CONFIG_FILE&amp;quot; | nl -w2 -s&#039;. &#039;&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}${CYAN}=== Активные сессии ===${NC}&amp;quot;&lt;br /&gt;
    mita_cli get connections 2&amp;gt;&amp;amp;1 | head -20&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
add_user() {&lt;br /&gt;
    echo &amp;quot;&amp;quot;; read -rp &amp;quot;Имя пользователя: &amp;quot; name&lt;br /&gt;
    name=$(echo &amp;quot;$name&amp;quot; | tr -d &#039; &#039;)&lt;br /&gt;
    [[ -z &amp;quot;$name&amp;quot; ]] &amp;amp;&amp;amp; { echo &amp;quot;Пусто.&amp;quot;; press_enter; return; }&lt;br /&gt;
    if jq -e --arg n &amp;quot;$name&amp;quot; &#039;.users[] | select(.name == $n)&#039; &amp;quot;$CONFIG_FILE&amp;quot; &amp;gt;/dev/null; then&lt;br /&gt;
        echo &amp;quot;Уже есть.&amp;quot;; press_enter; return&lt;br /&gt;
    fi&lt;br /&gt;
    read -rp &amp;quot;Пароль (Enter — сгенерировать): &amp;quot; pwd&lt;br /&gt;
    [[ -z &amp;quot;$pwd&amp;quot; ]] &amp;amp;&amp;amp; pwd=$(generate_password)&lt;br /&gt;
&lt;br /&gt;
    backup_config&lt;br /&gt;
    local tmp; tmp=$(mktemp)&lt;br /&gt;
    jq --arg n &amp;quot;$name&amp;quot; --arg p &amp;quot;$pwd&amp;quot; &#039;.users += [{&amp;quot;name&amp;quot;:$n,&amp;quot;password&amp;quot;:$p}]&#039; &amp;quot;$CONFIG_FILE&amp;quot; &amp;gt; &amp;quot;$tmp&amp;quot; &amp;amp;&amp;amp; mv &amp;quot;$tmp&amp;quot; &amp;quot;$CONFIG_FILE&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    if apply_config; then&lt;br /&gt;
        echo -e &amp;quot;${GREEN}Пользователь $name добавлен.${NC}&amp;quot;&lt;br /&gt;
        print_uri_for &amp;quot;$name&amp;quot; &amp;quot;$pwd&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
delete_user() {&lt;br /&gt;
    mapfile -t users &amp;lt; &amp;lt;(jq -r &#039;.users[].name&#039; &amp;quot;$CONFIG_FILE&amp;quot;)&lt;br /&gt;
    [[ ${#users[@]} -eq 0 ]] &amp;amp;&amp;amp; { echo &amp;quot;Пусто.&amp;quot;; press_enter; return; }&lt;br /&gt;
    for i in &amp;quot;${!users[@]}&amp;quot;; do echo &amp;quot;  $((i+1))) ${users[$i]}&amp;quot;; done&lt;br /&gt;
    echo &amp;quot;  0) Отмена&amp;quot;; read -rp &amp;quot;Номер: &amp;quot; n&lt;br /&gt;
    [[ &amp;quot;$n&amp;quot; == &amp;quot;0&amp;quot; || -z &amp;quot;$n&amp;quot; ]] &amp;amp;&amp;amp; return&lt;br /&gt;
    local target=&amp;quot;${users[$((n-1))]}&amp;quot;&lt;br /&gt;
    read -rp &amp;quot;Удалить &#039;$target&#039;? (y/N): &amp;quot; yn&lt;br /&gt;
    [[ ! &amp;quot;$yn&amp;quot; =~ ^[Yy]$ ]] &amp;amp;&amp;amp; return&lt;br /&gt;
&lt;br /&gt;
    mita_cli delete user &amp;quot;$target&amp;quot; 2&amp;gt;&amp;amp;1&lt;br /&gt;
    backup_config&lt;br /&gt;
    local tmp; tmp=$(mktemp)&lt;br /&gt;
    jq --arg n &amp;quot;$target&amp;quot; &#039;del(.users[] | select(.name == $n))&#039; &amp;quot;$CONFIG_FILE&amp;quot; &amp;gt; &amp;quot;$tmp&amp;quot; &amp;amp;&amp;amp; mv &amp;quot;$tmp&amp;quot; &amp;quot;$CONFIG_FILE&amp;quot;&lt;br /&gt;
    apply_config &amp;amp;&amp;amp; echo -e &amp;quot;${GREEN}Удалён.${NC}&amp;quot;&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
show_uri() {&lt;br /&gt;
    mapfile -t users &amp;lt; &amp;lt;(jq -r &#039;.users[].name&#039; &amp;quot;$CONFIG_FILE&amp;quot;)&lt;br /&gt;
    [[ ${#users[@]} -eq 0 ]] &amp;amp;&amp;amp; { echo &amp;quot;Пусто.&amp;quot;; press_enter; return; }&lt;br /&gt;
    for i in &amp;quot;${!users[@]}&amp;quot;; do echo &amp;quot;  $((i+1))) ${users[$i]}&amp;quot;; done&lt;br /&gt;
    read -rp &amp;quot;Номер: &amp;quot; n&lt;br /&gt;
    [[ -z &amp;quot;$n&amp;quot; ]] &amp;amp;&amp;amp; return&lt;br /&gt;
    local user=&amp;quot;${users[$((n-1))]}&amp;quot;&lt;br /&gt;
    local pwd; pwd=$(jq -r --arg n &amp;quot;$user&amp;quot; &#039;.users[] | select(.name == $n) | .password&#039; &amp;quot;$CONFIG_FILE&amp;quot;)&lt;br /&gt;
    print_uri_for &amp;quot;$user&amp;quot; &amp;quot;$pwd&amp;quot;&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
server_status() {&lt;br /&gt;
    mita_cli status 2&amp;gt;&amp;amp;1&lt;br /&gt;
    echo&lt;br /&gt;
    mita_cli get connections 2&amp;gt;&amp;amp;1&lt;br /&gt;
    echo&lt;br /&gt;
    mita_cli get metrics 2&amp;gt;&amp;amp;1 | head -30&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
main_menu() {&lt;br /&gt;
    check_root; check_deps&lt;br /&gt;
    while true; do&lt;br /&gt;
        clear&lt;br /&gt;
        echo &amp;quot;╔══════════════════════════════════════╗&amp;quot;&lt;br /&gt;
        echo &amp;quot;║   mieru User Manager                 ║&amp;quot;&lt;br /&gt;
        echo &amp;quot;║   IP: $SERVER_IP&amp;quot;&lt;br /&gt;
        echo &amp;quot;╚══════════════════════════════════════╝&amp;quot;&lt;br /&gt;
        echo&lt;br /&gt;
        echo &amp;quot;  1) Список пользователей&amp;quot;&lt;br /&gt;
        echo &amp;quot;  2) Добавить&amp;quot;&lt;br /&gt;
        echo &amp;quot;  3) Удалить&amp;quot;&lt;br /&gt;
        echo &amp;quot;  4) URI клиента&amp;quot;&lt;br /&gt;
        echo &amp;quot;  5) Статус сервера&amp;quot;&lt;br /&gt;
        echo &amp;quot;  0) Выход&amp;quot;&lt;br /&gt;
        read -rp &amp;quot;Выбор: &amp;quot; opt&lt;br /&gt;
        case &amp;quot;$opt&amp;quot; in&lt;br /&gt;
            1) list_users ;; 2) add_user ;;&lt;br /&gt;
            3) delete_user ;; 4) show_uri ;;&lt;br /&gt;
            5) server_status ;; 0) exit 0 ;;&lt;br /&gt;
        esac&lt;br /&gt;
    done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
main_menu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/enfein/mieru Официальный репозиторий mieru]&lt;br /&gt;
* [https://github.com/enfein/mieru/blob/master/docs/protocol.md Спецификация протокола mieru]&lt;br /&gt;
* [https://github.com/enfein/mieru/blob/master/docs/traffic-pattern.md Документация по traffic pattern]&lt;br /&gt;
* [https://github.com/enfein/mieru/blob/master/docs/security.md Руководство по безопасности]&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A1%D1%83%D0%B2%D0%B5%D1%80%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82&amp;diff=967</id>
		<title>Суверенный интернет</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A1%D1%83%D0%B2%D0%B5%D1%80%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82&amp;diff=967"/>
		<updated>2026-05-10T18:40:53Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Эта страница посвящается всему что связано с ограничим доступа в интернет.&lt;br /&gt;
&lt;br /&gt;
На данный момент 20.04.26 мы имеем полную блокировку по белыми IP у операторов мобильной связи. И предпосылки к блокировкам на уровне провайдеров домашнего интернета.&lt;br /&gt;
&lt;br /&gt;
* [[Обход НКР|Установка и настройка связки Zapret + Podkop на OpenWRT]]&lt;br /&gt;
* [[Hysteria 2 каскад]]&lt;br /&gt;
* [[Whitelist-bypass: VK Creator (headless на сервере) + Joiner (Android)]]&lt;br /&gt;
* [[Установка MTProto Proxy (mtg) на Linux-сервере]]&lt;br /&gt;
* [[VK Turn Proxy + FreeTurn + VLESS]]&lt;br /&gt;
* [[NaïveProxy: установка полной каскадной цепочки]]&lt;br /&gt;
* [[OlcRTC: туннель через WebRTC-сервисы|olcRTC: туннель через легальные WebRTC-сервисы]]&lt;br /&gt;
* mieru: каскадный шифрованный SOCKS5-туннель&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A1%D1%83%D0%B2%D0%B5%D1%80%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82&amp;diff=966</id>
		<title>Суверенный интернет</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A1%D1%83%D0%B2%D0%B5%D1%80%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82&amp;diff=966"/>
		<updated>2026-05-09T18:22:26Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Эта страница посвящается всему что связано с ограничим доступа в интернет.&lt;br /&gt;
&lt;br /&gt;
На данный момент 20.04.26 мы имеем полную блокировку по белыми IP у операторов мобильной связи. И предпосылки к блокировкам на уровне провайдеров домашнего интернета.&lt;br /&gt;
&lt;br /&gt;
* [[Обход НКР|Установка и настройка связки Zapret + Podkop на OpenWRT]]&lt;br /&gt;
* [[Hysteria 2 каскад]]&lt;br /&gt;
* [[Whitelist-bypass: VK Creator (headless на сервере) + Joiner (Android)]]&lt;br /&gt;
* [[Установка MTProto Proxy (mtg) на Linux-сервере]]&lt;br /&gt;
* [[VK Turn Proxy + FreeTurn + VLESS]]&lt;br /&gt;
* [[NaïveProxy: установка полной каскадной цепочки]]&lt;br /&gt;
* [[OlcRTC: туннель через WebRTC-сервисы|olcRTC: туннель через легальные WebRTC-сервисы]]&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A1%D1%83%D0%B2%D0%B5%D1%80%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82&amp;diff=965</id>
		<title>Суверенный интернет</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A1%D1%83%D0%B2%D0%B5%D1%80%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82&amp;diff=965"/>
		<updated>2026-05-09T18:21:43Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Эта страница посвящается всему что связано с ограничим доступа в интернет.&lt;br /&gt;
&lt;br /&gt;
На данный момент 20.04.26 мы имеем полную блокировку по белыми IP у операторов мобильной связи. И предпосылки к блокировкам на уровне провайдеров домашнего интернета.&lt;br /&gt;
&lt;br /&gt;
* [[Обход НКР|Установка и настройка связки Zapret + Podkop на OpenWRT]]&lt;br /&gt;
* [[Hysteria 2 каскад]]&lt;br /&gt;
* [[Whitelist-bypass: VK Creator (headless на сервере) + Joiner (Android)]]&lt;br /&gt;
* [[Установка MTProto Proxy (mtg) на Linux-сервере]]&lt;br /&gt;
* [[VK Turn Proxy + FreeTurn + VLESS]]&lt;br /&gt;
* [[NaïveProxy: установка полной каскадной цепочки]]&lt;br /&gt;
* [[olcRTC: туннель через легальные WebRTC-сервисы]]&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=OlcRTC:_%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D1%8C_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_WebRTC-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D1%8B&amp;diff=964</id>
		<title>OlcRTC: туннель через WebRTC-сервисы</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=OlcRTC:_%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D1%8C_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_WebRTC-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D1%8B&amp;diff=964"/>
		<updated>2026-05-09T07:56:51Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* Поток данных */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= olcRTC: туннелирование SOCKS5-трафика через публичные WebRTC-сервисы =&lt;br /&gt;
&lt;br /&gt;
== Введение ==&lt;br /&gt;
&lt;br /&gt;
=== Что такое olcRTC ===&lt;br /&gt;
olcRTC — это инструмент для построения SOCKS5-туннеля поверх инфраструктуры публичных сервисов видеосвязи. В отличие от классических VPN-протоколов, которые работают через выделенные UDP/TCP-порты на собственном сервере, olcRTC использует уже существующие WebRTC-каналы общедоступных видеоконференц-сервисов в качестве несущей среды.&lt;br /&gt;
&lt;br /&gt;
Поддерживаются три сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Carrier&lt;br /&gt;
!Сервис&lt;br /&gt;
!Адрес&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;wbstream&amp;lt;/code&amp;gt;&lt;br /&gt;
|WB Stream&lt;br /&gt;
|&amp;lt;code&amp;gt;stream.wb.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;telemost&amp;lt;/code&amp;gt;&lt;br /&gt;
|Yandex Telemost&lt;br /&gt;
|&amp;lt;code&amp;gt;telemost.yandex.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;jazz&amp;lt;/code&amp;gt;&lt;br /&gt;
|SaluteJazz&lt;br /&gt;
|&amp;lt;code&amp;gt;salutejazz.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Сервер olcRTC выступает в роли участника виртуальной видеоконференции (с автоматически сгенерированным именем). Клиент подключается к той же конференции и через peer-connection обменивается с сервером данными — поверх этого канала идёт трафик SOCKS5-туннеля.&lt;br /&gt;
&lt;br /&gt;
=== Когда применяется ===&lt;br /&gt;
&lt;br /&gt;
* Канал между клиентом и обычными VPN-серверами нестабилен или имеет высокий процент потерь.&lt;br /&gt;
* Требуется передать данные через инфраструктуру, использующую WebRTC, а не выделенные транспортные порты.&lt;br /&gt;
* Нужна альтернатива, которая работает поверх стандартного для пользовательских устройств WebRTC-стека (браузер, мобильное приложение).&lt;br /&gt;
&lt;br /&gt;
=== Сравнение с другими методами туннелирования ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Метод&lt;br /&gt;
!Транспорт&lt;br /&gt;
!Особенность&lt;br /&gt;
|-&lt;br /&gt;
|WireGuard&lt;br /&gt;
|UDP&lt;br /&gt;
|Прямое соединение с собственным сервером, минимальные накладные расходы&lt;br /&gt;
|-&lt;br /&gt;
|OpenVPN&lt;br /&gt;
|UDP/TCP&lt;br /&gt;
|Универсальная совместимость, выше накладные расходы&lt;br /&gt;
|-&lt;br /&gt;
|Shadowsocks&lt;br /&gt;
|TCP&lt;br /&gt;
|Шифрованный поток, маскировка под произвольный TCP&lt;br /&gt;
|-&lt;br /&gt;
|VLESS + REALITY&lt;br /&gt;
|TCP (TLS)&lt;br /&gt;
|TLS-handshake донора (стороннего сайта)&lt;br /&gt;
|-&lt;br /&gt;
|NaiveProxy&lt;br /&gt;
|TCP (HTTP/2)&lt;br /&gt;
|Использует Chrome-стек, неотличим от обычного HTTPS&lt;br /&gt;
|-&lt;br /&gt;
|Hysteria2&lt;br /&gt;
|UDP (QUIC)&lt;br /&gt;
|QUIC поверх UDP с маскировкой под HTTPS&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;olcRTC&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;WebRTC поверх QUIC/UDP&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Использует существующую инфраструктуру SFU публичного сервиса видеосвязи в качестве несущей&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Принципы работы ==&lt;br /&gt;
&lt;br /&gt;
=== Поток данных ===&lt;br /&gt;
[[Файл:Olcrtc-data-flow.png|центр|мини|841x841пкс|Поток данных olcRTC: от клиентского приложения через SOCKS5, smux + ChaCha20-Poly1305, транспорт и WebRTC peer-connection в видеоконференции, до серверного outbound и целевого сайта]]&lt;br /&gt;
&lt;br /&gt;
=== Слои кода ===&lt;br /&gt;
Кодовая база разделена на четыре независимых слоя с реестром расширений:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Слой&lt;br /&gt;
!Ответственность&lt;br /&gt;
!Реализации&lt;br /&gt;
|-&lt;br /&gt;
|Carrier&lt;br /&gt;
|Сессия в видеосервисе: вход в конференцию, регистрация участника, peer-connection через SFU&lt;br /&gt;
|&amp;lt;code&amp;gt;wbstream&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;telemost&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jazz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Link&lt;br /&gt;
|Поверх транспорта; в текущей версии только &amp;lt;code&amp;gt;direct&amp;lt;/code&amp;gt; (passthrough)&lt;br /&gt;
|&amp;lt;code&amp;gt;direct&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Transport&lt;br /&gt;
|Способ кодирования байтов внутри WebRTC-канала&lt;br /&gt;
|&amp;lt;code&amp;gt;datachannel&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vp8channel&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;seichannel&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;videochannel&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Application&lt;br /&gt;
|Сервер (приём входящих туннелей) или клиент (локальный SOCKS5)&lt;br /&gt;
|&amp;lt;code&amp;gt;server&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;client&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Транспорты ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Транспорт&lt;br /&gt;
!Несущая в WebRTC&lt;br /&gt;
!Идея&lt;br /&gt;
!Скорость&lt;br /&gt;
!Пинг&lt;br /&gt;
!WB Stream&lt;br /&gt;
!Telemost&lt;br /&gt;
!Jazz&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;datachannel&amp;lt;/code&amp;gt;&lt;br /&gt;
|RTCDataChannel&lt;br /&gt;
|Прямые байты в датаканале&lt;br /&gt;
|Максимум&lt;br /&gt;
|Минимум&lt;br /&gt;
|✓&lt;br /&gt;
|✗&lt;br /&gt;
|⚠&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vp8channel&amp;lt;/code&amp;gt;&lt;br /&gt;
|VP8-видеотрек&lt;br /&gt;
|KCP-пакеты внутри валидных VP8-кадров&lt;br /&gt;
|Высокая&lt;br /&gt;
|Средний&lt;br /&gt;
|✓&lt;br /&gt;
|✓&lt;br /&gt;
|✓&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;seichannel&amp;lt;/code&amp;gt;&lt;br /&gt;
|H.264 SEI NAL&lt;br /&gt;
|Полезные данные в SEI-сообщениях видеопотока&lt;br /&gt;
|Низкая&lt;br /&gt;
|Низкий&lt;br /&gt;
|✓&lt;br /&gt;
|✗&lt;br /&gt;
|✓&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;videochannel&amp;lt;/code&amp;gt;&lt;br /&gt;
|Видеокадры&lt;br /&gt;
|QR-коды или тайлы Reed-Solomon в видеопотоке&lt;br /&gt;
|Минимум&lt;br /&gt;
|Максимум&lt;br /&gt;
|✓&lt;br /&gt;
|✓&lt;br /&gt;
|✓&lt;br /&gt;
|}&lt;br /&gt;
Рекомендуемая универсальная связка: &amp;lt;code&amp;gt;wbstream + vp8channel&amp;lt;/code&amp;gt;. Она используется в данной статье как основная конфигурация.&lt;br /&gt;
&lt;br /&gt;
=== Шифрование ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Алгоритм&lt;br /&gt;
|XChaCha20-Poly1305 (AEAD)&lt;br /&gt;
|-&lt;br /&gt;
|Длина ключа&lt;br /&gt;
|32 байта (64 hex-символа)&lt;br /&gt;
|-&lt;br /&gt;
|Nonce&lt;br /&gt;
|24 байта, случайный, на каждый фрейм, префиксится к шифротексту&lt;br /&gt;
|-&lt;br /&gt;
|Идентификация клиента&lt;br /&gt;
|Поле &amp;lt;code&amp;gt;client_id&amp;lt;/code&amp;gt; в открытом JSON, сравнивается с серверным значением&lt;br /&gt;
|}&lt;br /&gt;
Реальная криптографическая защита — это ключ. &amp;lt;code&amp;gt;client_id&amp;lt;/code&amp;gt; — лишь дополнительная проверка от случайных подключений в той же конференции, не криптографическая.&lt;br /&gt;
&lt;br /&gt;
=== Smux: мультиплексирование ===&lt;br /&gt;
Поверх единого WebRTC-канала работает &amp;lt;code&amp;gt;xtaci/smux&amp;lt;/code&amp;gt; v2. Один физический канал содержит много логических TCP-стримов: каждый запрос SOCKS5 от приложения открывается как отдельный smux-стрим.&lt;br /&gt;
&lt;br /&gt;
=== Архитектурное ограничение: один сервер — один клиент ===&lt;br /&gt;
Это важное свойство кода, которое необходимо понимать.&lt;br /&gt;
&lt;br /&gt;
Один экземпляр сервера olcRTC обслуживает &#039;&#039;&#039;ровно одного клиента в момент времени&#039;&#039;&#039;. Это не упущение, а сознательное архитектурное решение.&lt;br /&gt;
&lt;br /&gt;
Причины:&lt;br /&gt;
&lt;br /&gt;
* Сервер хранит &#039;&#039;&#039;одну&#039;&#039;&#039; переменную &amp;lt;code&amp;gt;clientID&amp;lt;/code&amp;gt; и сравнивает с присланным значением (см. &amp;lt;code&amp;gt;internal/server/server.go:399-401&amp;lt;/code&amp;gt;).&lt;br /&gt;
* Сервер держит &#039;&#039;&#039;один&#039;&#039;&#039; link и &#039;&#039;&#039;одну&#039;&#039;&#039; smux-сессию, не словарь по идентификатору.&lt;br /&gt;
* Провайдер carrier держит один RTCPeerConnection.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сценарий&lt;br /&gt;
!Поведение&lt;br /&gt;
|-&lt;br /&gt;
|Один владелец, разные устройства, по очереди (выключил ноутбук, включил телефон)&lt;br /&gt;
|Работает с одной ссылкой&lt;br /&gt;
|-&lt;br /&gt;
|Один владелец, разные устройства, одновременно&lt;br /&gt;
|Устройства конкурируют за peer-connection, рвут друг друга&lt;br /&gt;
|-&lt;br /&gt;
|Несколько разных людей, одна ссылка на всех, одновременно&lt;br /&gt;
|То же — рвут друг друга&lt;br /&gt;
|-&lt;br /&gt;
|Несколько пользователей, у каждого своя ссылка&lt;br /&gt;
|Работает; &#039;&#039;&#039;требуется отдельный контейнер на каждого пользователя&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
Для предоставления доступа нескольким людям одновременно необходимо запустить несколько независимых контейнеров — каждый со своими &amp;lt;code&amp;gt;room_id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;client_id&amp;lt;/code&amp;gt;. В разделе «Управление несколькими пользователями» описан скрипт, который автоматизирует это.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что должно быть на сервере перед установкой ==&lt;br /&gt;
&lt;br /&gt;
=== Минимально необходимая конфигурация ===&lt;br /&gt;
Перед началом установки olcRTC сервер должен находиться в следующем состоянии:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!№&lt;br /&gt;
!Требование&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Установлена операционная система Linux (Ubuntu 22.04+, Debian 12+, Fedora 38+ или сравнимая)&lt;br /&gt;
|Среда выполнения Docker&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Доступ по SSH с правами &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; (либо аккаунт с &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; без пароля)&lt;br /&gt;
|Установка пакетов и управление контейнерами&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Установлены Docker Engine 24.0+ и Docker Compose v2.20+&lt;br /&gt;
|Запуск контейнера olcRTC&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Установлена утилита &amp;lt;code&amp;gt;git&amp;lt;/code&amp;gt;&lt;br /&gt;
|Скачивание исходного кода olcRTC с репозитория&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Установлена утилита &amp;lt;code&amp;gt;openssl&amp;lt;/code&amp;gt;&lt;br /&gt;
|Генерация ключа шифрования&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Опциональная (но настоятельно рекомендуемая) конфигурация: egress через WARP ===&lt;br /&gt;
По умолчанию olcRTC сервер выходит в интернет напрямую с публичного IP вашей виртуальной машины. Все целевые сайты будут видеть именно этот адрес.&lt;br /&gt;
&lt;br /&gt;
Чтобы выходной трафик уходил через Cloudflare WARP, требуется промежуточная цепочка через локальный SOCKS5-прокси. Самая распространённая реализация — панель &#039;&#039;&#039;3x-ui&#039;&#039;&#039; (web-интерфейс над xray-core).&lt;br /&gt;
&lt;br /&gt;
==== Что должно быть подготовлено в 3x-ui ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!№&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение для нашей статьи&lt;br /&gt;
!Комментарий&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Сама панель 3x-ui установлена и доступна&lt;br /&gt;
|—&lt;br /&gt;
|Установка описана в отдельной статье ([[Установка 3x-ui]]); если её ещё нет — выполните установку до начала&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Outbound в WARP активен и протестирован&lt;br /&gt;
|tag &amp;lt;code&amp;gt;warp&amp;lt;/code&amp;gt; или аналогичный&lt;br /&gt;
|Должен быть настроен как WireGuard-outbound к Cloudflare WARP. Проверка: маршрут с outbound отдаёт IPv6 из диапазона &amp;lt;code&amp;gt;2a09:bac5::/29&amp;lt;/code&amp;gt; или IPv4 &amp;lt;code&amp;gt;104.28.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Inbound типа &#039;&#039;&#039;mixed&#039;&#039;&#039; (SOCKS5 + HTTP), слушающий &#039;&#039;&#039;только на 127.0.0.1&#039;&#039;&#039;&lt;br /&gt;
|порт &amp;lt;code&amp;gt;24365&amp;lt;/code&amp;gt;&lt;br /&gt;
|Этот порт мы будем указывать в конфигурации olcRTC. Выберите любой свободный, мы используем 24365 как пример&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Аутентификация (логин/пароль) на этом mixed-inbound &#039;&#039;&#039;отключена&#039;&#039;&#039;&lt;br /&gt;
|—&lt;br /&gt;
|olcRTC-сервер умеет работать только с режимом NOAUTH; если включена авторизация, цепочка не будет работать&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Routing-rule в xray: трафик с inbound mixed → outbound warp&lt;br /&gt;
|—&lt;br /&gt;
|В 3x-ui это настраивается в разделе «Настройки xray → Маршрутизация»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Как проверить, что цепочка работает ====&lt;br /&gt;
Команда ниже выполняется на самом сервере (не на компьютере пользователя). Она запрашивает свой IP-адрес через локальный SOCKS5-прокси, который должен направить запрос в WARP.&lt;br /&gt;
&lt;br /&gt;
Замените &amp;lt;code&amp;gt;24365&amp;lt;/code&amp;gt; на ваш реальный номер порта mixed-inbound.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl --socks5-hostname 127.0.0.1:24365 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидаемый результат: IP-адрес из диапазона Cloudflare WARP (например, &amp;lt;code&amp;gt;104.28.218.x&amp;lt;/code&amp;gt; или IPv6 &amp;lt;code&amp;gt;2a09:bac5:...&amp;lt;/code&amp;gt;). Если возвращается публичный IP вашего сервера — значит цепочка не сработала и трафик идёт мимо WARP. В этом случае проверьте настройки routing в 3x-ui.&lt;br /&gt;
&lt;br /&gt;
Если egress через WARP вам не нужен (готовы выходить с публичного IP сервера), можно пропустить этот раздел. В дальнейших шагах указания для случая «без WARP» помечены явно.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Параметры, которые нужно подготовить заранее ==&lt;br /&gt;
Перед началом установки заполните таблицу ниже своими значениями. На каждом шаге, где встретится плейсхолдер, мы будем ссылаться на эту таблицу.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Плейсхолдер&lt;br /&gt;
!Что это&lt;br /&gt;
!Где взять&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_SERVER_HOST&amp;lt;/code&amp;gt;&lt;br /&gt;
|Адрес сервера для подключения по SSH: либо публичный IP, либо имя из &amp;lt;code&amp;gt;~/.ssh/config&amp;lt;/code&amp;gt;, либо доменное имя&lt;br /&gt;
|У хостинг-провайдера в панели управления виртуальной машиной&lt;br /&gt;
|&amp;lt;code&amp;gt;198.51.100.42&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my-vps&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_SSH_USER&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя пользователя SSH&lt;br /&gt;
|В письме от хостинга при создании VM. Чаще всего &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_KEY_HEX&amp;lt;/code&amp;gt;&lt;br /&gt;
|32-байтный ключ шифрования olcRTC в hex-формате (64 символа)&lt;br /&gt;
|Будет сгенерирован командой на шаге 4. Сохраните в надёжное место&lt;br /&gt;
|&amp;lt;code&amp;gt;1c3f8a2b...d4e5f6a7&amp;lt;/code&amp;gt; (64 hex-символа)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_CLIENT_ID&amp;lt;/code&amp;gt;&lt;br /&gt;
|Идентификатор клиента; должен совпадать на сервере и в клиентском приложении&lt;br /&gt;
|Любое имя на латинице длиной 1–32 символа: буквы, цифры, &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;my-laptop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_ROOM_ID&amp;lt;/code&amp;gt;&lt;br /&gt;
|Идентификатор виртуальной видеоконференции&lt;br /&gt;
|Будет получен из логов сервера на шаге 7&lt;br /&gt;
|&amp;lt;code&amp;gt;019e07b8-e292-73ec-a40b-6a6e4957ce01&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_SOCKS_PORT&amp;lt;/code&amp;gt;&lt;br /&gt;
|Порт mixed-inbound в 3x-ui для egress через WARP (опционально)&lt;br /&gt;
|См. раздел «Что должно быть на сервере перед установкой»&lt;br /&gt;
|&amp;lt;code&amp;gt;24365&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Сохраните эту таблицу в текстовом файле — заполните по мере прохождения шагов. Особенно важно сохранить &amp;lt;code&amp;gt;YOUR_KEY_HEX&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;YOUR_ROOM_ID&amp;lt;/code&amp;gt; — без них нельзя восстановить доступ к серверу после перезапуска.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Установка сервера: пошаговая инструкция ==&lt;br /&gt;
В этом разделе все команды выполняются на сервере (через SSH). Каждое пояснение — одна команда. Если команда выдала ошибку — остановитесь, не выполняйте следующую, и сверьтесь с предыдущим шагом.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Подключение к серверу по SSH ===&lt;br /&gt;
Откройте терминал на своём компьютере. На Windows можно использовать встроенный PowerShell или Windows Terminal, на macOS — Terminal, на Linux — любой эмулятор терминала.&lt;br /&gt;
&lt;br /&gt;
Замените &amp;lt;code&amp;gt;YOUR_SSH_USER&amp;lt;/code&amp;gt; на имя пользователя из подготовленной таблицы (обычно &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;), а &amp;lt;code&amp;gt;YOUR_SERVER_HOST&amp;lt;/code&amp;gt; — на адрес или имя сервера.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh YOUR_SSH_USER@YOUR_SERVER_HOST&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если подключение прошло успешно — вы увидите приглашение командной строки сервера. Все следующие команды выполняются именно в нём.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Проверка наличия Docker ===&lt;br /&gt;
Прежде чем что-то ставить, проверим, есть ли Docker уже на сервере.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker --version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если команда вывела что-то вроде &amp;lt;code&amp;gt;Docker version 24.0.5, build ...&amp;lt;/code&amp;gt; — Docker установлен, переходите к шагу 3.&lt;br /&gt;
&lt;br /&gt;
Если команда выдала &amp;lt;code&amp;gt;command not found&amp;lt;/code&amp;gt; — Docker нужно установить. Выберите один из подразделов ниже в зависимости от вашего дистрибутива.&lt;br /&gt;
&lt;br /&gt;
==== 2a. Установка Docker на Ubuntu / Debian ====&lt;br /&gt;
Обновите список пакетов.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установите вспомогательные утилиты.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install -y ca-certificates curl gnupg&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подготовьте каталог для GPG-ключей репозитория Docker.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Скачайте GPG-ключ официального репозитория Docker.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Дайте права на чтение всем.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.gpg&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Добавьте репозиторий Docker в систему.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;$VERSION_CODENAME&amp;quot;) stable&amp;quot; | tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Снова обновите список пакетов (теперь уже с новым репозиторием).&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установите Docker и плагины.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 2b. Установка Docker на Fedora / RHEL ====&lt;br /&gt;
Установите менеджер репозиториев.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dnf -y install dnf-plugins-core&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подключите репозиторий Docker.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установите Docker.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dnf -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Запустите и включите автозапуск Docker.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl enable --now docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 2c. Проверка установки Docker (любая ОС) ====&lt;br /&gt;
Проверьте, что Docker установлен и работает.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker --version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должно вывести что-то вроде &amp;lt;code&amp;gt;Docker version 24.0.5&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Проверьте, что плагин Compose доступен.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должно вывести что-то вроде &amp;lt;code&amp;gt;Docker Compose version v2.20.2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если обе команды отработали без ошибок — переходите к шагу 3.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создание рабочего каталога ===&lt;br /&gt;
Создайте каталог, в котором будет лежать репозиторий olcRTC.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/olcrtc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Перейдите в этот каталог.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/olcrtc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Скачивание исходного кода olcRTC ===&lt;br /&gt;
Скачайте репозиторий вместе с подмодулями (флаг &amp;lt;code&amp;gt;--recurse-submodules&amp;lt;/code&amp;gt; обязателен — без него транспорт &amp;lt;code&amp;gt;videochannel&amp;lt;/code&amp;gt; не соберётся).&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git clone --depth 1 --recurse-submodules --branch master https://github.com/openlibrecommunity/olcrtc.git .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Точка в конце команды означает «скачать в текущий каталог», не создавая вложенной папки. Если вы пропустили шаг 3 (&amp;lt;code&amp;gt;cd /opt/olcrtc&amp;lt;/code&amp;gt;), команда создаст репозиторий не в том месте.&lt;br /&gt;
&lt;br /&gt;
Проверьте, что скачивание прошло успешно.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls /opt/olcrtc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В выводе должны быть файлы &amp;lt;code&amp;gt;Dockerfile&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;go.mod&amp;lt;/code&amp;gt;, каталоги &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;internal&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;script&amp;lt;/code&amp;gt; и другие.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Генерация ключа шифрования ===&lt;br /&gt;
Сгенерируйте ключ командой &amp;lt;code&amp;gt;openssl&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl rand -hex 32&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Команда выведет строку из 64 hex-символов. Например:&lt;br /&gt;
 1c3f8a2b3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8091a2b3c4d5e6f7a8b9c0d1e2&lt;br /&gt;
&#039;&#039;&#039;Скопируйте этот ключ&#039;&#039;&#039; и впишите его в свою таблицу подготовки как &amp;lt;code&amp;gt;YOUR_KEY_HEX&amp;lt;/code&amp;gt;. Этот же ключ потом понадобится для настройки клиента.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 6. Создание конфигурационного файла .env ===&lt;br /&gt;
Файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; хранит параметры запуска. Создадим его, подставив ваши значения.&lt;br /&gt;
&lt;br /&gt;
Замените:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;ВАШ_КЛЮЧ&amp;lt;/code&amp;gt; — на значение &amp;lt;code&amp;gt;YOUR_KEY_HEX&amp;lt;/code&amp;gt; из шага 5.&lt;br /&gt;
* &amp;lt;code&amp;gt;my-laptop&amp;lt;/code&amp;gt; — на значение &amp;lt;code&amp;gt;YOUR_CLIENT_ID&amp;lt;/code&amp;gt; из таблицы подготовки.&lt;br /&gt;
&lt;br /&gt;
Если вы &#039;&#039;&#039;используете&#039;&#039;&#039; egress через WARP (раздел «Что должно быть на сервере перед установкой»), также замените &amp;lt;code&amp;gt;24365&amp;lt;/code&amp;gt; на свой &amp;lt;code&amp;gt;YOUR_SOCKS_PORT&amp;lt;/code&amp;gt;. Если &#039;&#039;&#039;не используете&#039;&#039;&#039; WARP — удалите две строки &amp;lt;code&amp;gt;OLCRTC_SOCKS_PROXY=...&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/olcrtc/.env&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В открывшемся редакторе вставьте следующее содержимое:&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
OLCRTC_CARRIER=wbstream&lt;br /&gt;
OLCRTC_TRANSPORT=vp8channel&lt;br /&gt;
OLCRTC_ROOM_ID=any&lt;br /&gt;
OLCRTC_CLIENT_ID=my-laptop&lt;br /&gt;
OLCRTC_KEY=ВАШ_КЛЮЧ&lt;br /&gt;
OLCRTC_DNS=1.1.1.1:53&lt;br /&gt;
OLCRTC_SOCKS_PROXY=127.0.0.1&lt;br /&gt;
OLCRTC_SOCKS_PROXY_PORT=24365&lt;br /&gt;
OLCRTC_VP8_FPS=60&lt;br /&gt;
OLCRTC_VP8_BATCH=64&lt;br /&gt;
OLCRTC_DEBUG=false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните файл: нажмите &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, затем &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, затем &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Защитите файл от чтения посторонними (он содержит ваш ключ).&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /opt/olcrtc/.env&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Проверьте, что значения подставились правильно.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat /opt/olcrtc/.env&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В строке &amp;lt;code&amp;gt;OLCRTC_KEY=...&amp;lt;/code&amp;gt; должен быть ваш ключ, в строке &amp;lt;code&amp;gt;OLCRTC_CLIENT_ID=...&amp;lt;/code&amp;gt; — ваше имя пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 7. Замена docker-compose.server.yml ===&lt;br /&gt;
Стандартный compose-файл из репозитория не использует режим &amp;lt;code&amp;gt;host&amp;lt;/code&amp;gt;, который нужен для доступа к локальному xray. Заменим его на нашу версию.&lt;br /&gt;
&lt;br /&gt;
Откройте файл для редактирования.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/olcrtc/docker-compose.server.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Удалите всё содержимое (зажмите &amp;lt;code&amp;gt;Ctrl+K&amp;lt;/code&amp;gt; до полной очистки) и вставьте следующее:&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  olcrtc-server:&lt;br /&gt;
    build:&lt;br /&gt;
      context: .&lt;br /&gt;
    image: olcrtc/server:local&lt;br /&gt;
    container_name: olcrtc-server&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    environment:&lt;br /&gt;
      OLCRTC_MODE: srv&lt;br /&gt;
      OLCRTC_CARRIER: &amp;quot;${OLCRTC_CARRIER:?set OLCRTC_CARRIER}&amp;quot;&lt;br /&gt;
      OLCRTC_TRANSPORT: &amp;quot;${OLCRTC_TRANSPORT:?set OLCRTC_TRANSPORT}&amp;quot;&lt;br /&gt;
      OLCRTC_ROOM_ID: &amp;quot;${OLCRTC_ROOM_ID:?set OLCRTC_ROOM_ID}&amp;quot;&lt;br /&gt;
      OLCRTC_CLIENT_ID: &amp;quot;${OLCRTC_CLIENT_ID:?set OLCRTC_CLIENT_ID}&amp;quot;&lt;br /&gt;
      OLCRTC_KEY: &amp;quot;${OLCRTC_KEY:?set OLCRTC_KEY}&amp;quot;&lt;br /&gt;
      OLCRTC_DNS: &amp;quot;${OLCRTC_DNS:-1.1.1.1:53}&amp;quot;&lt;br /&gt;
      OLCRTC_SOCKS_PROXY: &amp;quot;${OLCRTC_SOCKS_PROXY:-}&amp;quot;&lt;br /&gt;
      OLCRTC_SOCKS_PROXY_PORT: &amp;quot;${OLCRTC_SOCKS_PROXY_PORT:-1080}&amp;quot;&lt;br /&gt;
      OLCRTC_VP8_FPS: &amp;quot;${OLCRTC_VP8_FPS:-60}&amp;quot;&lt;br /&gt;
      OLCRTC_VP8_BATCH: &amp;quot;${OLCRTC_VP8_BATCH:-64}&amp;quot;&lt;br /&gt;
      OLCRTC_DEBUG: &amp;quot;${OLCRTC_DEBUG:-false}&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - olcrtc-state:/var/lib/olcrtc&lt;br /&gt;
    init: true&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  olcrtc-state:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните файл: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 8. Сборка Docker-образа olcRTC ===&lt;br /&gt;
Перейдите в каталог проекта (если ещё не там).&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/olcrtc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Запустите сборку.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f docker-compose.server.yml --env-file .env build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сборка длится 1–3 минуты. Скачиваются зависимости Go и компилируется бинарник. Если в процессе возникает ошибка вида «context canceled» или «network unreachable» — повторите команду; первый прогон бывает прерывистым из-за нестабильности зеркал.&lt;br /&gt;
&lt;br /&gt;
Когда сборка успешно завершится, в выводе появится строка &amp;lt;code&amp;gt;Image olcrtc/server:local Built&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 9. Запуск контейнера ===&lt;br /&gt;
Запустите контейнер в фоновом режиме.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f docker-compose.server.yml --env-file .env up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подождите 15–20 секунд, чтобы сервер успел подключиться к WB Stream и создать виртуальную конференцию.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sleep 20&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Посмотрите логи.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs olcrtc-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидаемый вывод:&lt;br /&gt;
 Connecting link via direct/vp8channel/wbstream...&lt;br /&gt;
 WB Stream room created: 019e07b8-e292-73ec-a40b-6a6e4957ce01&lt;br /&gt;
 To connect client use: -id 019e07b8-e292-73ec-a40b-6a6e4957ce01&lt;br /&gt;
 Link connected&lt;br /&gt;
&#039;&#039;&#039;Скопируйте идентификатор после &amp;lt;code&amp;gt;WB Stream room created:&amp;lt;/code&amp;gt;&#039;&#039;&#039; и впишите его в таблицу подготовки как &amp;lt;code&amp;gt;YOUR_ROOM_ID&amp;lt;/code&amp;gt;. Без этого значения невозможно настроить клиента.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 10. Фиксация room_id в .env ===&lt;br /&gt;
Сейчас в файле &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;OLCRTC_ROOM_ID=any&amp;lt;/code&amp;gt;. Это значение означает «при каждом запуске создавать новую конференцию». Если оставить его — после следующего перезапуска контейнера все ссылки клиентов перестанут работать, потому что комната окажется новой.&lt;br /&gt;
&lt;br /&gt;
Зафиксируйте полученный идентификатор.&lt;br /&gt;
&lt;br /&gt;
Замените &amp;lt;code&amp;gt;YOUR_ROOM_ID&amp;lt;/code&amp;gt; в команде ниже на скопированное значение из шага 9.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sed -i &#039;s/^OLCRTC_ROOM_ID=any$/OLCRTC_ROOM_ID=YOUR_ROOM_ID/&#039; /opt/olcrtc/.env&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Перезапустите контейнер с новым значением.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/olcrtc/docker-compose.server.yml --env-file /opt/olcrtc/.env up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подождите 10 секунд и снова проверьте логи.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sleep 10 &amp;amp;&amp;amp; docker logs --tail 5 olcrtc-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Теперь в логе не должно быть строки &amp;lt;code&amp;gt;WB Stream room created&amp;lt;/code&amp;gt; — должна быть только &amp;lt;code&amp;gt;Connecting link via direct/vp8channel/wbstream...&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Link connected&amp;lt;/code&amp;gt;. Это означает, что сервер заходит в существующую комнату, а не создаёт новую.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 11. Формирование ссылки для клиента ===&lt;br /&gt;
Ссылка имеет фиксированный текстовый формат:&lt;br /&gt;
 olcrtc://CARRIER?TRANSPORT@ROOM_ID#KEY%CLIENT_ID$ПОДПИСЬ&lt;br /&gt;
Подставьте свои значения. Подпись — произвольная строка, которая отобразится в названии локации в клиентском приложении (она не влияет на работу).&lt;br /&gt;
&lt;br /&gt;
Пример итоговой ссылки:&amp;lt;pre&amp;gt;&lt;br /&gt;
olcrtc://wbstream?vp8channel@019e07b8-e292-73ec-a40b-6a6e4957ce01#1c3f8a2b...d4e5f6a7%my-laptop$home laptop, vp8 over wbstream&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Часть ссылки&lt;br /&gt;
!Откуда берётся&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;wbstream&amp;lt;/code&amp;gt;&lt;br /&gt;
|Из &amp;lt;code&amp;gt;OLCRTC_CARRIER&amp;lt;/code&amp;gt; в .env&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vp8channel&amp;lt;/code&amp;gt;&lt;br /&gt;
|Из &amp;lt;code&amp;gt;OLCRTC_TRANSPORT&amp;lt;/code&amp;gt; в .env&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;019e07b8-...&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_ROOM_ID&amp;lt;/code&amp;gt; из шага 9&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;1c3f8a2b...&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_KEY_HEX&amp;lt;/code&amp;gt; из шага 5&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;my-laptop&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_CLIENT_ID&amp;lt;/code&amp;gt; из шага 6&lt;br /&gt;
|-&lt;br /&gt;
|Подпись после &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;&lt;br /&gt;
|Любой описательный текст&lt;br /&gt;
|}&lt;br /&gt;
Сохраните полученную ссылку в надёжное место. Её нужно будет ввести в клиентское приложение.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 12. Подключение клиента ===&lt;br /&gt;
&lt;br /&gt;
==== 12a. Olcbox (Android, рекомендуется для смартфона) ====&lt;br /&gt;
Скачайте APK из репозитория [https://github.com/alananisimov/olcbox alananisimov/olcbox] (раздел Releases) и установите его на телефон.&lt;br /&gt;
&lt;br /&gt;
Откройте приложение. Перейдите в раздел Locations. Нажмите Add → &#039;&#039;&#039;Import from clipboard&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Перед нажатием убедитесь, что в буфере обмена телефона лежит ваша ссылка &amp;lt;code&amp;gt;olcrtc://...&amp;lt;/code&amp;gt; из шага 11. Скопируйте её любым способом — например, отправив самому себе в Telegram-секретный чат.&lt;br /&gt;
&lt;br /&gt;
После импорта откройте созданную локацию и проверьте поля:&lt;br /&gt;
&lt;br /&gt;
* Carrier должен быть &amp;lt;code&amp;gt;wbstream&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Transport должен быть &amp;lt;code&amp;gt;vp8channel&amp;lt;/code&amp;gt;.&lt;br /&gt;
* VP8 FPS — установите &amp;lt;code&amp;gt;60&amp;lt;/code&amp;gt; вручную (при импорте URI этот параметр сбрасывается на дефолт приложения).&lt;br /&gt;
* VP8 Batch — установите &amp;lt;code&amp;gt;64&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Включите тумблер VPN.&lt;br /&gt;
&lt;br /&gt;
==== 12b. CLI-клиент (Linux, macOS, Windows) ====&lt;br /&gt;
Скачайте бинарник olcrtc для своей операционной системы из релизов репозитория или соберите из исходников.&lt;br /&gt;
&lt;br /&gt;
Запустите туннель. Замените все плейсхолдеры &amp;lt;code&amp;gt;YOUR_*&amp;lt;/code&amp;gt; на свои значения из таблицы подготовки.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./olcrtc -mode cnc -carrier wbstream -transport vp8channel -id YOUR_ROOM_ID -client-id YOUR_CLIENT_ID -key YOUR_KEY_HEX -link direct -data data -dns 1.1.1.1:53 -vp8-fps 60 -vp8-batch 64 -socks-host 127.0.0.1 -socks-port 1080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска клиент поднимет локальный SOCKS5-прокси на &amp;lt;code&amp;gt;127.0.0.1:1080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Проверьте, что туннель работает.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl --socks5-hostname 127.0.0.1:1080 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если egress настроен через WARP — должен вернуть IP Cloudflare WARP. Если не настроен — IP вашего сервера. В обоих случаях это &#039;&#039;&#039;не должен быть&#039;&#039;&#039; IP вашего домашнего интернета.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Команды управления одним сервером ==&lt;br /&gt;
Все команды выполняются на сервере по SSH.&lt;br /&gt;
&lt;br /&gt;
Посмотреть логи в реальном времени (для выхода нажать &amp;lt;code&amp;gt;Ctrl+C&amp;lt;/code&amp;gt;).&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f olcrtc-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Посмотреть статус контейнера.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps --filter name=olcrtc-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Перезапустить сервер (например, после изменения .env).&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/olcrtc/docker-compose.server.yml --env-file /opt/olcrtc/.env up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Остановить сервер.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/olcrtc/docker-compose.server.yml --env-file /opt/olcrtc/.env down&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Обновить исходный код до свежей версии master.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/olcrtc &amp;amp;&amp;amp; git pull --recurse-submodules&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Пересобрать образ после обновления кода.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/olcrtc/docker-compose.server.yml --env-file /opt/olcrtc/.env build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Применить новый образ.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/olcrtc/docker-compose.server.yml --env-file /opt/olcrtc/.env up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Управление несколькими пользователями: скрипт &amp;lt;code&amp;gt;olcrtc-users&amp;lt;/code&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
=== Зачем он нужен ===&lt;br /&gt;
Из-за архитектурного ограничения «один сервер — один клиент» (раздел «Принципы работы → Архитектурное ограничение») для каждого пользователя нужен отдельный контейнер со своим room_id, ключом и client_id. Чтобы не повторять шаги установки руками каждый раз, написан bash-скрипт &amp;lt;code&amp;gt;olcrtc-users&amp;lt;/code&amp;gt;, который автоматизирует:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Создание пользователя:&#039;&#039;&#039; генерация ключа, создание контейнера с уникальным client_id, ловля room_id из логов, формирование готовой ссылки.&lt;br /&gt;
* &#039;&#039;&#039;Удаление пользователя:&#039;&#039;&#039; остановка и удаление контейнера, удаление volume и каталога.&lt;br /&gt;
* &#039;&#039;&#039;Просмотр списка и информации:&#039;&#039;&#039; таблица всех пользователей с возможностью получить ссылку по выбору номера.&lt;br /&gt;
&lt;br /&gt;
=== Что получает каждый пользователь ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Атрибут&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Контейнер&lt;br /&gt;
|&amp;lt;code&amp;gt;olcrtc-user-&amp;amp;#x3C;имя&amp;amp;#x3E;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Каталог конфигурации&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/olcrtc-users/&amp;amp;#x3C;имя&amp;amp;#x3E;/&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Файл с переменными&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/olcrtc-users/&amp;amp;#x3C;имя&amp;amp;#x3E;/.env&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Compose project&lt;br /&gt;
|&amp;lt;code&amp;gt;olcrtc-user-&amp;amp;#x3C;имя&amp;amp;#x3E;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Docker volume&lt;br /&gt;
|&amp;lt;code&amp;gt;olcrtc-user-&amp;amp;#x3C;имя&amp;amp;#x3E;_state&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Виртуальная конференция&lt;br /&gt;
|Уникальная, создаётся при первом запуске&lt;br /&gt;
|-&lt;br /&gt;
|Ключ шифрования&lt;br /&gt;
|Уникальный, 32 случайных байта&lt;br /&gt;
|-&lt;br /&gt;
|Ссылка вида &amp;lt;code&amp;gt;olcrtc://...&amp;lt;/code&amp;gt;&lt;br /&gt;
|Уникальная&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Структура каталогов ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/olcrtc/                           # репозиторий + Dockerfile (build context)&lt;br /&gt;
└── (код, не меняется после установки)&lt;br /&gt;
&lt;br /&gt;
/opt/olcrtc-users/                     # каталог менеджера пользователей&lt;br /&gt;
├── shared/&lt;br /&gt;
│   ├── docker-compose.user.yml        # один шаблон compose для всех пользователей&lt;br /&gt;
│   └── defaults.env                   # значения по умолчанию для новых пользователей&lt;br /&gt;
├── alice/&lt;br /&gt;
│   └── .env                           # личные данные пользователя alice&lt;br /&gt;
├── bob/&lt;br /&gt;
│   └── .env&lt;br /&gt;
└── carol/&lt;br /&gt;
    └── .env&lt;br /&gt;
&lt;br /&gt;
/usr/local/bin/olcrtc-users            # сам скрипт-меню&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Установка скрипта ===&lt;br /&gt;
Все команды выполняются на сервере по SSH.&lt;br /&gt;
&lt;br /&gt;
==== Шаг 1. Создание общего каталога ====&lt;br /&gt;
Создайте корневой каталог для пользователей.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/olcrtc-users/shared&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Защитите каталог.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 700 /opt/olcrtc-users&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Шаг 2. Создание общего шаблона docker-compose ====&lt;br /&gt;
Откройте файл для редактирования.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/olcrtc-users/shared/docker-compose.user.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте следующее содержимое.&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  olcrtc:&lt;br /&gt;
    image: olcrtc/server:local&lt;br /&gt;
    container_name: &amp;quot;olcrtc-user-${OLCRTC_CLIENT_ID}&amp;quot;&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    environment:&lt;br /&gt;
      OLCRTC_MODE: srv&lt;br /&gt;
      OLCRTC_CARRIER: &amp;quot;${OLCRTC_CARRIER}&amp;quot;&lt;br /&gt;
      OLCRTC_TRANSPORT: &amp;quot;${OLCRTC_TRANSPORT}&amp;quot;&lt;br /&gt;
      OLCRTC_ROOM_ID: &amp;quot;${OLCRTC_ROOM_ID}&amp;quot;&lt;br /&gt;
      OLCRTC_CLIENT_ID: &amp;quot;${OLCRTC_CLIENT_ID}&amp;quot;&lt;br /&gt;
      OLCRTC_KEY: &amp;quot;${OLCRTC_KEY}&amp;quot;&lt;br /&gt;
      OLCRTC_DNS: &amp;quot;${OLCRTC_DNS}&amp;quot;&lt;br /&gt;
      OLCRTC_SOCKS_PROXY: &amp;quot;${OLCRTC_SOCKS_PROXY}&amp;quot;&lt;br /&gt;
      OLCRTC_SOCKS_PROXY_PORT: &amp;quot;${OLCRTC_SOCKS_PROXY_PORT}&amp;quot;&lt;br /&gt;
      OLCRTC_VP8_FPS: &amp;quot;${OLCRTC_VP8_FPS}&amp;quot;&lt;br /&gt;
      OLCRTC_VP8_BATCH: &amp;quot;${OLCRTC_VP8_BATCH}&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - state:/var/lib/olcrtc&lt;br /&gt;
    init: true&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  state:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Шаг 3. Создание файла значений по умолчанию ====&lt;br /&gt;
Откройте файл для редактирования.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/olcrtc-users/shared/defaults.env&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте следующее (если используете egress через WARP — оставьте порт &amp;lt;code&amp;gt;24365&amp;lt;/code&amp;gt; или замените на свой &amp;lt;code&amp;gt;YOUR_SOCKS_PORT&amp;lt;/code&amp;gt;).&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
OLCRTC_CARRIER=wbstream&lt;br /&gt;
OLCRTC_TRANSPORT=vp8channel&lt;br /&gt;
OLCRTC_DNS=1.1.1.1:53&lt;br /&gt;
OLCRTC_SOCKS_PROXY=127.0.0.1&lt;br /&gt;
OLCRTC_SOCKS_PROXY_PORT=24365&lt;br /&gt;
OLCRTC_VP8_FPS=60&lt;br /&gt;
OLCRTC_VP8_BATCH=64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните файл: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Защитите файл.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /opt/olcrtc-users/shared/defaults.env&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если egress через WARP вам &#039;&#039;&#039;не нужен&#039;&#039;&#039;, выполните дополнительную команду — она очистит поле SOCKS-прокси.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sed -i &#039;s|OLCRTC_SOCKS_PROXY=127.0.0.1|OLCRTC_SOCKS_PROXY=|&#039; /opt/olcrtc-users/shared/defaults.env&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Шаг 4. Создание самого скрипта ====&lt;br /&gt;
Откройте файл скрипта в редакторе.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /usr/local/bin/olcrtc-users&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте полное содержимое скрипта (исходный код целиком — в спойлере «Исходный код скрипта &amp;lt;code&amp;gt;olcrtc-users&amp;lt;/code&amp;gt;» в конце статьи).&lt;br /&gt;
&lt;br /&gt;
Сохраните файл: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сделайте файл исполняемым.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 0755 /usr/local/bin/olcrtc-users&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Проверьте корректность синтаксиса.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
bash -n /usr/local/bin/olcrtc-users &amp;amp;&amp;amp; echo OK&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если в выводе &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt; — скрипт установлен правильно.&lt;br /&gt;
&lt;br /&gt;
=== Использование скрипта ===&lt;br /&gt;
Запустите.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
olcrtc-users&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Появится меню:&amp;lt;pre&amp;gt;&lt;br /&gt;
=== olcrtc users ===&lt;br /&gt;
  1) Список пользователей (выбор → ссылка)&lt;br /&gt;
  2) Создать пользователя&lt;br /&gt;
  3) Удалить пользователя&lt;br /&gt;
  0) Выход&lt;br /&gt;
&amp;gt; _&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Пункт 1: список пользователей ====&lt;br /&gt;
После выбора отобразится таблица:&amp;lt;pre&amp;gt;&lt;br /&gt;
    #  name                           status&lt;br /&gt;
  ---  ------------------------------ ------------&lt;br /&gt;
    1) alice                          running&lt;br /&gt;
    2) bob                            running&lt;br /&gt;
    3) carol                          exited&lt;br /&gt;
&amp;lt;/pre&amp;gt;Введите номер пользователя и нажмите &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; — появится полная карточка с готовой ссылкой &amp;lt;code&amp;gt;olcrtc://...&amp;lt;/code&amp;gt;:&amp;lt;pre&amp;gt;&lt;br /&gt;
name        : alice&lt;br /&gt;
status      : running&lt;br /&gt;
carrier     : wbstream&lt;br /&gt;
transport   : vp8channel&lt;br /&gt;
room_id     : 019e07b8-e292-73ec-a40b-6a6e4957ce01&lt;br /&gt;
client_id   : alice&lt;br /&gt;
key         : 1c3f8a2b...d4e5f6a7&lt;br /&gt;
&lt;br /&gt;
URI for olcbox:&lt;br /&gt;
olcrtc://wbstream?vp8channel@019e07b8-e292-73ec-a40b-6a6e4957ce01#1c3f8a2b...d4e5f6a7%alice$alice&lt;br /&gt;
&amp;lt;/pre&amp;gt;Чтобы пропустить выбор и вернуться в меню — нажмите &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; без ввода номера.&lt;br /&gt;
&lt;br /&gt;
==== Пункт 2: создание пользователя ====&lt;br /&gt;
Скрипт спросит имя.&amp;lt;pre&amp;gt;&lt;br /&gt;
Имя пользователя:&lt;br /&gt;
&amp;lt;/pre&amp;gt;Введите имя на латинице (буквы, цифры, &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;, длина 1–32 символа), например &amp;lt;code&amp;gt;alice&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Затем спросит, как получить ключ.&amp;lt;pre&amp;gt;&lt;br /&gt;
Ключ шифрования: [a]uto / [m]anual (по умолчанию a):&lt;br /&gt;
&amp;lt;/pre&amp;gt;Введите &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; (или просто нажмите &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;) — скрипт сгенерирует ключ автоматически.&lt;br /&gt;
&lt;br /&gt;
Если хотите ввести ключ вручную — введите &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; и затем 64-символьный hex-ключ.&lt;br /&gt;
&lt;br /&gt;
После этого скрипт сам:&lt;br /&gt;
&lt;br /&gt;
* создаст каталог пользователя;&lt;br /&gt;
* запустит контейнер;&lt;br /&gt;
* подождёт создания виртуальной конференции;&lt;br /&gt;
* запишет полученный room_id в .env;&lt;br /&gt;
* перезапустит контейнер с фиксированным room_id;&lt;br /&gt;
* выведет готовую карточку с ссылкой.&lt;br /&gt;
&lt;br /&gt;
==== Пункт 3: удаление пользователя ====&lt;br /&gt;
Скрипт покажет список.&amp;lt;pre&amp;gt;&lt;br /&gt;
    1) alice&lt;br /&gt;
    2) bob&lt;br /&gt;
    3) carol&lt;br /&gt;
&amp;lt;/pre&amp;gt;Введите номер удаляемого пользователя, нажмите &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Скрипт спросит подтверждение.&amp;lt;pre&amp;gt;&lt;br /&gt;
Удалить пользователя &amp;quot;carol&amp;quot;? (y/N):&lt;br /&gt;
&amp;lt;/pre&amp;gt;Введите &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; и нажмите &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;. Если введёте что-то другое или просто &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; — операция отменится.&lt;br /&gt;
&lt;br /&gt;
После подтверждения:&lt;br /&gt;
&lt;br /&gt;
* контейнер будет остановлен и удалён;&lt;br /&gt;
* docker volume будет удалён;&lt;br /&gt;
* каталог пользователя будет удалён;&lt;br /&gt;
* ссылка &amp;lt;code&amp;gt;olcrtc://...&amp;lt;/code&amp;gt; у этого пользователя &#039;&#039;&#039;перестанет работать&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Исходный код скрипта olcrtc-users ==&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
!Развернуть полный исходный код и подробное объяснение архитектуры скрипта&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
=== Полный исходный код ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env bash&lt;br /&gt;
# olcrtc-users — управление пользователями olcrtc через docker compose.&lt;br /&gt;
# UI: 3 пункта (список / создать / удалить), под капотом — отдельный контейнер на пользователя.&lt;br /&gt;
&lt;br /&gt;
set -euo pipefail&lt;br /&gt;
&lt;br /&gt;
USERS_DIR=/opt/olcrtc-users&lt;br /&gt;
SHARED=$USERS_DIR/shared&lt;br /&gt;
COMPOSE=$SHARED/docker-compose.user.yml&lt;br /&gt;
DEFAULTS=$SHARED/defaults.env&lt;br /&gt;
&lt;br /&gt;
if [ ! -f &amp;quot;$COMPOSE&amp;quot; ] || [ ! -f &amp;quot;$DEFAULTS&amp;quot; ]; then&lt;br /&gt;
    echo &amp;quot;[X] $SHARED is not initialized. Aborting.&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# ----- helpers -----&lt;br /&gt;
list_users() {&lt;br /&gt;
    find &amp;quot;$USERS_DIR&amp;quot; -mindepth 1 -maxdepth 1 -type d ! -name shared -printf &amp;quot;%f\n&amp;quot; | sort&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
container_status() {&lt;br /&gt;
    docker inspect -f &amp;quot;{{.State.Status}}&amp;quot; &amp;quot;olcrtc-user-$1&amp;quot; 2&amp;gt;/dev/null || echo &amp;quot;missing&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
read_env() {&lt;br /&gt;
    local f=$1 k=$2&lt;br /&gt;
    grep -E &amp;quot;^${k}=&amp;quot; &amp;quot;$f&amp;quot; | cut -d= -f2-&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
build_uri() {&lt;br /&gt;
    local f=$1&lt;br /&gt;
    local carrier transport room key cid&lt;br /&gt;
    carrier=$(read_env &amp;quot;$f&amp;quot; OLCRTC_CARRIER)&lt;br /&gt;
    transport=$(read_env &amp;quot;$f&amp;quot; OLCRTC_TRANSPORT)&lt;br /&gt;
    room=$(read_env &amp;quot;$f&amp;quot; OLCRTC_ROOM_ID)&lt;br /&gt;
    key=$(read_env &amp;quot;$f&amp;quot; OLCRTC_KEY)&lt;br /&gt;
    cid=$(read_env &amp;quot;$f&amp;quot; OLCRTC_CLIENT_ID)&lt;br /&gt;
    printf &amp;quot;olcrtc://%s?%s@%s#%s%%%s\$%s\n&amp;quot; \&lt;br /&gt;
        &amp;quot;$carrier&amp;quot; &amp;quot;$transport&amp;quot; &amp;quot;$room&amp;quot; &amp;quot;$key&amp;quot; &amp;quot;$cid&amp;quot; &amp;quot;$cid&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
show_user() {&lt;br /&gt;
    local user=$1&lt;br /&gt;
    local f=$USERS_DIR/$user/.env&lt;br /&gt;
    local status; status=$(container_status &amp;quot;$user&amp;quot;)&lt;br /&gt;
    echo &amp;quot;name        : $user&amp;quot;&lt;br /&gt;
    echo &amp;quot;status      : $status&amp;quot;&lt;br /&gt;
    echo &amp;quot;carrier     : $(read_env &amp;quot;$f&amp;quot; OLCRTC_CARRIER)&amp;quot;&lt;br /&gt;
    echo &amp;quot;transport   : $(read_env &amp;quot;$f&amp;quot; OLCRTC_TRANSPORT)&amp;quot;&lt;br /&gt;
    echo &amp;quot;room_id     : $(read_env &amp;quot;$f&amp;quot; OLCRTC_ROOM_ID)&amp;quot;&lt;br /&gt;
    echo &amp;quot;client_id   : $(read_env &amp;quot;$f&amp;quot; OLCRTC_CLIENT_ID)&amp;quot;&lt;br /&gt;
    echo &amp;quot;key         : $(read_env &amp;quot;$f&amp;quot; OLCRTC_KEY)&amp;quot;&lt;br /&gt;
    echo&lt;br /&gt;
    echo &amp;quot;URI for olcbox:&amp;quot;&lt;br /&gt;
    build_uri &amp;quot;$f&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
valid_name() { [[ &amp;quot;$1&amp;quot; =~ ^[a-zA-Z0-9_-]{1,32}$ ]]; }&lt;br /&gt;
&lt;br /&gt;
compose_up() {&lt;br /&gt;
    local user=$1&lt;br /&gt;
    docker compose -f &amp;quot;$COMPOSE&amp;quot; --env-file &amp;quot;$USERS_DIR/$user/.env&amp;quot; \&lt;br /&gt;
        -p &amp;quot;olcrtc-user-$user&amp;quot; up -d&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
compose_down() {&lt;br /&gt;
    local user=$1&lt;br /&gt;
    docker compose -f &amp;quot;$COMPOSE&amp;quot; --env-file &amp;quot;$USERS_DIR/$user/.env&amp;quot; \&lt;br /&gt;
        -p &amp;quot;olcrtc-user-$user&amp;quot; down -v&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# ----- menu actions -----&lt;br /&gt;
action_list() {&lt;br /&gt;
    mapfile -t users &amp;lt; &amp;lt;(list_users)&lt;br /&gt;
    if [ ${#users[@]} -eq 0 ]; then&lt;br /&gt;
        echo &amp;quot;(пользователей нет)&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
    printf &amp;quot;  %3s  %-30s %-12s\n&amp;quot; &amp;quot;#&amp;quot; &amp;quot;name&amp;quot; &amp;quot;status&amp;quot;&lt;br /&gt;
    printf &amp;quot;  %3s  %-30s %-12s\n&amp;quot; &amp;quot;---&amp;quot; &amp;quot;------------------------------&amp;quot; &amp;quot;------------&amp;quot;&lt;br /&gt;
    local i&lt;br /&gt;
    for i in &amp;quot;${!users[@]}&amp;quot;; do&lt;br /&gt;
        printf &amp;quot;  %3d) %-30s %-12s\n&amp;quot; \&lt;br /&gt;
            &amp;quot;$((i+1))&amp;quot; &amp;quot;${users[$i]}&amp;quot; &amp;quot;$(container_status &amp;quot;${users[$i]}&amp;quot;)&amp;quot;&lt;br /&gt;
    done&lt;br /&gt;
    echo&lt;br /&gt;
    read -rp &amp;quot;Введите номер чтобы показать ссылку (Enter — пропустить): &amp;quot; pick&lt;br /&gt;
    [ -z &amp;quot;$pick&amp;quot; ] &amp;amp;&amp;amp; return&lt;br /&gt;
    if ! [[ &amp;quot;$pick&amp;quot; =~ ^[0-9]+$ ]] || [ &amp;quot;$pick&amp;quot; -lt 1 ] || [ &amp;quot;$pick&amp;quot; -gt &amp;quot;${#users[@]}&amp;quot; ]; then&lt;br /&gt;
        echo &amp;quot;(неверный номер)&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
    echo&lt;br /&gt;
    show_user &amp;quot;${users[$((pick-1))]}&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
action_new() {&lt;br /&gt;
    read -rp &amp;quot;Имя пользователя: &amp;quot; name&lt;br /&gt;
    if ! valid_name &amp;quot;$name&amp;quot;; then&lt;br /&gt;
        echo &amp;quot;(имя должно быть 1..32 символа, только a-z A-Z 0-9 _ -)&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
    if [ -d &amp;quot;$USERS_DIR/$name&amp;quot; ]; then&lt;br /&gt;
        echo &amp;quot;(пользователь \&amp;quot;$name\&amp;quot; уже существует)&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    local key&lt;br /&gt;
    read -rp &amp;quot;Ключ шифрования: [a]uto / [m]anual (по умолчанию a): &amp;quot; mode&lt;br /&gt;
    case &amp;quot;${mode:-a}&amp;quot; in&lt;br /&gt;
        m|M)&lt;br /&gt;
            read -rp &amp;quot;Введите 64-символьный hex-ключ: &amp;quot; key&lt;br /&gt;
            if ! [[ &amp;quot;$key&amp;quot; =~ ^[0-9a-fA-F]{64}$ ]]; then&lt;br /&gt;
                echo &amp;quot;(не выглядит как 64-hex)&amp;quot;&lt;br /&gt;
                return&lt;br /&gt;
            fi&lt;br /&gt;
            ;;&lt;br /&gt;
        *)&lt;br /&gt;
            key=$(openssl rand -hex 32)&lt;br /&gt;
            echo &amp;quot;[*] сгенерирован ключ: $key&amp;quot;&lt;br /&gt;
            ;;&lt;br /&gt;
    esac&lt;br /&gt;
&lt;br /&gt;
    mkdir -p &amp;quot;$USERS_DIR/$name&amp;quot;&lt;br /&gt;
    # shellcheck disable=SC1090&lt;br /&gt;
    set -a; source &amp;quot;$DEFAULTS&amp;quot;; set +a&lt;br /&gt;
    cat &amp;gt; &amp;quot;$USERS_DIR/$name/.env&amp;quot; &amp;lt;&amp;lt;EOF&lt;br /&gt;
OLCRTC_CARRIER=$OLCRTC_CARRIER&lt;br /&gt;
OLCRTC_TRANSPORT=$OLCRTC_TRANSPORT&lt;br /&gt;
OLCRTC_ROOM_ID=any&lt;br /&gt;
OLCRTC_CLIENT_ID=$name&lt;br /&gt;
OLCRTC_KEY=$key&lt;br /&gt;
OLCRTC_DNS=$OLCRTC_DNS&lt;br /&gt;
OLCRTC_SOCKS_PROXY=$OLCRTC_SOCKS_PROXY&lt;br /&gt;
OLCRTC_SOCKS_PROXY_PORT=$OLCRTC_SOCKS_PROXY_PORT&lt;br /&gt;
OLCRTC_VP8_FPS=$OLCRTC_VP8_FPS&lt;br /&gt;
OLCRTC_VP8_BATCH=$OLCRTC_VP8_BATCH&lt;br /&gt;
EOF&lt;br /&gt;
    chmod 600 &amp;quot;$USERS_DIR/$name/.env&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    echo &amp;quot;[*] стартую контейнер...&amp;quot;&lt;br /&gt;
    compose_up &amp;quot;$name&amp;quot; &amp;gt;/dev/null&lt;br /&gt;
    echo &amp;quot;[*] жду создания комнаты WB Stream...&amp;quot;&lt;br /&gt;
    local room=&amp;quot;&amp;quot;&lt;br /&gt;
    local i&lt;br /&gt;
    for i in $(seq 1 30); do&lt;br /&gt;
        sleep 2&lt;br /&gt;
        room=$(docker logs &amp;quot;olcrtc-user-$name&amp;quot; 2&amp;gt;&amp;amp;1 \&lt;br /&gt;
            | grep -oE &amp;quot;WB Stream room created: [0-9a-f-]+&amp;quot; \&lt;br /&gt;
            | head -1 | awk &amp;quot;{print \$NF}&amp;quot;)&lt;br /&gt;
        [ -n &amp;quot;$room&amp;quot; ] &amp;amp;&amp;amp; break&lt;br /&gt;
    done&lt;br /&gt;
    if [ -z &amp;quot;$room&amp;quot; ]; then&lt;br /&gt;
        echo &amp;quot;[!] не удалось получить room_id. Логи:&amp;quot;&lt;br /&gt;
        docker logs --tail 30 &amp;quot;olcrtc-user-$name&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
    echo &amp;quot;[+] комната создана: $room&amp;quot;&lt;br /&gt;
    sed -i &amp;quot;s/^OLCRTC_ROOM_ID=any\$/OLCRTC_ROOM_ID=$room/&amp;quot; &amp;quot;$USERS_DIR/$name/.env&amp;quot;&lt;br /&gt;
    compose_up &amp;quot;$name&amp;quot; &amp;gt;/dev/null&lt;br /&gt;
    sleep 3&lt;br /&gt;
    echo&lt;br /&gt;
    show_user &amp;quot;$name&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
action_delete() {&lt;br /&gt;
    mapfile -t users &amp;lt; &amp;lt;(list_users)&lt;br /&gt;
    if [ ${#users[@]} -eq 0 ]; then&lt;br /&gt;
        echo &amp;quot;(пользователей нет)&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
    local i&lt;br /&gt;
    for i in &amp;quot;${!users[@]}&amp;quot;; do&lt;br /&gt;
        printf &amp;quot;  %3d) %s\n&amp;quot; &amp;quot;$((i+1))&amp;quot; &amp;quot;${users[$i]}&amp;quot;&lt;br /&gt;
    done&lt;br /&gt;
    echo&lt;br /&gt;
    read -rp &amp;quot;Номер удаляемого: &amp;quot; pick&lt;br /&gt;
    if ! [[ &amp;quot;$pick&amp;quot; =~ ^[0-9]+$ ]] || [ &amp;quot;$pick&amp;quot; -lt 1 ] || [ &amp;quot;$pick&amp;quot; -gt &amp;quot;${#users[@]}&amp;quot; ]; then&lt;br /&gt;
        echo &amp;quot;(неверный номер)&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
    local user=${users[$((pick-1))]}&lt;br /&gt;
    read -rp &amp;quot;Удалить пользователя \&amp;quot;$user\&amp;quot;? (y/N): &amp;quot; conf&lt;br /&gt;
    if ! [[ &amp;quot;$conf&amp;quot; =~ ^[yY]$ ]]; then&lt;br /&gt;
        echo &amp;quot;(отменено)&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
    compose_down &amp;quot;$user&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || true&lt;br /&gt;
    rm -rf &amp;quot;${USERS_DIR:?}/$user&amp;quot;&lt;br /&gt;
    echo &amp;quot;[+] пользователь $user удалён&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# ----- main -----&lt;br /&gt;
while true; do&lt;br /&gt;
    echo&lt;br /&gt;
    echo &amp;quot;=== olcrtc users ===&amp;quot;&lt;br /&gt;
    echo &amp;quot;  1) Список пользователей (выбор → ссылка)&amp;quot;&lt;br /&gt;
    echo &amp;quot;  2) Создать пользователя&amp;quot;&lt;br /&gt;
    echo &amp;quot;  3) Удалить пользователя&amp;quot;&lt;br /&gt;
    echo &amp;quot;  0) Выход&amp;quot;&lt;br /&gt;
    read -rp &amp;quot;&amp;gt; &amp;quot; choice&lt;br /&gt;
    case &amp;quot;$choice&amp;quot; in&lt;br /&gt;
        1) action_list ;;&lt;br /&gt;
        2) action_new ;;&lt;br /&gt;
        3) action_delete ;;&lt;br /&gt;
        0|q|Q|&amp;quot;&amp;quot;) exit 0 ;;&lt;br /&gt;
        *) echo &amp;quot;(неверный выбор)&amp;quot; ;;&lt;br /&gt;
    esac&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Устройство скрипта ===&lt;br /&gt;
&lt;br /&gt;
==== Общий принцип ====&lt;br /&gt;
Скрипт — это интерактивная обёртка над &amp;lt;code&amp;gt;docker compose&amp;lt;/code&amp;gt;. Никакой собственной бизнес-логики у него нет — все действия сводятся к запуску и остановке контейнеров с разными параметрами.&lt;br /&gt;
&lt;br /&gt;
Каждый пользователь — это отдельный compose-проект с уникальным именем &amp;lt;code&amp;gt;olcrtc-user-&amp;amp;#x3C;имя&amp;amp;#x3E;&amp;lt;/code&amp;gt;. Compose-файл единый для всех (&amp;lt;code&amp;gt;shared/docker-compose.user.yml&amp;lt;/code&amp;gt;); различия задаются через &amp;lt;code&amp;gt;--env-file&amp;lt;/code&amp;gt;, который указывает на личный &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; пользователя.&lt;br /&gt;
&lt;br /&gt;
==== Защитные механизмы ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;set -euo pipefail&amp;lt;/code&amp;gt; — прерывание при любой ошибке, защита от использования несуществующих переменных, корректная обработка пайпов.&lt;br /&gt;
* Проверка наличия &amp;lt;code&amp;gt;shared/&amp;lt;/code&amp;gt; в самом начале — скрипт не запустится в неинициализированной системе.&lt;br /&gt;
* Валидация имени по регулярному выражению &amp;lt;code&amp;gt;^[a-zA-Z0-9_-]{1,32}$&amp;lt;/code&amp;gt; — защита от инъекций в имена контейнеров и путей файловой системы.&lt;br /&gt;
* Валидация ключа по регулярному выражению &amp;lt;code&amp;gt;^[0-9a-fA-F]{64}$&amp;lt;/code&amp;gt; — защита от неправильного формата при ручном вводе.&lt;br /&gt;
* Подтверждение &amp;lt;code&amp;gt;(y/N)&amp;lt;/code&amp;gt; при удалении — защита от случайного удаления.&lt;br /&gt;
* Конструкция &amp;lt;code&amp;gt;${USERS_DIR:?}&amp;lt;/code&amp;gt; в &amp;lt;code&amp;gt;rm -rf&amp;lt;/code&amp;gt; — защита от случайного &amp;lt;code&amp;gt;rm -rf /&amp;lt;/code&amp;gt;, если переменная окажется пустой.&lt;br /&gt;
&lt;br /&gt;
==== Хелперы ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Функция&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;list_users()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Возвращает список всех пользователей. Использует &amp;lt;code&amp;gt;find&amp;lt;/code&amp;gt; с фильтром &amp;lt;code&amp;gt;-mindepth 1 -maxdepth 1 -type d&amp;lt;/code&amp;gt; и исключает каталог &amp;lt;code&amp;gt;shared&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;container_status()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Опрашивает Docker через &amp;lt;code&amp;gt;docker inspect -f {{.State.Status}}&amp;lt;/code&amp;gt;. При отсутствии контейнера возвращает строку &amp;lt;code&amp;gt;missing&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;read_env()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Читает значение переменной из &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;grep + cut&amp;lt;/code&amp;gt;. Не использует &amp;lt;code&amp;gt;source&amp;lt;/code&amp;gt;, чтобы избежать побочных эффектов от загрузки переменных.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;build_uri()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Конкатенирует значения переменных в URI &amp;lt;code&amp;gt;olcrtc://CARRIER?TRANSPORT@ROOM#KEY%CID$MIMO&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;show_user()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Полная карточка пользователя: статус, все поля, готовый URI.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;valid_name()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Проверка имени пользователя по регулярному выражению.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;compose_up()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;compose_down()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запуск и остановка контейнера через &amp;lt;code&amp;gt;docker compose&amp;lt;/code&amp;gt; с правильными флагами &amp;lt;code&amp;gt;-f&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;--env-file&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-p&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Действие «Список пользователей» ====&lt;br /&gt;
&lt;br /&gt;
# Получает массив пользователей в переменной &amp;lt;code&amp;gt;users&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;mapfile&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Печатает заголовок таблицы.&lt;br /&gt;
# Для каждого пользователя печатает номер, имя и статус контейнера.&lt;br /&gt;
# Спрашивает номер. Пустой ввод — выход. Невалидный номер — сообщение об ошибке.&lt;br /&gt;
# При корректном выборе вызывает &amp;lt;code&amp;gt;show_user&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Действие «Создать пользователя» ====&lt;br /&gt;
&lt;br /&gt;
# Запрашивает имя, валидирует.&lt;br /&gt;
# Проверяет, что каталог &amp;lt;code&amp;gt;$USERS_DIR/$name&amp;lt;/code&amp;gt; ещё не существует.&lt;br /&gt;
# Запрашивает режим ключа: &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; (auto, по умолчанию) или &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; (manual).&lt;br /&gt;
# При auto вызывает &amp;lt;code&amp;gt;openssl rand -hex 32&amp;lt;/code&amp;gt;; при manual запрашивает и валидирует ввод.&lt;br /&gt;
# Создаёт каталог пользователя.&lt;br /&gt;
# Через &amp;lt;code&amp;gt;set -a; source $DEFAULTS; set +a&amp;lt;/code&amp;gt; подгружает дефолты в окружение.&lt;br /&gt;
# Записывает &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; пользователя через here-doc.&lt;br /&gt;
# Меняет права на &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; на &amp;lt;code&amp;gt;0600&amp;lt;/code&amp;gt; (только владелец).&lt;br /&gt;
# Запускает контейнер через &amp;lt;code&amp;gt;compose_up&amp;lt;/code&amp;gt;.&lt;br /&gt;
# В цикле до 60 секунд (&amp;lt;code&amp;gt;30 итераций × 2 сек&amp;lt;/code&amp;gt;) парсит логи контейнера регулярным выражением &amp;lt;code&amp;gt;WB Stream room created: [0-9a-f-]+&amp;lt;/code&amp;gt;.&lt;br /&gt;
# При получении room_id обновляет &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;sed -i&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Перезапускает контейнер с фиксированным room_id.&lt;br /&gt;
# Выводит карточку пользователя через &amp;lt;code&amp;gt;show_user&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Действие «Удалить пользователя» ====&lt;br /&gt;
&lt;br /&gt;
# Получает массив пользователей.&lt;br /&gt;
# Печатает пронумерованный список.&lt;br /&gt;
# Запрашивает номер, валидирует.&lt;br /&gt;
# Запрашивает подтверждение &amp;lt;code&amp;gt;(y/N)&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Вызывает &amp;lt;code&amp;gt;compose_down&amp;lt;/code&amp;gt; с флагом &amp;lt;code&amp;gt;-v&amp;lt;/code&amp;gt; — это удалит и docker volume.&lt;br /&gt;
# Удаляет каталог пользователя через &amp;lt;code&amp;gt;rm -rf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Главный цикл ====&lt;br /&gt;
Бесконечный цикл с &amp;lt;code&amp;gt;case&amp;lt;/code&amp;gt;-разбором ввода:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; → действие «Список»&lt;br /&gt;
* &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; → действие «Создать»&lt;br /&gt;
* &amp;lt;code&amp;gt;3&amp;lt;/code&amp;gt; → действие «Удалить»&lt;br /&gt;
* &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt;, пустой ввод (Enter, Ctrl+D) → выход.&lt;br /&gt;
* Любой другой ввод — сообщение «неверный выбор» и продолжение цикла.&lt;br /&gt;
&lt;br /&gt;
=== Возможные расширения ===&lt;br /&gt;
Скрипт намеренно простой и легко расширяется. Возможные улучшения:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Что добавить&lt;br /&gt;
!Как&lt;br /&gt;
|-&lt;br /&gt;
|Перезапуск отдельного пользователя&lt;br /&gt;
|Новый пункт меню → &amp;lt;code&amp;gt;compose_down&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;compose_up&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Просмотр логов пользователя&lt;br /&gt;
|&amp;lt;code&amp;gt;docker logs --tail 50 olcrtc-user-$name&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Экспорт всех URI в файл подписки&lt;br /&gt;
|Цикл по &amp;lt;code&amp;gt;list_users&amp;lt;/code&amp;gt;, на каждом — &amp;lt;code&amp;gt;build_uri&amp;lt;/code&amp;gt;; добавить заголовок согласно &amp;lt;code&amp;gt;docs/sub.md&amp;lt;/code&amp;gt; upstream-репозитория&lt;br /&gt;
|-&lt;br /&gt;
|Автоматическое обновление образа&lt;br /&gt;
|&amp;lt;code&amp;gt;git -C /opt/olcrtc pull --recurse-submodules&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;docker compose build&amp;lt;/code&amp;gt;, затем перезапуск всех пользователей&lt;br /&gt;
|-&lt;br /&gt;
|HTTPS-эндпоинт &amp;lt;code&amp;gt;/sub&amp;lt;/code&amp;gt; для раздачи конфигов&lt;br /&gt;
|Reverse proxy (caddy / nginx) на статический файл, который генерируется крон-задачей из &amp;lt;code&amp;gt;build_uri&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
=== Почему «один сервер ↔ один клиент»? ===&lt;br /&gt;
Это архитектурное свойство кода: сервер хранит одну сессию &amp;lt;code&amp;gt;smux&amp;lt;/code&amp;gt; и одно поле &amp;lt;code&amp;gt;clientID&amp;lt;/code&amp;gt;, не таблицу пиров. Изменение этой модели потребовало бы существенной переработки &amp;lt;code&amp;gt;internal/server/server.go&amp;lt;/code&amp;gt; и поддержки множественных peer-connection в каждом провайдере.&lt;br /&gt;
&lt;br /&gt;
=== Почему рекомендуется &amp;lt;code&amp;gt;vp8channel&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;datachannel&amp;lt;/code&amp;gt;? ===&lt;br /&gt;
&amp;lt;code&amp;gt;datachannel&amp;lt;/code&amp;gt; быстрее и имеет минимальный пинг, но: Telemost его не поддерживает, а Jazz может ограничивать IP-адреса серверов, использующих этот тип канала. &amp;lt;code&amp;gt;vp8channel&amp;lt;/code&amp;gt; работает со всеми тремя сервисами и подходит для большинства сценариев.&lt;br /&gt;
&lt;br /&gt;
=== Что такое «ограничение IP» со стороны carrier? ===&lt;br /&gt;
Некоторые carrier-сервисы используют автоматические эвристики против ботов. После срабатывания таких эвристик подключения с конкретного IP могут перестать пропускаться в виртуальные конференции. Лечится сменой IP сервера или ожиданием снятия ограничения. На момент написания статьи WB Stream таких эвристик не применяет.&lt;br /&gt;
&lt;br /&gt;
=== Сколько контейнеров можно запустить на одной виртуальной машине? ===&lt;br /&gt;
В простое каждый контейнер потребляет приблизительно 10–15 МБ RAM и около 0% CPU. На VM с 4 GiB RAM реалистично запустить 50–100 пользователей. Узкими местами обычно становятся пропускная способность сетевого канала и допустимое количество одновременных WebRTC-сессий со стороны carrier-сервиса.&lt;br /&gt;
&lt;br /&gt;
=== Можно ли использовать одну ссылку с нескольких устройств? ===&lt;br /&gt;
Технически — да, но не одновременно. Если включить туннель на двух устройствах с одной ссылкой, они будут конкурировать за один peer-connection и периодически разрывать друг друга. Для параллельной работы нужны разные пользователи (разные ссылки).&lt;br /&gt;
&lt;br /&gt;
=== Виден ли реальный видеосигнал участникам конференции? ===&lt;br /&gt;
В транспортах &amp;lt;code&amp;gt;vp8channel&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;seichannel&amp;lt;/code&amp;gt; поверх WebRTC отправляется минимально валидный видеопоток, в который встроены полезные данные. Внешне это выглядит как очень тихая «моностатичная» камера. В &amp;lt;code&amp;gt;videochannel&amp;lt;/code&amp;gt; отправляется реальный видеоряд (QR-коды или тайлы) — формально это видимая «картинка». Если в виртуальной конференции, кроме сервера и клиента, никого нет — это никак не проявляется.&lt;br /&gt;
&lt;br /&gt;
=== Что делать, если конкретный transport перестал работать? ===&lt;br /&gt;
Если carrier изменил проверки SFU и какой-то transport стал ненадёжен — переключитесь на другой transport (&amp;lt;code&amp;gt;seichannel&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;videochannel&amp;lt;/code&amp;gt;) или другой carrier. Меняется в &amp;lt;code&amp;gt;defaults.env&amp;lt;/code&amp;gt; для новых пользователей и в личном &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; для существующих (с последующим перезапуском контейнера).&lt;br /&gt;
&lt;br /&gt;
=== Можно ли совместить olcRTC с другими методами? ===&lt;br /&gt;
Да. С точки зрения клиентского приложения olcRTC — это локальный SOCKS5-прокси. Его можно использовать как один из outbound в xray, sing-box и подобных инструментах. На стороне сервера выходной трафик может быть направлен через xray + WARP (опциональный шаг 11 раздела установки) для дополнительной анонимизации.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Полезные ссылки ==&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/openlibrecommunity/olcrtc Репозиторий olcrtc на GitHub] — основной upstream проекта.&lt;br /&gt;
* [https://github.com/alananisimov/olcbox Olcbox] — мультиплатформенный клиент с UI (Android, macOS, Windows, Linux).&lt;br /&gt;
* [https://github.com/openlibrecommunity/olcrtc/blob/master/docs/uri.md docs/uri.md] — официальное описание формата URI.&lt;br /&gt;
* [https://github.com/openlibrecommunity/olcrtc/blob/master/docs/sub.md docs/sub.md] — формат файла подписки для нескольких локаций.&lt;br /&gt;
* [https://github.com/openlibrecommunity/olcrtc/blob/master/docs/settings.md docs/settings.md] — матрица совместимости carrier × transport, описание всех флагов.&lt;br /&gt;
* [https://github.com/MHSanaei/3x-ui 3x-ui] — панель управления xray-core (для настройки egress через WARP).&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Olcrtc-data-flow.png&amp;diff=963</id>
		<title>Файл:Olcrtc-data-flow.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Olcrtc-data-flow.png&amp;diff=963"/>
		<updated>2026-05-09T07:55:30Z</updated>

		<summary type="html">&lt;p&gt;Владимир: Поток данных olcRTC: от клиентского приложения через SOCKS5, smux + ChaCha20-Poly1305, транспорт и WebRTC peer-connection в видеоконференции, до серверного outbound и целевого сайта&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Краткое описание ==&lt;br /&gt;
Поток данных olcRTC: от клиентского приложения через SOCKS5, smux + ChaCha20-Poly1305, транспорт и WebRTC peer-connection в видеоконференции, до серверного outbound и целевого сайта&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=OlcRTC:_%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D1%8C_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_WebRTC-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D1%8B&amp;diff=962</id>
		<title>OlcRTC: туннель через WebRTC-сервисы</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=OlcRTC:_%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D1%8C_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_WebRTC-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D1%8B&amp;diff=962"/>
		<updated>2026-05-09T07:42:53Z</updated>

		<summary type="html">&lt;p&gt;Владимир: Новая страница: «= olcRTC: туннелирование SOCKS5-трафика через публичные WebRTC-сервисы =  == Введение ==  === Что такое olcRTC === olcRTC — это инструмент для построения SOCKS5-туннеля поверх инфраструктуры публичных сервисов видеосвязи. В отличие от классических VPN-протоколов, которые работ...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= olcRTC: туннелирование SOCKS5-трафика через публичные WebRTC-сервисы =&lt;br /&gt;
&lt;br /&gt;
== Введение ==&lt;br /&gt;
&lt;br /&gt;
=== Что такое olcRTC ===&lt;br /&gt;
olcRTC — это инструмент для построения SOCKS5-туннеля поверх инфраструктуры публичных сервисов видеосвязи. В отличие от классических VPN-протоколов, которые работают через выделенные UDP/TCP-порты на собственном сервере, olcRTC использует уже существующие WebRTC-каналы общедоступных видеоконференц-сервисов в качестве несущей среды.&lt;br /&gt;
&lt;br /&gt;
Поддерживаются три сервиса:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Carrier&lt;br /&gt;
!Сервис&lt;br /&gt;
!Адрес&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;wbstream&amp;lt;/code&amp;gt;&lt;br /&gt;
|WB Stream&lt;br /&gt;
|&amp;lt;code&amp;gt;stream.wb.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;telemost&amp;lt;/code&amp;gt;&lt;br /&gt;
|Yandex Telemost&lt;br /&gt;
|&amp;lt;code&amp;gt;telemost.yandex.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;jazz&amp;lt;/code&amp;gt;&lt;br /&gt;
|SaluteJazz&lt;br /&gt;
|&amp;lt;code&amp;gt;salutejazz.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Сервер olcRTC выступает в роли участника виртуальной видеоконференции (с автоматически сгенерированным именем). Клиент подключается к той же конференции и через peer-connection обменивается с сервером данными — поверх этого канала идёт трафик SOCKS5-туннеля.&lt;br /&gt;
&lt;br /&gt;
=== Когда применяется ===&lt;br /&gt;
&lt;br /&gt;
* Канал между клиентом и обычными VPN-серверами нестабилен или имеет высокий процент потерь.&lt;br /&gt;
* Требуется передать данные через инфраструктуру, использующую WebRTC, а не выделенные транспортные порты.&lt;br /&gt;
* Нужна альтернатива, которая работает поверх стандартного для пользовательских устройств WebRTC-стека (браузер, мобильное приложение).&lt;br /&gt;
&lt;br /&gt;
=== Сравнение с другими методами туннелирования ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Метод&lt;br /&gt;
!Транспорт&lt;br /&gt;
!Особенность&lt;br /&gt;
|-&lt;br /&gt;
|WireGuard&lt;br /&gt;
|UDP&lt;br /&gt;
|Прямое соединение с собственным сервером, минимальные накладные расходы&lt;br /&gt;
|-&lt;br /&gt;
|OpenVPN&lt;br /&gt;
|UDP/TCP&lt;br /&gt;
|Универсальная совместимость, выше накладные расходы&lt;br /&gt;
|-&lt;br /&gt;
|Shadowsocks&lt;br /&gt;
|TCP&lt;br /&gt;
|Шифрованный поток, маскировка под произвольный TCP&lt;br /&gt;
|-&lt;br /&gt;
|VLESS + REALITY&lt;br /&gt;
|TCP (TLS)&lt;br /&gt;
|TLS-handshake донора (стороннего сайта)&lt;br /&gt;
|-&lt;br /&gt;
|NaiveProxy&lt;br /&gt;
|TCP (HTTP/2)&lt;br /&gt;
|Использует Chrome-стек, неотличим от обычного HTTPS&lt;br /&gt;
|-&lt;br /&gt;
|Hysteria2&lt;br /&gt;
|UDP (QUIC)&lt;br /&gt;
|QUIC поверх UDP с маскировкой под HTTPS&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;olcRTC&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;WebRTC поверх QUIC/UDP&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Использует существующую инфраструктуру SFU публичного сервиса видеосвязи в качестве несущей&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Принципы работы ==&lt;br /&gt;
&lt;br /&gt;
=== Поток данных ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[Браузер / приложение клиента]&lt;br /&gt;
        │&lt;br /&gt;
        │  SOCKS5 на 127.0.0.1:1080&lt;br /&gt;
        ▼&lt;br /&gt;
[olcRTC client (cnc)]&lt;br /&gt;
        │&lt;br /&gt;
        │  smux мультиплексирование&lt;br /&gt;
        │  ChaCha20-Poly1305 шифрование&lt;br /&gt;
        ▼&lt;br /&gt;
[Транспорт: datachannel / vp8 / sei / video]&lt;br /&gt;
        │&lt;br /&gt;
        │  WebRTC (peer-connection через SFU)&lt;br /&gt;
        ▼&lt;br /&gt;
[Видеоконференция WB Stream / Telemost / Jazz]&lt;br /&gt;
        │&lt;br /&gt;
        ▲&lt;br /&gt;
        │  тот же канал, серверная сторона&lt;br /&gt;
        │&lt;br /&gt;
[Транспорт] ← [olcRTC server (srv)]&lt;br /&gt;
        │&lt;br /&gt;
        │  SOCKS5 (опционально, через локальный xray)&lt;br /&gt;
        ▼&lt;br /&gt;
[Outbound: прямой выход в интернет ИЛИ xray + WARP]&lt;br /&gt;
        │&lt;br /&gt;
        ▼&lt;br /&gt;
[Целевой сайт]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Слои кода ===&lt;br /&gt;
Кодовая база разделена на четыре независимых слоя с реестром расширений:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Слой&lt;br /&gt;
!Ответственность&lt;br /&gt;
!Реализации&lt;br /&gt;
|-&lt;br /&gt;
|Carrier&lt;br /&gt;
|Сессия в видеосервисе: вход в конференцию, регистрация участника, peer-connection через SFU&lt;br /&gt;
|&amp;lt;code&amp;gt;wbstream&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;telemost&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jazz&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Link&lt;br /&gt;
|Поверх транспорта; в текущей версии только &amp;lt;code&amp;gt;direct&amp;lt;/code&amp;gt; (passthrough)&lt;br /&gt;
|&amp;lt;code&amp;gt;direct&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Transport&lt;br /&gt;
|Способ кодирования байтов внутри WebRTC-канала&lt;br /&gt;
|&amp;lt;code&amp;gt;datachannel&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vp8channel&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;seichannel&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;videochannel&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Application&lt;br /&gt;
|Сервер (приём входящих туннелей) или клиент (локальный SOCKS5)&lt;br /&gt;
|&amp;lt;code&amp;gt;server&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;client&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Транспорты ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Транспорт&lt;br /&gt;
!Несущая в WebRTC&lt;br /&gt;
!Идея&lt;br /&gt;
!Скорость&lt;br /&gt;
!Пинг&lt;br /&gt;
!WB Stream&lt;br /&gt;
!Telemost&lt;br /&gt;
!Jazz&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;datachannel&amp;lt;/code&amp;gt;&lt;br /&gt;
|RTCDataChannel&lt;br /&gt;
|Прямые байты в датаканале&lt;br /&gt;
|Максимум&lt;br /&gt;
|Минимум&lt;br /&gt;
|✓&lt;br /&gt;
|✗&lt;br /&gt;
|⚠&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vp8channel&amp;lt;/code&amp;gt;&lt;br /&gt;
|VP8-видеотрек&lt;br /&gt;
|KCP-пакеты внутри валидных VP8-кадров&lt;br /&gt;
|Высокая&lt;br /&gt;
|Средний&lt;br /&gt;
|✓&lt;br /&gt;
|✓&lt;br /&gt;
|✓&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;seichannel&amp;lt;/code&amp;gt;&lt;br /&gt;
|H.264 SEI NAL&lt;br /&gt;
|Полезные данные в SEI-сообщениях видеопотока&lt;br /&gt;
|Низкая&lt;br /&gt;
|Низкий&lt;br /&gt;
|✓&lt;br /&gt;
|✗&lt;br /&gt;
|✓&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;videochannel&amp;lt;/code&amp;gt;&lt;br /&gt;
|Видеокадры&lt;br /&gt;
|QR-коды или тайлы Reed-Solomon в видеопотоке&lt;br /&gt;
|Минимум&lt;br /&gt;
|Максимум&lt;br /&gt;
|✓&lt;br /&gt;
|✓&lt;br /&gt;
|✓&lt;br /&gt;
|}&lt;br /&gt;
Рекомендуемая универсальная связка: &amp;lt;code&amp;gt;wbstream + vp8channel&amp;lt;/code&amp;gt;. Она используется в данной статье как основная конфигурация.&lt;br /&gt;
&lt;br /&gt;
=== Шифрование ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Алгоритм&lt;br /&gt;
|XChaCha20-Poly1305 (AEAD)&lt;br /&gt;
|-&lt;br /&gt;
|Длина ключа&lt;br /&gt;
|32 байта (64 hex-символа)&lt;br /&gt;
|-&lt;br /&gt;
|Nonce&lt;br /&gt;
|24 байта, случайный, на каждый фрейм, префиксится к шифротексту&lt;br /&gt;
|-&lt;br /&gt;
|Идентификация клиента&lt;br /&gt;
|Поле &amp;lt;code&amp;gt;client_id&amp;lt;/code&amp;gt; в открытом JSON, сравнивается с серверным значением&lt;br /&gt;
|}&lt;br /&gt;
Реальная криптографическая защита — это ключ. &amp;lt;code&amp;gt;client_id&amp;lt;/code&amp;gt; — лишь дополнительная проверка от случайных подключений в той же конференции, не криптографическая.&lt;br /&gt;
&lt;br /&gt;
=== Smux: мультиплексирование ===&lt;br /&gt;
Поверх единого WebRTC-канала работает &amp;lt;code&amp;gt;xtaci/smux&amp;lt;/code&amp;gt; v2. Один физический канал содержит много логических TCP-стримов: каждый запрос SOCKS5 от приложения открывается как отдельный smux-стрим.&lt;br /&gt;
&lt;br /&gt;
=== Архитектурное ограничение: один сервер — один клиент ===&lt;br /&gt;
Это важное свойство кода, которое необходимо понимать.&lt;br /&gt;
&lt;br /&gt;
Один экземпляр сервера olcRTC обслуживает &#039;&#039;&#039;ровно одного клиента в момент времени&#039;&#039;&#039;. Это не упущение, а сознательное архитектурное решение.&lt;br /&gt;
&lt;br /&gt;
Причины:&lt;br /&gt;
&lt;br /&gt;
* Сервер хранит &#039;&#039;&#039;одну&#039;&#039;&#039; переменную &amp;lt;code&amp;gt;clientID&amp;lt;/code&amp;gt; и сравнивает с присланным значением (см. &amp;lt;code&amp;gt;internal/server/server.go:399-401&amp;lt;/code&amp;gt;).&lt;br /&gt;
* Сервер держит &#039;&#039;&#039;один&#039;&#039;&#039; link и &#039;&#039;&#039;одну&#039;&#039;&#039; smux-сессию, не словарь по идентификатору.&lt;br /&gt;
* Провайдер carrier держит один RTCPeerConnection.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Сценарий&lt;br /&gt;
!Поведение&lt;br /&gt;
|-&lt;br /&gt;
|Один владелец, разные устройства, по очереди (выключил ноутбук, включил телефон)&lt;br /&gt;
|Работает с одной ссылкой&lt;br /&gt;
|-&lt;br /&gt;
|Один владелец, разные устройства, одновременно&lt;br /&gt;
|Устройства конкурируют за peer-connection, рвут друг друга&lt;br /&gt;
|-&lt;br /&gt;
|Несколько разных людей, одна ссылка на всех, одновременно&lt;br /&gt;
|То же — рвут друг друга&lt;br /&gt;
|-&lt;br /&gt;
|Несколько пользователей, у каждого своя ссылка&lt;br /&gt;
|Работает; &#039;&#039;&#039;требуется отдельный контейнер на каждого пользователя&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
Для предоставления доступа нескольким людям одновременно необходимо запустить несколько независимых контейнеров — каждый со своими &amp;lt;code&amp;gt;room_id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;client_id&amp;lt;/code&amp;gt;. В разделе «Управление несколькими пользователями» описан скрипт, который автоматизирует это.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Что должно быть на сервере перед установкой ==&lt;br /&gt;
&lt;br /&gt;
=== Минимально необходимая конфигурация ===&lt;br /&gt;
Перед началом установки olcRTC сервер должен находиться в следующем состоянии:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!№&lt;br /&gt;
!Требование&lt;br /&gt;
!Зачем&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Установлена операционная система Linux (Ubuntu 22.04+, Debian 12+, Fedora 38+ или сравнимая)&lt;br /&gt;
|Среда выполнения Docker&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Доступ по SSH с правами &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; (либо аккаунт с &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; без пароля)&lt;br /&gt;
|Установка пакетов и управление контейнерами&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Установлены Docker Engine 24.0+ и Docker Compose v2.20+&lt;br /&gt;
|Запуск контейнера olcRTC&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Установлена утилита &amp;lt;code&amp;gt;git&amp;lt;/code&amp;gt;&lt;br /&gt;
|Скачивание исходного кода olcRTC с репозитория&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Установлена утилита &amp;lt;code&amp;gt;openssl&amp;lt;/code&amp;gt;&lt;br /&gt;
|Генерация ключа шифрования&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Опциональная (но настоятельно рекомендуемая) конфигурация: egress через WARP ===&lt;br /&gt;
По умолчанию olcRTC сервер выходит в интернет напрямую с публичного IP вашей виртуальной машины. Все целевые сайты будут видеть именно этот адрес.&lt;br /&gt;
&lt;br /&gt;
Чтобы выходной трафик уходил через Cloudflare WARP, требуется промежуточная цепочка через локальный SOCKS5-прокси. Самая распространённая реализация — панель &#039;&#039;&#039;3x-ui&#039;&#039;&#039; (web-интерфейс над xray-core).&lt;br /&gt;
&lt;br /&gt;
==== Что должно быть подготовлено в 3x-ui ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!№&lt;br /&gt;
!Параметр&lt;br /&gt;
!Значение для нашей статьи&lt;br /&gt;
!Комментарий&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Сама панель 3x-ui установлена и доступна&lt;br /&gt;
|—&lt;br /&gt;
|Установка описана в отдельной статье ([[Установка 3x-ui]]); если её ещё нет — выполните установку до начала&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Outbound в WARP активен и протестирован&lt;br /&gt;
|tag &amp;lt;code&amp;gt;warp&amp;lt;/code&amp;gt; или аналогичный&lt;br /&gt;
|Должен быть настроен как WireGuard-outbound к Cloudflare WARP. Проверка: маршрут с outbound отдаёт IPv6 из диапазона &amp;lt;code&amp;gt;2a09:bac5::/29&amp;lt;/code&amp;gt; или IPv4 &amp;lt;code&amp;gt;104.28.x.x&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Inbound типа &#039;&#039;&#039;mixed&#039;&#039;&#039; (SOCKS5 + HTTP), слушающий &#039;&#039;&#039;только на 127.0.0.1&#039;&#039;&#039;&lt;br /&gt;
|порт &amp;lt;code&amp;gt;24365&amp;lt;/code&amp;gt;&lt;br /&gt;
|Этот порт мы будем указывать в конфигурации olcRTC. Выберите любой свободный, мы используем 24365 как пример&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Аутентификация (логин/пароль) на этом mixed-inbound &#039;&#039;&#039;отключена&#039;&#039;&#039;&lt;br /&gt;
|—&lt;br /&gt;
|olcRTC-сервер умеет работать только с режимом NOAUTH; если включена авторизация, цепочка не будет работать&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Routing-rule в xray: трафик с inbound mixed → outbound warp&lt;br /&gt;
|—&lt;br /&gt;
|В 3x-ui это настраивается в разделе «Настройки xray → Маршрутизация»&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Как проверить, что цепочка работает ====&lt;br /&gt;
Команда ниже выполняется на самом сервере (не на компьютере пользователя). Она запрашивает свой IP-адрес через локальный SOCKS5-прокси, который должен направить запрос в WARP.&lt;br /&gt;
&lt;br /&gt;
Замените &amp;lt;code&amp;gt;24365&amp;lt;/code&amp;gt; на ваш реальный номер порта mixed-inbound.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl --socks5-hostname 127.0.0.1:24365 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидаемый результат: IP-адрес из диапазона Cloudflare WARP (например, &amp;lt;code&amp;gt;104.28.218.x&amp;lt;/code&amp;gt; или IPv6 &amp;lt;code&amp;gt;2a09:bac5:...&amp;lt;/code&amp;gt;). Если возвращается публичный IP вашего сервера — значит цепочка не сработала и трафик идёт мимо WARP. В этом случае проверьте настройки routing в 3x-ui.&lt;br /&gt;
&lt;br /&gt;
Если egress через WARP вам не нужен (готовы выходить с публичного IP сервера), можно пропустить этот раздел. В дальнейших шагах указания для случая «без WARP» помечены явно.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Параметры, которые нужно подготовить заранее ==&lt;br /&gt;
Перед началом установки заполните таблицу ниже своими значениями. На каждом шаге, где встретится плейсхолдер, мы будем ссылаться на эту таблицу.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Плейсхолдер&lt;br /&gt;
!Что это&lt;br /&gt;
!Где взять&lt;br /&gt;
!Пример&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_SERVER_HOST&amp;lt;/code&amp;gt;&lt;br /&gt;
|Адрес сервера для подключения по SSH: либо публичный IP, либо имя из &amp;lt;code&amp;gt;~/.ssh/config&amp;lt;/code&amp;gt;, либо доменное имя&lt;br /&gt;
|У хостинг-провайдера в панели управления виртуальной машиной&lt;br /&gt;
|&amp;lt;code&amp;gt;198.51.100.42&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;my-vps&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_SSH_USER&amp;lt;/code&amp;gt;&lt;br /&gt;
|Имя пользователя SSH&lt;br /&gt;
|В письме от хостинга при создании VM. Чаще всего &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_KEY_HEX&amp;lt;/code&amp;gt;&lt;br /&gt;
|32-байтный ключ шифрования olcRTC в hex-формате (64 символа)&lt;br /&gt;
|Будет сгенерирован командой на шаге 4. Сохраните в надёжное место&lt;br /&gt;
|&amp;lt;code&amp;gt;1c3f8a2b...d4e5f6a7&amp;lt;/code&amp;gt; (64 hex-символа)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_CLIENT_ID&amp;lt;/code&amp;gt;&lt;br /&gt;
|Идентификатор клиента; должен совпадать на сервере и в клиентском приложении&lt;br /&gt;
|Любое имя на латинице длиной 1–32 символа: буквы, цифры, &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;my-laptop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_ROOM_ID&amp;lt;/code&amp;gt;&lt;br /&gt;
|Идентификатор виртуальной видеоконференции&lt;br /&gt;
|Будет получен из логов сервера на шаге 7&lt;br /&gt;
|&amp;lt;code&amp;gt;019e07b8-e292-73ec-a40b-6a6e4957ce01&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_SOCKS_PORT&amp;lt;/code&amp;gt;&lt;br /&gt;
|Порт mixed-inbound в 3x-ui для egress через WARP (опционально)&lt;br /&gt;
|См. раздел «Что должно быть на сервере перед установкой»&lt;br /&gt;
|&amp;lt;code&amp;gt;24365&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Сохраните эту таблицу в текстовом файле — заполните по мере прохождения шагов. Особенно важно сохранить &amp;lt;code&amp;gt;YOUR_KEY_HEX&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;YOUR_ROOM_ID&amp;lt;/code&amp;gt; — без них нельзя восстановить доступ к серверу после перезапуска.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Установка сервера: пошаговая инструкция ==&lt;br /&gt;
В этом разделе все команды выполняются на сервере (через SSH). Каждое пояснение — одна команда. Если команда выдала ошибку — остановитесь, не выполняйте следующую, и сверьтесь с предыдущим шагом.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1. Подключение к серверу по SSH ===&lt;br /&gt;
Откройте терминал на своём компьютере. На Windows можно использовать встроенный PowerShell или Windows Terminal, на macOS — Terminal, на Linux — любой эмулятор терминала.&lt;br /&gt;
&lt;br /&gt;
Замените &amp;lt;code&amp;gt;YOUR_SSH_USER&amp;lt;/code&amp;gt; на имя пользователя из подготовленной таблицы (обычно &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;), а &amp;lt;code&amp;gt;YOUR_SERVER_HOST&amp;lt;/code&amp;gt; — на адрес или имя сервера.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh YOUR_SSH_USER@YOUR_SERVER_HOST&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если подключение прошло успешно — вы увидите приглашение командной строки сервера. Все следующие команды выполняются именно в нём.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Проверка наличия Docker ===&lt;br /&gt;
Прежде чем что-то ставить, проверим, есть ли Docker уже на сервере.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker --version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если команда вывела что-то вроде &amp;lt;code&amp;gt;Docker version 24.0.5, build ...&amp;lt;/code&amp;gt; — Docker установлен, переходите к шагу 3.&lt;br /&gt;
&lt;br /&gt;
Если команда выдала &amp;lt;code&amp;gt;command not found&amp;lt;/code&amp;gt; — Docker нужно установить. Выберите один из подразделов ниже в зависимости от вашего дистрибутива.&lt;br /&gt;
&lt;br /&gt;
==== 2a. Установка Docker на Ubuntu / Debian ====&lt;br /&gt;
Обновите список пакетов.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установите вспомогательные утилиты.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install -y ca-certificates curl gnupg&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подготовьте каталог для GPG-ключей репозитория Docker.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Скачайте GPG-ключ официального репозитория Docker.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Дайте права на чтение всем.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.gpg&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Добавьте репозиторий Docker в систему.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;$VERSION_CODENAME&amp;quot;) stable&amp;quot; | tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Снова обновите список пакетов (теперь уже с новым репозиторием).&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установите Docker и плагины.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 2b. Установка Docker на Fedora / RHEL ====&lt;br /&gt;
Установите менеджер репозиториев.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dnf -y install dnf-plugins-core&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подключите репозиторий Docker.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установите Docker.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dnf -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Запустите и включите автозапуск Docker.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl enable --now docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 2c. Проверка установки Docker (любая ОС) ====&lt;br /&gt;
Проверьте, что Docker установлен и работает.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker --version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должно вывести что-то вроде &amp;lt;code&amp;gt;Docker version 24.0.5&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Проверьте, что плагин Compose доступен.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Должно вывести что-то вроде &amp;lt;code&amp;gt;Docker Compose version v2.20.2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если обе команды отработали без ошибок — переходите к шагу 3.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3. Создание рабочего каталога ===&lt;br /&gt;
Создайте каталог, в котором будет лежать репозиторий olcRTC.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/olcrtc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Перейдите в этот каталог.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/olcrtc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Шаг 4. Скачивание исходного кода olcRTC ===&lt;br /&gt;
Скачайте репозиторий вместе с подмодулями (флаг &amp;lt;code&amp;gt;--recurse-submodules&amp;lt;/code&amp;gt; обязателен — без него транспорт &amp;lt;code&amp;gt;videochannel&amp;lt;/code&amp;gt; не соберётся).&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git clone --depth 1 --recurse-submodules --branch master https://github.com/openlibrecommunity/olcrtc.git .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Точка в конце команды означает «скачать в текущий каталог», не создавая вложенной папки. Если вы пропустили шаг 3 (&amp;lt;code&amp;gt;cd /opt/olcrtc&amp;lt;/code&amp;gt;), команда создаст репозиторий не в том месте.&lt;br /&gt;
&lt;br /&gt;
Проверьте, что скачивание прошло успешно.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls /opt/olcrtc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В выводе должны быть файлы &amp;lt;code&amp;gt;Dockerfile&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;go.mod&amp;lt;/code&amp;gt;, каталоги &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;internal&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;script&amp;lt;/code&amp;gt; и другие.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 5. Генерация ключа шифрования ===&lt;br /&gt;
Сгенерируйте ключ командой &amp;lt;code&amp;gt;openssl&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl rand -hex 32&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Команда выведет строку из 64 hex-символов. Например:&lt;br /&gt;
 1c3f8a2b3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8091a2b3c4d5e6f7a8b9c0d1e2&lt;br /&gt;
&#039;&#039;&#039;Скопируйте этот ключ&#039;&#039;&#039; и впишите его в свою таблицу подготовки как &amp;lt;code&amp;gt;YOUR_KEY_HEX&amp;lt;/code&amp;gt;. Этот же ключ потом понадобится для настройки клиента.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 6. Создание конфигурационного файла .env ===&lt;br /&gt;
Файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; хранит параметры запуска. Создадим его, подставив ваши значения.&lt;br /&gt;
&lt;br /&gt;
Замените:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;ВАШ_КЛЮЧ&amp;lt;/code&amp;gt; — на значение &amp;lt;code&amp;gt;YOUR_KEY_HEX&amp;lt;/code&amp;gt; из шага 5.&lt;br /&gt;
* &amp;lt;code&amp;gt;my-laptop&amp;lt;/code&amp;gt; — на значение &amp;lt;code&amp;gt;YOUR_CLIENT_ID&amp;lt;/code&amp;gt; из таблицы подготовки.&lt;br /&gt;
&lt;br /&gt;
Если вы &#039;&#039;&#039;используете&#039;&#039;&#039; egress через WARP (раздел «Что должно быть на сервере перед установкой»), также замените &amp;lt;code&amp;gt;24365&amp;lt;/code&amp;gt; на свой &amp;lt;code&amp;gt;YOUR_SOCKS_PORT&amp;lt;/code&amp;gt;. Если &#039;&#039;&#039;не используете&#039;&#039;&#039; WARP — удалите две строки &amp;lt;code&amp;gt;OLCRTC_SOCKS_PROXY=...&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/olcrtc/.env&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В открывшемся редакторе вставьте следующее содержимое:&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
OLCRTC_CARRIER=wbstream&lt;br /&gt;
OLCRTC_TRANSPORT=vp8channel&lt;br /&gt;
OLCRTC_ROOM_ID=any&lt;br /&gt;
OLCRTC_CLIENT_ID=my-laptop&lt;br /&gt;
OLCRTC_KEY=ВАШ_КЛЮЧ&lt;br /&gt;
OLCRTC_DNS=1.1.1.1:53&lt;br /&gt;
OLCRTC_SOCKS_PROXY=127.0.0.1&lt;br /&gt;
OLCRTC_SOCKS_PROXY_PORT=24365&lt;br /&gt;
OLCRTC_VP8_FPS=60&lt;br /&gt;
OLCRTC_VP8_BATCH=64&lt;br /&gt;
OLCRTC_DEBUG=false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните файл: нажмите &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, затем &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, затем &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Защитите файл от чтения посторонними (он содержит ваш ключ).&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /opt/olcrtc/.env&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Проверьте, что значения подставились правильно.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat /opt/olcrtc/.env&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В строке &amp;lt;code&amp;gt;OLCRTC_KEY=...&amp;lt;/code&amp;gt; должен быть ваш ключ, в строке &amp;lt;code&amp;gt;OLCRTC_CLIENT_ID=...&amp;lt;/code&amp;gt; — ваше имя пользователя.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 7. Замена docker-compose.server.yml ===&lt;br /&gt;
Стандартный compose-файл из репозитория не использует режим &amp;lt;code&amp;gt;host&amp;lt;/code&amp;gt;, который нужен для доступа к локальному xray. Заменим его на нашу версию.&lt;br /&gt;
&lt;br /&gt;
Откройте файл для редактирования.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/olcrtc/docker-compose.server.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Удалите всё содержимое (зажмите &amp;lt;code&amp;gt;Ctrl+K&amp;lt;/code&amp;gt; до полной очистки) и вставьте следующее:&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  olcrtc-server:&lt;br /&gt;
    build:&lt;br /&gt;
      context: .&lt;br /&gt;
    image: olcrtc/server:local&lt;br /&gt;
    container_name: olcrtc-server&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    environment:&lt;br /&gt;
      OLCRTC_MODE: srv&lt;br /&gt;
      OLCRTC_CARRIER: &amp;quot;${OLCRTC_CARRIER:?set OLCRTC_CARRIER}&amp;quot;&lt;br /&gt;
      OLCRTC_TRANSPORT: &amp;quot;${OLCRTC_TRANSPORT:?set OLCRTC_TRANSPORT}&amp;quot;&lt;br /&gt;
      OLCRTC_ROOM_ID: &amp;quot;${OLCRTC_ROOM_ID:?set OLCRTC_ROOM_ID}&amp;quot;&lt;br /&gt;
      OLCRTC_CLIENT_ID: &amp;quot;${OLCRTC_CLIENT_ID:?set OLCRTC_CLIENT_ID}&amp;quot;&lt;br /&gt;
      OLCRTC_KEY: &amp;quot;${OLCRTC_KEY:?set OLCRTC_KEY}&amp;quot;&lt;br /&gt;
      OLCRTC_DNS: &amp;quot;${OLCRTC_DNS:-1.1.1.1:53}&amp;quot;&lt;br /&gt;
      OLCRTC_SOCKS_PROXY: &amp;quot;${OLCRTC_SOCKS_PROXY:-}&amp;quot;&lt;br /&gt;
      OLCRTC_SOCKS_PROXY_PORT: &amp;quot;${OLCRTC_SOCKS_PROXY_PORT:-1080}&amp;quot;&lt;br /&gt;
      OLCRTC_VP8_FPS: &amp;quot;${OLCRTC_VP8_FPS:-60}&amp;quot;&lt;br /&gt;
      OLCRTC_VP8_BATCH: &amp;quot;${OLCRTC_VP8_BATCH:-64}&amp;quot;&lt;br /&gt;
      OLCRTC_DEBUG: &amp;quot;${OLCRTC_DEBUG:-false}&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - olcrtc-state:/var/lib/olcrtc&lt;br /&gt;
    init: true&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  olcrtc-state:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните файл: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 8. Сборка Docker-образа olcRTC ===&lt;br /&gt;
Перейдите в каталог проекта (если ещё не там).&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/olcrtc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Запустите сборку.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f docker-compose.server.yml --env-file .env build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сборка длится 1–3 минуты. Скачиваются зависимости Go и компилируется бинарник. Если в процессе возникает ошибка вида «context canceled» или «network unreachable» — повторите команду; первый прогон бывает прерывистым из-за нестабильности зеркал.&lt;br /&gt;
&lt;br /&gt;
Когда сборка успешно завершится, в выводе появится строка &amp;lt;code&amp;gt;Image olcrtc/server:local Built&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 9. Запуск контейнера ===&lt;br /&gt;
Запустите контейнер в фоновом режиме.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f docker-compose.server.yml --env-file .env up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подождите 15–20 секунд, чтобы сервер успел подключиться к WB Stream и создать виртуальную конференцию.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sleep 20&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Посмотрите логи.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs olcrtc-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ожидаемый вывод:&lt;br /&gt;
 Connecting link via direct/vp8channel/wbstream...&lt;br /&gt;
 WB Stream room created: 019e07b8-e292-73ec-a40b-6a6e4957ce01&lt;br /&gt;
 To connect client use: -id 019e07b8-e292-73ec-a40b-6a6e4957ce01&lt;br /&gt;
 Link connected&lt;br /&gt;
&#039;&#039;&#039;Скопируйте идентификатор после &amp;lt;code&amp;gt;WB Stream room created:&amp;lt;/code&amp;gt;&#039;&#039;&#039; и впишите его в таблицу подготовки как &amp;lt;code&amp;gt;YOUR_ROOM_ID&amp;lt;/code&amp;gt;. Без этого значения невозможно настроить клиента.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 10. Фиксация room_id в .env ===&lt;br /&gt;
Сейчас в файле &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;OLCRTC_ROOM_ID=any&amp;lt;/code&amp;gt;. Это значение означает «при каждом запуске создавать новую конференцию». Если оставить его — после следующего перезапуска контейнера все ссылки клиентов перестанут работать, потому что комната окажется новой.&lt;br /&gt;
&lt;br /&gt;
Зафиксируйте полученный идентификатор.&lt;br /&gt;
&lt;br /&gt;
Замените &amp;lt;code&amp;gt;YOUR_ROOM_ID&amp;lt;/code&amp;gt; в команде ниже на скопированное значение из шага 9.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sed -i &#039;s/^OLCRTC_ROOM_ID=any$/OLCRTC_ROOM_ID=YOUR_ROOM_ID/&#039; /opt/olcrtc/.env&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Перезапустите контейнер с новым значением.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/olcrtc/docker-compose.server.yml --env-file /opt/olcrtc/.env up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подождите 10 секунд и снова проверьте логи.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sleep 10 &amp;amp;&amp;amp; docker logs --tail 5 olcrtc-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Теперь в логе не должно быть строки &amp;lt;code&amp;gt;WB Stream room created&amp;lt;/code&amp;gt; — должна быть только &amp;lt;code&amp;gt;Connecting link via direct/vp8channel/wbstream...&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Link connected&amp;lt;/code&amp;gt;. Это означает, что сервер заходит в существующую комнату, а не создаёт новую.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 11. Формирование ссылки для клиента ===&lt;br /&gt;
Ссылка имеет фиксированный текстовый формат:&lt;br /&gt;
 olcrtc://CARRIER?TRANSPORT@ROOM_ID#KEY%CLIENT_ID$ПОДПИСЬ&lt;br /&gt;
Подставьте свои значения. Подпись — произвольная строка, которая отобразится в названии локации в клиентском приложении (она не влияет на работу).&lt;br /&gt;
&lt;br /&gt;
Пример итоговой ссылки:&amp;lt;pre&amp;gt;&lt;br /&gt;
olcrtc://wbstream?vp8channel@019e07b8-e292-73ec-a40b-6a6e4957ce01#1c3f8a2b...d4e5f6a7%my-laptop$home laptop, vp8 over wbstream&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Часть ссылки&lt;br /&gt;
!Откуда берётся&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;wbstream&amp;lt;/code&amp;gt;&lt;br /&gt;
|Из &amp;lt;code&amp;gt;OLCRTC_CARRIER&amp;lt;/code&amp;gt; в .env&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vp8channel&amp;lt;/code&amp;gt;&lt;br /&gt;
|Из &amp;lt;code&amp;gt;OLCRTC_TRANSPORT&amp;lt;/code&amp;gt; в .env&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;019e07b8-...&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_ROOM_ID&amp;lt;/code&amp;gt; из шага 9&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;1c3f8a2b...&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_KEY_HEX&amp;lt;/code&amp;gt; из шага 5&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;my-laptop&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;YOUR_CLIENT_ID&amp;lt;/code&amp;gt; из шага 6&lt;br /&gt;
|-&lt;br /&gt;
|Подпись после &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;&lt;br /&gt;
|Любой описательный текст&lt;br /&gt;
|}&lt;br /&gt;
Сохраните полученную ссылку в надёжное место. Её нужно будет ввести в клиентское приложение.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 12. Подключение клиента ===&lt;br /&gt;
&lt;br /&gt;
==== 12a. Olcbox (Android, рекомендуется для смартфона) ====&lt;br /&gt;
Скачайте APK из репозитория [https://github.com/alananisimov/olcbox alananisimov/olcbox] (раздел Releases) и установите его на телефон.&lt;br /&gt;
&lt;br /&gt;
Откройте приложение. Перейдите в раздел Locations. Нажмите Add → &#039;&#039;&#039;Import from clipboard&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Перед нажатием убедитесь, что в буфере обмена телефона лежит ваша ссылка &amp;lt;code&amp;gt;olcrtc://...&amp;lt;/code&amp;gt; из шага 11. Скопируйте её любым способом — например, отправив самому себе в Telegram-секретный чат.&lt;br /&gt;
&lt;br /&gt;
После импорта откройте созданную локацию и проверьте поля:&lt;br /&gt;
&lt;br /&gt;
* Carrier должен быть &amp;lt;code&amp;gt;wbstream&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Transport должен быть &amp;lt;code&amp;gt;vp8channel&amp;lt;/code&amp;gt;.&lt;br /&gt;
* VP8 FPS — установите &amp;lt;code&amp;gt;60&amp;lt;/code&amp;gt; вручную (при импорте URI этот параметр сбрасывается на дефолт приложения).&lt;br /&gt;
* VP8 Batch — установите &amp;lt;code&amp;gt;64&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Включите тумблер VPN.&lt;br /&gt;
&lt;br /&gt;
==== 12b. CLI-клиент (Linux, macOS, Windows) ====&lt;br /&gt;
Скачайте бинарник olcrtc для своей операционной системы из релизов репозитория или соберите из исходников.&lt;br /&gt;
&lt;br /&gt;
Запустите туннель. Замените все плейсхолдеры &amp;lt;code&amp;gt;YOUR_*&amp;lt;/code&amp;gt; на свои значения из таблицы подготовки.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./olcrtc -mode cnc -carrier wbstream -transport vp8channel -id YOUR_ROOM_ID -client-id YOUR_CLIENT_ID -key YOUR_KEY_HEX -link direct -data data -dns 1.1.1.1:53 -vp8-fps 60 -vp8-batch 64 -socks-host 127.0.0.1 -socks-port 1080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска клиент поднимет локальный SOCKS5-прокси на &amp;lt;code&amp;gt;127.0.0.1:1080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Проверьте, что туннель работает.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl --socks5-hostname 127.0.0.1:1080 https://icanhazip.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если egress настроен через WARP — должен вернуть IP Cloudflare WARP. Если не настроен — IP вашего сервера. В обоих случаях это &#039;&#039;&#039;не должен быть&#039;&#039;&#039; IP вашего домашнего интернета.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Команды управления одним сервером ==&lt;br /&gt;
Все команды выполняются на сервере по SSH.&lt;br /&gt;
&lt;br /&gt;
Посмотреть логи в реальном времени (для выхода нажать &amp;lt;code&amp;gt;Ctrl+C&amp;lt;/code&amp;gt;).&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f olcrtc-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Посмотреть статус контейнера.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps --filter name=olcrtc-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Перезапустить сервер (например, после изменения .env).&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/olcrtc/docker-compose.server.yml --env-file /opt/olcrtc/.env up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Остановить сервер.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/olcrtc/docker-compose.server.yml --env-file /opt/olcrtc/.env down&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Обновить исходный код до свежей версии master.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/olcrtc &amp;amp;&amp;amp; git pull --recurse-submodules&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Пересобрать образ после обновления кода.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/olcrtc/docker-compose.server.yml --env-file /opt/olcrtc/.env build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Применить новый образ.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/olcrtc/docker-compose.server.yml --env-file /opt/olcrtc/.env up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Управление несколькими пользователями: скрипт &amp;lt;code&amp;gt;olcrtc-users&amp;lt;/code&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
=== Зачем он нужен ===&lt;br /&gt;
Из-за архитектурного ограничения «один сервер — один клиент» (раздел «Принципы работы → Архитектурное ограничение») для каждого пользователя нужен отдельный контейнер со своим room_id, ключом и client_id. Чтобы не повторять шаги установки руками каждый раз, написан bash-скрипт &amp;lt;code&amp;gt;olcrtc-users&amp;lt;/code&amp;gt;, который автоматизирует:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Создание пользователя:&#039;&#039;&#039; генерация ключа, создание контейнера с уникальным client_id, ловля room_id из логов, формирование готовой ссылки.&lt;br /&gt;
* &#039;&#039;&#039;Удаление пользователя:&#039;&#039;&#039; остановка и удаление контейнера, удаление volume и каталога.&lt;br /&gt;
* &#039;&#039;&#039;Просмотр списка и информации:&#039;&#039;&#039; таблица всех пользователей с возможностью получить ссылку по выбору номера.&lt;br /&gt;
&lt;br /&gt;
=== Что получает каждый пользователь ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Атрибут&lt;br /&gt;
!Значение&lt;br /&gt;
|-&lt;br /&gt;
|Контейнер&lt;br /&gt;
|&amp;lt;code&amp;gt;olcrtc-user-&amp;amp;#x3C;имя&amp;amp;#x3E;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Каталог конфигурации&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/olcrtc-users/&amp;amp;#x3C;имя&amp;amp;#x3E;/&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Файл с переменными&lt;br /&gt;
|&amp;lt;code&amp;gt;/opt/olcrtc-users/&amp;amp;#x3C;имя&amp;amp;#x3E;/.env&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Compose project&lt;br /&gt;
|&amp;lt;code&amp;gt;olcrtc-user-&amp;amp;#x3C;имя&amp;amp;#x3E;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Docker volume&lt;br /&gt;
|&amp;lt;code&amp;gt;olcrtc-user-&amp;amp;#x3C;имя&amp;amp;#x3E;_state&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Виртуальная конференция&lt;br /&gt;
|Уникальная, создаётся при первом запуске&lt;br /&gt;
|-&lt;br /&gt;
|Ключ шифрования&lt;br /&gt;
|Уникальный, 32 случайных байта&lt;br /&gt;
|-&lt;br /&gt;
|Ссылка вида &amp;lt;code&amp;gt;olcrtc://...&amp;lt;/code&amp;gt;&lt;br /&gt;
|Уникальная&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Структура каталогов ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/olcrtc/                           # репозиторий + Dockerfile (build context)&lt;br /&gt;
└── (код, не меняется после установки)&lt;br /&gt;
&lt;br /&gt;
/opt/olcrtc-users/                     # каталог менеджера пользователей&lt;br /&gt;
├── shared/&lt;br /&gt;
│   ├── docker-compose.user.yml        # один шаблон compose для всех пользователей&lt;br /&gt;
│   └── defaults.env                   # значения по умолчанию для новых пользователей&lt;br /&gt;
├── alice/&lt;br /&gt;
│   └── .env                           # личные данные пользователя alice&lt;br /&gt;
├── bob/&lt;br /&gt;
│   └── .env&lt;br /&gt;
└── carol/&lt;br /&gt;
    └── .env&lt;br /&gt;
&lt;br /&gt;
/usr/local/bin/olcrtc-users            # сам скрипт-меню&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Установка скрипта ===&lt;br /&gt;
Все команды выполняются на сервере по SSH.&lt;br /&gt;
&lt;br /&gt;
==== Шаг 1. Создание общего каталога ====&lt;br /&gt;
Создайте корневой каталог для пользователей.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/olcrtc-users/shared&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Защитите каталог.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 700 /opt/olcrtc-users&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Шаг 2. Создание общего шаблона docker-compose ====&lt;br /&gt;
Откройте файл для редактирования.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/olcrtc-users/shared/docker-compose.user.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте следующее содержимое.&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  olcrtc:&lt;br /&gt;
    image: olcrtc/server:local&lt;br /&gt;
    container_name: &amp;quot;olcrtc-user-${OLCRTC_CLIENT_ID}&amp;quot;&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    environment:&lt;br /&gt;
      OLCRTC_MODE: srv&lt;br /&gt;
      OLCRTC_CARRIER: &amp;quot;${OLCRTC_CARRIER}&amp;quot;&lt;br /&gt;
      OLCRTC_TRANSPORT: &amp;quot;${OLCRTC_TRANSPORT}&amp;quot;&lt;br /&gt;
      OLCRTC_ROOM_ID: &amp;quot;${OLCRTC_ROOM_ID}&amp;quot;&lt;br /&gt;
      OLCRTC_CLIENT_ID: &amp;quot;${OLCRTC_CLIENT_ID}&amp;quot;&lt;br /&gt;
      OLCRTC_KEY: &amp;quot;${OLCRTC_KEY}&amp;quot;&lt;br /&gt;
      OLCRTC_DNS: &amp;quot;${OLCRTC_DNS}&amp;quot;&lt;br /&gt;
      OLCRTC_SOCKS_PROXY: &amp;quot;${OLCRTC_SOCKS_PROXY}&amp;quot;&lt;br /&gt;
      OLCRTC_SOCKS_PROXY_PORT: &amp;quot;${OLCRTC_SOCKS_PROXY_PORT}&amp;quot;&lt;br /&gt;
      OLCRTC_VP8_FPS: &amp;quot;${OLCRTC_VP8_FPS}&amp;quot;&lt;br /&gt;
      OLCRTC_VP8_BATCH: &amp;quot;${OLCRTC_VP8_BATCH}&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - state:/var/lib/olcrtc&lt;br /&gt;
    init: true&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  state:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Шаг 3. Создание файла значений по умолчанию ====&lt;br /&gt;
Откройте файл для редактирования.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/olcrtc-users/shared/defaults.env&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте следующее (если используете egress через WARP — оставьте порт &amp;lt;code&amp;gt;24365&amp;lt;/code&amp;gt; или замените на свой &amp;lt;code&amp;gt;YOUR_SOCKS_PORT&amp;lt;/code&amp;gt;).&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
OLCRTC_CARRIER=wbstream&lt;br /&gt;
OLCRTC_TRANSPORT=vp8channel&lt;br /&gt;
OLCRTC_DNS=1.1.1.1:53&lt;br /&gt;
OLCRTC_SOCKS_PROXY=127.0.0.1&lt;br /&gt;
OLCRTC_SOCKS_PROXY_PORT=24365&lt;br /&gt;
OLCRTC_VP8_FPS=60&lt;br /&gt;
OLCRTC_VP8_BATCH=64&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Сохраните файл: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Защитите файл.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 600 /opt/olcrtc-users/shared/defaults.env&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если egress через WARP вам &#039;&#039;&#039;не нужен&#039;&#039;&#039;, выполните дополнительную команду — она очистит поле SOCKS-прокси.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sed -i &#039;s|OLCRTC_SOCKS_PROXY=127.0.0.1|OLCRTC_SOCKS_PROXY=|&#039; /opt/olcrtc-users/shared/defaults.env&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Шаг 4. Создание самого скрипта ====&lt;br /&gt;
Откройте файл скрипта в редакторе.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /usr/local/bin/olcrtc-users&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Вставьте полное содержимое скрипта (исходный код целиком — в спойлере «Исходный код скрипта &amp;lt;code&amp;gt;olcrtc-users&amp;lt;/code&amp;gt;» в конце статьи).&lt;br /&gt;
&lt;br /&gt;
Сохраните файл: &amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сделайте файл исполняемым.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod 0755 /usr/local/bin/olcrtc-users&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Проверьте корректность синтаксиса.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
bash -n /usr/local/bin/olcrtc-users &amp;amp;&amp;amp; echo OK&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если в выводе &amp;lt;code&amp;gt;OK&amp;lt;/code&amp;gt; — скрипт установлен правильно.&lt;br /&gt;
&lt;br /&gt;
=== Использование скрипта ===&lt;br /&gt;
Запустите.&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
olcrtc-users&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Появится меню:&amp;lt;pre&amp;gt;&lt;br /&gt;
=== olcrtc users ===&lt;br /&gt;
  1) Список пользователей (выбор → ссылка)&lt;br /&gt;
  2) Создать пользователя&lt;br /&gt;
  3) Удалить пользователя&lt;br /&gt;
  0) Выход&lt;br /&gt;
&amp;gt; _&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Пункт 1: список пользователей ====&lt;br /&gt;
После выбора отобразится таблица:&amp;lt;pre&amp;gt;&lt;br /&gt;
    #  name                           status&lt;br /&gt;
  ---  ------------------------------ ------------&lt;br /&gt;
    1) alice                          running&lt;br /&gt;
    2) bob                            running&lt;br /&gt;
    3) carol                          exited&lt;br /&gt;
&amp;lt;/pre&amp;gt;Введите номер пользователя и нажмите &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; — появится полная карточка с готовой ссылкой &amp;lt;code&amp;gt;olcrtc://...&amp;lt;/code&amp;gt;:&amp;lt;pre&amp;gt;&lt;br /&gt;
name        : alice&lt;br /&gt;
status      : running&lt;br /&gt;
carrier     : wbstream&lt;br /&gt;
transport   : vp8channel&lt;br /&gt;
room_id     : 019e07b8-e292-73ec-a40b-6a6e4957ce01&lt;br /&gt;
client_id   : alice&lt;br /&gt;
key         : 1c3f8a2b...d4e5f6a7&lt;br /&gt;
&lt;br /&gt;
URI for olcbox:&lt;br /&gt;
olcrtc://wbstream?vp8channel@019e07b8-e292-73ec-a40b-6a6e4957ce01#1c3f8a2b...d4e5f6a7%alice$alice&lt;br /&gt;
&amp;lt;/pre&amp;gt;Чтобы пропустить выбор и вернуться в меню — нажмите &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; без ввода номера.&lt;br /&gt;
&lt;br /&gt;
==== Пункт 2: создание пользователя ====&lt;br /&gt;
Скрипт спросит имя.&amp;lt;pre&amp;gt;&lt;br /&gt;
Имя пользователя:&lt;br /&gt;
&amp;lt;/pre&amp;gt;Введите имя на латинице (буквы, цифры, &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;, длина 1–32 символа), например &amp;lt;code&amp;gt;alice&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Затем спросит, как получить ключ.&amp;lt;pre&amp;gt;&lt;br /&gt;
Ключ шифрования: [a]uto / [m]anual (по умолчанию a):&lt;br /&gt;
&amp;lt;/pre&amp;gt;Введите &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; (или просто нажмите &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;) — скрипт сгенерирует ключ автоматически.&lt;br /&gt;
&lt;br /&gt;
Если хотите ввести ключ вручную — введите &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; и затем 64-символьный hex-ключ.&lt;br /&gt;
&lt;br /&gt;
После этого скрипт сам:&lt;br /&gt;
&lt;br /&gt;
* создаст каталог пользователя;&lt;br /&gt;
* запустит контейнер;&lt;br /&gt;
* подождёт создания виртуальной конференции;&lt;br /&gt;
* запишет полученный room_id в .env;&lt;br /&gt;
* перезапустит контейнер с фиксированным room_id;&lt;br /&gt;
* выведет готовую карточку с ссылкой.&lt;br /&gt;
&lt;br /&gt;
==== Пункт 3: удаление пользователя ====&lt;br /&gt;
Скрипт покажет список.&amp;lt;pre&amp;gt;&lt;br /&gt;
    1) alice&lt;br /&gt;
    2) bob&lt;br /&gt;
    3) carol&lt;br /&gt;
&amp;lt;/pre&amp;gt;Введите номер удаляемого пользователя, нажмите &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Скрипт спросит подтверждение.&amp;lt;pre&amp;gt;&lt;br /&gt;
Удалить пользователя &amp;quot;carol&amp;quot;? (y/N):&lt;br /&gt;
&amp;lt;/pre&amp;gt;Введите &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; и нажмите &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;. Если введёте что-то другое или просто &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; — операция отменится.&lt;br /&gt;
&lt;br /&gt;
После подтверждения:&lt;br /&gt;
&lt;br /&gt;
* контейнер будет остановлен и удалён;&lt;br /&gt;
* docker volume будет удалён;&lt;br /&gt;
* каталог пользователя будет удалён;&lt;br /&gt;
* ссылка &amp;lt;code&amp;gt;olcrtc://...&amp;lt;/code&amp;gt; у этого пользователя &#039;&#039;&#039;перестанет работать&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Исходный код скрипта olcrtc-users ==&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
!Развернуть полный исходный код и подробное объяснение архитектуры скрипта&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
=== Полный исходный код ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env bash&lt;br /&gt;
# olcrtc-users — управление пользователями olcrtc через docker compose.&lt;br /&gt;
# UI: 3 пункта (список / создать / удалить), под капотом — отдельный контейнер на пользователя.&lt;br /&gt;
&lt;br /&gt;
set -euo pipefail&lt;br /&gt;
&lt;br /&gt;
USERS_DIR=/opt/olcrtc-users&lt;br /&gt;
SHARED=$USERS_DIR/shared&lt;br /&gt;
COMPOSE=$SHARED/docker-compose.user.yml&lt;br /&gt;
DEFAULTS=$SHARED/defaults.env&lt;br /&gt;
&lt;br /&gt;
if [ ! -f &amp;quot;$COMPOSE&amp;quot; ] || [ ! -f &amp;quot;$DEFAULTS&amp;quot; ]; then&lt;br /&gt;
    echo &amp;quot;[X] $SHARED is not initialized. Aborting.&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# ----- helpers -----&lt;br /&gt;
list_users() {&lt;br /&gt;
    find &amp;quot;$USERS_DIR&amp;quot; -mindepth 1 -maxdepth 1 -type d ! -name shared -printf &amp;quot;%f\n&amp;quot; | sort&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
container_status() {&lt;br /&gt;
    docker inspect -f &amp;quot;{{.State.Status}}&amp;quot; &amp;quot;olcrtc-user-$1&amp;quot; 2&amp;gt;/dev/null || echo &amp;quot;missing&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
read_env() {&lt;br /&gt;
    local f=$1 k=$2&lt;br /&gt;
    grep -E &amp;quot;^${k}=&amp;quot; &amp;quot;$f&amp;quot; | cut -d= -f2-&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
build_uri() {&lt;br /&gt;
    local f=$1&lt;br /&gt;
    local carrier transport room key cid&lt;br /&gt;
    carrier=$(read_env &amp;quot;$f&amp;quot; OLCRTC_CARRIER)&lt;br /&gt;
    transport=$(read_env &amp;quot;$f&amp;quot; OLCRTC_TRANSPORT)&lt;br /&gt;
    room=$(read_env &amp;quot;$f&amp;quot; OLCRTC_ROOM_ID)&lt;br /&gt;
    key=$(read_env &amp;quot;$f&amp;quot; OLCRTC_KEY)&lt;br /&gt;
    cid=$(read_env &amp;quot;$f&amp;quot; OLCRTC_CLIENT_ID)&lt;br /&gt;
    printf &amp;quot;olcrtc://%s?%s@%s#%s%%%s\$%s\n&amp;quot; \&lt;br /&gt;
        &amp;quot;$carrier&amp;quot; &amp;quot;$transport&amp;quot; &amp;quot;$room&amp;quot; &amp;quot;$key&amp;quot; &amp;quot;$cid&amp;quot; &amp;quot;$cid&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
show_user() {&lt;br /&gt;
    local user=$1&lt;br /&gt;
    local f=$USERS_DIR/$user/.env&lt;br /&gt;
    local status; status=$(container_status &amp;quot;$user&amp;quot;)&lt;br /&gt;
    echo &amp;quot;name        : $user&amp;quot;&lt;br /&gt;
    echo &amp;quot;status      : $status&amp;quot;&lt;br /&gt;
    echo &amp;quot;carrier     : $(read_env &amp;quot;$f&amp;quot; OLCRTC_CARRIER)&amp;quot;&lt;br /&gt;
    echo &amp;quot;transport   : $(read_env &amp;quot;$f&amp;quot; OLCRTC_TRANSPORT)&amp;quot;&lt;br /&gt;
    echo &amp;quot;room_id     : $(read_env &amp;quot;$f&amp;quot; OLCRTC_ROOM_ID)&amp;quot;&lt;br /&gt;
    echo &amp;quot;client_id   : $(read_env &amp;quot;$f&amp;quot; OLCRTC_CLIENT_ID)&amp;quot;&lt;br /&gt;
    echo &amp;quot;key         : $(read_env &amp;quot;$f&amp;quot; OLCRTC_KEY)&amp;quot;&lt;br /&gt;
    echo&lt;br /&gt;
    echo &amp;quot;URI for olcbox:&amp;quot;&lt;br /&gt;
    build_uri &amp;quot;$f&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
valid_name() { [[ &amp;quot;$1&amp;quot; =~ ^[a-zA-Z0-9_-]{1,32}$ ]]; }&lt;br /&gt;
&lt;br /&gt;
compose_up() {&lt;br /&gt;
    local user=$1&lt;br /&gt;
    docker compose -f &amp;quot;$COMPOSE&amp;quot; --env-file &amp;quot;$USERS_DIR/$user/.env&amp;quot; \&lt;br /&gt;
        -p &amp;quot;olcrtc-user-$user&amp;quot; up -d&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
compose_down() {&lt;br /&gt;
    local user=$1&lt;br /&gt;
    docker compose -f &amp;quot;$COMPOSE&amp;quot; --env-file &amp;quot;$USERS_DIR/$user/.env&amp;quot; \&lt;br /&gt;
        -p &amp;quot;olcrtc-user-$user&amp;quot; down -v&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# ----- menu actions -----&lt;br /&gt;
action_list() {&lt;br /&gt;
    mapfile -t users &amp;lt; &amp;lt;(list_users)&lt;br /&gt;
    if [ ${#users[@]} -eq 0 ]; then&lt;br /&gt;
        echo &amp;quot;(пользователей нет)&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
    printf &amp;quot;  %3s  %-30s %-12s\n&amp;quot; &amp;quot;#&amp;quot; &amp;quot;name&amp;quot; &amp;quot;status&amp;quot;&lt;br /&gt;
    printf &amp;quot;  %3s  %-30s %-12s\n&amp;quot; &amp;quot;---&amp;quot; &amp;quot;------------------------------&amp;quot; &amp;quot;------------&amp;quot;&lt;br /&gt;
    local i&lt;br /&gt;
    for i in &amp;quot;${!users[@]}&amp;quot;; do&lt;br /&gt;
        printf &amp;quot;  %3d) %-30s %-12s\n&amp;quot; \&lt;br /&gt;
            &amp;quot;$((i+1))&amp;quot; &amp;quot;${users[$i]}&amp;quot; &amp;quot;$(container_status &amp;quot;${users[$i]}&amp;quot;)&amp;quot;&lt;br /&gt;
    done&lt;br /&gt;
    echo&lt;br /&gt;
    read -rp &amp;quot;Введите номер чтобы показать ссылку (Enter — пропустить): &amp;quot; pick&lt;br /&gt;
    [ -z &amp;quot;$pick&amp;quot; ] &amp;amp;&amp;amp; return&lt;br /&gt;
    if ! [[ &amp;quot;$pick&amp;quot; =~ ^[0-9]+$ ]] || [ &amp;quot;$pick&amp;quot; -lt 1 ] || [ &amp;quot;$pick&amp;quot; -gt &amp;quot;${#users[@]}&amp;quot; ]; then&lt;br /&gt;
        echo &amp;quot;(неверный номер)&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
    echo&lt;br /&gt;
    show_user &amp;quot;${users[$((pick-1))]}&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
action_new() {&lt;br /&gt;
    read -rp &amp;quot;Имя пользователя: &amp;quot; name&lt;br /&gt;
    if ! valid_name &amp;quot;$name&amp;quot;; then&lt;br /&gt;
        echo &amp;quot;(имя должно быть 1..32 символа, только a-z A-Z 0-9 _ -)&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
    if [ -d &amp;quot;$USERS_DIR/$name&amp;quot; ]; then&lt;br /&gt;
        echo &amp;quot;(пользователь \&amp;quot;$name\&amp;quot; уже существует)&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    local key&lt;br /&gt;
    read -rp &amp;quot;Ключ шифрования: [a]uto / [m]anual (по умолчанию a): &amp;quot; mode&lt;br /&gt;
    case &amp;quot;${mode:-a}&amp;quot; in&lt;br /&gt;
        m|M)&lt;br /&gt;
            read -rp &amp;quot;Введите 64-символьный hex-ключ: &amp;quot; key&lt;br /&gt;
            if ! [[ &amp;quot;$key&amp;quot; =~ ^[0-9a-fA-F]{64}$ ]]; then&lt;br /&gt;
                echo &amp;quot;(не выглядит как 64-hex)&amp;quot;&lt;br /&gt;
                return&lt;br /&gt;
            fi&lt;br /&gt;
            ;;&lt;br /&gt;
        *)&lt;br /&gt;
            key=$(openssl rand -hex 32)&lt;br /&gt;
            echo &amp;quot;[*] сгенерирован ключ: $key&amp;quot;&lt;br /&gt;
            ;;&lt;br /&gt;
    esac&lt;br /&gt;
&lt;br /&gt;
    mkdir -p &amp;quot;$USERS_DIR/$name&amp;quot;&lt;br /&gt;
    # shellcheck disable=SC1090&lt;br /&gt;
    set -a; source &amp;quot;$DEFAULTS&amp;quot;; set +a&lt;br /&gt;
    cat &amp;gt; &amp;quot;$USERS_DIR/$name/.env&amp;quot; &amp;lt;&amp;lt;EOF&lt;br /&gt;
OLCRTC_CARRIER=$OLCRTC_CARRIER&lt;br /&gt;
OLCRTC_TRANSPORT=$OLCRTC_TRANSPORT&lt;br /&gt;
OLCRTC_ROOM_ID=any&lt;br /&gt;
OLCRTC_CLIENT_ID=$name&lt;br /&gt;
OLCRTC_KEY=$key&lt;br /&gt;
OLCRTC_DNS=$OLCRTC_DNS&lt;br /&gt;
OLCRTC_SOCKS_PROXY=$OLCRTC_SOCKS_PROXY&lt;br /&gt;
OLCRTC_SOCKS_PROXY_PORT=$OLCRTC_SOCKS_PROXY_PORT&lt;br /&gt;
OLCRTC_VP8_FPS=$OLCRTC_VP8_FPS&lt;br /&gt;
OLCRTC_VP8_BATCH=$OLCRTC_VP8_BATCH&lt;br /&gt;
EOF&lt;br /&gt;
    chmod 600 &amp;quot;$USERS_DIR/$name/.env&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    echo &amp;quot;[*] стартую контейнер...&amp;quot;&lt;br /&gt;
    compose_up &amp;quot;$name&amp;quot; &amp;gt;/dev/null&lt;br /&gt;
    echo &amp;quot;[*] жду создания комнаты WB Stream...&amp;quot;&lt;br /&gt;
    local room=&amp;quot;&amp;quot;&lt;br /&gt;
    local i&lt;br /&gt;
    for i in $(seq 1 30); do&lt;br /&gt;
        sleep 2&lt;br /&gt;
        room=$(docker logs &amp;quot;olcrtc-user-$name&amp;quot; 2&amp;gt;&amp;amp;1 \&lt;br /&gt;
            | grep -oE &amp;quot;WB Stream room created: [0-9a-f-]+&amp;quot; \&lt;br /&gt;
            | head -1 | awk &amp;quot;{print \$NF}&amp;quot;)&lt;br /&gt;
        [ -n &amp;quot;$room&amp;quot; ] &amp;amp;&amp;amp; break&lt;br /&gt;
    done&lt;br /&gt;
    if [ -z &amp;quot;$room&amp;quot; ]; then&lt;br /&gt;
        echo &amp;quot;[!] не удалось получить room_id. Логи:&amp;quot;&lt;br /&gt;
        docker logs --tail 30 &amp;quot;olcrtc-user-$name&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
    echo &amp;quot;[+] комната создана: $room&amp;quot;&lt;br /&gt;
    sed -i &amp;quot;s/^OLCRTC_ROOM_ID=any\$/OLCRTC_ROOM_ID=$room/&amp;quot; &amp;quot;$USERS_DIR/$name/.env&amp;quot;&lt;br /&gt;
    compose_up &amp;quot;$name&amp;quot; &amp;gt;/dev/null&lt;br /&gt;
    sleep 3&lt;br /&gt;
    echo&lt;br /&gt;
    show_user &amp;quot;$name&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
action_delete() {&lt;br /&gt;
    mapfile -t users &amp;lt; &amp;lt;(list_users)&lt;br /&gt;
    if [ ${#users[@]} -eq 0 ]; then&lt;br /&gt;
        echo &amp;quot;(пользователей нет)&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
    local i&lt;br /&gt;
    for i in &amp;quot;${!users[@]}&amp;quot;; do&lt;br /&gt;
        printf &amp;quot;  %3d) %s\n&amp;quot; &amp;quot;$((i+1))&amp;quot; &amp;quot;${users[$i]}&amp;quot;&lt;br /&gt;
    done&lt;br /&gt;
    echo&lt;br /&gt;
    read -rp &amp;quot;Номер удаляемого: &amp;quot; pick&lt;br /&gt;
    if ! [[ &amp;quot;$pick&amp;quot; =~ ^[0-9]+$ ]] || [ &amp;quot;$pick&amp;quot; -lt 1 ] || [ &amp;quot;$pick&amp;quot; -gt &amp;quot;${#users[@]}&amp;quot; ]; then&lt;br /&gt;
        echo &amp;quot;(неверный номер)&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
    local user=${users[$((pick-1))]}&lt;br /&gt;
    read -rp &amp;quot;Удалить пользователя \&amp;quot;$user\&amp;quot;? (y/N): &amp;quot; conf&lt;br /&gt;
    if ! [[ &amp;quot;$conf&amp;quot; =~ ^[yY]$ ]]; then&lt;br /&gt;
        echo &amp;quot;(отменено)&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
    compose_down &amp;quot;$user&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || true&lt;br /&gt;
    rm -rf &amp;quot;${USERS_DIR:?}/$user&amp;quot;&lt;br /&gt;
    echo &amp;quot;[+] пользователь $user удалён&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# ----- main -----&lt;br /&gt;
while true; do&lt;br /&gt;
    echo&lt;br /&gt;
    echo &amp;quot;=== olcrtc users ===&amp;quot;&lt;br /&gt;
    echo &amp;quot;  1) Список пользователей (выбор → ссылка)&amp;quot;&lt;br /&gt;
    echo &amp;quot;  2) Создать пользователя&amp;quot;&lt;br /&gt;
    echo &amp;quot;  3) Удалить пользователя&amp;quot;&lt;br /&gt;
    echo &amp;quot;  0) Выход&amp;quot;&lt;br /&gt;
    read -rp &amp;quot;&amp;gt; &amp;quot; choice&lt;br /&gt;
    case &amp;quot;$choice&amp;quot; in&lt;br /&gt;
        1) action_list ;;&lt;br /&gt;
        2) action_new ;;&lt;br /&gt;
        3) action_delete ;;&lt;br /&gt;
        0|q|Q|&amp;quot;&amp;quot;) exit 0 ;;&lt;br /&gt;
        *) echo &amp;quot;(неверный выбор)&amp;quot; ;;&lt;br /&gt;
    esac&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Устройство скрипта ===&lt;br /&gt;
&lt;br /&gt;
==== Общий принцип ====&lt;br /&gt;
Скрипт — это интерактивная обёртка над &amp;lt;code&amp;gt;docker compose&amp;lt;/code&amp;gt;. Никакой собственной бизнес-логики у него нет — все действия сводятся к запуску и остановке контейнеров с разными параметрами.&lt;br /&gt;
&lt;br /&gt;
Каждый пользователь — это отдельный compose-проект с уникальным именем &amp;lt;code&amp;gt;olcrtc-user-&amp;amp;#x3C;имя&amp;amp;#x3E;&amp;lt;/code&amp;gt;. Compose-файл единый для всех (&amp;lt;code&amp;gt;shared/docker-compose.user.yml&amp;lt;/code&amp;gt;); различия задаются через &amp;lt;code&amp;gt;--env-file&amp;lt;/code&amp;gt;, который указывает на личный &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; пользователя.&lt;br /&gt;
&lt;br /&gt;
==== Защитные механизмы ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;set -euo pipefail&amp;lt;/code&amp;gt; — прерывание при любой ошибке, защита от использования несуществующих переменных, корректная обработка пайпов.&lt;br /&gt;
* Проверка наличия &amp;lt;code&amp;gt;shared/&amp;lt;/code&amp;gt; в самом начале — скрипт не запустится в неинициализированной системе.&lt;br /&gt;
* Валидация имени по регулярному выражению &amp;lt;code&amp;gt;^[a-zA-Z0-9_-]{1,32}$&amp;lt;/code&amp;gt; — защита от инъекций в имена контейнеров и путей файловой системы.&lt;br /&gt;
* Валидация ключа по регулярному выражению &amp;lt;code&amp;gt;^[0-9a-fA-F]{64}$&amp;lt;/code&amp;gt; — защита от неправильного формата при ручном вводе.&lt;br /&gt;
* Подтверждение &amp;lt;code&amp;gt;(y/N)&amp;lt;/code&amp;gt; при удалении — защита от случайного удаления.&lt;br /&gt;
* Конструкция &amp;lt;code&amp;gt;${USERS_DIR:?}&amp;lt;/code&amp;gt; в &amp;lt;code&amp;gt;rm -rf&amp;lt;/code&amp;gt; — защита от случайного &amp;lt;code&amp;gt;rm -rf /&amp;lt;/code&amp;gt;, если переменная окажется пустой.&lt;br /&gt;
&lt;br /&gt;
==== Хелперы ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Функция&lt;br /&gt;
!Назначение&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;list_users()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Возвращает список всех пользователей. Использует &amp;lt;code&amp;gt;find&amp;lt;/code&amp;gt; с фильтром &amp;lt;code&amp;gt;-mindepth 1 -maxdepth 1 -type d&amp;lt;/code&amp;gt; и исключает каталог &amp;lt;code&amp;gt;shared&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;container_status()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Опрашивает Docker через &amp;lt;code&amp;gt;docker inspect -f {{.State.Status}}&amp;lt;/code&amp;gt;. При отсутствии контейнера возвращает строку &amp;lt;code&amp;gt;missing&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;read_env()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Читает значение переменной из &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;grep + cut&amp;lt;/code&amp;gt;. Не использует &amp;lt;code&amp;gt;source&amp;lt;/code&amp;gt;, чтобы избежать побочных эффектов от загрузки переменных.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;build_uri()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Конкатенирует значения переменных в URI &amp;lt;code&amp;gt;olcrtc://CARRIER?TRANSPORT@ROOM#KEY%CID$MIMO&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;show_user()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Полная карточка пользователя: статус, все поля, готовый URI.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;valid_name()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Проверка имени пользователя по регулярному выражению.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;compose_up()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;compose_down()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Запуск и остановка контейнера через &amp;lt;code&amp;gt;docker compose&amp;lt;/code&amp;gt; с правильными флагами &amp;lt;code&amp;gt;-f&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;--env-file&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-p&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Действие «Список пользователей» ====&lt;br /&gt;
&lt;br /&gt;
# Получает массив пользователей в переменной &amp;lt;code&amp;gt;users&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;mapfile&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Печатает заголовок таблицы.&lt;br /&gt;
# Для каждого пользователя печатает номер, имя и статус контейнера.&lt;br /&gt;
# Спрашивает номер. Пустой ввод — выход. Невалидный номер — сообщение об ошибке.&lt;br /&gt;
# При корректном выборе вызывает &amp;lt;code&amp;gt;show_user&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Действие «Создать пользователя» ====&lt;br /&gt;
&lt;br /&gt;
# Запрашивает имя, валидирует.&lt;br /&gt;
# Проверяет, что каталог &amp;lt;code&amp;gt;$USERS_DIR/$name&amp;lt;/code&amp;gt; ещё не существует.&lt;br /&gt;
# Запрашивает режим ключа: &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; (auto, по умолчанию) или &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; (manual).&lt;br /&gt;
# При auto вызывает &amp;lt;code&amp;gt;openssl rand -hex 32&amp;lt;/code&amp;gt;; при manual запрашивает и валидирует ввод.&lt;br /&gt;
# Создаёт каталог пользователя.&lt;br /&gt;
# Через &amp;lt;code&amp;gt;set -a; source $DEFAULTS; set +a&amp;lt;/code&amp;gt; подгружает дефолты в окружение.&lt;br /&gt;
# Записывает &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; пользователя через here-doc.&lt;br /&gt;
# Меняет права на &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; на &amp;lt;code&amp;gt;0600&amp;lt;/code&amp;gt; (только владелец).&lt;br /&gt;
# Запускает контейнер через &amp;lt;code&amp;gt;compose_up&amp;lt;/code&amp;gt;.&lt;br /&gt;
# В цикле до 60 секунд (&amp;lt;code&amp;gt;30 итераций × 2 сек&amp;lt;/code&amp;gt;) парсит логи контейнера регулярным выражением &amp;lt;code&amp;gt;WB Stream room created: [0-9a-f-]+&amp;lt;/code&amp;gt;.&lt;br /&gt;
# При получении room_id обновляет &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; через &amp;lt;code&amp;gt;sed -i&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Перезапускает контейнер с фиксированным room_id.&lt;br /&gt;
# Выводит карточку пользователя через &amp;lt;code&amp;gt;show_user&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Действие «Удалить пользователя» ====&lt;br /&gt;
&lt;br /&gt;
# Получает массив пользователей.&lt;br /&gt;
# Печатает пронумерованный список.&lt;br /&gt;
# Запрашивает номер, валидирует.&lt;br /&gt;
# Запрашивает подтверждение &amp;lt;code&amp;gt;(y/N)&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Вызывает &amp;lt;code&amp;gt;compose_down&amp;lt;/code&amp;gt; с флагом &amp;lt;code&amp;gt;-v&amp;lt;/code&amp;gt; — это удалит и docker volume.&lt;br /&gt;
# Удаляет каталог пользователя через &amp;lt;code&amp;gt;rm -rf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Главный цикл ====&lt;br /&gt;
Бесконечный цикл с &amp;lt;code&amp;gt;case&amp;lt;/code&amp;gt;-разбором ввода:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; → действие «Список»&lt;br /&gt;
* &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; → действие «Создать»&lt;br /&gt;
* &amp;lt;code&amp;gt;3&amp;lt;/code&amp;gt; → действие «Удалить»&lt;br /&gt;
* &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt;, пустой ввод (Enter, Ctrl+D) → выход.&lt;br /&gt;
* Любой другой ввод — сообщение «неверный выбор» и продолжение цикла.&lt;br /&gt;
&lt;br /&gt;
=== Возможные расширения ===&lt;br /&gt;
Скрипт намеренно простой и легко расширяется. Возможные улучшения:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Что добавить&lt;br /&gt;
!Как&lt;br /&gt;
|-&lt;br /&gt;
|Перезапуск отдельного пользователя&lt;br /&gt;
|Новый пункт меню → &amp;lt;code&amp;gt;compose_down&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;compose_up&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Просмотр логов пользователя&lt;br /&gt;
|&amp;lt;code&amp;gt;docker logs --tail 50 olcrtc-user-$name&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Экспорт всех URI в файл подписки&lt;br /&gt;
|Цикл по &amp;lt;code&amp;gt;list_users&amp;lt;/code&amp;gt;, на каждом — &amp;lt;code&amp;gt;build_uri&amp;lt;/code&amp;gt;; добавить заголовок согласно &amp;lt;code&amp;gt;docs/sub.md&amp;lt;/code&amp;gt; upstream-репозитория&lt;br /&gt;
|-&lt;br /&gt;
|Автоматическое обновление образа&lt;br /&gt;
|&amp;lt;code&amp;gt;git -C /opt/olcrtc pull --recurse-submodules&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;docker compose build&amp;lt;/code&amp;gt;, затем перезапуск всех пользователей&lt;br /&gt;
|-&lt;br /&gt;
|HTTPS-эндпоинт &amp;lt;code&amp;gt;/sub&amp;lt;/code&amp;gt; для раздачи конфигов&lt;br /&gt;
|Reverse proxy (caddy / nginx) на статический файл, который генерируется крон-задачей из &amp;lt;code&amp;gt;build_uri&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
=== Почему «один сервер ↔ один клиент»? ===&lt;br /&gt;
Это архитектурное свойство кода: сервер хранит одну сессию &amp;lt;code&amp;gt;smux&amp;lt;/code&amp;gt; и одно поле &amp;lt;code&amp;gt;clientID&amp;lt;/code&amp;gt;, не таблицу пиров. Изменение этой модели потребовало бы существенной переработки &amp;lt;code&amp;gt;internal/server/server.go&amp;lt;/code&amp;gt; и поддержки множественных peer-connection в каждом провайдере.&lt;br /&gt;
&lt;br /&gt;
=== Почему рекомендуется &amp;lt;code&amp;gt;vp8channel&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;datachannel&amp;lt;/code&amp;gt;? ===&lt;br /&gt;
&amp;lt;code&amp;gt;datachannel&amp;lt;/code&amp;gt; быстрее и имеет минимальный пинг, но: Telemost его не поддерживает, а Jazz может ограничивать IP-адреса серверов, использующих этот тип канала. &amp;lt;code&amp;gt;vp8channel&amp;lt;/code&amp;gt; работает со всеми тремя сервисами и подходит для большинства сценариев.&lt;br /&gt;
&lt;br /&gt;
=== Что такое «ограничение IP» со стороны carrier? ===&lt;br /&gt;
Некоторые carrier-сервисы используют автоматические эвристики против ботов. После срабатывания таких эвристик подключения с конкретного IP могут перестать пропускаться в виртуальные конференции. Лечится сменой IP сервера или ожиданием снятия ограничения. На момент написания статьи WB Stream таких эвристик не применяет.&lt;br /&gt;
&lt;br /&gt;
=== Сколько контейнеров можно запустить на одной виртуальной машине? ===&lt;br /&gt;
В простое каждый контейнер потребляет приблизительно 10–15 МБ RAM и около 0% CPU. На VM с 4 GiB RAM реалистично запустить 50–100 пользователей. Узкими местами обычно становятся пропускная способность сетевого канала и допустимое количество одновременных WebRTC-сессий со стороны carrier-сервиса.&lt;br /&gt;
&lt;br /&gt;
=== Можно ли использовать одну ссылку с нескольких устройств? ===&lt;br /&gt;
Технически — да, но не одновременно. Если включить туннель на двух устройствах с одной ссылкой, они будут конкурировать за один peer-connection и периодически разрывать друг друга. Для параллельной работы нужны разные пользователи (разные ссылки).&lt;br /&gt;
&lt;br /&gt;
=== Виден ли реальный видеосигнал участникам конференции? ===&lt;br /&gt;
В транспортах &amp;lt;code&amp;gt;vp8channel&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;seichannel&amp;lt;/code&amp;gt; поверх WebRTC отправляется минимально валидный видеопоток, в который встроены полезные данные. Внешне это выглядит как очень тихая «моностатичная» камера. В &amp;lt;code&amp;gt;videochannel&amp;lt;/code&amp;gt; отправляется реальный видеоряд (QR-коды или тайлы) — формально это видимая «картинка». Если в виртуальной конференции, кроме сервера и клиента, никого нет — это никак не проявляется.&lt;br /&gt;
&lt;br /&gt;
=== Что делать, если конкретный transport перестал работать? ===&lt;br /&gt;
Если carrier изменил проверки SFU и какой-то transport стал ненадёжен — переключитесь на другой transport (&amp;lt;code&amp;gt;seichannel&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;videochannel&amp;lt;/code&amp;gt;) или другой carrier. Меняется в &amp;lt;code&amp;gt;defaults.env&amp;lt;/code&amp;gt; для новых пользователей и в личном &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; для существующих (с последующим перезапуском контейнера).&lt;br /&gt;
&lt;br /&gt;
=== Можно ли совместить olcRTC с другими методами? ===&lt;br /&gt;
Да. С точки зрения клиентского приложения olcRTC — это локальный SOCKS5-прокси. Его можно использовать как один из outbound в xray, sing-box и подобных инструментах. На стороне сервера выходной трафик может быть направлен через xray + WARP (опциональный шаг 11 раздела установки) для дополнительной анонимизации.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Полезные ссылки ==&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/openlibrecommunity/olcrtc Репозиторий olcrtc на GitHub] — основной upstream проекта.&lt;br /&gt;
* [https://github.com/alananisimov/olcbox Olcbox] — мультиплатформенный клиент с UI (Android, macOS, Windows, Linux).&lt;br /&gt;
* [https://github.com/openlibrecommunity/olcrtc/blob/master/docs/uri.md docs/uri.md] — официальное описание формата URI.&lt;br /&gt;
* [https://github.com/openlibrecommunity/olcrtc/blob/master/docs/sub.md docs/sub.md] — формат файла подписки для нескольких локаций.&lt;br /&gt;
* [https://github.com/openlibrecommunity/olcrtc/blob/master/docs/settings.md docs/settings.md] — матрица совместимости carrier × transport, описание всех флагов.&lt;br /&gt;
* [https://github.com/MHSanaei/3x-ui 3x-ui] — панель управления xray-core (для настройки egress через WARP).&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A1%D1%83%D0%B2%D0%B5%D1%80%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82&amp;diff=961</id>
		<title>Суверенный интернет</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A1%D1%83%D0%B2%D0%B5%D1%80%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82&amp;diff=961"/>
		<updated>2026-05-09T07:19:01Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Эта страница посвящается всему что связано с ограничим доступа в интернет.&lt;br /&gt;
&lt;br /&gt;
На данный момент 20.04.26 мы имеем полную блокировку по белыми IP у операторов мобильной связи. И предпосылки к блокировкам на уровне провайдеров домашнего интернета.&lt;br /&gt;
&lt;br /&gt;
* [[Обход НКР|Установка и настройка связки Zapret + Podkop на OpenWRT]]&lt;br /&gt;
* [[Hysteria 2 каскад]]&lt;br /&gt;
* [[Whitelist-bypass: VK Creator (headless на сервере) + Joiner (Android)]]&lt;br /&gt;
* [[Установка MTProto Proxy (mtg) на Linux-сервере]]&lt;br /&gt;
* [[VK Turn Proxy + FreeTurn + VLESS]]&lt;br /&gt;
* [[NaïveProxy: установка полной каскадной цепочки]]&lt;br /&gt;
* olcRTC: туннель через легальные WebRTC-сервисы&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%9E%D0%B1%D1%85%D0%BE%D0%B4_%D0%9D%D0%9A%D0%A0&amp;diff=960</id>
		<title>Обход НКР</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%9E%D0%B1%D1%85%D0%BE%D0%B4_%D0%9D%D0%9A%D0%A0&amp;diff=960"/>
		<updated>2026-05-07T07:03:05Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* Исходный код скрипта */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Установка и настройка связки Zapret + Podkop на OpenWRT =&lt;br /&gt;
&lt;br /&gt;
== Введение ==&lt;br /&gt;
Данная инструкция описывает установку и настройку связки двух сервисов обхода блокировок на роутере OpenWRT:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Zapret&#039;&#039;&#039; — утилита DPI-обхода (anti-DPI), работает без VPN&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Podkop&#039;&#039;&#039; — прокси-менеджер на базе sing-box с поддержкой VPN&lt;br /&gt;
&lt;br /&gt;
=== Суть связки ===&lt;br /&gt;
Комбинация Zapret + Podkop позволяет реализовать оптимальную стратегию обхода блокировок:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Zapret&#039;&#039;&#039; обрабатывает трафик &#039;&#039;&#039;первым&#039;&#039;&#039; (приоритет firewall -150/-100) и применяет DPI-обход для популярных сервисов (YouTube, Discord, Steam и др.) &#039;&#039;&#039;без использования VPN&#039;&#039;&#039;. Это обеспечивает:&lt;br /&gt;
&lt;br /&gt;
#* Высокую скорость (нет шифрования VPN)&lt;br /&gt;
&lt;br /&gt;
#* Сохранение геолокации РФ (важно для YouTube, Twitch и других региональных сервисов)&lt;br /&gt;
&lt;br /&gt;
#* Минимальную нагрузку на роутер&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Podkop&#039;&#039;&#039; обрабатывает трафик &#039;&#039;&#039;вторым&#039;&#039;&#039; (приоритет firewall 0) и направляет через VPN/прокси &#039;&#039;&#039;только те домены&#039;&#039;&#039;, которые Zapret не может обойти или требуют смены региона&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-message-box mw-message-box-notice&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Важно.&#039;&#039;&#039; Эта архитектура позволяет &#039;&#039;&#039;экономить VPN-трафик&#039;&#039;&#039; и &#039;&#039;&#039;сохранять региональный контент&#039;&#039;&#039; (например, русскоязычные каналы YouTube), при этом имея полноценный VPN для заблокированных ресурсов.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Требования ==&lt;br /&gt;
&lt;br /&gt;
* OpenWRT версии 24 или выше&lt;br /&gt;
&lt;br /&gt;
* Минимум 25 МБ свободного места в памяти роутера&lt;br /&gt;
&lt;br /&gt;
* Доступ к интернету для загрузки пакетов&lt;br /&gt;
&lt;br /&gt;
* Базовые навыки работы с SSH/терминалом&lt;br /&gt;
&lt;br /&gt;
== Установка Zapret ==&lt;br /&gt;
&lt;br /&gt;
=== Шаг 1: Установка вспомогательных пакетов ===&lt;br /&gt;
Через веб-интерфейс OpenWRT перейдите в &#039;&#039;&#039;System → Software&#039;&#039;&#039; и установите:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;curl&amp;lt;/code&amp;gt; — для скачивания установщика&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;luci-app-ttyd&amp;lt;/code&amp;gt; — для доступа к терминалу через веб-интерфейс&lt;br /&gt;
&lt;br /&gt;
После установки &amp;lt;code&amp;gt;luci-app-ttyd&amp;lt;/code&amp;gt; в меню появится раздел &#039;&#039;&#039;Services → Terminal&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2: Запуск установщика Zapret ===&lt;br /&gt;
Откройте терминал (&#039;&#039;&#039;Services → Terminal&#039;&#039;&#039;) и выполните команду:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
curl -fsSL https://raw.githubusercontent.com/remittor/zapret-openwrt/zap1/zapret/update-pkg.sh -o /tmp/zap.sh &amp;amp;&amp;amp; sh /tmp/zap.sh -u 1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Дождитесь завершения установки.&lt;br /&gt;
&lt;br /&gt;
=== Шаг 3: Перезагрузка интерфейса ===&lt;br /&gt;
Выйдите из веб-интерфейса (&#039;&#039;&#039;Log Out&#039;&#039;&#039;) и войдите снова. В меню &#039;&#039;&#039;Services&#039;&#039;&#039; появится раздел &#039;&#039;&#039;Zapret&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Установка Podkop ==&lt;br /&gt;
Выполните команду в терминале:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sh &amp;lt;(wget -O - https://raw.githubusercontent.com/itdoginfo/podkop/refs/heads/main/install.sh)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После установки &#039;&#039;&#039;обязательно очистите кэш браузера&#039;&#039;&#039; и перезайдите в LuCI. В меню &#039;&#039;&#039;Services&#039;&#039;&#039; появится раздел &#039;&#039;&#039;Podkop&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Настройка Zapret ==&lt;br /&gt;
&lt;br /&gt;
После установки пакет &#039;&#039;&#039;уже содержит&#039;&#039;&#039; нужные домены и параметры — &#039;&#039;&#039;ручную настройку проходить не нужно&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Откройте &#039;&#039;&#039;Services → Zapret → Service&#039;&#039;&#039; и проверьте только следующее:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Service daemons control&#039;&#039;&#039; — включён (сервис Zapret активен).&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Service autorun control&#039;&#039;&#039; — включён (Zapret поднимается после перезагрузки роутера).&lt;br /&gt;
&lt;br /&gt;
При необходимости можно добавить свои домены в поле &#039;&#039;&#039;User hostname entries&#039;&#039;&#039; в веб-интерфейсе (как правило — &#039;&#039;&#039;по одному домену на строку&#039;&#039;&#039;); для типовой установки это &#039;&#039;&#039;не обязательно&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Настройка Podkop ==&lt;br /&gt;
&lt;br /&gt;
=== Важное предупреждение о списках сообщества ===&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-message-box mw-message-box-warning&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;ПРЕДУПРЕЖДЕНИЕ:&#039;&#039;&#039; Не используйте готовые списки сообщества &#039;&#039;&#039;Russian inside&#039;&#039;&#039; в базовой конфигурации!&lt;br /&gt;
&amp;lt;/div&amp;gt;&#039;&#039;&#039;Почему нельзя использовать готовые списки:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Готовые списки сообщества (например, Russian inside) включают домены YouTube, Google, Discord, которые &#039;&#039;&#039;уже обрабатываются Zapret&#039;&#039;&#039;. Если добавить их в Podkop, весь трафик этих сервисов будет принудительно направлен через VPN, что приведёт к:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Увеличению расхода VPN-трафика в десятки раз&#039;&#039;&#039; (YouTube потребляет гигабайты данных)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Смене региона&#039;&#039;&#039; на регион VPN-сервера (потеряете русскоязычный контент YouTube, региональные рекомендации)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Конфликту с Zapret&#039;&#039;&#039; (один и тот же домен будет обрабатываться дважды)&lt;br /&gt;
&lt;br /&gt;
=== Использование готового списка доменов ===&lt;br /&gt;
Для удобства мы подготовили &#039;&#039;&#039;готовый список доменов&#039;&#039;&#039; для Podkop, который:&lt;br /&gt;
&lt;br /&gt;
* Основан на актуальном списке &#039;&#039;&#039;Russian inside&#039;&#039;&#039; (&amp;lt;code&amp;gt;inside-raw.lst&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Исключает&#039;&#039;&#039; все домены из &amp;lt;code&amp;gt;zapret-hosts-google.txt&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;zapret-hosts-user.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Дополнен&#039;&#039;&#039; специализированными доменами (торрент-трекеры, облачные сервисы, AI-инструменты и др.)&lt;br /&gt;
&lt;br /&gt;
==== Шаг 1: Скопируйте список доменов ====&lt;br /&gt;
&amp;lt;div class=&amp;quot;toccolours mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;width:100%; overflow:auto;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;font-weight:bold;line-height:1.6;&amp;quot;&amp;gt;Список доменов для Podkop (нажмите, чтобы развернуть)&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot;&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
.ua&lt;br /&gt;
10minutemail.com&lt;br /&gt;
1337x.to&lt;br /&gt;
1fichier.com&lt;br /&gt;
24.kg&lt;br /&gt;
4freerussia.org&lt;br /&gt;
4pda.to&lt;br /&gt;
4pda.ws&lt;br /&gt;
4pna.com&lt;br /&gt;
529055.xyz&lt;br /&gt;
5sim.net&lt;br /&gt;
7dniv.rv.ua&lt;br /&gt;
7tv.app&lt;br /&gt;
7tv.io&lt;br /&gt;
9tv.co.il&lt;br /&gt;
a-13.1fichier.com&lt;br /&gt;
a-vrv.akamaized.net&lt;br /&gt;
abercrombie.com&lt;br /&gt;
abook-club.ru&lt;br /&gt;
academy.terrasoft.ua&lt;br /&gt;
activatica.org&lt;br /&gt;
adguard.com&lt;br /&gt;
adidas.com&lt;br /&gt;
adminforge.de&lt;br /&gt;
adobe.com&lt;br /&gt;
ads-twitter.com&lt;br /&gt;
adultmult.tv&lt;br /&gt;
agents.media&lt;br /&gt;
ahrefs.com&lt;br /&gt;
ai-chat.bsg.brave.com&lt;br /&gt;
ai.com&lt;br /&gt;
aircanada.com&lt;br /&gt;
akc.org&lt;br /&gt;
allegro.pl&lt;br /&gt;
alphacoders.com&lt;br /&gt;
alza.hu&lt;br /&gt;
amazfitwatchfaces.com&lt;br /&gt;
amdm.ru&lt;br /&gt;
amedia.site&lt;br /&gt;
amnezia.org&lt;br /&gt;
amplitude.com&lt;br /&gt;
amx.com&lt;br /&gt;
analog.com&lt;br /&gt;
andrevi.ch&lt;br /&gt;
anidub.com&lt;br /&gt;
anilib.me&lt;br /&gt;
anilibria.org&lt;br /&gt;
anilibria.top&lt;br /&gt;
anilibria.tv&lt;br /&gt;
anilibria.uno&lt;br /&gt;
anilibria.wtf&lt;br /&gt;
animaunt.org&lt;br /&gt;
anime-portal.su&lt;br /&gt;
anime1.best&lt;br /&gt;
animebest.org&lt;br /&gt;
animedia.tv&lt;br /&gt;
animego.org&lt;br /&gt;
animespirit.ru&lt;br /&gt;
anistar.org&lt;br /&gt;
anistars.ru&lt;br /&gt;
annas-archive.org&lt;br /&gt;
ansys.com&lt;br /&gt;
anthropic.com&lt;br /&gt;
any.do&lt;br /&gt;
aol.com&lt;br /&gt;
api.jetbrains.ai&lt;br /&gt;
api.service-kp.com&lt;br /&gt;
api.theins.info&lt;br /&gt;
api.themoviedb.org&lt;br /&gt;
apkmirror.com&lt;br /&gt;
app.zerossl.com&lt;br /&gt;
arbat.media&lt;br /&gt;
arc.net&lt;br /&gt;
archive.midnightchannel.net&lt;br /&gt;
archive.ph&lt;br /&gt;
archiveofourown.org&lt;br /&gt;
arduino.cc&lt;br /&gt;
as6723.net&lt;br /&gt;
assets.heroku.com&lt;br /&gt;
atlassian.com&lt;br /&gt;
atn.ua&lt;br /&gt;
att.com&lt;br /&gt;
attachments.f95zone.to&lt;br /&gt;
atv4.dnskp.cc&lt;br /&gt;
audiobookbay.lu&lt;br /&gt;
augmentcode.com&lt;br /&gt;
autodesk.com&lt;br /&gt;
avira.com&lt;br /&gt;
azathabar.com&lt;br /&gt;
azattyq.org&lt;br /&gt;
babook.org&lt;br /&gt;
baginya.org&lt;br /&gt;
baikal-journal.ru&lt;br /&gt;
bato.to&lt;br /&gt;
bbc.co.uk&lt;br /&gt;
bbc.com&lt;br /&gt;
bbci.co.uk&lt;br /&gt;
bcbits.com&lt;br /&gt;
bell-sw.com&lt;br /&gt;
bellingcat.com&lt;br /&gt;
bestbuy.com&lt;br /&gt;
bestchange.ru&lt;br /&gt;
bihus.info&lt;br /&gt;
bitdefender.com&lt;br /&gt;
bitnami.com&lt;br /&gt;
blackseanews.net&lt;br /&gt;
blinkshot.io&lt;br /&gt;
bluehost.com&lt;br /&gt;
booktracker.org&lt;br /&gt;
boominfo.org&lt;br /&gt;
booth.pm&lt;br /&gt;
booth.pximg.net&lt;br /&gt;
bosch.com&lt;br /&gt;
boschaftermarket.com&lt;br /&gt;
boschautoparts.com&lt;br /&gt;
botnadzor.org&lt;br /&gt;
brawlstarsgame.com&lt;br /&gt;
bricklink.com&lt;br /&gt;
broadcom.com&lt;br /&gt;
broncosportforum.com&lt;br /&gt;
bt4gprx.com&lt;br /&gt;
btdig.com&lt;br /&gt;
btod.com&lt;br /&gt;
buanzo.org&lt;br /&gt;
buf.build&lt;br /&gt;
bufferbloat.net&lt;br /&gt;
builds.parsec.app&lt;br /&gt;
buymeacoffee.com&lt;br /&gt;
byteoversea.com&lt;br /&gt;
canva.com&lt;br /&gt;
canva.dev&lt;br /&gt;
capacitorjs.com&lt;br /&gt;
capcut.com&lt;br /&gt;
carnegieendowment.org&lt;br /&gt;
carrefouruae.com&lt;br /&gt;
cats.com&lt;br /&gt;
cbilling.eu&lt;br /&gt;
cbilling.vip&lt;br /&gt;
cdn.web-platform.io&lt;br /&gt;
cdnbunny.org&lt;br /&gt;
cdninstagram.com&lt;br /&gt;
cdromance.org&lt;br /&gt;
cdw.com&lt;br /&gt;
censor.net&lt;br /&gt;
censortracker.org&lt;br /&gt;
chaos.com&lt;br /&gt;
chat.com&lt;br /&gt;
chat.openai.com.cdn.cloudflare.net&lt;br /&gt;
chatgpt.com&lt;br /&gt;
chaturbate.com&lt;br /&gt;
chenbro.com&lt;br /&gt;
cherta.media&lt;br /&gt;
chess.com&lt;br /&gt;
chesscomfiles.com&lt;br /&gt;
chub.ai&lt;br /&gt;
circlecrewpinkcrowd.com&lt;br /&gt;
cisco.com&lt;br /&gt;
cisecurity.org&lt;br /&gt;
citrix.com&lt;br /&gt;
clamav.net&lt;br /&gt;
clashofclans.com&lt;br /&gt;
clashroyaleapp.com&lt;br /&gt;
claude.ai&lt;br /&gt;
clevelandclinic.org&lt;br /&gt;
clickup.com&lt;br /&gt;
clip.opus.pro&lt;br /&gt;
cloudtorrents.com&lt;br /&gt;
cms-twdigitalassets.com&lt;br /&gt;
cnd2exp.online&lt;br /&gt;
cock.li&lt;br /&gt;
code.gist.build&lt;br /&gt;
codecguide.com&lt;br /&gt;
codeium.com&lt;br /&gt;
codelinaro.org&lt;br /&gt;
coingate.com&lt;br /&gt;
coinpayments.net&lt;br /&gt;
coinsbee.com&lt;br /&gt;
coldfilm.city&lt;br /&gt;
coldfilm.ink&lt;br /&gt;
coldfilm.xyz&lt;br /&gt;
colta.ru&lt;br /&gt;
community.sophos.com&lt;br /&gt;
connect.ngrok-agent.com&lt;br /&gt;
contabo.com&lt;br /&gt;
coomer.su&lt;br /&gt;
copilot.microsoft.com&lt;br /&gt;
corsair.com&lt;br /&gt;
coursera.org&lt;br /&gt;
cpu-monkey.com&lt;br /&gt;
credly.com&lt;br /&gt;
croxyproxy.com&lt;br /&gt;
crunchyroll.com&lt;br /&gt;
csskor.ill.in.ua&lt;br /&gt;
cub.red&lt;br /&gt;
currenttime.tv&lt;br /&gt;
cursorinfo.co.il&lt;br /&gt;
cvedetails.com&lt;br /&gt;
cyberghostvpn.com&lt;br /&gt;
cyxymu.info&lt;br /&gt;
daemon-tools.cc&lt;br /&gt;
dailylviv.com&lt;br /&gt;
dailymotion.com&lt;br /&gt;
danbooru.donmai.us&lt;br /&gt;
darthsternie.net&lt;br /&gt;
data-cdn.mbamupdates.com&lt;br /&gt;
data.cline.bot&lt;br /&gt;
deckbrew.xyz&lt;br /&gt;
decrypt.day&lt;br /&gt;
deepl.com&lt;br /&gt;
deepstatemap.live&lt;br /&gt;
deezer.com&lt;br /&gt;
delfi.lt&lt;br /&gt;
delfi.lv&lt;br /&gt;
delivery.2d.net.co&lt;br /&gt;
dell.com&lt;br /&gt;
dellcdn.com&lt;br /&gt;
depositphotos.com&lt;br /&gt;
designer.microsoft.com&lt;br /&gt;
designify.com&lt;br /&gt;
developer.nvidia.com&lt;br /&gt;
devexpress.com&lt;br /&gt;
deviantart.com&lt;br /&gt;
diabrowser.com&lt;br /&gt;
digash.live&lt;br /&gt;
digikey.com&lt;br /&gt;
digitalcontent.sky&lt;br /&gt;
digitalocean.com&lt;br /&gt;
discord.tools&lt;br /&gt;
discours.io&lt;br /&gt;
disctech.com&lt;br /&gt;
disneyplus.com&lt;br /&gt;
dlpsgame.com&lt;br /&gt;
docs.liquibase.com&lt;br /&gt;
document360.com&lt;br /&gt;
document360.io&lt;br /&gt;
dorama.live&lt;br /&gt;
doramalive.ru&lt;br /&gt;
doramy.club&lt;br /&gt;
dovod.online&lt;br /&gt;
download3.omnissa.com&lt;br /&gt;
doxa.team&lt;br /&gt;
dpidetector.org&lt;br /&gt;
dreamhost.com&lt;br /&gt;
dreamina.capcut.com&lt;br /&gt;
dub.sh&lt;br /&gt;
ducati.com&lt;br /&gt;
dumka.media&lt;br /&gt;
dw.com&lt;br /&gt;
dyson.com&lt;br /&gt;
e-hentai.org&lt;br /&gt;
e621.net&lt;br /&gt;
easydmarc.com&lt;br /&gt;
echofm.online&lt;br /&gt;
edemtv.me&lt;br /&gt;
editorx.com&lt;br /&gt;
edu-cisco.org&lt;br /&gt;
ef.com&lt;br /&gt;
ef.edu&lt;br /&gt;
eggertspiele.de&lt;br /&gt;
ej.ru&lt;br /&gt;
ekhokavkaza.com&lt;br /&gt;
element14.com&lt;br /&gt;
elements.envato.com&lt;br /&gt;
elevenlabs.io&lt;br /&gt;
elgato.com&lt;br /&gt;
eneba.com&lt;br /&gt;
epidemz.net.co&lt;br /&gt;
eporner.com&lt;br /&gt;
espreso.tv&lt;br /&gt;
etahub.com&lt;br /&gt;
etsy.com&lt;br /&gt;
euronews.com&lt;br /&gt;
euroradio.fm&lt;br /&gt;
eutrp.eu&lt;br /&gt;
everand.com&lt;br /&gt;
exchanger.bits.media&lt;br /&gt;
exler.ru&lt;br /&gt;
expandrive.com&lt;br /&gt;
expres.online&lt;br /&gt;
extremetech.com&lt;br /&gt;
f1.com&lt;br /&gt;
f95-zone.to&lt;br /&gt;
facebook.com&lt;br /&gt;
facebook.net&lt;br /&gt;
fansly.com&lt;br /&gt;
fast-torrent.club&lt;br /&gt;
fast.com&lt;br /&gt;
fastpic.org&lt;br /&gt;
fb.com&lt;br /&gt;
fbcdn.net&lt;br /&gt;
fbsbx.com&lt;br /&gt;
ficbook.net&lt;br /&gt;
filebin.net&lt;br /&gt;
filmitorrent.net&lt;br /&gt;
filmix.ac&lt;br /&gt;
filmix.biz&lt;br /&gt;
filmix.day&lt;br /&gt;
filmix.fan&lt;br /&gt;
filmix.fm&lt;br /&gt;
filmix.la&lt;br /&gt;
flibusta.is&lt;br /&gt;
flibusta.net&lt;br /&gt;
flipboard.com&lt;br /&gt;
flir.com&lt;br /&gt;
flir.eu&lt;br /&gt;
flisland.net&lt;br /&gt;
flourish.studio&lt;br /&gt;
fls.guru&lt;br /&gt;
fluke.com&lt;br /&gt;
flukenetworks.com&lt;br /&gt;
flyertalk.com&lt;br /&gt;
fn-volga.ru&lt;br /&gt;
fonge.org&lt;br /&gt;
footballapi.pulselive.com&lt;br /&gt;
force-user-content.com&lt;br /&gt;
force.com&lt;br /&gt;
forklog.com&lt;br /&gt;
formula1.com&lt;br /&gt;
fortanga.org&lt;br /&gt;
forum.netgate.com&lt;br /&gt;
forum.ru-board.com&lt;br /&gt;
foxnews.com&lt;br /&gt;
framer.com&lt;br /&gt;
freedomletters.org&lt;br /&gt;
freeimages.com&lt;br /&gt;
freemedia.io&lt;br /&gt;
freeones.com&lt;br /&gt;
fxnetworks.com&lt;br /&gt;
g2a.com&lt;br /&gt;
gagadget.com&lt;br /&gt;
gamedistribution.com&lt;br /&gt;
gamesrepack.com&lt;br /&gt;
gamestop.com&lt;br /&gt;
gaming.amazon.com&lt;br /&gt;
geforcenow.com&lt;br /&gt;
gelbooru.com&lt;br /&gt;
genspark.ai&lt;br /&gt;
geolocation.onetrust.com&lt;br /&gt;
germania.one&lt;br /&gt;
getoutline.com&lt;br /&gt;
getoutline.org&lt;br /&gt;
gfn.am&lt;br /&gt;
ghostrc.game.idtech.services&lt;br /&gt;
gifyu.com&lt;br /&gt;
git.new&lt;br /&gt;
glavred.info&lt;br /&gt;
glavred.net&lt;br /&gt;
global.fncstatic.com&lt;br /&gt;
global.platform.seconddinnertech.com&lt;br /&gt;
glpals.com&lt;br /&gt;
godaddy.com&lt;br /&gt;
gofile.io&lt;br /&gt;
gofundme.com&lt;br /&gt;
golosameriki.com&lt;br /&gt;
gonitro.com&lt;br /&gt;
goodreads.com&lt;br /&gt;
&lt;br /&gt;
gpsonextra.net&lt;br /&gt;
gpu-monkey.com&lt;br /&gt;
gql.twitch.tv&lt;br /&gt;
gr-assets.com&lt;br /&gt;
grafana.com&lt;br /&gt;
grani.ru&lt;br /&gt;
graty.me&lt;br /&gt;
graylog.org&lt;br /&gt;
grizzlysms.com&lt;br /&gt;
grok.com&lt;br /&gt;
groq.com&lt;br /&gt;
groupon.com&lt;br /&gt;
guilded.gg&lt;br /&gt;
gulagu.net&lt;br /&gt;
habr.com&lt;br /&gt;
hackernoon.com&lt;br /&gt;
hackmd.io&lt;br /&gt;
halooglasi.com&lt;br /&gt;
hashicorp.com&lt;br /&gt;
haydaygame.com&lt;br /&gt;
hbomax.com&lt;br /&gt;
hc-ping.com&lt;br /&gt;
hchk.io&lt;br /&gt;
hd-rezka.tv&lt;br /&gt;
hdkinoteatr.com&lt;br /&gt;
hdrezka.ac&lt;br /&gt;
hdrezka.ag&lt;br /&gt;
hdrezka.app&lt;br /&gt;
hdrezka.me&lt;br /&gt;
hdrezka.tech&lt;br /&gt;
hdrezka.tv&lt;br /&gt;
hdrzk.org&lt;br /&gt;
hdstudio.org&lt;br /&gt;
healthline.com&lt;br /&gt;
hentai-foundry.com&lt;br /&gt;
herokucdn.com&lt;br /&gt;
hetzner.com&lt;br /&gt;
hitomi.la&lt;br /&gt;
hollisterco.com&lt;br /&gt;
holod.media&lt;br /&gt;
home-connect.com&lt;br /&gt;
home.by.me&lt;br /&gt;
hostgator.com&lt;br /&gt;
hostinger.com&lt;br /&gt;
hotels.com&lt;br /&gt;
housebrand.com&lt;br /&gt;
hqporner.com&lt;br /&gt;
hromadske.ua&lt;br /&gt;
hs.fi&lt;br /&gt;
htmhell.dev&lt;br /&gt;
hume.ai&lt;br /&gt;
hybrid-analysis.com&lt;br /&gt;
i.sakh.com&lt;br /&gt;
ibm.com&lt;br /&gt;
ibytedtos.com&lt;br /&gt;
idelreal.org&lt;br /&gt;
iditelesombase.org&lt;br /&gt;
iedb.org&lt;br /&gt;
ig.me&lt;br /&gt;
ign.com&lt;br /&gt;
iherb.com&lt;br /&gt;
iichan.hk&lt;br /&gt;
ikea.com&lt;br /&gt;
ilook.tv&lt;br /&gt;
image.tmdb.org&lt;br /&gt;
imgburn.com&lt;br /&gt;
imgur.com&lt;br /&gt;
important-stories.com&lt;br /&gt;
indeed.com&lt;br /&gt;
indiehackers.com&lt;br /&gt;
infineon.com&lt;br /&gt;
insearch.site&lt;br /&gt;
instagram.com&lt;br /&gt;
install.launcher.omniverse.nvidia.com&lt;br /&gt;
intel.com&lt;br /&gt;
intel.de&lt;br /&gt;
intel.nl&lt;br /&gt;
intelix.sophos.com&lt;br /&gt;
interactivebrokers.co.uk&lt;br /&gt;
interfax.com.ua&lt;br /&gt;
internalfb.com&lt;br /&gt;
intuit.com&lt;br /&gt;
intuitibits.com&lt;br /&gt;
ionos.com&lt;br /&gt;
iptv.online&lt;br /&gt;
is.fi&lt;br /&gt;
istories.media&lt;br /&gt;
itch.io&lt;br /&gt;
itninja.com&lt;br /&gt;
itsmycity.ru&lt;br /&gt;
jamf.com&lt;br /&gt;
jellyfin.org&lt;br /&gt;
jetbrains.com&lt;br /&gt;
jetbrains.space&lt;br /&gt;
jetkvm.com&lt;br /&gt;
jskor.ill.in.ua&lt;br /&gt;
jut-su.net&lt;br /&gt;
jut.su&lt;br /&gt;
jw-russia.org&lt;br /&gt;
jw.org&lt;br /&gt;
kaktus.media&lt;br /&gt;
kaleido.ai&lt;br /&gt;
kamatera.com&lt;br /&gt;
kara.su&lt;br /&gt;
kasparov.ru&lt;br /&gt;
kavkaz-uzel.eu&lt;br /&gt;
kavkazr.com&lt;br /&gt;
kemono.su&lt;br /&gt;
keysight.com&lt;br /&gt;
kilo.ai&lt;br /&gt;
kilocode.ai&lt;br /&gt;
kino.pub&lt;br /&gt;
kinogo.ec&lt;br /&gt;
kinogo.la&lt;br /&gt;
kinogo.uk&lt;br /&gt;
kinopub.me&lt;br /&gt;
kinovod.net&lt;br /&gt;
kinozal.guru&lt;br /&gt;
kinozal.me&lt;br /&gt;
kinozal.tv&lt;br /&gt;
kinozaltv.life&lt;br /&gt;
klarna.com&lt;br /&gt;
kmail-lists.com&lt;br /&gt;
knaben.xyz&lt;br /&gt;
knews.kg&lt;br /&gt;
knowyourmeme.com&lt;br /&gt;
kolsar.org&lt;br /&gt;
kor.ill.in.ua&lt;br /&gt;
korrespondent.net&lt;br /&gt;
kovcheg.live&lt;br /&gt;
krymr.com&lt;br /&gt;
kupujemprodajem.com&lt;br /&gt;
kym-cdn.com&lt;br /&gt;
lambdalabs.com&lt;br /&gt;
lamcdn.net&lt;br /&gt;
langdock.com&lt;br /&gt;
lantern.io&lt;br /&gt;
latestmodapks.com&lt;br /&gt;
ldoceonline.com&lt;br /&gt;
le-production.tv&lt;br /&gt;
leafletjs.com&lt;br /&gt;
legalshield.com&lt;br /&gt;
lgeapi.com&lt;br /&gt;
lgthinq.com&lt;br /&gt;
lib.rus.ec&lt;br /&gt;
libgen.li&lt;br /&gt;
licdn.com&lt;br /&gt;
lidarr.audio&lt;br /&gt;
lifehacker.com&lt;br /&gt;
liga.net&lt;br /&gt;
lightning.ai&lt;br /&gt;
linear.app&lt;br /&gt;
lingq.com&lt;br /&gt;
linkedin.com&lt;br /&gt;
linktr.ee&lt;br /&gt;
livetv.sx&lt;br /&gt;
liveuamap.com&lt;br /&gt;
locals.md&lt;br /&gt;
lolz.guru&lt;br /&gt;
lostfilm.download&lt;br /&gt;
lostfilm.tv&lt;br /&gt;
lostfilm.tw&lt;br /&gt;
lostfilm.uno&lt;br /&gt;
lostfilmtv2.site&lt;br /&gt;
lu4.org&lt;br /&gt;
lucid.app&lt;br /&gt;
magaz.global&lt;br /&gt;
mail-api.proton.me&lt;br /&gt;
mailerlite.com&lt;br /&gt;
mailfence.com&lt;br /&gt;
mailinator.com&lt;br /&gt;
mailo.com&lt;br /&gt;
make.com&lt;br /&gt;
malwarebytes.com&lt;br /&gt;
mangadex.org&lt;br /&gt;
mangahub.ru&lt;br /&gt;
mangapark.net&lt;br /&gt;
manus.im&lt;br /&gt;
manybooks.net&lt;br /&gt;
manyvids.com&lt;br /&gt;
marvelsnap.com&lt;br /&gt;
mashable.com&lt;br /&gt;
mattermost.com&lt;br /&gt;
max.com&lt;br /&gt;
mbk-news.appspot.com&lt;br /&gt;
mediazona.ca&lt;br /&gt;
medicalnewstoday.com&lt;br /&gt;
medium.com&lt;br /&gt;
meduza.io&lt;br /&gt;
mega.nz&lt;br /&gt;
megapeer.ru&lt;br /&gt;
megapeer.vip&lt;br /&gt;
merezha.co&lt;br /&gt;
meta.com&lt;br /&gt;
metacritic.com&lt;br /&gt;
metal-archives.com&lt;br /&gt;
metla.press&lt;br /&gt;
metopera.org&lt;br /&gt;
middlewareinventory.com&lt;br /&gt;
mignews.com&lt;br /&gt;
mintmobile.com&lt;br /&gt;
miracleptr.wordpress.com&lt;br /&gt;
mirror.jellyfin.org&lt;br /&gt;
mixcloud.com&lt;br /&gt;
modrinth.com&lt;br /&gt;
mongodb.com&lt;br /&gt;
monolisa.dev&lt;br /&gt;
monoprice.com&lt;br /&gt;
more.fm&lt;br /&gt;
moscowtimes.ru&lt;br /&gt;
mouser.com&lt;br /&gt;
mouser.fi&lt;br /&gt;
mssg.me&lt;br /&gt;
mullvad.net&lt;br /&gt;
multporn.net&lt;br /&gt;
muscdn.com&lt;br /&gt;
musical.ly&lt;br /&gt;
musicbrainz.org&lt;br /&gt;
musixmatch.com&lt;br /&gt;
mw2.wiki&lt;br /&gt;
myanimelist.net&lt;br /&gt;
mydoramy.club&lt;br /&gt;
myheritage.com&lt;br /&gt;
myjetbrains.com&lt;br /&gt;
myparallels.com&lt;br /&gt;
myqrcode.com&lt;br /&gt;
navalny.com&lt;br /&gt;
nba.com&lt;br /&gt;
neformat.com.ua&lt;br /&gt;
neo4j.com&lt;br /&gt;
netacad.com&lt;br /&gt;
netapp.com&lt;br /&gt;
netflix.ca&lt;br /&gt;
netflix.com&lt;br /&gt;
netflix.net&lt;br /&gt;
netflixinvestor.com&lt;br /&gt;
netflixtechblog.com&lt;br /&gt;
netlify.com&lt;br /&gt;
networksolutions.com&lt;br /&gt;
new.abb.com&lt;br /&gt;
newark.com&lt;br /&gt;
newsroom.porsche.com&lt;br /&gt;
newsru.co.il&lt;br /&gt;
newsru.com&lt;br /&gt;
newtimes.ru&lt;br /&gt;
nexus-cdn.com&lt;br /&gt;
nfl.com&lt;br /&gt;
nflxext.com&lt;br /&gt;
nflximg.com&lt;br /&gt;
nflximg.net&lt;br /&gt;
nflxsearch.net&lt;br /&gt;
nflxso.net&lt;br /&gt;
nflxvideo.net&lt;br /&gt;
ngrok.com&lt;br /&gt;
nhentai.com&lt;br /&gt;
nhentai.net&lt;br /&gt;
nhl.com&lt;br /&gt;
nih.gov&lt;br /&gt;
nike.com&lt;br /&gt;
nippon.com&lt;br /&gt;
nitropdf.com&lt;br /&gt;
nnmclub.to&lt;br /&gt;
nnmstatic.win&lt;br /&gt;
nordaccount.com&lt;br /&gt;
nordcdn.com&lt;br /&gt;
nordvpn.com&lt;br /&gt;
notepad-plus-plus.org&lt;br /&gt;
notion-emojis.s3-us-west-2.amazonaws.com&lt;br /&gt;
notion-static.com&lt;br /&gt;
notion.com&lt;br /&gt;
notion.new&lt;br /&gt;
notion.site&lt;br /&gt;
notion.so&lt;br /&gt;
novaline.fm&lt;br /&gt;
novaya.no&lt;br /&gt;
novayagazeta.eu&lt;br /&gt;
novayagazeta.ru&lt;br /&gt;
novyny.live&lt;br /&gt;
ntc.party&lt;br /&gt;
ntp.msn.com&lt;br /&gt;
nude-moon.org&lt;br /&gt;
nxp.com&lt;br /&gt;
oaistatic.com&lt;br /&gt;
oaiusercontent.com&lt;br /&gt;
obozrevatel.com&lt;br /&gt;
ocstore.com&lt;br /&gt;
oculus.com&lt;br /&gt;
ohmyswift.ru&lt;br /&gt;
oi.legal&lt;br /&gt;
okx.com&lt;br /&gt;
olx.ua&lt;br /&gt;
omnissa.com&lt;br /&gt;
omv-extras.org&lt;br /&gt;
onfastspring.com&lt;br /&gt;
onlinesim.io&lt;br /&gt;
onshape.com&lt;br /&gt;
open-vsx.org&lt;br /&gt;
openai.com&lt;br /&gt;
openh264.org&lt;br /&gt;
openmedia.io&lt;br /&gt;
openrouter.ai&lt;br /&gt;
opensanctions.org&lt;br /&gt;
opensea.io&lt;br /&gt;
opentrackr.org&lt;br /&gt;
openvsx.eclipsecontent.org&lt;br /&gt;
opposition-news.com&lt;br /&gt;
oracle.com&lt;br /&gt;
orbispatches.com&lt;br /&gt;
orcaslicer.com&lt;br /&gt;
ottplayer.tv&lt;br /&gt;
ovd.info&lt;br /&gt;
ovd.legal&lt;br /&gt;
ovd.news&lt;br /&gt;
ovdinfo.org&lt;br /&gt;
ozodi.org&lt;br /&gt;
paddle.com&lt;br /&gt;
paddlestatus.com&lt;br /&gt;
pages.dev&lt;br /&gt;
pandasecurity.com&lt;br /&gt;
pap.pl&lt;br /&gt;
paperpaper.io&lt;br /&gt;
paperpaper.ru&lt;br /&gt;
parallels.cn&lt;br /&gt;
parallels.com&lt;br /&gt;
parallels.net&lt;br /&gt;
parallelsaccess.com&lt;br /&gt;
paritydeals.com&lt;br /&gt;
patreon.com&lt;br /&gt;
patreonusercontent.com&lt;br /&gt;
patriot.dp.ua&lt;br /&gt;
pb.wtf&lt;br /&gt;
pcgamesn.com&lt;br /&gt;
pcmag.com&lt;br /&gt;
penguin.com&lt;br /&gt;
penguinrandomhouse.com&lt;br /&gt;
periscope.tv&lt;br /&gt;
pexels.com&lt;br /&gt;
phncdn.com&lt;br /&gt;
phncdn.com.sds.rncdn7.com&lt;br /&gt;
pimpletv.ru&lt;br /&gt;
pingdom.com&lt;br /&gt;
piratbit.top&lt;br /&gt;
pixabay.com&lt;br /&gt;
pkg-zone.com&lt;br /&gt;
pkgs.tailscale.com&lt;br /&gt;
platform.activestate.com&lt;br /&gt;
playboy.com&lt;br /&gt;
plugshare.com&lt;br /&gt;
polit.ru&lt;br /&gt;
politico.eu&lt;br /&gt;
politiken.dk&lt;br /&gt;
polymarket.com&lt;br /&gt;
pornhub.com&lt;br /&gt;
pornhub.org&lt;br /&gt;
pornolab.net&lt;br /&gt;
portal.lviv.ua&lt;br /&gt;
posle.media&lt;br /&gt;
posthog.com&lt;br /&gt;
postimees.ee&lt;br /&gt;
pravda.com&lt;br /&gt;
pravda.com.ua&lt;br /&gt;
premierleague.com&lt;br /&gt;
primevideo.com&lt;br /&gt;
primevue.org&lt;br /&gt;
privatekeys.pw&lt;br /&gt;
prnt.sc&lt;br /&gt;
production-openaicom-storage.azureedge.net&lt;br /&gt;
proekt.media&lt;br /&gt;
profitwell.com&lt;br /&gt;
prosleduetmedia.com&lt;br /&gt;
prosperopatches.com&lt;br /&gt;
prostovpn.org&lt;br /&gt;
proton.me&lt;br /&gt;
protonvpn.com&lt;br /&gt;
provereno.media&lt;br /&gt;
prowlarr.com&lt;br /&gt;
pscp.tv&lt;br /&gt;
psiphon.ca&lt;br /&gt;
psxhax.com&lt;br /&gt;
public.parsec.app&lt;br /&gt;
pvpessence.com&lt;br /&gt;
qdrant.io&lt;br /&gt;
qdrant.tech&lt;br /&gt;
qt.io&lt;br /&gt;
quadratichq.com&lt;br /&gt;
qualcomm.com&lt;br /&gt;
quicknode.com&lt;br /&gt;
quora.com&lt;br /&gt;
quora.com.cdn.cloudflare.net&lt;br /&gt;
qwant.com&lt;br /&gt;
r4.err.ee&lt;br /&gt;
radiojar.com&lt;br /&gt;
radiosakharov.org&lt;br /&gt;
radiosvoboda.org&lt;br /&gt;
rbc.ua&lt;br /&gt;
reactflow.dev&lt;br /&gt;
realbooru.com&lt;br /&gt;
realist.online&lt;br /&gt;
recraft.ai&lt;br /&gt;
reddxxx.com&lt;br /&gt;
redgifs.com&lt;br /&gt;
redis.io&lt;br /&gt;
redislabs.com&lt;br /&gt;
redshieldvpn.com&lt;br /&gt;
refactoring.guru&lt;br /&gt;
remna.st&lt;br /&gt;
remove.bg&lt;br /&gt;
render-state.to&lt;br /&gt;
rentry.co&lt;br /&gt;
rentry.org&lt;br /&gt;
repo.jellyfin.org&lt;br /&gt;
republic.ru&lt;br /&gt;
research.net&lt;br /&gt;
restream.io&lt;br /&gt;
reve.art&lt;br /&gt;
rezka-ua.in&lt;br /&gt;
rezka.ag&lt;br /&gt;
rezka.cc&lt;br /&gt;
rezka.fi&lt;br /&gt;
rezka.land&lt;br /&gt;
rezka.my&lt;br /&gt;
rezka.tv&lt;br /&gt;
rezkify.com&lt;br /&gt;
rezonans.media&lt;br /&gt;
rf.dobrochan.net&lt;br /&gt;
rferl.org&lt;br /&gt;
rima.media&lt;br /&gt;
riperam.org&lt;br /&gt;
riseup.net&lt;br /&gt;
roar-review.com&lt;br /&gt;
root-nation.com&lt;br /&gt;
roskomsvoboda.org&lt;br /&gt;
rublacklist.net&lt;br /&gt;
rule34.art&lt;br /&gt;
rule34.us&lt;br /&gt;
rule34.xxx&lt;br /&gt;
rus.delfi.ee&lt;br /&gt;
rus.jauns.lv&lt;br /&gt;
ruscryde.net&lt;br /&gt;
rustorka.com&lt;br /&gt;
rutor.info&lt;br /&gt;
rutor.is&lt;br /&gt;
rutor.org&lt;br /&gt;
rutracker.cc&lt;br /&gt;
rutracker.net&lt;br /&gt;
rutracker.org&lt;br /&gt;
rutracker.wiki&lt;br /&gt;
sakhalin.info&lt;br /&gt;
sakharovfoundation.org&lt;br /&gt;
salesforce-experience.com&lt;br /&gt;
salesforce-hub.com&lt;br /&gt;
salesforce-scrt.com&lt;br /&gt;
salesforce-setup.com&lt;br /&gt;
salesforce-sites.com&lt;br /&gt;
salesforce.com&lt;br /&gt;
salesforceiq.com&lt;br /&gt;
salesforceliveagent.com&lt;br /&gt;
sap.com&lt;br /&gt;
saverudata.net&lt;br /&gt;
schemas.microsoft.com&lt;br /&gt;
schemas.openxmlformats.org&lt;br /&gt;
sci-hub.se&lt;br /&gt;
sci-hub.st&lt;br /&gt;
scrollrevealjs.org&lt;br /&gt;
scryde.io&lt;br /&gt;
scryde.net&lt;br /&gt;
scryde.ru&lt;br /&gt;
scryde.world&lt;br /&gt;
scryde1.net&lt;br /&gt;
scryde10.net&lt;br /&gt;
scryde11.net&lt;br /&gt;
scryde12.net&lt;br /&gt;
scryde2.net&lt;br /&gt;
scryde3.net&lt;br /&gt;
scryde4.net&lt;br /&gt;
scryde5.net&lt;br /&gt;
scryde6.net&lt;br /&gt;
scryde7.net&lt;br /&gt;
scryde8.net&lt;br /&gt;
scryde9.net&lt;br /&gt;
sdxcentral.com&lt;br /&gt;
searchfloor.org&lt;br /&gt;
seasonvar.ru&lt;br /&gt;
selezen.org&lt;br /&gt;
semnasem.org&lt;br /&gt;
semrush.com&lt;br /&gt;
sentry.dev&lt;br /&gt;
sentry.io&lt;br /&gt;
sephora.com&lt;br /&gt;
servarr.com&lt;br /&gt;
severreal.org&lt;br /&gt;
sfdcopens.com&lt;br /&gt;
shikimori.me&lt;br /&gt;
shinyhardware.co.uk&lt;br /&gt;
shiza-project.com&lt;br /&gt;
shop.gameloft.com&lt;br /&gt;
showip.net&lt;br /&gt;
sibreal.org&lt;br /&gt;
signal.org&lt;br /&gt;
simplex.chat&lt;br /&gt;
simplex.im&lt;br /&gt;
simplix.info&lt;br /&gt;
singlekey-id.com&lt;br /&gt;
site.com&lt;br /&gt;
siteground.com&lt;br /&gt;
skat.media&lt;br /&gt;
sketchup.com&lt;br /&gt;
skiff.com&lt;br /&gt;
skladchik.com&lt;br /&gt;
sklatchiki.ru&lt;br /&gt;
sky.com&lt;br /&gt;
skycdp.com&lt;br /&gt;
slashlib.me&lt;br /&gt;
slavicsac.com&lt;br /&gt;
slifki.biz&lt;br /&gt;
smartbear.co&lt;br /&gt;
smartbear.com&lt;br /&gt;
smartdeploy.com&lt;br /&gt;
sms-activate.io&lt;br /&gt;
snapgene.com&lt;br /&gt;
sndcdn.com&lt;br /&gt;
snort.org&lt;br /&gt;
snyk.io&lt;br /&gt;
sobesednik.com&lt;br /&gt;
solarwinds.com&lt;br /&gt;
sonara.ai&lt;br /&gt;
sophos.com&lt;br /&gt;
sora.com&lt;br /&gt;
sotaproject.com&lt;br /&gt;
soundcloud.cloud&lt;br /&gt;
soundcloud.com&lt;br /&gt;
sovetromantica.com&lt;br /&gt;
spacelift.io&lt;br /&gt;
speedtest.net&lt;br /&gt;
spektr.press&lt;br /&gt;
spiceworks.com&lt;br /&gt;
spiegel.de&lt;br /&gt;
spitfireaudio.com&lt;br /&gt;
spotify.com&lt;br /&gt;
spreadthesign.com&lt;br /&gt;
sputnikipogrom.com&lt;br /&gt;
squadbustersgame.com&lt;br /&gt;
squareup.com&lt;br /&gt;
squietpc.com&lt;br /&gt;
startmail.com&lt;br /&gt;
startpage.com&lt;br /&gt;
static.lostfilm.top&lt;br /&gt;
statology.org&lt;br /&gt;
steamstat.info&lt;br /&gt;
strana.news&lt;br /&gt;
strana.today&lt;br /&gt;
strava.com&lt;br /&gt;
supercell.com&lt;br /&gt;
supersliv.biz&lt;br /&gt;
support.anydesk.com&lt;br /&gt;
support.xerox.com&lt;br /&gt;
surfshark.com&lt;br /&gt;
surveymonkey.com&lt;br /&gt;
suspilne.media&lt;br /&gt;
svidomi.in.ua&lt;br /&gt;
svoboda.org&lt;br /&gt;
svoi.kr.ua&lt;br /&gt;
svtv.org&lt;br /&gt;
swagger.io&lt;br /&gt;
swapd.co&lt;br /&gt;
swissinfo.ch&lt;br /&gt;
synoforum.com&lt;br /&gt;
t-invariant.org&lt;br /&gt;
t.co&lt;br /&gt;
tableau.com&lt;br /&gt;
talosintelligence.com&lt;br /&gt;
tampermonkey.net&lt;br /&gt;
tayga.info&lt;br /&gt;
te-st.org&lt;br /&gt;
teamviewer.com&lt;br /&gt;
techbargains.com&lt;br /&gt;
telegraf.by&lt;br /&gt;
telegraf.news&lt;br /&gt;
telegram.org&lt;br /&gt;
telegraph.co.uk&lt;br /&gt;
telemetr.io&lt;br /&gt;
tellapart.com&lt;br /&gt;
tempmail.plus&lt;br /&gt;
temu.com&lt;br /&gt;
terraform.io&lt;br /&gt;
the-village.ru&lt;br /&gt;
theaudiodb.com&lt;br /&gt;
thebarentsobserver.com&lt;br /&gt;
thebell.io&lt;br /&gt;
theins.press&lt;br /&gt;
theins.ru&lt;br /&gt;
themoviedb.org&lt;br /&gt;
thepiratebay.org&lt;br /&gt;
theporndude.com&lt;br /&gt;
therarbg.to&lt;br /&gt;
thetruestory.news&lt;br /&gt;
thetvdb.com&lt;br /&gt;
threads.net&lt;br /&gt;
threema.ch&lt;br /&gt;
ti.com&lt;br /&gt;
tidal.com&lt;br /&gt;
tik-tokapi.com&lt;br /&gt;
tiktok.com&lt;br /&gt;
tiktokcdn-eu.com&lt;br /&gt;
tiktokcdn-us.com&lt;br /&gt;
tiktokcdn.com&lt;br /&gt;
tiktokd.net&lt;br /&gt;
tiktokd.org&lt;br /&gt;
tiktokv.com&lt;br /&gt;
tiktokv.eu&lt;br /&gt;
tiktokv.us&lt;br /&gt;
tiktokw.us&lt;br /&gt;
timberland.de&lt;br /&gt;
tiptop-vpn.com&lt;br /&gt;
tmdb-image-prod.b-cdn.net&lt;br /&gt;
tmdb.com&lt;br /&gt;
tmdb.org&lt;br /&gt;
toolbox.app&lt;br /&gt;
torproject.org&lt;br /&gt;
torrenteditor.com&lt;br /&gt;
torrentgalaxy.to&lt;br /&gt;
trae.ai&lt;br /&gt;
trailblazer.me&lt;br /&gt;
trailhead.com&lt;br /&gt;
transferwise.com&lt;br /&gt;
trellix.com&lt;br /&gt;
tria.ge&lt;br /&gt;
trueblackmetalradio.com&lt;br /&gt;
truthsocial.com&lt;br /&gt;
tsmc.com&lt;br /&gt;
ttwstatic.com&lt;br /&gt;
turbobit.net&lt;br /&gt;
tuta.com&lt;br /&gt;
tuta.io&lt;br /&gt;
tutanota.com&lt;br /&gt;
tvdevinfo.com&lt;br /&gt;
tvfreedom.io&lt;br /&gt;
tvrain.ru&lt;br /&gt;
tvrain.tv&lt;br /&gt;
tweetdeck.com&lt;br /&gt;
twimg.com&lt;br /&gt;
twin.me&lt;br /&gt;
twinlife-systems.com&lt;br /&gt;
twinme.com&lt;br /&gt;
twirpx.com&lt;br /&gt;
twitpic.com&lt;br /&gt;
twitter.biz&lt;br /&gt;
twitter.com&lt;br /&gt;
twitter.jp&lt;br /&gt;
twittercommunity.com&lt;br /&gt;
twitterflightschool.com&lt;br /&gt;
twitterinc.com&lt;br /&gt;
twitteroauth.com&lt;br /&gt;
twitterstat.us&lt;br /&gt;
twtrdns.net&lt;br /&gt;
twttr.com&lt;br /&gt;
twttr.net&lt;br /&gt;
twvid.com&lt;br /&gt;
typing.com&lt;br /&gt;
uaudio.com&lt;br /&gt;
ui.ill.in.ua&lt;br /&gt;
uizard.io&lt;br /&gt;
ukdevilz.com&lt;br /&gt;
ukr.net&lt;br /&gt;
ukr.radio&lt;br /&gt;
ukrtelcdn.net&lt;br /&gt;
unian.ua&lt;br /&gt;
unscreen.com&lt;br /&gt;
unsplash.com&lt;br /&gt;
upwork.com&lt;br /&gt;
urlr.me&lt;br /&gt;
usa.one&lt;br /&gt;
usatoday.com&lt;br /&gt;
usher.ttvnw.net&lt;br /&gt;
uupdump.net&lt;br /&gt;
v.vrv.co&lt;br /&gt;
vagrantcloud.com&lt;br /&gt;
veeam.com&lt;br /&gt;
verstka.media&lt;br /&gt;
vesma.one&lt;br /&gt;
vesma.today&lt;br /&gt;
vesty.co.il&lt;br /&gt;
viber.com&lt;br /&gt;
vice.com&lt;br /&gt;
vine.co&lt;br /&gt;
vip110.vip&lt;br /&gt;
vipergirls.to&lt;br /&gt;
visualcapitalist.com&lt;br /&gt;
vmware.com&lt;br /&gt;
vndb.org&lt;br /&gt;
voanews.com&lt;br /&gt;
vod-fy.crunchyrollcdn.com&lt;br /&gt;
voidboost.cc&lt;br /&gt;
volkswagen-classic-parts.com&lt;br /&gt;
vot-tak.tv&lt;br /&gt;
vpngate.net&lt;br /&gt;
vpngen.org&lt;br /&gt;
vpnlove.me&lt;br /&gt;
vpnpay.io&lt;br /&gt;
vyos.io&lt;br /&gt;
w.atwiki.jp&lt;br /&gt;
wa.me&lt;br /&gt;
walmart.com&lt;br /&gt;
watchguard.com&lt;br /&gt;
watermarkremover.io&lt;br /&gt;
wbgames.com&lt;br /&gt;
weather.com&lt;br /&gt;
webmd.com&lt;br /&gt;
webnames.ca&lt;br /&gt;
webtoons.com&lt;br /&gt;
weebly.com&lt;br /&gt;
welt.de&lt;br /&gt;
whatsapp.biz&lt;br /&gt;
whatsapp.com&lt;br /&gt;
whatsapp.net&lt;br /&gt;
widgetapp.stream&lt;br /&gt;
wiki.fextralife.com&lt;br /&gt;
wikidot.com&lt;br /&gt;
wilsoncenter.org&lt;br /&gt;
windows10spotlight.com&lt;br /&gt;
windsurf.com&lt;br /&gt;
wise.com&lt;br /&gt;
wonderzine.com&lt;br /&gt;
wpengine.com&lt;br /&gt;
wunderground.com&lt;br /&gt;
www3.corsair.com&lt;br /&gt;
x.ai&lt;br /&gt;
x.com&lt;br /&gt;
xhamster.com&lt;br /&gt;
xhamsterlive.com&lt;br /&gt;
xhcdn.com&lt;br /&gt;
xiaomi.eu&lt;br /&gt;
xnxx-cdn.com&lt;br /&gt;
xnxx-ru.com&lt;br /&gt;
xnxx.com&lt;br /&gt;
xnxx.net&lt;br /&gt;
xnxx.tv&lt;br /&gt;
xnxx3.com&lt;br /&gt;
xsts.auth.xboxlive.com&lt;br /&gt;
xtracloud.net&lt;br /&gt;
xv-ru.com&lt;br /&gt;
xvideos-cdn.com&lt;br /&gt;
xvideos.com&lt;br /&gt;
yande.re&lt;br /&gt;
yeggi.com&lt;br /&gt;
yle.fi&lt;br /&gt;
youtrack.cloud&lt;br /&gt;
yummyani.me&lt;br /&gt;
z.ai&lt;br /&gt;
zahav.ru&lt;br /&gt;
zapier.com&lt;br /&gt;
zaxid.net&lt;br /&gt;
zbigz.com&lt;br /&gt;
zedge.net&lt;br /&gt;
zendesk.com&lt;br /&gt;
zerkalo.io&lt;br /&gt;
zona.media&lt;br /&gt;
2fa.fb.tools&lt;br /&gt;
pytorch.org&lt;br /&gt;
rutracker.cc&lt;br /&gt;
uvnc.com&lt;br /&gt;
api.pwnedpasswords.com&lt;br /&gt;
pwnedpasswords.com&lt;br /&gt;
haveibeenpwned.com&lt;br /&gt;
nekoray.org&lt;br /&gt;
cursor.directory&lt;br /&gt;
fedoraproject.org&lt;br /&gt;
jdownloader.org&lt;br /&gt;
oii.la&lt;br /&gt;
sysdig.com&lt;br /&gt;
lizardbyte.dev&lt;br /&gt;
lego.com&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
google.com&lt;br /&gt;
lookerstudio.google.com&lt;br /&gt;
news.google.com&lt;br /&gt;
googleapis.com&lt;br /&gt;
suggestqueries.google.com&lt;br /&gt;
gemini.google.com&lt;br /&gt;
2ip.ru&lt;br /&gt;
cline.bot&lt;br /&gt;
fragment.com&lt;br /&gt;
shikimori.one&lt;br /&gt;
thingiverse.com&lt;br /&gt;
rippersanime.info&lt;br /&gt;
forum.rippersanime.info&lt;br /&gt;
weloma.art&lt;br /&gt;
brave.com&lt;br /&gt;
search.brave.com&lt;br /&gt;
claude.com&lt;br /&gt;
roocode.com&lt;br /&gt;
unsloth.ai&lt;br /&gt;
sourceforge.net&lt;br /&gt;
trakt.tv&lt;br /&gt;
statics.life&lt;br /&gt;
openstat.net&lt;br /&gt;
google-analytics.com&lt;br /&gt;
googletagmanager.com&lt;br /&gt;
torrenttip220.top&lt;br /&gt;
529072.xyz&lt;br /&gt;
asnet.pw&lt;br /&gt;
apachetorrent.com&lt;br /&gt;
bangumi.moe&lt;br /&gt;
bigfangroup.org&lt;br /&gt;
bitru.org&lt;br /&gt;
bitsearch.to&lt;br /&gt;
demonoid.nl&lt;br /&gt;
share.dmhy.org&lt;br /&gt;
extratorrent.st&lt;br /&gt;
eztvx.to&lt;br /&gt;
limontorrents.vip&lt;br /&gt;
www.frozen-layer.com&lt;br /&gt;
kickass.torrentbay.st&lt;br /&gt;
kickass.ws&lt;br /&gt;
limetorrents.fun&lt;br /&gt;
magnetcatcat.com&lt;br /&gt;
newstudio.tv&lt;br /&gt;
ww3-nortorrent.com&lt;br /&gt;
nyaa.si&lt;br /&gt;
torrentcore.xyz&lt;br /&gt;
torrenttip220.top&lt;br /&gt;
dontorrent.cash&lt;br /&gt;
electro-torrent.pl&lt;br /&gt;
extratorrent.ninjaproxy1.com&lt;br /&gt;
extratorrent.proxyninja.org&lt;br /&gt;
extratorrent.proxyninja.net&lt;br /&gt;
hdrtorrent.com&lt;br /&gt;
ilcorsaronero.link&lt;br /&gt;
magnetcatcat.com&lt;br /&gt;
clmclm.com&lt;br /&gt;
8800546.xyz&lt;br /&gt;
torrentbay.st&lt;br /&gt;
torrentsbay.org&lt;br /&gt;
unblockninja.com&lt;br /&gt;
ninjaproxy1.com&lt;br /&gt;
proxyninja.org&lt;br /&gt;
proxyninja.net&lt;br /&gt;
newstudio.tv&lt;br /&gt;
nekobt.to&lt;br /&gt;
moviesdvdr.co&lt;br /&gt;
nyaa.iss.ink&lt;br /&gt;
nyaa.land&lt;br /&gt;
nyaa.mom&lt;br /&gt;
nyaa.unblockninja.com&lt;br /&gt;
zktorrent.com&lt;br /&gt;
zamunda.rip&lt;br /&gt;
yts.bz&lt;br /&gt;
yts.unblockninja.com&lt;br /&gt;
yts.ninjaproxy1.com&lt;br /&gt;
yts.proxyninja.org&lt;br /&gt;
yts.proxyninja.net&lt;br /&gt;
yts.torrentbay.st&lt;br /&gt;
yts.torrentsbay.org&lt;br /&gt;
mania-torrent.org&lt;br /&gt;
cine-torrent.org&lt;br /&gt;
magnet-torrent.org&lt;br /&gt;
mega-torrent.cc&lt;br /&gt;
zone-torrent.com&lt;br /&gt;
warez-torrent.org&lt;br /&gt;
wolfmax4k.com&lt;br /&gt;
uztracker.net&lt;br /&gt;
uindex.org&lt;br /&gt;
ygg.gratis&lt;br /&gt;
torrenttip219.top&lt;br /&gt;
torrentsome238.com&lt;br /&gt;
torrentqq412.com&lt;br /&gt;
torrentegg87.com&lt;br /&gt;
torrentgalaxy.one&lt;br /&gt;
torrentgalaxy.info&lt;br /&gt;
torrentgalaxy.space&lt;br /&gt;
torrentdownload.info&lt;br /&gt;
torrentcore.xyz&lt;br /&gt;
www5.torrent9.to&lt;br /&gt;
www.torrentdownloads.pro&lt;br /&gt;
torrentdownloads.unblockninja.com&lt;br /&gt;
torrentdownloads.ninjaproxy1.com&lt;br /&gt;
torrentdownloads.proxyninja.org&lt;br /&gt;
torrentdownloads.proxyninja.net&lt;br /&gt;
therarbg.to&lt;br /&gt;
therarbg.com&lt;br /&gt;
therar.site&lt;br /&gt;
rarbg.unblockninja.com&lt;br /&gt;
rarbg.ninjaproxy1.com&lt;br /&gt;
rarbg.proxyninja.org&lt;br /&gt;
rarbg.proxyninja.net&lt;br /&gt;
rarbg.torrentbay.st&lt;br /&gt;
thepiratebay.org&lt;br /&gt;
solidtorrents.eu&lt;br /&gt;
kickasstorrents.bz&lt;br /&gt;
dolby.com&lt;br /&gt;
repo.webosbrew.org&lt;br /&gt;
qt.io&lt;br /&gt;
cursor.com&lt;br /&gt;
cursor.sh&lt;br /&gt;
cursorapi.com&lt;br /&gt;
duckdns.org&lt;br /&gt;
funpay.com&lt;br /&gt;
anidub.vip&lt;br /&gt;
anidub.shop&lt;br /&gt;
skillsmp.com&lt;br /&gt;
reactbits.dev&lt;br /&gt;
mediaarea.net&lt;br /&gt;
mkvtoolnix.download&lt;br /&gt;
excalidraw.com&lt;br /&gt;
claudeusercontent.com&lt;br /&gt;
kodi.tv&lt;br /&gt;
githubusercontent.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Шаг 2: Добавьте список в Podkop ====&lt;br /&gt;
&lt;br /&gt;
# Откройте веб-интерфейс Podkop: &#039;&#039;&#039;Services → Podkop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Перейдите в раздел конфигурации секции (обычно &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
# Найдите параметр &#039;&#039;&#039;Custom Domain Lists&#039;&#039;&#039; (Список пользовательских доменов)&lt;br /&gt;
&lt;br /&gt;
# Убедитесь, что &#039;&#039;&#039;Тип пользовательского списка доменов&#039;&#039;&#039; установлен в &amp;lt;code&amp;gt;Текстовый список&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Скопируйте весь список из спойлера выше&lt;br /&gt;
&lt;br /&gt;
# Вставьте его в поле &#039;&#039;&#039;Список пользовательских доменов&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Нажмите &#039;&#039;&#039;Save &amp;amp; Apply&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Самостоятельная генерация списка (опционально) ===&lt;br /&gt;
Если вы хотите &#039;&#039;&#039;самостоятельно сгенерировать&#039;&#039;&#039; актуальный список или добавить свои домены, используйте наш скрипт.&lt;br /&gt;
&lt;br /&gt;
==== Требования ====&lt;br /&gt;
&lt;br /&gt;
* Python 3.6 или выше&lt;br /&gt;
&lt;br /&gt;
* 4 файла:&lt;br /&gt;
&lt;br /&gt;
** &amp;lt;code&amp;gt;inside-raw.lst&amp;lt;/code&amp;gt; — актуальный список Russian inside&lt;br /&gt;
&lt;br /&gt;
** &amp;lt;code&amp;gt;zapret-hosts-google.txt&amp;lt;/code&amp;gt; — скопируйте с роутера из &amp;lt;code&amp;gt;/opt/zapret/ipset/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
** &amp;lt;code&amp;gt;zapret-hosts-user.txt&amp;lt;/code&amp;gt; — скопируйте с роутера из &amp;lt;code&amp;gt;/opt/zapret/ipset/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
** &amp;lt;code&amp;gt;custom-user-list.txt&amp;lt;/code&amp;gt; — ваши дополнительные домены (по одному на строку)&lt;br /&gt;
&lt;br /&gt;
==== Исходный код скрипта ====&lt;br /&gt;
Создайте файл &amp;lt;code&amp;gt;generate_podkop_list.py&amp;lt;/code&amp;gt;:&amp;lt;div class=&amp;quot;toccolours mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;width:100%; overflow:auto;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;font-weight:bold;line-height:1.6;&amp;quot;&amp;gt;Список доменов для Podkop (нажмите, чтобы развернуть)&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot;&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#!/usr/bin/env python3&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Domain List Generator for Podkop&lt;br /&gt;
&lt;br /&gt;
Merges inside-raw.lst with custom domains while removing duplicates from Zapret lists&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
from pathlib import Path&lt;br /&gt;
&lt;br /&gt;
def read_domains(filepath):&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Read domains from file, cleaning and normalizing them&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    domains = set()&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
&lt;br /&gt;
        with open(filepath, &#039;r&#039;, encoding=&#039;utf-8&#039;) as f:&lt;br /&gt;
&lt;br /&gt;
            for line in f:&lt;br /&gt;
&lt;br /&gt;
                # Remove comments, whitespace, and normalize&lt;br /&gt;
&lt;br /&gt;
                domain = line.split(&#039;#&#039;)[0].strip().lower()&lt;br /&gt;
&lt;br /&gt;
                if domain and not domain.startswith(&#039;[&#039;):&lt;br /&gt;
&lt;br /&gt;
                    # Remove trailing dots&lt;br /&gt;
&lt;br /&gt;
                    domain = domain.rstrip(&#039;.&#039;)&lt;br /&gt;
&lt;br /&gt;
                    domains.add(domain)&lt;br /&gt;
&lt;br /&gt;
    except FileNotFoundError:&lt;br /&gt;
&lt;br /&gt;
        print(f&amp;quot;Warning: File {filepath} not found, skipping&amp;quot;, file=sys.stderr)&lt;br /&gt;
&lt;br /&gt;
    except Exception as e:&lt;br /&gt;
&lt;br /&gt;
        print(f&amp;quot;Error reading {filepath}: {e}&amp;quot;, file=sys.stderr)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    return domains&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
&lt;br /&gt;
    # Define input files&lt;br /&gt;
&lt;br /&gt;
    inside_raw = Path(&#039;inside-raw.lst&#039;)&lt;br /&gt;
&lt;br /&gt;
    zapret_google = Path(&#039;zapret-hosts-google.txt&#039;)&lt;br /&gt;
&lt;br /&gt;
    zapret_user = Path(&#039;zapret-hosts-user.txt&#039;)&lt;br /&gt;
&lt;br /&gt;
    custom_list = Path(&#039;custom-user-list.txt&#039;)&lt;br /&gt;
&lt;br /&gt;
    output_file = Path(&#039;podkop-final-list.txt&#039;)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;=== Podkop Domain List Generator ===\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    # Read all domain lists&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;Reading inside-raw.lst...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    inside_domains = read_domains(inside_raw)&lt;br /&gt;
&lt;br /&gt;
    print(f&amp;quot;  Loaded {len(inside_domains)} domains&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;Reading zapret-hosts-google.txt...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    zapret_google_domains = read_domains(zapret_google)&lt;br /&gt;
&lt;br /&gt;
    print(f&amp;quot;  Loaded {len(zapret_google_domains)} domains&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;Reading zapret-hosts-user.txt...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    zapret_user_domains = read_domains(zapret_user)&lt;br /&gt;
&lt;br /&gt;
    print(f&amp;quot;  Loaded {len(zapret_user_domains)} domains&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;Reading custom-user-list.txt...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    custom_domains = read_domains(custom_list)&lt;br /&gt;
&lt;br /&gt;
    print(f&amp;quot;  Loaded {len(custom_domains)} domains&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    # Combine Zapret lists (domains to exclude from inside-raw)&lt;br /&gt;
&lt;br /&gt;
    zapret_combined = zapret_google_domains | zapret_user_domains&lt;br /&gt;
&lt;br /&gt;
    print(f&amp;quot;\nTotal Zapret domains to exclude: {len(zapret_combined)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    # Remove Zapret domains from inside-raw&lt;br /&gt;
&lt;br /&gt;
    filtered_inside = inside_domains - zapret_combined&lt;br /&gt;
&lt;br /&gt;
    print(f&amp;quot;Inside-raw after filtering: {len(filtered_inside)} domains&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    # Combine filtered inside-raw with custom domains&lt;br /&gt;
&lt;br /&gt;
    final_domains = filtered_inside | custom_domains&lt;br /&gt;
&lt;br /&gt;
    print(f&amp;quot;\nFinal domain count: {len(final_domains)} domains&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    # Sort and save&lt;br /&gt;
&lt;br /&gt;
    sorted_domains = sorted(final_domains)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    with open(output_file, &#039;w&#039;, encoding=&#039;utf-8&#039;) as f:&lt;br /&gt;
&lt;br /&gt;
        f.write(&amp;quot;# Podkop Domain List\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        f.write(&amp;quot;# Generated automatically from inside-raw.lst (filtered) + custom domains\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        f.write(f&amp;quot;# Total: {len(sorted_domains)} domains\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        f.write(&amp;quot;#\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        f.write(&amp;quot;# Excludes domains already handled by Zapret:\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        f.write(f&amp;quot;#   - zapret-hosts-google.txt ({len(zapret_google_domains)} domains)\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        f.write(f&amp;quot;#   - zapret-hosts-user.txt ({len(zapret_user_domains)} domains)\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        f.write(&amp;quot;#\n\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
        for domain in sorted_domains:&lt;br /&gt;
&lt;br /&gt;
            f.write(f&amp;quot;{domain}\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    print(f&amp;quot;\n✓ Successfully created {output_file}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    print(f&amp;quot;  Ready to use in Podkop Custom Domain Lists&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
&lt;br /&gt;
    main()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Использование скрипта ====&lt;br /&gt;
&lt;br /&gt;
# Скачайте актуальный &amp;lt;code&amp;gt;inside-raw.lst&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wget https://community.antifilter.download/list/inside-raw.lst&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Скопируйте с роутера файлы &amp;lt;code&amp;gt;zapret-hosts-google.txt&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;zapret-hosts-user.txt&amp;lt;/code&amp;gt; из &amp;lt;code&amp;gt;/opt/zapret/ipset/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Создайте файл &amp;lt;code&amp;gt;custom-user-list.txt&amp;lt;/code&amp;gt; со своими доменами (если нужно)&lt;br /&gt;
&lt;br /&gt;
# Запустите скрипт:&lt;br /&gt;
&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
python3 generate_podkop_list.py&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Используйте полученный файл &amp;lt;code&amp;gt;podkop-final-list.txt&amp;lt;/code&amp;gt; в Podkop&lt;br /&gt;
&lt;br /&gt;
=== Настройка прокси/VPN ===&lt;br /&gt;
После добавления списка доменов настройте подключение к вашему VPN/прокси-серверу.&lt;br /&gt;
&lt;br /&gt;
В разделе &#039;&#039;&#039;Outbounds&#039;&#039;&#039; (в интерфейсе Podkop) настройте:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Connection Type&#039;&#039;&#039;: &amp;lt;code&amp;gt;proxy&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;vpn&amp;lt;/code&amp;gt; (в зависимости от вашего сервера)&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Proxy String&#039;&#039;&#039;: вставьте ссылку на ваш VPN/прокси (формат: &amp;lt;code&amp;gt;protocol://user:pass@server:port&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
# Или настройте &#039;&#039;&#039;Interface&#039;&#039;&#039; для WireGuard/OpenVPN&lt;br /&gt;
&lt;br /&gt;
=== Применение настроек ===&lt;br /&gt;
Нажмите &#039;&#039;&#039;Save &amp;amp; Restart&#039;&#039;&#039; для применения конфигурации Podkop.&lt;br /&gt;
&lt;br /&gt;
== Проверка работы ==&lt;br /&gt;
&lt;br /&gt;
=== Тестирование Zapret ===&lt;br /&gt;
&lt;br /&gt;
# Откройте YouTube — должен работать &#039;&#039;&#039;без VPN&#039;&#039;&#039; (регион РФ, русскоязычные рекомендации)&lt;br /&gt;
&lt;br /&gt;
# Проверьте Discord — должен открываться &#039;&#039;&#039;через Zapret&#039;&#039;&#039; (без VPN)&lt;br /&gt;
&lt;br /&gt;
=== Тестирование Podkop ===&lt;br /&gt;
&lt;br /&gt;
# Откройте домен из вашего списка Podkop (например, &amp;lt;code&amp;gt;rutracker.org&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
# Проверьте смену IP (через &amp;lt;code&amp;gt;2ip.ru&amp;lt;/code&amp;gt; или аналог) — должен показать IP вашего VPN-сервера&lt;br /&gt;
&lt;br /&gt;
=== Диагностика ===&lt;br /&gt;
Если что-то не работает:&lt;br /&gt;
&lt;br /&gt;
# Проверьте логи Zapret: &#039;&#039;&#039;Services → Zapret → Log Viewer&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Проверьте статус Podkop: &#039;&#039;&#039;Services → Podkop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Убедитесь, что домен &#039;&#039;&#039;не находится одновременно&#039;&#039;&#039; в списках Zapret и Podkop&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Связка Zapret + Podkop — это оптимальное решение для обхода блокировок на OpenWRT, которое позволяет:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Использовать DPI-обход&#039;&#039;&#039; (Zapret) для потоковых сервисов (YouTube, Twitch, Discord, Steam)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Оставаться в регионе РФ&#039;&#039;&#039; на YouTube и других сервисах (получать русскоязычный контент и рекомендации)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Экономить VPN-трафик&#039;&#039;&#039; (95% трафика идёт через Zapret без шифрования)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Использовать VPN&#039;&#039;&#039; (Podkop) только для действительно заблокированных ресурсов (торрент-трекеры, специализированные сервисы)&lt;br /&gt;
&lt;br /&gt;
Таким образом, вы получаете &#039;&#039;&#039;лучшее из обоих миров&#039;&#039;&#039;: быстрый доступ к популярным сервисам без потери региона и полноценный VPN для всего остального.&lt;br /&gt;
&lt;br /&gt;
== Полезные ссылки ==&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/remittor/zapret-openwrt Zapret для OpenWRT (GitHub)]&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/itdoginfo/podkop Podkop (GitHub)]&lt;br /&gt;
&lt;br /&gt;
* [https://podkop.net/ Документация Podkop]&lt;br /&gt;
&lt;br /&gt;
* [https://community.antifilter.download/ Списки Russian inside]&lt;br /&gt;
&lt;br /&gt;
== Дополнительно ==&lt;br /&gt;
&lt;br /&gt;
=== Автоматизация обновления списков ===&lt;br /&gt;
Для автоматического обновления пользовательских списков доменов можно настроить cron-задачу, которая будет периодически скачивать обновлённый список и перезапускать сервисы.&lt;br /&gt;
&lt;br /&gt;
=== Мониторинг ===&lt;br /&gt;
Рекомендуется периодически проверять:&lt;br /&gt;
&lt;br /&gt;
* Логи Zapret на наличие ошибок&lt;br /&gt;
&lt;br /&gt;
* Статус подключения Podkop к VPN-серверу&lt;br /&gt;
&lt;br /&gt;
* Актуальность версий обоих сервисов&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=Hysteria_2_%D0%BA%D0%B0%D1%81%D0%BA%D0%B0%D0%B4&amp;diff=959</id>
		<title>Hysteria 2 каскад</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=Hysteria_2_%D0%BA%D0%B0%D1%81%D0%BA%D0%B0%D0%B4&amp;diff=959"/>
		<updated>2026-04-26T10:14:44Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* 3.4 Исходный код скрипта */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Hysteria2: установка каскадной цепочки Entry Node → Exit Node → WARP =&lt;br /&gt;
&lt;br /&gt;
== Что такое Hysteria2 и зачем он нужен ==&lt;br /&gt;
&lt;br /&gt;
=== Проблема: ограничения традиционных прокси-протоколов ===&lt;br /&gt;
&lt;br /&gt;
Современные системы глубокой инспекции пакетов (DPI — Deep Packet Inspection), применяемые интернет-провайдерами и регуляторами по всему миру, умеют анализировать не только адреса назначения, но и &#039;&#039;&#039;характер самого трафика&#039;&#039;&#039;. Даже зашифрованное соединение можно идентифицировать — по поведению, по паузам между пакетами, по размерам передаваемых блоков данных, по TLS-fingerprint.&lt;br /&gt;
&lt;br /&gt;
Большинство прокси-протоколов работают поверх &#039;&#039;&#039;TCP&#039;&#039;&#039;. Это означает:&lt;br /&gt;
* Все потери пакетов обрабатываются дважды — сначала на уровне транспорта, затем внутри туннеля (head-of-line blocking).&lt;br /&gt;
* При нестабильном канале (мобильная сеть, спутник, VPN на слабом железе) скорость резко падает.&lt;br /&gt;
* TCP-fingerprint легче распознаётся и блокируется.&lt;br /&gt;
&lt;br /&gt;
Hysteria2 решает эту проблему фундаментально иначе: он работает поверх &#039;&#039;&#039;QUIC&#039;&#039;&#039; — транспортного протокола на базе UDP, разработанного в Google и стандартизированного в RFC 9000.&lt;br /&gt;
&lt;br /&gt;
=== Решение: QUIC/UDP с маскировкой под HTTPS ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 строит зашифрованный туннель поверх UDP, используя QUIC:&lt;br /&gt;
* &#039;&#039;&#039;Нет head-of-line blocking:&#039;&#039;&#039; потеря одного пакета не блокирует остальные потоки.&lt;br /&gt;
* &#039;&#039;&#039;Быстрое восстановление соединения:&#039;&#039;&#039; QUIC переподключается за 0-RTT (без дополнительного round-trip).&lt;br /&gt;
* &#039;&#039;&#039;Маскировка под HTTPS:&#039;&#039;&#039; снаружи трафик Hysteria2 выглядит как обычный QUIC/HTTP3 браузерный трафик — сервер «притворяется» обычным HTTPS-сайтом и возвращает реальный веб-контент при неавторизованных запросах.&lt;br /&gt;
* &#039;&#039;&#039;Congestion control:&#039;&#039;&#039; поддерживает несколько алгоритмов управления перегрузкой, включая BBR.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Протокол !! Транспорт !! Как выглядит для DPI !! Устойчивость к блокировке !! Скорость при потерях&lt;br /&gt;
|-&lt;br /&gt;
|| Обычный VPN (WireGuard, OpenVPN) || UDP / TCP || Характерный шаблон || Низкая — fingerprint легко детектируется || Высокая (WG) / Низкая (OpenVPN)&lt;br /&gt;
|-&lt;br /&gt;
|| Shadowsocks || TCP || Случайный зашифрованный поток || Средняя — выявляется по энтропии || Средняя&lt;br /&gt;
|-&lt;br /&gt;
|| VLESS + REALITY || TCP (TLS) || TLS с реальным сертификатом стороннего сайта || Высокая || Средняя&lt;br /&gt;
|-&lt;br /&gt;
|| NaïveProxy || TCP (HTTP/2 TLS) || Неотличим от Chrome HTTPS || Очень высокая || Средняя (TCP Head-of-Line)&lt;br /&gt;
|-&lt;br /&gt;
|| &#039;&#039;&#039;Hysteria2&#039;&#039;&#039; || &#039;&#039;&#039;UDP (QUIC/TLS)&#039;&#039;&#039; || &#039;&#039;&#039;QUIC/HTTP3, маскировка под HTTPS&#039;&#039;&#039; || &#039;&#039;&#039;Очень высокая&#039;&#039;&#039; || &#039;&#039;&#039;Высокая — устойчив к потерям&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Как работает Hysteria2 технически ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 использует протокол QUIC в качестве транспорта:&lt;br /&gt;
&lt;br /&gt;
# Клиент устанавливает QUIC-соединение с сервером — это TLS 1.3 поверх UDP.&lt;br /&gt;
# Внутри QUIC-соединения открываются независимые потоки (streams) для каждого проксируемого соединения.&lt;br /&gt;
# Сервер обрабатывает входящий трафик: авторизует клиента (по паролю или через внешний скрипт), затем перенаправляет трафик через указанный outbound.&lt;br /&gt;
# Если к серверу обращаются без правильного пароля — сервер ведёт себя как обычный HTTPS-сайт (&#039;&#039;&#039;masquerade&#039;&#039;&#039;) и возвращает реальный контент с заданного URL.&lt;br /&gt;
&lt;br /&gt;
Особенности аутентификации в данной схеме:&lt;br /&gt;
* &#039;&#039;&#039;EU сервер:&#039;&#039;&#039; использует одиночный пароль — только для входящих соединений от RU клиента (не клиентских устройств).&lt;br /&gt;
* &#039;&#039;&#039;RU сервер:&#039;&#039;&#039; использует &#039;&#039;&#039;command-аутентификацию&#039;&#039;&#039; — при каждом подключении вызывается внешний bash-скрипт, который проверяет пароль по файлу &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt;. Это позволяет добавлять и удалять пользователей &#039;&#039;&#039;без перезапуска сервера&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Каскадная цепочка: зачем два сервера ===&lt;br /&gt;
&lt;br /&gt;
В данном решении используется &#039;&#039;&#039;каскад из двух серверов&#039;&#039;&#039;: Entry Node (ближайший к клиентам сервер-вход) и Exit Node (сервер-выход в интернет). Это архитектурное решение принято намеренно по нескольким причинам:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Снижение риска для клиента:&#039;&#039;&#039; клиентские устройства подключаются только к ближайшему серверу. Соединение с соседним узлом менее заметно, чем прямое соединение с зарубежным сервером.&lt;br /&gt;
* &#039;&#039;&#039;Раздельная аутентификация:&#039;&#039;&#039; пароль «клиент → Entry Node» знают только конечные пользователи. Пароль «Entry Node → Exit Node» знают только серверы. Компрометация клиентского пароля не раскрывает пароль соединения между серверами.&lt;br /&gt;
* &#039;&#039;&#039;Анонимизация выхода:&#039;&#039;&#039; Exit Node передаёт трафик через Cloudflare WARP. Конечные сайты видят IP Cloudflare, а не IP ваших серверов.&lt;br /&gt;
* &#039;&#039;&#039;Параллельные независимые каналы:&#039;&#039;&#039; Hysteria2 работает рядом с NaïveProxy и 3x-ui на тех же серверах, не конфликтуя с ними. Падение одного канала не блокирует другие.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Схема конкретного решения ==&lt;br /&gt;
&lt;br /&gt;
=== Компоненты инфраструктуры ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Компонент !! Роль !! Адрес / Домен !! ОС&lt;br /&gt;
|-&lt;br /&gt;
|| Клиентские устройства || Конечные пользователи || — || iOS, Android, Windows, macOS, Linux&lt;br /&gt;
|-&lt;br /&gt;
|| OpenWrt роутер || Прозрачный обход для всей домашней сети || — || OpenWrt 24.10 (podkop нативно поддерживает hy2 URI)&lt;br /&gt;
|-&lt;br /&gt;
|| RU сервер (&#039;&#039;&#039;Entry Node&#039;&#039;&#039;) || Точка входа клиентов || &amp;lt;code&amp;gt;YOUR_RU_SERVER_IP&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;your-hy2-ru-domain.example.com&amp;lt;/code&amp;gt; || Ubuntu 24.04&lt;br /&gt;
|-&lt;br /&gt;
|| EU сервер (&#039;&#039;&#039;Exit Node&#039;&#039;&#039;) || Точка выхода в интернет || &amp;lt;code&amp;gt;YOUR_EU_SERVER_IP&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;your-hy2-eu-domain.example.com&amp;lt;/code&amp;gt; || Ubuntu 24.04&lt;br /&gt;
|-&lt;br /&gt;
|| Cloudflare WARP || Финальный выход в интернет || IP Cloudflare || —&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Полная схема прохождения трафика ===&lt;br /&gt;
&lt;br /&gt;
[[File:hysteria2-chain-traffic-flow.png|center|768x768px|Схема трафика Hysteria2: Клиенты → RU Entry Node → EU Exit Node → WARP → Интернет]]&lt;br /&gt;
&lt;br /&gt;
=== Протоколы на каждом участке цепочки ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Участок !! Протокол !! Шифрование !! Что видит наблюдатель&lt;br /&gt;
|-&lt;br /&gt;
|| Устройство → Роутер || Обычный TCP/UDP || Нет (локальная сеть) || Локальный трафик&lt;br /&gt;
|-&lt;br /&gt;
|| Роутер / ПК → RU сервер || QUIC / UDP (Hysteria2) || TLS 1.3 (Let&#039;s Encrypt) || HTTPS/HTTP3 трафик к обычному сайту&lt;br /&gt;
|-&lt;br /&gt;
|| RU клиент → EU сервер || QUIC / UDP (Hysteria2) || TLS 1.3 (Let&#039;s Encrypt) || HTTPS/HTTP3 трафик к обычному сайту&lt;br /&gt;
|-&lt;br /&gt;
|| EU сервер → 3x-ui inbound || SOCKS5 (localhost) || — (только на EU сервере) || Только локально&lt;br /&gt;
|-&lt;br /&gt;
|| EU 3x-ui → WARP || WireGuard (gVisor TUN) || WireGuard || Зашифрованный WireGuard к Cloudflare&lt;br /&gt;
|-&lt;br /&gt;
|| WARP → Интернет || Обычный TCP/UDP || — || IP Cloudflare&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Дополнительные каналы (параллельно Hysteria2) ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 работает &#039;&#039;&#039;независимо&#039;&#039;&#039; от NaïveProxy и 3x-ui. Все три канала активны одновременно:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Канал !! Протокол !! Маршрут !! Статус&lt;br /&gt;
|-&lt;br /&gt;
|| 3x-ui каскад (основной) || VLESS / REALITY || Клиенты → RU 3x-ui → EU 3x-ui → Интернет || ✅ Активен&lt;br /&gt;
|-&lt;br /&gt;
|| NaïveProxy каскад || HTTP/2 naïve || Роутер/ПК → RU Caddy → EU Caddy → WARP || ✅ Активен&lt;br /&gt;
|-&lt;br /&gt;
|| &#039;&#039;&#039;Hysteria2 каскад (этот гайд)&#039;&#039;&#039; || &#039;&#039;&#039;QUIC/UDP hy2&#039;&#039;&#039; || &#039;&#039;&#039;Клиенты → RU hy2 → EU hy2 → WARP&#039;&#039;&#039; || &#039;&#039;&#039;✅ Активен&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|| MTProto (Telegram) || MTProto || Клиенты Telegram → EU :8443, :2443 || ✅ Активен&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
=== Инфраструктура ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Компонент !! Требования&lt;br /&gt;
|-&lt;br /&gt;
|| EU сервер || Ubuntu 24.04, публичный IP, домен с A-записью → IP сервера&lt;br /&gt;
|-&lt;br /&gt;
|| RU сервер || Ubuntu 24.04, публичный IP, домен с A-записью → IP сервера&lt;br /&gt;
|-&lt;br /&gt;
|| 3x-ui на EU сервере || Уже установлен и работает; настроен outbound WARP&lt;br /&gt;
|-&lt;br /&gt;
|| Docker || Установлен на обоих серверах&lt;br /&gt;
|-&lt;br /&gt;
|| Порт 2053 UDP || Должен быть свободен на обоих серверах&lt;br /&gt;
|-&lt;br /&gt;
|| TLS-сертификат || Получается через Caddy (caddy-naive), либо через certbot — описано в разделе ниже&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DNS-записи (создать заранее, до установки) ===&lt;br /&gt;
&lt;br /&gt;
Let&#039;s Encrypt проверяет доступность домена по HTTP (порт 80) перед выдачей сертификата. DNS-записи должны быть созданы и распространены (propagated) до первого запуска Caddy.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Запись !! Тип !! Значение !! Примечание&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;your-hy2-ru-domain.example.com&amp;lt;/code&amp;gt; || A || IP RU сервера || Используется Hysteria2 сервером на RU&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;your-hy2-eu-domain.example.com&amp;lt;/code&amp;gt; || A || IP EU сервера || Используется Hysteria2 сервером на EU&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Примечание:&#039;&#039;&#039; если NaïveProxy (Caddy) уже настроен на тех же серверах с теми же доменами, отдельные DNS-записи для Hysteria2 не нужны — используется тот же домен и тот же сертификат.&lt;br /&gt;
&lt;br /&gt;
=== Используемые заглушки ===&lt;br /&gt;
&lt;br /&gt;
В данном руководстве применяются следующие заглушки. Замени их реальными значениями перед использованием:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Заглушка !! Описание&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;YOUR_RU_SERVER_IP&amp;lt;/code&amp;gt; || Публичный IP RU сервера&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;YOUR_EU_SERVER_IP&amp;lt;/code&amp;gt; || Публичный IP EU сервера&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;your-hy2-ru-domain.example.com&amp;lt;/code&amp;gt; || Домен для RU сервера (для TLS-сертификата)&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;your-hy2-eu-domain.example.com&amp;lt;/code&amp;gt; || Домен для EU сервера (для TLS-сертификата)&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;YOUR_EMAIL@example.com&amp;lt;/code&amp;gt; || Email для Let&#039;s Encrypt (уведомления об истечении сертификата)&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;EU_HY2_PASSWORD&amp;lt;/code&amp;gt; || Пароль соединения RU клиент → EU сервер (генерируется один раз)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Для генерации пароля EU_HY2_PASSWORD используй:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl rand -base64 18&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Сохрани результат — он понадобится в конфигах обоих серверов.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 1: EU сервер (Exit Node) ==&lt;br /&gt;
&lt;br /&gt;
Цель: развернуть Hysteria2 сервер в Docker, который принимает соединения от RU клиента и перенаправляет трафик через 3x-ui → Cloudflare WARP.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Все команды в этом разделе выполняются на EU сервере под root.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== 1.1 Установка Docker ===&lt;br /&gt;
&lt;br /&gt;
Если Docker уже установлен (проверить: &amp;lt;code&amp;gt;docker --version&amp;lt;/code&amp;gt;) — пропусти этот шаг.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Обновить пакеты&lt;br /&gt;
apt-get update &amp;amp;&amp;amp; apt-get upgrade -y&lt;br /&gt;
&lt;br /&gt;
# Установить зависимости&lt;br /&gt;
apt-get install -y ca-certificates curl gnupg lsb-release&lt;br /&gt;
&lt;br /&gt;
# Добавить GPG-ключ Docker&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \&lt;br /&gt;
  -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
# Добавить репозиторий Docker&lt;br /&gt;
echo &amp;quot;deb [arch=$(dpkg --print-architecture) \&lt;br /&gt;
  signed-by=/etc/apt/keyrings/docker.asc] \&lt;br /&gt;
  https://download.docker.com/linux/ubuntu \&lt;br /&gt;
  $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;$VERSION_CODENAME&amp;quot;) stable&amp;quot; \&lt;br /&gt;
  &amp;gt; /etc/apt/sources.list.d/docker.list&lt;br /&gt;
&lt;br /&gt;
# Установить Docker Engine&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin&lt;br /&gt;
&lt;br /&gt;
# Включить автозапуск&lt;br /&gt;
systemctl enable docker&lt;br /&gt;
systemctl start docker&lt;br /&gt;
&lt;br /&gt;
# Проверить&lt;br /&gt;
docker --version&lt;br /&gt;
docker compose version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Docker version 27.x.x, build ...&lt;br /&gt;
Docker Compose version v2.x.x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 1.2 Настройка 3x-ui: создание inbound hy2-out → WARP ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 Exit Node направляет трафик через 3x-ui SOCKS5 inbound, который в свою очередь маршрутизирует его в Cloudflare WARP. Этот шаг выполняется в веб-интерфейсе 3x-ui &#039;&#039;&#039;до&#039;&#039;&#039; запуска Hysteria2.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Условие:&#039;&#039;&#039; в 3x-ui должен быть настроен outbound WARP (WireGuard/gVisor).&lt;br /&gt;
&lt;br /&gt;
==== 1.2.1 Создать новый inbound в 3x-ui ====&lt;br /&gt;
&lt;br /&gt;
В веб-интерфейсе 3x-ui (EU сервер) перейди в &#039;&#039;&#039;Inbounds → Add Inbound&#039;&#039;&#039; и заполни следующие поля:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Параметр !! Значение !! Пояснение&lt;br /&gt;
|-&lt;br /&gt;
|| Примечание (Remark) || &amp;lt;code&amp;gt;hy2-out&amp;lt;/code&amp;gt; || Произвольное имя для идентификации в правилах маршрутизации&lt;br /&gt;
|-&lt;br /&gt;
|| Протокол || &amp;lt;code&amp;gt;mixed&amp;lt;/code&amp;gt; || Поддерживает SOCKS5 и HTTP одновременно&lt;br /&gt;
|-&lt;br /&gt;
|| Listen IP || &amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt; || Только localhost — недоступен извне&lt;br /&gt;
|-&lt;br /&gt;
|| Порт || &amp;lt;code&amp;gt;24364&amp;lt;/code&amp;gt; || Должен быть свободен; проверить: &amp;lt;code&amp;gt;ss -tlnp | grep 24364&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|| Аутентификация || Выключена || Hysteria2 сам отвечает за авторизацию клиентов&lt;br /&gt;
|-&lt;br /&gt;
|| UDP || Включён || Требуется для DNS-запросов через туннель&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Нажми &#039;&#039;&#039;Save&#039;&#039;&#039; — inbound немедленно активируется.&lt;br /&gt;
&lt;br /&gt;
==== 1.2.2 Создать правило маршрутизации ====&lt;br /&gt;
&lt;br /&gt;
В 3x-ui перейди в &#039;&#039;&#039;Routing → Add Rule&#039;&#039;&#039; (или Settings → Routing Rules):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
|| Inbound Tag || &amp;lt;code&amp;gt;hy2-out&amp;lt;/code&amp;gt; (тег созданного выше inbound)&lt;br /&gt;
|-&lt;br /&gt;
|| Outbound Tag || &amp;lt;code&amp;gt;warp&amp;lt;/code&amp;gt; (или название твоего WARP outbound в 3x-ui)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохрани и перезапусти Xray внутри 3x-ui.&lt;br /&gt;
&lt;br /&gt;
==== 1.2.3 Проверить, что порт 24364 слушает ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -tlnp | grep 24364&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LISTEN  0  128  127.0.0.1:24364  0.0.0.0:*  users:((&amp;quot;xray&amp;quot;,...))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 1.3 TLS-сертификат для Hysteria2 ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 требует действующий TLS-сертификат (самоподписанный не рекомендуется — клиентам потребуется флаг &amp;lt;code&amp;gt;insecure: true&amp;lt;/code&amp;gt;). В нашей схеме используется &#039;&#039;&#039;Let&#039;s Encrypt сертификат&#039;&#039;&#039;, получаемый и автоматически обновляемый через Caddy (caddy-naive стек).&lt;br /&gt;
&lt;br /&gt;
Caddy хранит сертификаты в именованном Docker volume &amp;lt;code&amp;gt;caddy-naive_caddy_data&amp;lt;/code&amp;gt;, и Hysteria2 подключает их через bind mount (read-only) — никаких лишних сервисов, никакого дублирования.&lt;br /&gt;
&lt;br /&gt;
==== Вариант А: Caddy (caddy-naive) уже установлен — рекомендуется ====&lt;br /&gt;
&lt;br /&gt;
Если NaïveProxy (caddy-naive) уже настроен и работает, сертификат уже получен. Проверь:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Найти путь к сертификату в Docker volume&lt;br /&gt;
DOMAIN=&amp;quot;your-hy2-eu-domain.example.com&amp;quot;&lt;br /&gt;
CERT_DIR=&amp;quot;/var/lib/docker/volumes/caddy-naive_caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${DOMAIN}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ls -la &amp;quot;${CERT_DIR}/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод — два файла:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
your-hy2-eu-domain.example.com.crt&lt;br /&gt;
your-hy2-eu-domain.example.com.key&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если файлы есть — переходи к разделу &#039;&#039;&#039;1.4&#039;&#039;&#039;. Если volume или папка не существуют — сначала установи caddy-naive (NaïveProxy) или воспользуйся Вариантом Б.&lt;br /&gt;
&lt;br /&gt;
==== Вариант Б: получить сертификат через certbot (если Caddy не установлен) ====&lt;br /&gt;
&lt;br /&gt;
Этот вариант используется, если caddy-naive &#039;&#039;&#039;не установлен&#039;&#039;&#039; и на серверах нет другого HTTP-сервера на портах 80/443.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Установить certbot&lt;br /&gt;
apt-get install -y certbot&lt;br /&gt;
&lt;br /&gt;
# Получить сертификат (standalone — Certbot запустит временный HTTP-сервер на :80)&lt;br /&gt;
certbot certonly --standalone \&lt;br /&gt;
  -d your-hy2-eu-domain.example.com \&lt;br /&gt;
  --email YOUR_EMAIL@example.com \&lt;br /&gt;
  --agree-tos --non-interactive&lt;br /&gt;
&lt;br /&gt;
# Проверить&lt;br /&gt;
ls /etc/letsencrypt/live/your-hy2-eu-domain.example.com/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сертификаты будут по пути &amp;lt;code&amp;gt;/etc/letsencrypt/live/your-hy2-eu-domain.example.com/&amp;lt;/code&amp;gt;. В этом случае в &amp;lt;code&amp;gt;docker-compose.yml&amp;lt;/code&amp;gt; (раздел 1.6) замени volume на:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
- /etc/letsencrypt/live/your-hy2-eu-domain.example.com:/etc/hysteria/certs:ro&lt;br /&gt;
- /etc/letsencrypt/archive/your-hy2-eu-domain.example.com:/etc/letsencrypt/archive/your-hy2-eu-domain.example.com:ro&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И в &amp;lt;code&amp;gt;server.yaml&amp;lt;/code&amp;gt; пути к файлам:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
tls:&lt;br /&gt;
  cert: /etc/hysteria/certs/fullchain.pem&lt;br /&gt;
  key: /etc/hysteria/certs/privkey.pem&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 1.4 Создание структуры проекта ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/hysteria-eu&lt;br /&gt;
cd /opt/hysteria-eu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итоговая структура:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/hysteria-eu/&lt;br /&gt;
├── docker-compose.yml&lt;br /&gt;
└── server.yaml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 1.5 Конфигурация сервера: server.yaml ===&lt;br /&gt;
&lt;br /&gt;
Создай файл конфигурации. Замени &amp;lt;code&amp;gt;EU_HY2_PASSWORD&amp;lt;/code&amp;gt; сгенерированным паролем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-eu/server.yaml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
listen: :2053&lt;br /&gt;
&lt;br /&gt;
tls:&lt;br /&gt;
  cert: /etc/hysteria/certs/your-hy2-eu-domain.example.com.crt&lt;br /&gt;
  key: /etc/hysteria/certs/your-hy2-eu-domain.example.com.key&lt;br /&gt;
&lt;br /&gt;
auth:&lt;br /&gt;
  type: password&lt;br /&gt;
  password: EU_HY2_PASSWORD&lt;br /&gt;
&lt;br /&gt;
ignoreClientBandwidth: true&lt;br /&gt;
&lt;br /&gt;
masquerade:&lt;br /&gt;
  type: proxy&lt;br /&gt;
  proxy:&lt;br /&gt;
    url: https://news.ycombinator.com/&lt;br /&gt;
    rewriteHost: true&lt;br /&gt;
&lt;br /&gt;
outbounds:&lt;br /&gt;
  - name: warp&lt;br /&gt;
    type: socks5&lt;br /&gt;
    socks5:&lt;br /&gt;
      addr: 127.0.0.1:24364&lt;br /&gt;
&lt;br /&gt;
acl:&lt;br /&gt;
  inline:&lt;br /&gt;
    - &amp;quot;warp(all)&amp;quot;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Описание ключевых параметров:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Параметр !! Значение !! Пояснение&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;listen: :2053&amp;lt;/code&amp;gt; || UDP порт 2053 || Hysteria2 слушает на всех интерфейсах&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;tls.cert / tls.key&amp;lt;/code&amp;gt; || Пути к сертификату || Берутся из caddy-naive Docker volume (bind mount)&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;auth.type: password&amp;lt;/code&amp;gt; || Одиночный пароль || Для соединения RU клиент → EU сервер (клиентские устройства этот пароль не знают)&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;ignoreClientBandwidth: true&amp;lt;/code&amp;gt; || Игнорировать лимит клиента || Серверная сторона управляет congestion control самостоятельно&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;masquerade.type: proxy&amp;lt;/code&amp;gt; || Проксировать реальный сайт || Неавторизованные запросы получают реальный контент ycombinator.com — сервер выглядит как обычный HTTPS-сайт&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;outbounds.warp&amp;lt;/code&amp;gt; || SOCKS5 на 127.0.0.1:24364 || Исходящий трафик → 3x-ui inbound &amp;quot;hy2-out&amp;quot; → WARP&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;acl: warp(all)&amp;lt;/code&amp;gt; || Направить весь трафик в warp || Синтаксис: имя outbound в скобках, адрес/маска после&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 1.6 Конфигурация Docker Compose: docker-compose.yml ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-eu/docker-compose.yml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
services:&lt;br /&gt;
  hysteria-eu:&lt;br /&gt;
    image: tobyxdd/hysteria:latest&lt;br /&gt;
    container_name: hysteria-eu&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    command: server --config /etc/hysteria/server.yaml&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./server.yaml:/etc/hysteria/server.yaml:ro&lt;br /&gt;
      - /var/lib/docker/volumes/caddy-naive_caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/your-hy2-eu-domain.example.com:/etc/hysteria/certs:ro&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важные моменты:&lt;br /&gt;
* &amp;lt;code&amp;gt;network_mode: host&amp;lt;/code&amp;gt; — обязателен, чтобы контейнер видел &amp;lt;code&amp;gt;127.0.0.1:24364&amp;lt;/code&amp;gt; (3x-ui inbound).&lt;br /&gt;
* &amp;lt;code&amp;gt;:ro&amp;lt;/code&amp;gt; — сертификаты подключены только для чтения, Hysteria2 их не изменяет.&lt;br /&gt;
* Путь к сертификату — bind mount из Docker volume caddy-naive. Если используется certbot (Вариант Б) — замени путь согласно инструкции раздела 1.3.&lt;br /&gt;
&lt;br /&gt;
=== 1.7 Первый запуск ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/hysteria-eu&lt;br /&gt;
&lt;br /&gt;
# Скачать образ и запустить&lt;br /&gt;
docker compose pull&lt;br /&gt;
docker compose up -d&lt;br /&gt;
&lt;br /&gt;
# Подождать 3 секунды и проверить логи&lt;br /&gt;
sleep 3 &amp;amp;&amp;amp; docker compose logs&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод в логах:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
INFO  server mode&lt;br /&gt;
INFO  server up and running   {&amp;quot;listen&amp;quot;: &amp;quot;:2053&amp;quot;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если в логах ошибка — см. раздел «Диагностика проблем» (Часть 5).&lt;br /&gt;
&lt;br /&gt;
=== 1.8 Проверка: порт и соединение ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Проверить, что Hysteria2 слушает на UDP :2053&lt;br /&gt;
ss -ulnp | grep &#039;:2053&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UNCONN  0  0  0.0.0.0:2053  0.0.0.0:*  users:((&amp;quot;hysteria&amp;quot;,...))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Статус контейнера&lt;br /&gt;
docker compose ps&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NAME          IMAGE                     STATUS&lt;br /&gt;
hysteria-eu   tobyxdd/hysteria:latest   Up X minutes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 2: RU сервер (Entry Node) ==&lt;br /&gt;
&lt;br /&gt;
Цель: развернуть два Docker-контейнера:&lt;br /&gt;
* &amp;lt;code&amp;gt;hysteria-ru-server&amp;lt;/code&amp;gt; — принимает соединения от клиентов, аутентифицирует по &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;hysteria-ru-client&amp;lt;/code&amp;gt; — подключается к EU серверу, слушает SOCKS5 на &amp;lt;code&amp;gt;127.0.0.1:10810&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Между ними: hysteria-ru-server направляет трафик через SOCKS5 → hysteria-ru-client → EU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Все команды в этом разделе выполняются на RU сервере под root.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== 2.1 Установка Docker ===&lt;br /&gt;
&lt;br /&gt;
Аналогично EU серверу (раздел 1.1). Если Docker уже установлен — пропусти.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt-get update &amp;amp;&amp;amp; apt-get upgrade -y&lt;br /&gt;
apt-get install -y ca-certificates curl gnupg lsb-release&lt;br /&gt;
&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \&lt;br /&gt;
  -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;deb [arch=$(dpkg --print-architecture) \&lt;br /&gt;
  signed-by=/etc/apt/keyrings/docker.asc] \&lt;br /&gt;
  https://download.docker.com/linux/ubuntu \&lt;br /&gt;
  $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;$VERSION_CODENAME&amp;quot;) stable&amp;quot; \&lt;br /&gt;
  &amp;gt; /etc/apt/sources.list.d/docker.list&lt;br /&gt;
&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin&lt;br /&gt;
systemctl enable docker &amp;amp;&amp;amp; systemctl start docker&lt;br /&gt;
&lt;br /&gt;
docker --version &amp;amp;&amp;amp; docker compose version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2.2 TLS-сертификат для RU сервера ===&lt;br /&gt;
&lt;br /&gt;
Аналогично EU серверу. На RU сервере также используется сертификат от Caddy (caddy-naive), если NaïveProxy настроен.&lt;br /&gt;
&lt;br /&gt;
==== Вариант А: через Caddy (caddy-naive) — рекомендуется ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
DOMAIN=&amp;quot;your-hy2-ru-domain.example.com&amp;quot;&lt;br /&gt;
CERT_DIR=&amp;quot;/var/lib/docker/volumes/caddy-naive_caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${DOMAIN}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ls -la &amp;quot;${CERT_DIR}/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если файлы &amp;lt;code&amp;gt;.crt&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;.key&amp;lt;/code&amp;gt; присутствуют — всё готово, переходи к разделу 2.3.&lt;br /&gt;
&lt;br /&gt;
==== Вариант Б: через certbot (если Caddy не установлен) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt-get install -y certbot&lt;br /&gt;
&lt;br /&gt;
certbot certonly --standalone \&lt;br /&gt;
  -d your-hy2-ru-domain.example.com \&lt;br /&gt;
  --email YOUR_EMAIL@example.com \&lt;br /&gt;
  --agree-tos --non-interactive&lt;br /&gt;
&lt;br /&gt;
ls /etc/letsencrypt/live/your-hy2-ru-domain.example.com/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2.3 Создание структуры проекта ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/hysteria-ru/users&lt;br /&gt;
cd /opt/hysteria-ru&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итоговая структура:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/hysteria-ru/&lt;br /&gt;
├── docker-compose.yml&lt;br /&gt;
├── server.yaml&lt;br /&gt;
├── client.yaml&lt;br /&gt;
└── users/&lt;br /&gt;
    ├── users.txt        ← список пользователей (username password)&lt;br /&gt;
    └── check-auth.sh    ← скрипт авторизации, вызывается при каждом подключении&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2.4 Система аутентификации пользователей ===&lt;br /&gt;
&lt;br /&gt;
RU сервер использует &amp;lt;code&amp;gt;auth.type: command&amp;lt;/code&amp;gt; — при каждом входящем подключении Hysteria2 вызывает внешний скрипт и передаёт ему пароль клиента в аргументах. Скрипт ищет пароль в файле &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt;: если совпадение найдено — выводит имя пользователя (оно попадает в логи) и завершается с кодом 0. Если нет — завершается с кодом 1 (отказ в подключении).&lt;br /&gt;
&lt;br /&gt;
Преимущество этого подхода: &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt; можно редактировать в любой момент без перезапуска контейнера. Изменения применяются немедленно.&lt;br /&gt;
&lt;br /&gt;
==== 2.4.1 Файл пользователей: users/users.txt ====&lt;br /&gt;
&lt;br /&gt;
Формат: одна строка на пользователя — имя пользователя и пароль, разделённые пробелом.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Сгенерировать первого пользователя (пример: &amp;quot;default&amp;quot;)&lt;br /&gt;
PASS=$(openssl rand -base64 18)&lt;br /&gt;
echo &amp;quot;default $PASS&amp;quot; &amp;gt; /opt/hysteria-ru/users/users.txt&lt;br /&gt;
echo &amp;quot;Пароль пользователя default: $PASS&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Формат файла:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
username1 пароль1&lt;br /&gt;
username2 пароль2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Важно:&#039;&#039;&#039; не используй пробелы внутри пароля — пароль считывается по второму полю строки.&lt;br /&gt;
&lt;br /&gt;
==== 2.4.2 Скрипт авторизации: users/check-auth.sh ====&lt;br /&gt;
&lt;br /&gt;
Hysteria2 вызывает скрипт с тремя аргументами: &amp;lt;code&amp;gt;$1&amp;lt;/code&amp;gt; — адрес клиента, &amp;lt;code&amp;gt;$2&amp;lt;/code&amp;gt; — пароль, &amp;lt;code&amp;gt;$3&amp;lt;/code&amp;gt; — tx bandwidth.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-ru/users/check-auth.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
AUTH_PAYLOAD=&amp;quot;$2&amp;quot;&lt;br /&gt;
USERS_FILE=&amp;quot;/etc/hysteria/users/users.txt&amp;quot;&lt;br /&gt;
&lt;br /&gt;
USERNAME=$(awk -v pwd=&amp;quot;$AUTH_PAYLOAD&amp;quot; &#039;$2 == pwd {print $1; exit}&#039; &amp;quot;$USERS_FILE&amp;quot; 2&amp;gt;/dev/null)&lt;br /&gt;
&lt;br /&gt;
if [ -n &amp;quot;$USERNAME&amp;quot; ]; then&lt;br /&gt;
    echo &amp;quot;$USERNAME&amp;quot;&lt;br /&gt;
    exit 0&lt;br /&gt;
fi&lt;br /&gt;
exit 1&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
chmod +x /opt/hysteria-ru/users/check-auth.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Почему используется &amp;lt;code&amp;gt;awk&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;grep&amp;lt;/code&amp;gt;:&lt;br /&gt;
* Hysteria2 использует Docker-образ на базе Alpine Linux с BusyBox.&lt;br /&gt;
* BusyBox &amp;lt;code&amp;gt;grep&amp;lt;/code&amp;gt; не поддерживает флаг &amp;lt;code&amp;gt;-P&amp;lt;/code&amp;gt; (Perl-совместимые регулярки).&lt;br /&gt;
* &amp;lt;code&amp;gt;awk&amp;lt;/code&amp;gt; доступен во всех Unix/Linux окружениях и работает стабильно.&lt;br /&gt;
&lt;br /&gt;
=== 2.5 Конфигурация сервера: server.yaml ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-ru/server.yaml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
listen: :2053&lt;br /&gt;
&lt;br /&gt;
tls:&lt;br /&gt;
  cert: /etc/hysteria/certs/your-hy2-ru-domain.example.com.crt&lt;br /&gt;
  key: /etc/hysteria/certs/your-hy2-ru-domain.example.com.key&lt;br /&gt;
&lt;br /&gt;
auth:&lt;br /&gt;
  type: command&lt;br /&gt;
  command: /etc/hysteria/users/check-auth.sh&lt;br /&gt;
&lt;br /&gt;
ignoreClientBandwidth: true&lt;br /&gt;
&lt;br /&gt;
masquerade:&lt;br /&gt;
  type: proxy&lt;br /&gt;
  proxy:&lt;br /&gt;
    url: https://news.ycombinator.com/&lt;br /&gt;
    rewriteHost: true&lt;br /&gt;
&lt;br /&gt;
outbounds:&lt;br /&gt;
  - name: chain&lt;br /&gt;
    type: socks5&lt;br /&gt;
    socks5:&lt;br /&gt;
      addr: 127.0.0.1:10810&lt;br /&gt;
&lt;br /&gt;
acl:&lt;br /&gt;
  inline:&lt;br /&gt;
    - &amp;quot;chain(all)&amp;quot;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Описание ключевых параметров:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Параметр !! Значение !! Пояснение&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;auth.type: command&amp;lt;/code&amp;gt; || Внешний скрипт || При каждом подключении вызывается &amp;lt;code&amp;gt;check-auth.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;auth.command&amp;lt;/code&amp;gt; || Путь внутри контейнера || Скрипт смонтирован через volume: &amp;lt;code&amp;gt;./users:/etc/hysteria/users&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;outbounds.chain&amp;lt;/code&amp;gt; || SOCKS5 на 127.0.0.1:10810 || Трафик → hysteria-ru-client → EU&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;acl: chain(all)&amp;lt;/code&amp;gt; || Весь трафик через chain || Синтаксис: имя outbound, затем адрес в скобках&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 2.6 Конфигурация клиента: client.yaml ===&lt;br /&gt;
&lt;br /&gt;
RU клиент подключается к EU серверу и поднимает SOCKS5 на &amp;lt;code&amp;gt;127.0.0.1:10810&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-ru/client.yaml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
server: your-hy2-eu-domain.example.com:2053&lt;br /&gt;
&lt;br /&gt;
auth: EU_HY2_PASSWORD&lt;br /&gt;
&lt;br /&gt;
socks5:&lt;br /&gt;
  listen: 127.0.0.1:10810&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Замени &amp;lt;code&amp;gt;EU_HY2_PASSWORD&amp;lt;/code&amp;gt; на тот же пароль, который указан в &amp;lt;code&amp;gt;server.yaml&amp;lt;/code&amp;gt; EU сервера.&lt;br /&gt;
&lt;br /&gt;
=== 2.7 Конфигурация Docker Compose: docker-compose.yml ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-ru/docker-compose.yml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
services:&lt;br /&gt;
  hysteria-ru-server:&lt;br /&gt;
    image: tobyxdd/hysteria:latest&lt;br /&gt;
    container_name: hysteria-ru-server&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    command: server --config /etc/hysteria/server.yaml&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./server.yaml:/etc/hysteria/server.yaml:ro&lt;br /&gt;
      - ./users:/etc/hysteria/users:ro&lt;br /&gt;
      - /var/lib/docker/volumes/caddy-naive_caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/your-hy2-ru-domain.example.com:/etc/hysteria/certs:ro&lt;br /&gt;
&lt;br /&gt;
  hysteria-ru-client:&lt;br /&gt;
    image: tobyxdd/hysteria:latest&lt;br /&gt;
    container_name: hysteria-ru-client&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    command: client --config /etc/hysteria/client.yaml&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./client.yaml:/etc/hysteria/client.yaml:ro&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Критически важные моменты:&#039;&#039;&#039;&lt;br /&gt;
* Директория &amp;lt;code&amp;gt;./users&amp;lt;/code&amp;gt; монтируется в оба контейнера... нет, только в &amp;lt;code&amp;gt;hysteria-ru-server&amp;lt;/code&amp;gt;. Клиентский контейнер видит только свой &amp;lt;code&amp;gt;client.yaml&amp;lt;/code&amp;gt;.&lt;br /&gt;
* При изменении &amp;lt;code&amp;gt;docker-compose.yml&amp;lt;/code&amp;gt; (добавлении volume) нужен пересоздать контейнер: &amp;lt;code&amp;gt;docker compose down &amp;amp;&amp;amp; docker compose up -d&amp;lt;/code&amp;gt;. Простой &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt; не применяет изменения volumes.&lt;br /&gt;
&lt;br /&gt;
=== 2.8 Первый запуск ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/hysteria-ru&lt;br /&gt;
&lt;br /&gt;
# Скачать образ&lt;br /&gt;
docker compose pull&lt;br /&gt;
&lt;br /&gt;
# Запустить оба контейнера&lt;br /&gt;
docker compose up -d&lt;br /&gt;
&lt;br /&gt;
# Подождать и проверить логи&lt;br /&gt;
sleep 3 &amp;amp;&amp;amp; docker compose logs&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hysteria-ru-server  | INFO  server mode&lt;br /&gt;
hysteria-ru-server  | INFO  server up and running  {&amp;quot;listen&amp;quot;: &amp;quot;:2053&amp;quot;}&lt;br /&gt;
hysteria-ru-client  | INFO  client mode&lt;br /&gt;
hysteria-ru-client  | INFO  connected to server  {&amp;quot;udpEnabled&amp;quot;: true, &amp;quot;count&amp;quot;: 1}&lt;br /&gt;
hysteria-ru-client  | INFO  SOCKS5 server listening  {&amp;quot;addr&amp;quot;: &amp;quot;127.0.0.1:10810&amp;quot;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2.9 Проверка цепочки с RU сервера ===&lt;br /&gt;
&lt;br /&gt;
Тест: запустить временный Hysteria2 клиент на RU сервере и проверить, что трафик выходит через WARP (IP Cloudflare):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Создать временный конфиг тест-клиента&lt;br /&gt;
cat &amp;gt; /tmp/hy2-test.yaml &amp;lt;&amp;lt; EOF&lt;br /&gt;
server: 127.0.0.1:2053&lt;br /&gt;
auth: $(awk &#039;NR==1{print $2}&#039; /opt/hysteria-ru/users/users.txt)&lt;br /&gt;
tls:&lt;br /&gt;
  insecure: true&lt;br /&gt;
  sni: your-hy2-ru-domain.example.com&lt;br /&gt;
socks5:&lt;br /&gt;
  listen: 127.0.0.1:11080&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
# Запустить тест-клиент&lt;br /&gt;
docker run -d --name hy2-test --network host \&lt;br /&gt;
  -v /tmp/hy2-test.yaml:/etc/hysteria/client.yaml:ro \&lt;br /&gt;
  tobyxdd/hysteria:latest client --config /etc/hysteria/client.yaml&lt;br /&gt;
&lt;br /&gt;
# Ждать 3 секунды&lt;br /&gt;
sleep 3&lt;br /&gt;
&lt;br /&gt;
# Проверить IP выхода — должен быть Cloudflare WARP IP&lt;br /&gt;
echo &amp;quot;IP через цепочку:&amp;quot;&lt;br /&gt;
curl -s --max-time 15 -x socks5h://127.0.0.1:11080 https://ifconfig.me&lt;br /&gt;
&lt;br /&gt;
# Очистить&lt;br /&gt;
docker rm -f hy2-test&lt;br /&gt;
rm -f /tmp/hy2-test.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если IP вывода принадлежит Cloudflare (начинается с &amp;lt;code&amp;gt;2a09:&amp;lt;/code&amp;gt; для IPv6 или относится к диапазонам WARP) — цепочка RU → EU → WARP работает корректно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Примечание:&#039;&#039;&#039; параметр &amp;lt;code&amp;gt;insecure: true&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;sni&amp;lt;/code&amp;gt; нужны в тест-клиенте, потому что он подключается по IP (&amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt;), а сертификат выдан на домен. Реальные клиенты подключаются по домену и такие параметры не требуются.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 3: Управление пользователями (hy2-users.sh) ==&lt;br /&gt;
&lt;br /&gt;
=== 3.1 Что это и зачем ===&lt;br /&gt;
&lt;br /&gt;
Для управления пользователями Hysteria2 на RU сервере предназначен скрипт &amp;lt;code&amp;gt;hy2-users.sh&amp;lt;/code&amp;gt;. Он предоставляет интерактивное меню с набором операций над файлом &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Скрипт решает следующие задачи:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Операция !! Описание&lt;br /&gt;
|-&lt;br /&gt;
|| Список пользователей || Показывает всех пользователей из users.txt с маскированными паролями&lt;br /&gt;
|-&lt;br /&gt;
|| Добавить пользователя || Запрашивает имя, автоматически генерирует криптостойкий пароль, сохраняет в users.txt, показывает готовый Hysteria2 URI&lt;br /&gt;
|-&lt;br /&gt;
|| Удалить пользователя || Интерактивный выбор из списка, удаление строки из users.txt&lt;br /&gt;
|-&lt;br /&gt;
|| Показать конфиг || Генерирует и показывает Hysteria2 URI для выбранного пользователя&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Ключевые особенности:&lt;br /&gt;
* &#039;&#039;&#039;Нет перезапуска контейнера.&#039;&#039;&#039; Hysteria2 с &amp;lt;code&amp;gt;auth.type: command&amp;lt;/code&amp;gt; читает файл при каждом подключении — изменения в &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt; применяются мгновенно.&lt;br /&gt;
* &#039;&#039;&#039;Пароли генерируются автоматически&#039;&#039;&#039; через &amp;lt;code&amp;gt;openssl rand&amp;lt;/code&amp;gt; — случайные, криптостойкие.&lt;br /&gt;
* &#039;&#039;&#039;URI формат&#039;&#039;&#039; соответствует стандарту Hysteria2 и принимается всеми клиентами: NekoBox, husi, Exclave, podkop.&lt;br /&gt;
&lt;br /&gt;
=== 3.2 Установка скрипта ===&lt;br /&gt;
&lt;br /&gt;
Скрипт хранится в репозитории по пути &amp;lt;code&amp;gt;scripts/hy2-users.sh&amp;lt;/code&amp;gt;. Установка на сервер:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Скопировать скрипт на сервер&lt;br /&gt;
scp scripts/hy2-users.sh root@YOUR_RU_SERVER_IP:/usr/local/bin/hy2-users.sh&lt;br /&gt;
&lt;br /&gt;
# Сделать исполняемым&lt;br /&gt;
ssh root@YOUR_RU_SERVER_IP &amp;quot;chmod +x /usr/local/bin/hy2-users.sh&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или выполнить непосредственно на RU сервере (если скрипт уже там):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x /usr/local/bin/hy2-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка переменных в начале скрипта.&#039;&#039;&#039; Открой скрипт и убедись, что следующие переменные указывают на правильные значения:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
head -15 /usr/local/bin/hy2-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Должны быть:&lt;br /&gt;
* &amp;lt;code&amp;gt;USERS_FILE=&amp;quot;/opt/hysteria-ru/users/users.txt&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DOMAIN=&amp;quot;your-hy2-ru-domain.example.com&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;PORT=&amp;quot;2053&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если домен указан неверно — исправь:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sed -i &#039;s|DOMAIN=.*|DOMAIN=&amp;quot;your-hy2-ru-domain.example.com&amp;quot;|&#039; /usr/local/bin/hy2-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3.3 Использование ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo bash /usr/local/bin/hy2-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скрипт показывает меню:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
┌─────────────────────────────────────────────┐&lt;br /&gt;
│  Hysteria2 — управление пользователями RU   │&lt;br /&gt;
└─────────────────────────────────────────────┘&lt;br /&gt;
&lt;br /&gt;
  1. Список пользователей&lt;br /&gt;
  2. Добавить пользователя&lt;br /&gt;
  3. Удалить пользователя&lt;br /&gt;
  4. Показать конфиг клиента&lt;br /&gt;
&lt;br /&gt;
  0. Выход&lt;br /&gt;
&lt;br /&gt;
Выбери действие:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При добавлении нового пользователя скрипт выводит готовый URI:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hysteria2://СГЕНЕРИРОВАННЫЙ_ПАРОЛЬ@your-hy2-ru-domain.example.com:2053&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот URI вставляется напрямую в клиентское приложение (см. Часть 4).&lt;br /&gt;
&lt;br /&gt;
=== 3.4 Исходный код скрипта ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight:bold; padding:4px 0;&amp;quot;&amp;gt;▶ Показать исходный код hy2-users.sh&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# =============================================================&lt;br /&gt;
# hy2-users — управление пользователями Hysteria2 на RU сервере&lt;br /&gt;
# users.txt: /opt/hysteria-ru/users/users.txt&lt;br /&gt;
# Формат: username password (по одной строке)&lt;br /&gt;
# Перезапуск контейнера НЕ требуется — изменения применяются мгновенно&lt;br /&gt;
# =============================================================&lt;br /&gt;
&lt;br /&gt;
USERS_FILE=&amp;quot;/opt/hysteria-ru/users/users.txt&amp;quot;&lt;br /&gt;
DOMAIN=&amp;quot;your-hy2-ru-domain.example.com&amp;quot;&lt;br /&gt;
PORT=&amp;quot;2053&amp;quot;&lt;br /&gt;
&lt;br /&gt;
RED=&#039;\033[0;31m&#039;&lt;br /&gt;
GREEN=&#039;\033[0;32m&#039;&lt;br /&gt;
YELLOW=&#039;\033[1;33m&#039;&lt;br /&gt;
CYAN=&#039;\033[0;36m&#039;&lt;br /&gt;
BOLD=&#039;\033[1m&#039;&lt;br /&gt;
NC=&#039;\033[0m&#039;&lt;br /&gt;
&lt;br /&gt;
# --- Вспомогательные функции ---&lt;br /&gt;
&lt;br /&gt;
check_root() {&lt;br /&gt;
    if [[ $EUID -ne 0 ]]; then&lt;br /&gt;
        echo -e &amp;quot;${RED}Ошибка: запусти скрипт от root (sudo bash hy2-users.sh)${NC}&amp;quot;&lt;br /&gt;
        exit 1&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
check_users_file() {&lt;br /&gt;
    if [[ ! -f &amp;quot;$USERS_FILE&amp;quot; ]]; then&lt;br /&gt;
        echo -e &amp;quot;${RED}Ошибка: файл пользователей не найден: $USERS_FILE${NC}&amp;quot;&lt;br /&gt;
        exit 1&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
get_usernames() {&lt;br /&gt;
    awk &#039;{print $1}&#039; &amp;quot;$USERS_FILE&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
get_password() {&lt;br /&gt;
    local user=&amp;quot;$1&amp;quot;&lt;br /&gt;
    awk -v u=&amp;quot;$user&amp;quot; &#039;$1 == u {print $2}&#039; &amp;quot;$USERS_FILE&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
press_enter() {&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    read -rp &amp;quot;Нажми Enter для возврата в меню...&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
print_config_for() {&lt;br /&gt;
    local user=&amp;quot;$1&amp;quot;&lt;br /&gt;
    local pass=&amp;quot;$2&amp;quot;&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}┌─────────────────────────────────────────────┐${NC}&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}│  Hysteria2 URI для клиента                  │${NC}&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}└─────────────────────────────────────────────┘${NC}&amp;quot;&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}  hysteria2://${pass}@${DOMAIN}:${PORT}${NC}&amp;quot;&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${CYAN}Для podkop (OpenWrt):${NC}  вставить URI как hy2 outbound&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${CYAN}Для мобильных клиентов:${NC}  NekoBox, husi, Exclave — импорт URI&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${CYAN}Пользователь:${NC}  ${user}&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# --- Функции меню ---&lt;br /&gt;
&lt;br /&gt;
list_users() {&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}${CYAN}=== Список пользователей ===${NC}&amp;quot;&lt;br /&gt;
    mapfile -t users &amp;lt; &amp;lt;(get_usernames)&lt;br /&gt;
    if [[ ${#users[@]} -eq 0 ]]; then&lt;br /&gt;
        echo -e &amp;quot;${YELLOW}Пользователей нет.${NC}&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        for i in &amp;quot;${!users[@]}&amp;quot;; do&lt;br /&gt;
            echo -e &amp;quot;  ${BOLD}$((i+1)).${NC} ${users[$i]}&amp;quot;&lt;br /&gt;
        done&lt;br /&gt;
        echo &amp;quot;&amp;quot;&lt;br /&gt;
        echo -e &amp;quot;  Всего: ${#users[@]} пользователь(ей)&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
add_user() {&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}${CYAN}=== Добавить пользователя ===${NC}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    read -rp &amp;quot;Имя пользователя: &amp;quot; username&lt;br /&gt;
    username=$(echo &amp;quot;$username&amp;quot; | tr -d &#039; &#039;)&lt;br /&gt;
&lt;br /&gt;
    if [[ -z &amp;quot;$username&amp;quot; ]]; then&lt;br /&gt;
        echo -e &amp;quot;${RED}Имя не может быть пустым.${NC}&amp;quot;&lt;br /&gt;
        press_enter&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    if grep -q &amp;quot;^${username} &amp;quot; &amp;quot;$USERS_FILE&amp;quot; 2&amp;gt;/dev/null; then&lt;br /&gt;
        echo -e &amp;quot;${RED}Пользователь &#039;${username}&#039; уже существует.${NC}&amp;quot;&lt;br /&gt;
        press_enter&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    read -rp &amp;quot;Пароль (Enter = сгенерировать автоматически): &amp;quot; password&lt;br /&gt;
    if [[ -z &amp;quot;$password&amp;quot; ]]; then&lt;br /&gt;
        password=$(openssl rand -base64 18 | tr -d &#039;=/+&#039; | head -c 22)&lt;br /&gt;
        echo -e &amp;quot;  Сгенерирован пароль: ${BOLD}${password}${NC}&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    echo &amp;quot;${username} ${password}&amp;quot; &amp;gt;&amp;gt; &amp;quot;$USERS_FILE&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${GREEN}Пользователь &#039;${username}&#039; добавлен.${NC}&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${YELLOW}Изменения применяются мгновенно — перезапуск не нужен.${NC}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    print_config_for &amp;quot;$username&amp;quot; &amp;quot;$password&amp;quot;&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
delete_user() {&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}${CYAN}=== Удалить пользователя ===${NC}&amp;quot;&lt;br /&gt;
    mapfile -t users &amp;lt; &amp;lt;(get_usernames)&lt;br /&gt;
&lt;br /&gt;
    if [[ ${#users[@]} -eq 0 ]]; then&lt;br /&gt;
        echo -e &amp;quot;${YELLOW}Нет пользователей для удаления.${NC}&amp;quot;&lt;br /&gt;
        press_enter&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    for i in &amp;quot;${!users[@]}&amp;quot;; do&lt;br /&gt;
        echo -e &amp;quot;  ${BOLD}$((i+1)).${NC} ${users[$i]}&amp;quot;&lt;br /&gt;
    done&lt;br /&gt;
    echo &amp;quot;  0. Отмена&amp;quot;&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    read -rp &amp;quot;Выбери номер для удаления: &amp;quot; choice&lt;br /&gt;
&lt;br /&gt;
    if [[ &amp;quot;$choice&amp;quot; == &amp;quot;0&amp;quot; || -z &amp;quot;$choice&amp;quot; ]]; then&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    if ! [[ &amp;quot;$choice&amp;quot; =~ ^[0-9]+$ ]] || (( choice &amp;lt; 1 || choice &amp;gt; ${#users[@]} )); then&lt;br /&gt;
        echo -e &amp;quot;${RED}Неверный номер.${NC}&amp;quot;&lt;br /&gt;
        press_enter&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    target=&amp;quot;${users[$((choice-1))]}&amp;quot;&lt;br /&gt;
    read -rp &amp;quot;Удалить пользователя &#039;${target}&#039;? (y/N): &amp;quot; confirm&lt;br /&gt;
    if [[ &amp;quot;$confirm&amp;quot; =~ ^[Yy]$ ]]; then&lt;br /&gt;
        sed -i &amp;quot;/^${target} /d&amp;quot; &amp;quot;$USERS_FILE&amp;quot;&lt;br /&gt;
        echo -e &amp;quot;${GREEN}Пользователь &#039;${target}&#039; удалён.${NC}&amp;quot;&lt;br /&gt;
        echo -e &amp;quot;${YELLOW}Изменения применяются мгновенно — перезапуск не нужен.${NC}&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        echo &amp;quot;Отменено.&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
show_config() {&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    echo -e &amp;quot;${BOLD}${CYAN}=== URI клиента ===${NC}&amp;quot;&lt;br /&gt;
    mapfile -t users &amp;lt; &amp;lt;(get_usernames)&lt;br /&gt;
&lt;br /&gt;
    if [[ ${#users[@]} -eq 0 ]]; then&lt;br /&gt;
        echo -e &amp;quot;${YELLOW}Нет пользователей.${NC}&amp;quot;&lt;br /&gt;
        press_enter&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    for i in &amp;quot;${!users[@]}&amp;quot;; do&lt;br /&gt;
        echo -e &amp;quot;  ${BOLD}$((i+1)).${NC} ${users[$i]}&amp;quot;&lt;br /&gt;
    done&lt;br /&gt;
    echo &amp;quot;  0. Отмена&amp;quot;&lt;br /&gt;
    echo &amp;quot;&amp;quot;&lt;br /&gt;
    read -rp &amp;quot;Выбери номер пользователя: &amp;quot; choice&lt;br /&gt;
&lt;br /&gt;
    if [[ &amp;quot;$choice&amp;quot; == &amp;quot;0&amp;quot; || -z &amp;quot;$choice&amp;quot; ]]; then&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    if ! [[ &amp;quot;$choice&amp;quot; =~ ^[0-9]+$ ]] || (( choice &amp;lt; 1 || choice &amp;gt; ${#users[@]} )); then&lt;br /&gt;
        echo -e &amp;quot;${RED}Неверный номер.${NC}&amp;quot;&lt;br /&gt;
        press_enter&lt;br /&gt;
        return&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    local user=&amp;quot;${users[$((choice-1))]}&amp;quot;&lt;br /&gt;
    local pass&lt;br /&gt;
    pass=$(get_password &amp;quot;$user&amp;quot;)&lt;br /&gt;
    print_config_for &amp;quot;$user&amp;quot; &amp;quot;$pass&amp;quot;&lt;br /&gt;
    press_enter&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# --- Главное меню ---&lt;br /&gt;
&lt;br /&gt;
main_menu() {&lt;br /&gt;
    check_root&lt;br /&gt;
    check_users_file&lt;br /&gt;
&lt;br /&gt;
    while true; do&lt;br /&gt;
        clear&lt;br /&gt;
        echo -e &amp;quot;${BOLD}${CYAN}&amp;quot;&lt;br /&gt;
        echo &amp;quot;╔══════════════════════════════════════╗&amp;quot;&lt;br /&gt;
        echo &amp;quot;║   Hysteria2 User Manager (RU)        ║&amp;quot;&lt;br /&gt;
        echo &amp;quot;║   Домен: ${DOMAIN}  ║&amp;quot;&lt;br /&gt;
        echo &amp;quot;╚══════════════════════════════════════╝&amp;quot;&lt;br /&gt;
        echo -e &amp;quot;${NC}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        mapfile -t users &amp;lt; &amp;lt;(get_usernames)&lt;br /&gt;
        echo -e &amp;quot;  Активных пользователей: ${BOLD}${#users[@]}${NC}&amp;quot;&lt;br /&gt;
        echo &amp;quot;&amp;quot;&lt;br /&gt;
        echo -e &amp;quot;  ${BOLD}1.${NC} Список пользователей&amp;quot;&lt;br /&gt;
        echo -e &amp;quot;  ${BOLD}2.${NC} Добавить пользователя&amp;quot;&lt;br /&gt;
        echo -e &amp;quot;  ${BOLD}3.${NC} Удалить пользователя&amp;quot;&lt;br /&gt;
        echo -e &amp;quot;  ${BOLD}4.${NC} Показать URI клиента&amp;quot;&lt;br /&gt;
        echo -e &amp;quot;  ${BOLD}0.${NC} Выход&amp;quot;&lt;br /&gt;
        echo &amp;quot;&amp;quot;&lt;br /&gt;
        read -rp &amp;quot;Выбор: &amp;quot; option&lt;br /&gt;
&lt;br /&gt;
        case &amp;quot;$option&amp;quot; in&lt;br /&gt;
            1) list_users ;;&lt;br /&gt;
            2) add_user ;;&lt;br /&gt;
            3) delete_user ;;&lt;br /&gt;
            4) show_config ;;&lt;br /&gt;
            0) echo &amp;quot;Выход.&amp;quot;; exit 0 ;;&lt;br /&gt;
            *) echo -e &amp;quot;${RED}Неверный выбор.${NC}&amp;quot;; sleep 1 ;;&lt;br /&gt;
        esac&lt;br /&gt;
    done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
main_menu&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 4: Настройка клиентов ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1 Формат URI Hysteria2 ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 использует стандартизированный URI для передачи параметров подключения клиентам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hysteria2://ПАРОЛЬ@ДОМЕН:ПОРТ&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hysteria2://aBcDeFgHiJkLmNoPqRsT@your-hy2-ru-domain.example.com:2053&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
URI можно получить через скрипт &amp;lt;code&amp;gt;hy2-users.sh&amp;lt;/code&amp;gt; (пункт 4 меню — «Показать конфиг клиента»).&lt;br /&gt;
&lt;br /&gt;
=== 4.2 Мобильные клиенты (iOS / Android) ===&lt;br /&gt;
&lt;br /&gt;
Рекомендуемые приложения с нативной поддержкой Hysteria2:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Приложение !! Платформа !! Как импортировать URI&lt;br /&gt;
|-&lt;br /&gt;
|| NekoBox || Android || Главный экран → + → Add → Hysteria2 → вставить URI&lt;br /&gt;
|-&lt;br /&gt;
|| husi || Android || Профили → + → Hysteria2 → вставить URI&lt;br /&gt;
|-&lt;br /&gt;
|| Exclave || iOS || Конфигурации → + → Hysteria2 → вставить URI&lt;br /&gt;
|-&lt;br /&gt;
|| Shadowrocket || iOS || Главная → + → Тип: Hysteria2 → вставить URI&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Все эти приложения принимают URI в формате &amp;lt;code&amp;gt;hysteria2://...&amp;lt;/code&amp;gt; напрямую — через кнопку импорта, QR-код или буфер обмена.&lt;br /&gt;
&lt;br /&gt;
=== 4.3 ПК-клиенты (Windows / macOS / Linux) ===&lt;br /&gt;
&lt;br /&gt;
==== Вариант А: официальный бинарь Hysteria2 ====&lt;br /&gt;
&lt;br /&gt;
Скачать бинарь с официального репозитория: https://github.com/apernet/hysteria/releases&lt;br /&gt;
&lt;br /&gt;
Создать файл конфигурации &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
server: your-hy2-ru-domain.example.com:2053&lt;br /&gt;
&lt;br /&gt;
auth: ВАШ_ПАРОЛЬ&lt;br /&gt;
&lt;br /&gt;
socks5:&lt;br /&gt;
  listen: 127.0.0.1:1080&lt;br /&gt;
&lt;br /&gt;
http:&lt;br /&gt;
  listen: 127.0.0.1:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Запустить:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Linux / macOS&lt;br /&gt;
./hysteria client --config config.yaml&lt;br /&gt;
&lt;br /&gt;
# Windows (PowerShell)&lt;br /&gt;
.\hysteria.exe client --config config.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После запуска:&lt;br /&gt;
* SOCKS5 прокси доступен на &amp;lt;code&amp;gt;127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
* HTTP прокси доступен на &amp;lt;code&amp;gt;127.0.0.1:8080&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Вариант Б: через NekoRay / Hiddify Next (Windows / Linux) ====&lt;br /&gt;
&lt;br /&gt;
Приложения NekoRay и Hiddify Next принимают Hysteria2 URI — импорт через меню или буфер обмена. Автоматически управляют запуском клиентского процесса.&lt;br /&gt;
&lt;br /&gt;
=== 4.4 OpenWrt / podkop ===&lt;br /&gt;
&lt;br /&gt;
podkop (реализация на базе sing-box) нативно поддерживает Hysteria2 URI. Никакой дополнительной установки бинарей не требуется.&lt;br /&gt;
&lt;br /&gt;
В интерфейсе podkop (LuCI → Network → podkop → Outbound):&lt;br /&gt;
* Тип: &amp;lt;code&amp;gt;Hysteria2&amp;lt;/code&amp;gt;&lt;br /&gt;
* URI: &amp;lt;code&amp;gt;hysteria2://ПАРОЛЬ@your-hy2-ru-domain.example.com:2053&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или через UCI:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
uci set podkop.main.proxy=&#039;hysteria2://ПАРОЛЬ@your-hy2-ru-domain.example.com:2053&#039;&lt;br /&gt;
uci commit podkop&lt;br /&gt;
/etc/init.d/podkop restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После сохранения все устройства домашней сети автоматически получают обход без дополнительной настройки.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 5: Проверка всей цепочки ==&lt;br /&gt;
&lt;br /&gt;
=== 5.1 Тест RU сервера: цепочка RU → EU → WARP ===&lt;br /&gt;
&lt;br /&gt;
Выполнить на RU сервере — проверяет, что трафик выходит через WARP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# SOCKS5 порт 10810 — это точка выхода RU клиента (= вход в EU сервер → WARP)&lt;br /&gt;
curl -s --max-time 20 -x socks5h://127.0.0.1:10810 https://ifconfig.me&lt;br /&gt;
echo &amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результат должен быть &#039;&#039;&#039;IP Cloudflare WARP&#039;&#039;&#039; — например, начинается с &amp;lt;code&amp;gt;2a09:&amp;lt;/code&amp;gt; (IPv6) или принадлежит AS13335 (Cloudflare).&lt;br /&gt;
&lt;br /&gt;
Проверить AS:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
IP=$(curl -s --max-time 20 -x socks5h://127.0.0.1:10810 https://ifconfig.me)&lt;br /&gt;
curl -s &amp;quot;https://ipinfo.io/${IP}/org&amp;quot;&lt;br /&gt;
echo &amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод: строка содержит &amp;lt;code&amp;gt;Cloudflare&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 5.2 Тест с реального клиента ===&lt;br /&gt;
&lt;br /&gt;
После добавления пользователя через &amp;lt;code&amp;gt;hy2-users.sh&amp;lt;/code&amp;gt; и получения URI:&lt;br /&gt;
&lt;br /&gt;
# Вставь URI в клиентское приложение (NekoBox, husi, Shadowrocket).&lt;br /&gt;
# Активируй профиль.&lt;br /&gt;
# Открой &amp;lt;code&amp;gt;https://ifconfig.me&amp;lt;/code&amp;gt; в браузере — должен отображаться IP Cloudflare WARP.&lt;br /&gt;
# Открой &amp;lt;code&amp;gt;https://www.whatismybrowser.com/detect/what-is-my-ip-address&amp;lt;/code&amp;gt; для проверки отсутствия WebRTC утечки.&lt;br /&gt;
&lt;br /&gt;
=== 5.3 Диагностика проблем ===&lt;br /&gt;
&lt;br /&gt;
==== Проблема: hysteria-eu не запускается — ошибка TLS ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/hysteria-eu/docker-compose.yml logs hysteria-eu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Возможные причины:&lt;br /&gt;
* Путь к сертификату неверен → проверь &amp;lt;code&amp;gt;ls&amp;lt;/code&amp;gt; по пути, указанному в volumes.&lt;br /&gt;
* Сертификат ещё не был получен Caddy → проверь, что caddy-naive запущен и прошёл ACME-проверку.&lt;br /&gt;
* Caddy хранит сертификат под другим именем → выполни &amp;lt;code&amp;gt;find /var/lib/docker/volumes/caddy-naive_caddy_data/_data -name &amp;quot;*.crt&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Проблема: hysteria-ru-server выдаёт auth error ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/hysteria-ru/docker-compose.yml logs hysteria-ru-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверить вручную (на RU сервере):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Проверить, что скрипт находится на месте внутри контейнера&lt;br /&gt;
docker exec hysteria-ru-server ls -la /etc/hysteria/users/&lt;br /&gt;
&lt;br /&gt;
# Запустить скрипт вручную с тестовым паролем&lt;br /&gt;
docker exec hysteria-ru-server /etc/hysteria/users/check-auth.sh addr ТЕСТОВЫЙ_ПАРОЛЬ 0&lt;br /&gt;
echo &amp;quot;Exit code: $?&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;code&amp;gt;Exit code: 0&amp;lt;/code&amp;gt; — скрипт работает. Если &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; — пароль не найден в &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Проблема: hysteria-ru-client не подключается к EU ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/hysteria-ru/docker-compose.yml logs hysteria-ru-client&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Возможные причины:&lt;br /&gt;
* &amp;lt;code&amp;gt;EU_HY2_PASSWORD&amp;lt;/code&amp;gt; в &amp;lt;code&amp;gt;client.yaml&amp;lt;/code&amp;gt; не совпадает с паролем в EU &amp;lt;code&amp;gt;server.yaml&amp;lt;/code&amp;gt;.&lt;br /&gt;
* UDP порт 2053 заблокирован на EU сервере (firewall) → проверь &amp;lt;code&amp;gt;ss -ulnp | grep 2053&amp;lt;/code&amp;gt; на EU сервере.&lt;br /&gt;
* EU сервер ещё не запущен.&lt;br /&gt;
&lt;br /&gt;
==== Проблема: ACL ошибка при запуске ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FATAL failed to load server config: invalid config: acl.inline: invalid syntax at line 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неверный синтаксис ACL. Правильный формат: &amp;lt;code&amp;gt;&amp;quot;outbound_name(address)&amp;quot;&amp;lt;/code&amp;gt;:&lt;br /&gt;
* ✅ &amp;lt;code&amp;gt;&amp;quot;warp(all)&amp;quot;&amp;lt;/code&amp;gt; — направить всё в outbound &amp;quot;warp&amp;quot;&lt;br /&gt;
* ✅ &amp;lt;code&amp;gt;&amp;quot;chain(all)&amp;quot;&amp;lt;/code&amp;gt; — направить всё в outbound &amp;quot;chain&amp;quot;&lt;br /&gt;
* ❌ &amp;lt;code&amp;gt;&amp;quot;outbound(warp) all&amp;quot;&amp;lt;/code&amp;gt; — неверно&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 6: Обслуживание ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1 Управление контейнерами ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# EU сервер&lt;br /&gt;
cd /opt/hysteria-eu&lt;br /&gt;
docker compose up -d         # запустить&lt;br /&gt;
docker compose down          # остановить&lt;br /&gt;
docker compose restart       # перезапустить&lt;br /&gt;
docker compose logs -f       # следить за логами в реальном времени&lt;br /&gt;
docker compose ps            # статус&lt;br /&gt;
&lt;br /&gt;
# RU сервер (оба контейнера)&lt;br /&gt;
cd /opt/hysteria-ru&lt;br /&gt;
docker compose up -d&lt;br /&gt;
docker compose down&lt;br /&gt;
docker compose restart&lt;br /&gt;
docker compose logs -f&lt;br /&gt;
&lt;br /&gt;
# RU сервер (по отдельности)&lt;br /&gt;
docker compose restart hysteria-ru-server   # только сервер&lt;br /&gt;
docker compose restart hysteria-ru-client   # только клиент&lt;br /&gt;
docker compose logs -f hysteria-ru-server   # логи только сервера&lt;br /&gt;
docker compose logs -f hysteria-ru-client   # логи только клиента&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 6.2 Обновление сертификатов ===&lt;br /&gt;
&lt;br /&gt;
TLS-сертификаты обновляются Caddy автоматически (за 30 дней до истечения). После автообновления Hysteria2 начнёт использовать новый сертификат при следующем перезапуске.&lt;br /&gt;
&lt;br /&gt;
Для принудительного применения нового сертификата:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# EU сервер&lt;br /&gt;
cd /opt/hysteria-eu &amp;amp;&amp;amp; docker compose restart&lt;br /&gt;
&lt;br /&gt;
# RU сервер&lt;br /&gt;
cd /opt/hysteria-ru &amp;amp;&amp;amp; docker compose restart hysteria-ru-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверить дату истечения текущего сертификата:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# EU сервер&lt;br /&gt;
DOMAIN=&amp;quot;your-hy2-eu-domain.example.com&amp;quot;&lt;br /&gt;
CERT=&amp;quot;/var/lib/docker/volumes/caddy-naive_caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${DOMAIN}/${DOMAIN}.crt&amp;quot;&lt;br /&gt;
openssl x509 -in &amp;quot;${CERT}&amp;quot; -noout -enddate&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 6.3 Обновление Docker-образа ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 активно развивается. Для обновления до последней версии:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# EU сервер&lt;br /&gt;
cd /opt/hysteria-eu&lt;br /&gt;
docker compose pull           # скачать новый образ&lt;br /&gt;
docker compose up -d          # перезапустить с новым образом&lt;br /&gt;
docker compose logs --tail=5  # проверить старт&lt;br /&gt;
&lt;br /&gt;
# RU сервер&lt;br /&gt;
cd /opt/hysteria-ru&lt;br /&gt;
docker compose pull&lt;br /&gt;
docker compose up -d&lt;br /&gt;
docker compose logs --tail=5&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Старые неиспользуемые образы можно удалить:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker image prune -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 6.4 Мониторинг логов ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 пишет структурированные JSON-логи. Полезные паттерны для мониторинга:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Смотреть все подключения на RU сервере&lt;br /&gt;
docker logs hysteria-ru-server 2&amp;gt;&amp;amp;1 | grep -E &amp;quot;connected|disconnected|auth&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Смотреть ошибки&lt;br /&gt;
docker logs hysteria-ru-server 2&amp;gt;&amp;amp;1 | grep -i &amp;quot;error\|fatal\|warn&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Считать количество уникальных пользователей (поле &amp;quot;id&amp;quot;)&lt;br /&gt;
docker logs hysteria-ru-server 2&amp;gt;&amp;amp;1 | grep &#039;&amp;quot;id&amp;quot;&#039; | grep -oP &#039;&amp;quot;id&amp;quot;: &amp;quot;\K[^&amp;quot;]+&#039; | sort -u&lt;br /&gt;
&lt;br /&gt;
# Следить за логами EU сервера в реальном времени&lt;br /&gt;
docker logs -f hysteria-eu 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример нормального лога RU сервера при входящем подключении:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
INFO  client connected     {&amp;quot;addr&amp;quot;: &amp;quot;CLIENT_IP:PORT&amp;quot;, &amp;quot;id&amp;quot;: &amp;quot;username&amp;quot;}&lt;br /&gt;
INFO  TCP request          {&amp;quot;addr&amp;quot;: &amp;quot;CLIENT_IP:PORT&amp;quot;, &amp;quot;id&amp;quot;: &amp;quot;username&amp;quot;, &amp;quot;reqAddr&amp;quot;: &amp;quot;example.com:443&amp;quot;}&lt;br /&gt;
INFO  client disconnected  {&amp;quot;addr&amp;quot;: &amp;quot;CLIENT_IP:PORT&amp;quot;, &amp;quot;id&amp;quot;: &amp;quot;username&amp;quot;, &amp;quot;error&amp;quot;: &amp;quot;...&amp;quot;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Поле &amp;lt;code&amp;gt;&amp;quot;id&amp;quot;&amp;lt;/code&amp;gt; — это имя пользователя, возвращённое скриптом &amp;lt;code&amp;gt;check-auth.sh&amp;lt;/code&amp;gt;. Это позволяет отслеживать активность конкретных пользователей в логах без хранения паролей.&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=Hysteria_2_%D0%BA%D0%B0%D1%81%D0%BA%D0%B0%D0%B4&amp;diff=958</id>
		<title>Hysteria 2 каскад</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=Hysteria_2_%D0%BA%D0%B0%D1%81%D0%BA%D0%B0%D0%B4&amp;diff=958"/>
		<updated>2026-04-26T10:12:48Z</updated>

		<summary type="html">&lt;p&gt;Владимир: /* Полная схема прохождения трафика */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Hysteria2: установка каскадной цепочки Entry Node → Exit Node → WARP =&lt;br /&gt;
&lt;br /&gt;
== Что такое Hysteria2 и зачем он нужен ==&lt;br /&gt;
&lt;br /&gt;
=== Проблема: ограничения традиционных прокси-протоколов ===&lt;br /&gt;
&lt;br /&gt;
Современные системы глубокой инспекции пакетов (DPI — Deep Packet Inspection), применяемые интернет-провайдерами и регуляторами по всему миру, умеют анализировать не только адреса назначения, но и &#039;&#039;&#039;характер самого трафика&#039;&#039;&#039;. Даже зашифрованное соединение можно идентифицировать — по поведению, по паузам между пакетами, по размерам передаваемых блоков данных, по TLS-fingerprint.&lt;br /&gt;
&lt;br /&gt;
Большинство прокси-протоколов работают поверх &#039;&#039;&#039;TCP&#039;&#039;&#039;. Это означает:&lt;br /&gt;
* Все потери пакетов обрабатываются дважды — сначала на уровне транспорта, затем внутри туннеля (head-of-line blocking).&lt;br /&gt;
* При нестабильном канале (мобильная сеть, спутник, VPN на слабом железе) скорость резко падает.&lt;br /&gt;
* TCP-fingerprint легче распознаётся и блокируется.&lt;br /&gt;
&lt;br /&gt;
Hysteria2 решает эту проблему фундаментально иначе: он работает поверх &#039;&#039;&#039;QUIC&#039;&#039;&#039; — транспортного протокола на базе UDP, разработанного в Google и стандартизированного в RFC 9000.&lt;br /&gt;
&lt;br /&gt;
=== Решение: QUIC/UDP с маскировкой под HTTPS ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 строит зашифрованный туннель поверх UDP, используя QUIC:&lt;br /&gt;
* &#039;&#039;&#039;Нет head-of-line blocking:&#039;&#039;&#039; потеря одного пакета не блокирует остальные потоки.&lt;br /&gt;
* &#039;&#039;&#039;Быстрое восстановление соединения:&#039;&#039;&#039; QUIC переподключается за 0-RTT (без дополнительного round-trip).&lt;br /&gt;
* &#039;&#039;&#039;Маскировка под HTTPS:&#039;&#039;&#039; снаружи трафик Hysteria2 выглядит как обычный QUIC/HTTP3 браузерный трафик — сервер «притворяется» обычным HTTPS-сайтом и возвращает реальный веб-контент при неавторизованных запросах.&lt;br /&gt;
* &#039;&#039;&#039;Congestion control:&#039;&#039;&#039; поддерживает несколько алгоритмов управления перегрузкой, включая BBR.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Протокол !! Транспорт !! Как выглядит для DPI !! Устойчивость к блокировке !! Скорость при потерях&lt;br /&gt;
|-&lt;br /&gt;
|| Обычный VPN (WireGuard, OpenVPN) || UDP / TCP || Характерный шаблон || Низкая — fingerprint легко детектируется || Высокая (WG) / Низкая (OpenVPN)&lt;br /&gt;
|-&lt;br /&gt;
|| Shadowsocks || TCP || Случайный зашифрованный поток || Средняя — выявляется по энтропии || Средняя&lt;br /&gt;
|-&lt;br /&gt;
|| VLESS + REALITY || TCP (TLS) || TLS с реальным сертификатом стороннего сайта || Высокая || Средняя&lt;br /&gt;
|-&lt;br /&gt;
|| NaïveProxy || TCP (HTTP/2 TLS) || Неотличим от Chrome HTTPS || Очень высокая || Средняя (TCP Head-of-Line)&lt;br /&gt;
|-&lt;br /&gt;
|| &#039;&#039;&#039;Hysteria2&#039;&#039;&#039; || &#039;&#039;&#039;UDP (QUIC/TLS)&#039;&#039;&#039; || &#039;&#039;&#039;QUIC/HTTP3, маскировка под HTTPS&#039;&#039;&#039; || &#039;&#039;&#039;Очень высокая&#039;&#039;&#039; || &#039;&#039;&#039;Высокая — устойчив к потерям&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Как работает Hysteria2 технически ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 использует протокол QUIC в качестве транспорта:&lt;br /&gt;
&lt;br /&gt;
# Клиент устанавливает QUIC-соединение с сервером — это TLS 1.3 поверх UDP.&lt;br /&gt;
# Внутри QUIC-соединения открываются независимые потоки (streams) для каждого проксируемого соединения.&lt;br /&gt;
# Сервер обрабатывает входящий трафик: авторизует клиента (по паролю или через внешний скрипт), затем перенаправляет трафик через указанный outbound.&lt;br /&gt;
# Если к серверу обращаются без правильного пароля — сервер ведёт себя как обычный HTTPS-сайт (&#039;&#039;&#039;masquerade&#039;&#039;&#039;) и возвращает реальный контент с заданного URL.&lt;br /&gt;
&lt;br /&gt;
Особенности аутентификации в данной схеме:&lt;br /&gt;
* &#039;&#039;&#039;EU сервер:&#039;&#039;&#039; использует одиночный пароль — только для входящих соединений от RU клиента (не клиентских устройств).&lt;br /&gt;
* &#039;&#039;&#039;RU сервер:&#039;&#039;&#039; использует &#039;&#039;&#039;command-аутентификацию&#039;&#039;&#039; — при каждом подключении вызывается внешний bash-скрипт, который проверяет пароль по файлу &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt;. Это позволяет добавлять и удалять пользователей &#039;&#039;&#039;без перезапуска сервера&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Каскадная цепочка: зачем два сервера ===&lt;br /&gt;
&lt;br /&gt;
В данном решении используется &#039;&#039;&#039;каскад из двух серверов&#039;&#039;&#039;: Entry Node (ближайший к клиентам сервер-вход) и Exit Node (сервер-выход в интернет). Это архитектурное решение принято намеренно по нескольким причинам:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Снижение риска для клиента:&#039;&#039;&#039; клиентские устройства подключаются только к ближайшему серверу. Соединение с соседним узлом менее заметно, чем прямое соединение с зарубежным сервером.&lt;br /&gt;
* &#039;&#039;&#039;Раздельная аутентификация:&#039;&#039;&#039; пароль «клиент → Entry Node» знают только конечные пользователи. Пароль «Entry Node → Exit Node» знают только серверы. Компрометация клиентского пароля не раскрывает пароль соединения между серверами.&lt;br /&gt;
* &#039;&#039;&#039;Анонимизация выхода:&#039;&#039;&#039; Exit Node передаёт трафик через Cloudflare WARP. Конечные сайты видят IP Cloudflare, а не IP ваших серверов.&lt;br /&gt;
* &#039;&#039;&#039;Параллельные независимые каналы:&#039;&#039;&#039; Hysteria2 работает рядом с NaïveProxy и 3x-ui на тех же серверах, не конфликтуя с ними. Падение одного канала не блокирует другие.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Схема конкретного решения ==&lt;br /&gt;
&lt;br /&gt;
=== Компоненты инфраструктуры ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Компонент !! Роль !! Адрес / Домен !! ОС&lt;br /&gt;
|-&lt;br /&gt;
|| Клиентские устройства || Конечные пользователи || — || iOS, Android, Windows, macOS, Linux&lt;br /&gt;
|-&lt;br /&gt;
|| OpenWrt роутер || Прозрачный обход для всей домашней сети || — || OpenWrt 24.10 (podkop нативно поддерживает hy2 URI)&lt;br /&gt;
|-&lt;br /&gt;
|| RU сервер (&#039;&#039;&#039;Entry Node&#039;&#039;&#039;) || Точка входа клиентов || &amp;lt;code&amp;gt;YOUR_RU_SERVER_IP&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;your-hy2-ru-domain.example.com&amp;lt;/code&amp;gt; || Ubuntu 24.04&lt;br /&gt;
|-&lt;br /&gt;
|| EU сервер (&#039;&#039;&#039;Exit Node&#039;&#039;&#039;) || Точка выхода в интернет || &amp;lt;code&amp;gt;YOUR_EU_SERVER_IP&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;your-hy2-eu-domain.example.com&amp;lt;/code&amp;gt; || Ubuntu 24.04&lt;br /&gt;
|-&lt;br /&gt;
|| Cloudflare WARP || Финальный выход в интернет || IP Cloudflare || —&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Полная схема прохождения трафика ===&lt;br /&gt;
&lt;br /&gt;
[[File:hysteria2-chain-traffic-flow.png|center|768x768px|Схема трафика Hysteria2: Клиенты → RU Entry Node → EU Exit Node → WARP → Интернет]]&lt;br /&gt;
&lt;br /&gt;
=== Протоколы на каждом участке цепочки ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Участок !! Протокол !! Шифрование !! Что видит наблюдатель&lt;br /&gt;
|-&lt;br /&gt;
|| Устройство → Роутер || Обычный TCP/UDP || Нет (локальная сеть) || Локальный трафик&lt;br /&gt;
|-&lt;br /&gt;
|| Роутер / ПК → RU сервер || QUIC / UDP (Hysteria2) || TLS 1.3 (Let&#039;s Encrypt) || HTTPS/HTTP3 трафик к обычному сайту&lt;br /&gt;
|-&lt;br /&gt;
|| RU клиент → EU сервер || QUIC / UDP (Hysteria2) || TLS 1.3 (Let&#039;s Encrypt) || HTTPS/HTTP3 трафик к обычному сайту&lt;br /&gt;
|-&lt;br /&gt;
|| EU сервер → 3x-ui inbound || SOCKS5 (localhost) || — (только на EU сервере) || Только локально&lt;br /&gt;
|-&lt;br /&gt;
|| EU 3x-ui → WARP || WireGuard (gVisor TUN) || WireGuard || Зашифрованный WireGuard к Cloudflare&lt;br /&gt;
|-&lt;br /&gt;
|| WARP → Интернет || Обычный TCP/UDP || — || IP Cloudflare&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Дополнительные каналы (параллельно Hysteria2) ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 работает &#039;&#039;&#039;независимо&#039;&#039;&#039; от NaïveProxy и 3x-ui. Все три канала активны одновременно:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Канал !! Протокол !! Маршрут !! Статус&lt;br /&gt;
|-&lt;br /&gt;
|| 3x-ui каскад (основной) || VLESS / REALITY || Клиенты → RU 3x-ui → EU 3x-ui → Интернет || ✅ Активен&lt;br /&gt;
|-&lt;br /&gt;
|| NaïveProxy каскад || HTTP/2 naïve || Роутер/ПК → RU Caddy → EU Caddy → WARP || ✅ Активен&lt;br /&gt;
|-&lt;br /&gt;
|| &#039;&#039;&#039;Hysteria2 каскад (этот гайд)&#039;&#039;&#039; || &#039;&#039;&#039;QUIC/UDP hy2&#039;&#039;&#039; || &#039;&#039;&#039;Клиенты → RU hy2 → EU hy2 → WARP&#039;&#039;&#039; || &#039;&#039;&#039;✅ Активен&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|| MTProto (Telegram) || MTProto || Клиенты Telegram → EU :8443, :2443 || ✅ Активен&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
=== Инфраструктура ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Компонент !! Требования&lt;br /&gt;
|-&lt;br /&gt;
|| EU сервер || Ubuntu 24.04, публичный IP, домен с A-записью → IP сервера&lt;br /&gt;
|-&lt;br /&gt;
|| RU сервер || Ubuntu 24.04, публичный IP, домен с A-записью → IP сервера&lt;br /&gt;
|-&lt;br /&gt;
|| 3x-ui на EU сервере || Уже установлен и работает; настроен outbound WARP&lt;br /&gt;
|-&lt;br /&gt;
|| Docker || Установлен на обоих серверах&lt;br /&gt;
|-&lt;br /&gt;
|| Порт 2053 UDP || Должен быть свободен на обоих серверах&lt;br /&gt;
|-&lt;br /&gt;
|| TLS-сертификат || Получается через Caddy (caddy-naive), либо через certbot — описано в разделе ниже&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DNS-записи (создать заранее, до установки) ===&lt;br /&gt;
&lt;br /&gt;
Let&#039;s Encrypt проверяет доступность домена по HTTP (порт 80) перед выдачей сертификата. DNS-записи должны быть созданы и распространены (propagated) до первого запуска Caddy.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Запись !! Тип !! Значение !! Примечание&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;your-hy2-ru-domain.example.com&amp;lt;/code&amp;gt; || A || IP RU сервера || Используется Hysteria2 сервером на RU&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;your-hy2-eu-domain.example.com&amp;lt;/code&amp;gt; || A || IP EU сервера || Используется Hysteria2 сервером на EU&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Примечание:&#039;&#039;&#039; если NaïveProxy (Caddy) уже настроен на тех же серверах с теми же доменами, отдельные DNS-записи для Hysteria2 не нужны — используется тот же домен и тот же сертификат.&lt;br /&gt;
&lt;br /&gt;
=== Используемые заглушки ===&lt;br /&gt;
&lt;br /&gt;
В данном руководстве применяются следующие заглушки. Замени их реальными значениями перед использованием:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Заглушка !! Описание&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;YOUR_RU_SERVER_IP&amp;lt;/code&amp;gt; || Публичный IP RU сервера&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;YOUR_EU_SERVER_IP&amp;lt;/code&amp;gt; || Публичный IP EU сервера&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;your-hy2-ru-domain.example.com&amp;lt;/code&amp;gt; || Домен для RU сервера (для TLS-сертификата)&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;your-hy2-eu-domain.example.com&amp;lt;/code&amp;gt; || Домен для EU сервера (для TLS-сертификата)&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;YOUR_EMAIL@example.com&amp;lt;/code&amp;gt; || Email для Let&#039;s Encrypt (уведомления об истечении сертификата)&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;EU_HY2_PASSWORD&amp;lt;/code&amp;gt; || Пароль соединения RU клиент → EU сервер (генерируется один раз)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Для генерации пароля EU_HY2_PASSWORD используй:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl rand -base64 18&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Сохрани результат — он понадобится в конфигах обоих серверов.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 1: EU сервер (Exit Node) ==&lt;br /&gt;
&lt;br /&gt;
Цель: развернуть Hysteria2 сервер в Docker, который принимает соединения от RU клиента и перенаправляет трафик через 3x-ui → Cloudflare WARP.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Все команды в этом разделе выполняются на EU сервере под root.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== 1.1 Установка Docker ===&lt;br /&gt;
&lt;br /&gt;
Если Docker уже установлен (проверить: &amp;lt;code&amp;gt;docker --version&amp;lt;/code&amp;gt;) — пропусти этот шаг.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Обновить пакеты&lt;br /&gt;
apt-get update &amp;amp;&amp;amp; apt-get upgrade -y&lt;br /&gt;
&lt;br /&gt;
# Установить зависимости&lt;br /&gt;
apt-get install -y ca-certificates curl gnupg lsb-release&lt;br /&gt;
&lt;br /&gt;
# Добавить GPG-ключ Docker&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \&lt;br /&gt;
  -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
# Добавить репозиторий Docker&lt;br /&gt;
echo &amp;quot;deb [arch=$(dpkg --print-architecture) \&lt;br /&gt;
  signed-by=/etc/apt/keyrings/docker.asc] \&lt;br /&gt;
  https://download.docker.com/linux/ubuntu \&lt;br /&gt;
  $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;$VERSION_CODENAME&amp;quot;) stable&amp;quot; \&lt;br /&gt;
  &amp;gt; /etc/apt/sources.list.d/docker.list&lt;br /&gt;
&lt;br /&gt;
# Установить Docker Engine&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin&lt;br /&gt;
&lt;br /&gt;
# Включить автозапуск&lt;br /&gt;
systemctl enable docker&lt;br /&gt;
systemctl start docker&lt;br /&gt;
&lt;br /&gt;
# Проверить&lt;br /&gt;
docker --version&lt;br /&gt;
docker compose version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Docker version 27.x.x, build ...&lt;br /&gt;
Docker Compose version v2.x.x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 1.2 Настройка 3x-ui: создание inbound hy2-out → WARP ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 Exit Node направляет трафик через 3x-ui SOCKS5 inbound, который в свою очередь маршрутизирует его в Cloudflare WARP. Этот шаг выполняется в веб-интерфейсе 3x-ui &#039;&#039;&#039;до&#039;&#039;&#039; запуска Hysteria2.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Условие:&#039;&#039;&#039; в 3x-ui должен быть настроен outbound WARP (WireGuard/gVisor).&lt;br /&gt;
&lt;br /&gt;
==== 1.2.1 Создать новый inbound в 3x-ui ====&lt;br /&gt;
&lt;br /&gt;
В веб-интерфейсе 3x-ui (EU сервер) перейди в &#039;&#039;&#039;Inbounds → Add Inbound&#039;&#039;&#039; и заполни следующие поля:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Параметр !! Значение !! Пояснение&lt;br /&gt;
|-&lt;br /&gt;
|| Примечание (Remark) || &amp;lt;code&amp;gt;hy2-out&amp;lt;/code&amp;gt; || Произвольное имя для идентификации в правилах маршрутизации&lt;br /&gt;
|-&lt;br /&gt;
|| Протокол || &amp;lt;code&amp;gt;mixed&amp;lt;/code&amp;gt; || Поддерживает SOCKS5 и HTTP одновременно&lt;br /&gt;
|-&lt;br /&gt;
|| Listen IP || &amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt; || Только localhost — недоступен извне&lt;br /&gt;
|-&lt;br /&gt;
|| Порт || &amp;lt;code&amp;gt;24364&amp;lt;/code&amp;gt; || Должен быть свободен; проверить: &amp;lt;code&amp;gt;ss -tlnp | grep 24364&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|| Аутентификация || Выключена || Hysteria2 сам отвечает за авторизацию клиентов&lt;br /&gt;
|-&lt;br /&gt;
|| UDP || Включён || Требуется для DNS-запросов через туннель&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Нажми &#039;&#039;&#039;Save&#039;&#039;&#039; — inbound немедленно активируется.&lt;br /&gt;
&lt;br /&gt;
==== 1.2.2 Создать правило маршрутизации ====&lt;br /&gt;
&lt;br /&gt;
В 3x-ui перейди в &#039;&#039;&#039;Routing → Add Rule&#039;&#039;&#039; (или Settings → Routing Rules):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
|| Inbound Tag || &amp;lt;code&amp;gt;hy2-out&amp;lt;/code&amp;gt; (тег созданного выше inbound)&lt;br /&gt;
|-&lt;br /&gt;
|| Outbound Tag || &amp;lt;code&amp;gt;warp&amp;lt;/code&amp;gt; (или название твоего WARP outbound в 3x-ui)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохрани и перезапусти Xray внутри 3x-ui.&lt;br /&gt;
&lt;br /&gt;
==== 1.2.3 Проверить, что порт 24364 слушает ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -tlnp | grep 24364&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LISTEN  0  128  127.0.0.1:24364  0.0.0.0:*  users:((&amp;quot;xray&amp;quot;,...))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 1.3 TLS-сертификат для Hysteria2 ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 требует действующий TLS-сертификат (самоподписанный не рекомендуется — клиентам потребуется флаг &amp;lt;code&amp;gt;insecure: true&amp;lt;/code&amp;gt;). В нашей схеме используется &#039;&#039;&#039;Let&#039;s Encrypt сертификат&#039;&#039;&#039;, получаемый и автоматически обновляемый через Caddy (caddy-naive стек).&lt;br /&gt;
&lt;br /&gt;
Caddy хранит сертификаты в именованном Docker volume &amp;lt;code&amp;gt;caddy-naive_caddy_data&amp;lt;/code&amp;gt;, и Hysteria2 подключает их через bind mount (read-only) — никаких лишних сервисов, никакого дублирования.&lt;br /&gt;
&lt;br /&gt;
==== Вариант А: Caddy (caddy-naive) уже установлен — рекомендуется ====&lt;br /&gt;
&lt;br /&gt;
Если NaïveProxy (caddy-naive) уже настроен и работает, сертификат уже получен. Проверь:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Найти путь к сертификату в Docker volume&lt;br /&gt;
DOMAIN=&amp;quot;your-hy2-eu-domain.example.com&amp;quot;&lt;br /&gt;
CERT_DIR=&amp;quot;/var/lib/docker/volumes/caddy-naive_caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${DOMAIN}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ls -la &amp;quot;${CERT_DIR}/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод — два файла:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
your-hy2-eu-domain.example.com.crt&lt;br /&gt;
your-hy2-eu-domain.example.com.key&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если файлы есть — переходи к разделу &#039;&#039;&#039;1.4&#039;&#039;&#039;. Если volume или папка не существуют — сначала установи caddy-naive (NaïveProxy) или воспользуйся Вариантом Б.&lt;br /&gt;
&lt;br /&gt;
==== Вариант Б: получить сертификат через certbot (если Caddy не установлен) ====&lt;br /&gt;
&lt;br /&gt;
Этот вариант используется, если caddy-naive &#039;&#039;&#039;не установлен&#039;&#039;&#039; и на серверах нет другого HTTP-сервера на портах 80/443.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Установить certbot&lt;br /&gt;
apt-get install -y certbot&lt;br /&gt;
&lt;br /&gt;
# Получить сертификат (standalone — Certbot запустит временный HTTP-сервер на :80)&lt;br /&gt;
certbot certonly --standalone \&lt;br /&gt;
  -d your-hy2-eu-domain.example.com \&lt;br /&gt;
  --email YOUR_EMAIL@example.com \&lt;br /&gt;
  --agree-tos --non-interactive&lt;br /&gt;
&lt;br /&gt;
# Проверить&lt;br /&gt;
ls /etc/letsencrypt/live/your-hy2-eu-domain.example.com/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сертификаты будут по пути &amp;lt;code&amp;gt;/etc/letsencrypt/live/your-hy2-eu-domain.example.com/&amp;lt;/code&amp;gt;. В этом случае в &amp;lt;code&amp;gt;docker-compose.yml&amp;lt;/code&amp;gt; (раздел 1.6) замени volume на:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
- /etc/letsencrypt/live/your-hy2-eu-domain.example.com:/etc/hysteria/certs:ro&lt;br /&gt;
- /etc/letsencrypt/archive/your-hy2-eu-domain.example.com:/etc/letsencrypt/archive/your-hy2-eu-domain.example.com:ro&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И в &amp;lt;code&amp;gt;server.yaml&amp;lt;/code&amp;gt; пути к файлам:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
tls:&lt;br /&gt;
  cert: /etc/hysteria/certs/fullchain.pem&lt;br /&gt;
  key: /etc/hysteria/certs/privkey.pem&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 1.4 Создание структуры проекта ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/hysteria-eu&lt;br /&gt;
cd /opt/hysteria-eu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итоговая структура:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/hysteria-eu/&lt;br /&gt;
├── docker-compose.yml&lt;br /&gt;
└── server.yaml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 1.5 Конфигурация сервера: server.yaml ===&lt;br /&gt;
&lt;br /&gt;
Создай файл конфигурации. Замени &amp;lt;code&amp;gt;EU_HY2_PASSWORD&amp;lt;/code&amp;gt; сгенерированным паролем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-eu/server.yaml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
listen: :2053&lt;br /&gt;
&lt;br /&gt;
tls:&lt;br /&gt;
  cert: /etc/hysteria/certs/your-hy2-eu-domain.example.com.crt&lt;br /&gt;
  key: /etc/hysteria/certs/your-hy2-eu-domain.example.com.key&lt;br /&gt;
&lt;br /&gt;
auth:&lt;br /&gt;
  type: password&lt;br /&gt;
  password: EU_HY2_PASSWORD&lt;br /&gt;
&lt;br /&gt;
ignoreClientBandwidth: true&lt;br /&gt;
&lt;br /&gt;
masquerade:&lt;br /&gt;
  type: proxy&lt;br /&gt;
  proxy:&lt;br /&gt;
    url: https://news.ycombinator.com/&lt;br /&gt;
    rewriteHost: true&lt;br /&gt;
&lt;br /&gt;
outbounds:&lt;br /&gt;
  - name: warp&lt;br /&gt;
    type: socks5&lt;br /&gt;
    socks5:&lt;br /&gt;
      addr: 127.0.0.1:24364&lt;br /&gt;
&lt;br /&gt;
acl:&lt;br /&gt;
  inline:&lt;br /&gt;
    - &amp;quot;warp(all)&amp;quot;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Описание ключевых параметров:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Параметр !! Значение !! Пояснение&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;listen: :2053&amp;lt;/code&amp;gt; || UDP порт 2053 || Hysteria2 слушает на всех интерфейсах&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;tls.cert / tls.key&amp;lt;/code&amp;gt; || Пути к сертификату || Берутся из caddy-naive Docker volume (bind mount)&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;auth.type: password&amp;lt;/code&amp;gt; || Одиночный пароль || Для соединения RU клиент → EU сервер (клиентские устройства этот пароль не знают)&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;ignoreClientBandwidth: true&amp;lt;/code&amp;gt; || Игнорировать лимит клиента || Серверная сторона управляет congestion control самостоятельно&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;masquerade.type: proxy&amp;lt;/code&amp;gt; || Проксировать реальный сайт || Неавторизованные запросы получают реальный контент ycombinator.com — сервер выглядит как обычный HTTPS-сайт&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;outbounds.warp&amp;lt;/code&amp;gt; || SOCKS5 на 127.0.0.1:24364 || Исходящий трафик → 3x-ui inbound &amp;quot;hy2-out&amp;quot; → WARP&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;acl: warp(all)&amp;lt;/code&amp;gt; || Направить весь трафик в warp || Синтаксис: имя outbound в скобках, адрес/маска после&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 1.6 Конфигурация Docker Compose: docker-compose.yml ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-eu/docker-compose.yml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
services:&lt;br /&gt;
  hysteria-eu:&lt;br /&gt;
    image: tobyxdd/hysteria:latest&lt;br /&gt;
    container_name: hysteria-eu&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    command: server --config /etc/hysteria/server.yaml&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./server.yaml:/etc/hysteria/server.yaml:ro&lt;br /&gt;
      - /var/lib/docker/volumes/caddy-naive_caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/your-hy2-eu-domain.example.com:/etc/hysteria/certs:ro&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важные моменты:&lt;br /&gt;
* &amp;lt;code&amp;gt;network_mode: host&amp;lt;/code&amp;gt; — обязателен, чтобы контейнер видел &amp;lt;code&amp;gt;127.0.0.1:24364&amp;lt;/code&amp;gt; (3x-ui inbound).&lt;br /&gt;
* &amp;lt;code&amp;gt;:ro&amp;lt;/code&amp;gt; — сертификаты подключены только для чтения, Hysteria2 их не изменяет.&lt;br /&gt;
* Путь к сертификату — bind mount из Docker volume caddy-naive. Если используется certbot (Вариант Б) — замени путь согласно инструкции раздела 1.3.&lt;br /&gt;
&lt;br /&gt;
=== 1.7 Первый запуск ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/hysteria-eu&lt;br /&gt;
&lt;br /&gt;
# Скачать образ и запустить&lt;br /&gt;
docker compose pull&lt;br /&gt;
docker compose up -d&lt;br /&gt;
&lt;br /&gt;
# Подождать 3 секунды и проверить логи&lt;br /&gt;
sleep 3 &amp;amp;&amp;amp; docker compose logs&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод в логах:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
INFO  server mode&lt;br /&gt;
INFO  server up and running   {&amp;quot;listen&amp;quot;: &amp;quot;:2053&amp;quot;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если в логах ошибка — см. раздел «Диагностика проблем» (Часть 5).&lt;br /&gt;
&lt;br /&gt;
=== 1.8 Проверка: порт и соединение ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Проверить, что Hysteria2 слушает на UDP :2053&lt;br /&gt;
ss -ulnp | grep &#039;:2053&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UNCONN  0  0  0.0.0.0:2053  0.0.0.0:*  users:((&amp;quot;hysteria&amp;quot;,...))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Статус контейнера&lt;br /&gt;
docker compose ps&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NAME          IMAGE                     STATUS&lt;br /&gt;
hysteria-eu   tobyxdd/hysteria:latest   Up X minutes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 2: RU сервер (Entry Node) ==&lt;br /&gt;
&lt;br /&gt;
Цель: развернуть два Docker-контейнера:&lt;br /&gt;
* &amp;lt;code&amp;gt;hysteria-ru-server&amp;lt;/code&amp;gt; — принимает соединения от клиентов, аутентифицирует по &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;hysteria-ru-client&amp;lt;/code&amp;gt; — подключается к EU серверу, слушает SOCKS5 на &amp;lt;code&amp;gt;127.0.0.1:10810&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Между ними: hysteria-ru-server направляет трафик через SOCKS5 → hysteria-ru-client → EU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Все команды в этом разделе выполняются на RU сервере под root.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== 2.1 Установка Docker ===&lt;br /&gt;
&lt;br /&gt;
Аналогично EU серверу (раздел 1.1). Если Docker уже установлен — пропусти.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt-get update &amp;amp;&amp;amp; apt-get upgrade -y&lt;br /&gt;
apt-get install -y ca-certificates curl gnupg lsb-release&lt;br /&gt;
&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \&lt;br /&gt;
  -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;deb [arch=$(dpkg --print-architecture) \&lt;br /&gt;
  signed-by=/etc/apt/keyrings/docker.asc] \&lt;br /&gt;
  https://download.docker.com/linux/ubuntu \&lt;br /&gt;
  $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;$VERSION_CODENAME&amp;quot;) stable&amp;quot; \&lt;br /&gt;
  &amp;gt; /etc/apt/sources.list.d/docker.list&lt;br /&gt;
&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin&lt;br /&gt;
systemctl enable docker &amp;amp;&amp;amp; systemctl start docker&lt;br /&gt;
&lt;br /&gt;
docker --version &amp;amp;&amp;amp; docker compose version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2.2 TLS-сертификат для RU сервера ===&lt;br /&gt;
&lt;br /&gt;
Аналогично EU серверу. На RU сервере также используется сертификат от Caddy (caddy-naive), если NaïveProxy настроен.&lt;br /&gt;
&lt;br /&gt;
==== Вариант А: через Caddy (caddy-naive) — рекомендуется ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
DOMAIN=&amp;quot;your-hy2-ru-domain.example.com&amp;quot;&lt;br /&gt;
CERT_DIR=&amp;quot;/var/lib/docker/volumes/caddy-naive_caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${DOMAIN}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ls -la &amp;quot;${CERT_DIR}/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если файлы &amp;lt;code&amp;gt;.crt&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;.key&amp;lt;/code&amp;gt; присутствуют — всё готово, переходи к разделу 2.3.&lt;br /&gt;
&lt;br /&gt;
==== Вариант Б: через certbot (если Caddy не установлен) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt-get install -y certbot&lt;br /&gt;
&lt;br /&gt;
certbot certonly --standalone \&lt;br /&gt;
  -d your-hy2-ru-domain.example.com \&lt;br /&gt;
  --email YOUR_EMAIL@example.com \&lt;br /&gt;
  --agree-tos --non-interactive&lt;br /&gt;
&lt;br /&gt;
ls /etc/letsencrypt/live/your-hy2-ru-domain.example.com/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2.3 Создание структуры проекта ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/hysteria-ru/users&lt;br /&gt;
cd /opt/hysteria-ru&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итоговая структура:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/hysteria-ru/&lt;br /&gt;
├── docker-compose.yml&lt;br /&gt;
├── server.yaml&lt;br /&gt;
├── client.yaml&lt;br /&gt;
└── users/&lt;br /&gt;
    ├── users.txt        ← список пользователей (username password)&lt;br /&gt;
    └── check-auth.sh    ← скрипт авторизации, вызывается при каждом подключении&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2.4 Система аутентификации пользователей ===&lt;br /&gt;
&lt;br /&gt;
RU сервер использует &amp;lt;code&amp;gt;auth.type: command&amp;lt;/code&amp;gt; — при каждом входящем подключении Hysteria2 вызывает внешний скрипт и передаёт ему пароль клиента в аргументах. Скрипт ищет пароль в файле &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt;: если совпадение найдено — выводит имя пользователя (оно попадает в логи) и завершается с кодом 0. Если нет — завершается с кодом 1 (отказ в подключении).&lt;br /&gt;
&lt;br /&gt;
Преимущество этого подхода: &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt; можно редактировать в любой момент без перезапуска контейнера. Изменения применяются немедленно.&lt;br /&gt;
&lt;br /&gt;
==== 2.4.1 Файл пользователей: users/users.txt ====&lt;br /&gt;
&lt;br /&gt;
Формат: одна строка на пользователя — имя пользователя и пароль, разделённые пробелом.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Сгенерировать первого пользователя (пример: &amp;quot;default&amp;quot;)&lt;br /&gt;
PASS=$(openssl rand -base64 18)&lt;br /&gt;
echo &amp;quot;default $PASS&amp;quot; &amp;gt; /opt/hysteria-ru/users/users.txt&lt;br /&gt;
echo &amp;quot;Пароль пользователя default: $PASS&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Формат файла:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
username1 пароль1&lt;br /&gt;
username2 пароль2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Важно:&#039;&#039;&#039; не используй пробелы внутри пароля — пароль считывается по второму полю строки.&lt;br /&gt;
&lt;br /&gt;
==== 2.4.2 Скрипт авторизации: users/check-auth.sh ====&lt;br /&gt;
&lt;br /&gt;
Hysteria2 вызывает скрипт с тремя аргументами: &amp;lt;code&amp;gt;$1&amp;lt;/code&amp;gt; — адрес клиента, &amp;lt;code&amp;gt;$2&amp;lt;/code&amp;gt; — пароль, &amp;lt;code&amp;gt;$3&amp;lt;/code&amp;gt; — tx bandwidth.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-ru/users/check-auth.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
AUTH_PAYLOAD=&amp;quot;$2&amp;quot;&lt;br /&gt;
USERS_FILE=&amp;quot;/etc/hysteria/users/users.txt&amp;quot;&lt;br /&gt;
&lt;br /&gt;
USERNAME=$(awk -v pwd=&amp;quot;$AUTH_PAYLOAD&amp;quot; &#039;$2 == pwd {print $1; exit}&#039; &amp;quot;$USERS_FILE&amp;quot; 2&amp;gt;/dev/null)&lt;br /&gt;
&lt;br /&gt;
if [ -n &amp;quot;$USERNAME&amp;quot; ]; then&lt;br /&gt;
    echo &amp;quot;$USERNAME&amp;quot;&lt;br /&gt;
    exit 0&lt;br /&gt;
fi&lt;br /&gt;
exit 1&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
chmod +x /opt/hysteria-ru/users/check-auth.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Почему используется &amp;lt;code&amp;gt;awk&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;grep&amp;lt;/code&amp;gt;:&lt;br /&gt;
* Hysteria2 использует Docker-образ на базе Alpine Linux с BusyBox.&lt;br /&gt;
* BusyBox &amp;lt;code&amp;gt;grep&amp;lt;/code&amp;gt; не поддерживает флаг &amp;lt;code&amp;gt;-P&amp;lt;/code&amp;gt; (Perl-совместимые регулярки).&lt;br /&gt;
* &amp;lt;code&amp;gt;awk&amp;lt;/code&amp;gt; доступен во всех Unix/Linux окружениях и работает стабильно.&lt;br /&gt;
&lt;br /&gt;
=== 2.5 Конфигурация сервера: server.yaml ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-ru/server.yaml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
listen: :2053&lt;br /&gt;
&lt;br /&gt;
tls:&lt;br /&gt;
  cert: /etc/hysteria/certs/your-hy2-ru-domain.example.com.crt&lt;br /&gt;
  key: /etc/hysteria/certs/your-hy2-ru-domain.example.com.key&lt;br /&gt;
&lt;br /&gt;
auth:&lt;br /&gt;
  type: command&lt;br /&gt;
  command: /etc/hysteria/users/check-auth.sh&lt;br /&gt;
&lt;br /&gt;
ignoreClientBandwidth: true&lt;br /&gt;
&lt;br /&gt;
masquerade:&lt;br /&gt;
  type: proxy&lt;br /&gt;
  proxy:&lt;br /&gt;
    url: https://news.ycombinator.com/&lt;br /&gt;
    rewriteHost: true&lt;br /&gt;
&lt;br /&gt;
outbounds:&lt;br /&gt;
  - name: chain&lt;br /&gt;
    type: socks5&lt;br /&gt;
    socks5:&lt;br /&gt;
      addr: 127.0.0.1:10810&lt;br /&gt;
&lt;br /&gt;
acl:&lt;br /&gt;
  inline:&lt;br /&gt;
    - &amp;quot;chain(all)&amp;quot;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Описание ключевых параметров:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Параметр !! Значение !! Пояснение&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;auth.type: command&amp;lt;/code&amp;gt; || Внешний скрипт || При каждом подключении вызывается &amp;lt;code&amp;gt;check-auth.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;auth.command&amp;lt;/code&amp;gt; || Путь внутри контейнера || Скрипт смонтирован через volume: &amp;lt;code&amp;gt;./users:/etc/hysteria/users&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;outbounds.chain&amp;lt;/code&amp;gt; || SOCKS5 на 127.0.0.1:10810 || Трафик → hysteria-ru-client → EU&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;acl: chain(all)&amp;lt;/code&amp;gt; || Весь трафик через chain || Синтаксис: имя outbound, затем адрес в скобках&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 2.6 Конфигурация клиента: client.yaml ===&lt;br /&gt;
&lt;br /&gt;
RU клиент подключается к EU серверу и поднимает SOCKS5 на &amp;lt;code&amp;gt;127.0.0.1:10810&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-ru/client.yaml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
server: your-hy2-eu-domain.example.com:2053&lt;br /&gt;
&lt;br /&gt;
auth: EU_HY2_PASSWORD&lt;br /&gt;
&lt;br /&gt;
socks5:&lt;br /&gt;
  listen: 127.0.0.1:10810&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Замени &amp;lt;code&amp;gt;EU_HY2_PASSWORD&amp;lt;/code&amp;gt; на тот же пароль, который указан в &amp;lt;code&amp;gt;server.yaml&amp;lt;/code&amp;gt; EU сервера.&lt;br /&gt;
&lt;br /&gt;
=== 2.7 Конфигурация Docker Compose: docker-compose.yml ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-ru/docker-compose.yml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
services:&lt;br /&gt;
  hysteria-ru-server:&lt;br /&gt;
    image: tobyxdd/hysteria:latest&lt;br /&gt;
    container_name: hysteria-ru-server&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    command: server --config /etc/hysteria/server.yaml&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./server.yaml:/etc/hysteria/server.yaml:ro&lt;br /&gt;
      - ./users:/etc/hysteria/users:ro&lt;br /&gt;
      - /var/lib/docker/volumes/caddy-naive_caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/your-hy2-ru-domain.example.com:/etc/hysteria/certs:ro&lt;br /&gt;
&lt;br /&gt;
  hysteria-ru-client:&lt;br /&gt;
    image: tobyxdd/hysteria:latest&lt;br /&gt;
    container_name: hysteria-ru-client&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    command: client --config /etc/hysteria/client.yaml&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./client.yaml:/etc/hysteria/client.yaml:ro&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Критически важные моменты:&#039;&#039;&#039;&lt;br /&gt;
* Директория &amp;lt;code&amp;gt;./users&amp;lt;/code&amp;gt; монтируется в оба контейнера... нет, только в &amp;lt;code&amp;gt;hysteria-ru-server&amp;lt;/code&amp;gt;. Клиентский контейнер видит только свой &amp;lt;code&amp;gt;client.yaml&amp;lt;/code&amp;gt;.&lt;br /&gt;
* При изменении &amp;lt;code&amp;gt;docker-compose.yml&amp;lt;/code&amp;gt; (добавлении volume) нужен пересоздать контейнер: &amp;lt;code&amp;gt;docker compose down &amp;amp;&amp;amp; docker compose up -d&amp;lt;/code&amp;gt;. Простой &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt; не применяет изменения volumes.&lt;br /&gt;
&lt;br /&gt;
=== 2.8 Первый запуск ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/hysteria-ru&lt;br /&gt;
&lt;br /&gt;
# Скачать образ&lt;br /&gt;
docker compose pull&lt;br /&gt;
&lt;br /&gt;
# Запустить оба контейнера&lt;br /&gt;
docker compose up -d&lt;br /&gt;
&lt;br /&gt;
# Подождать и проверить логи&lt;br /&gt;
sleep 3 &amp;amp;&amp;amp; docker compose logs&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hysteria-ru-server  | INFO  server mode&lt;br /&gt;
hysteria-ru-server  | INFO  server up and running  {&amp;quot;listen&amp;quot;: &amp;quot;:2053&amp;quot;}&lt;br /&gt;
hysteria-ru-client  | INFO  client mode&lt;br /&gt;
hysteria-ru-client  | INFO  connected to server  {&amp;quot;udpEnabled&amp;quot;: true, &amp;quot;count&amp;quot;: 1}&lt;br /&gt;
hysteria-ru-client  | INFO  SOCKS5 server listening  {&amp;quot;addr&amp;quot;: &amp;quot;127.0.0.1:10810&amp;quot;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2.9 Проверка цепочки с RU сервера ===&lt;br /&gt;
&lt;br /&gt;
Тест: запустить временный Hysteria2 клиент на RU сервере и проверить, что трафик выходит через WARP (IP Cloudflare):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Создать временный конфиг тест-клиента&lt;br /&gt;
cat &amp;gt; /tmp/hy2-test.yaml &amp;lt;&amp;lt; EOF&lt;br /&gt;
server: 127.0.0.1:2053&lt;br /&gt;
auth: $(awk &#039;NR==1{print $2}&#039; /opt/hysteria-ru/users/users.txt)&lt;br /&gt;
tls:&lt;br /&gt;
  insecure: true&lt;br /&gt;
  sni: your-hy2-ru-domain.example.com&lt;br /&gt;
socks5:&lt;br /&gt;
  listen: 127.0.0.1:11080&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
# Запустить тест-клиент&lt;br /&gt;
docker run -d --name hy2-test --network host \&lt;br /&gt;
  -v /tmp/hy2-test.yaml:/etc/hysteria/client.yaml:ro \&lt;br /&gt;
  tobyxdd/hysteria:latest client --config /etc/hysteria/client.yaml&lt;br /&gt;
&lt;br /&gt;
# Ждать 3 секунды&lt;br /&gt;
sleep 3&lt;br /&gt;
&lt;br /&gt;
# Проверить IP выхода — должен быть Cloudflare WARP IP&lt;br /&gt;
echo &amp;quot;IP через цепочку:&amp;quot;&lt;br /&gt;
curl -s --max-time 15 -x socks5h://127.0.0.1:11080 https://ifconfig.me&lt;br /&gt;
&lt;br /&gt;
# Очистить&lt;br /&gt;
docker rm -f hy2-test&lt;br /&gt;
rm -f /tmp/hy2-test.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если IP вывода принадлежит Cloudflare (начинается с &amp;lt;code&amp;gt;2a09:&amp;lt;/code&amp;gt; для IPv6 или относится к диапазонам WARP) — цепочка RU → EU → WARP работает корректно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Примечание:&#039;&#039;&#039; параметр &amp;lt;code&amp;gt;insecure: true&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;sni&amp;lt;/code&amp;gt; нужны в тест-клиенте, потому что он подключается по IP (&amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt;), а сертификат выдан на домен. Реальные клиенты подключаются по домену и такие параметры не требуются.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 3: Управление пользователями (hy2-users.sh) ==&lt;br /&gt;
&lt;br /&gt;
=== 3.1 Что это и зачем ===&lt;br /&gt;
&lt;br /&gt;
Для управления пользователями Hysteria2 на RU сервере предназначен скрипт &amp;lt;code&amp;gt;hy2-users.sh&amp;lt;/code&amp;gt;. Он предоставляет интерактивное меню с набором операций над файлом &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Скрипт решает следующие задачи:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Операция !! Описание&lt;br /&gt;
|-&lt;br /&gt;
|| Список пользователей || Показывает всех пользователей из users.txt с маскированными паролями&lt;br /&gt;
|-&lt;br /&gt;
|| Добавить пользователя || Запрашивает имя, автоматически генерирует криптостойкий пароль, сохраняет в users.txt, показывает готовый Hysteria2 URI&lt;br /&gt;
|-&lt;br /&gt;
|| Удалить пользователя || Интерактивный выбор из списка, удаление строки из users.txt&lt;br /&gt;
|-&lt;br /&gt;
|| Показать конфиг || Генерирует и показывает Hysteria2 URI для выбранного пользователя&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Ключевые особенности:&lt;br /&gt;
* &#039;&#039;&#039;Нет перезапуска контейнера.&#039;&#039;&#039; Hysteria2 с &amp;lt;code&amp;gt;auth.type: command&amp;lt;/code&amp;gt; читает файл при каждом подключении — изменения в &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt; применяются мгновенно.&lt;br /&gt;
* &#039;&#039;&#039;Пароли генерируются автоматически&#039;&#039;&#039; через &amp;lt;code&amp;gt;openssl rand&amp;lt;/code&amp;gt; — случайные, криптостойкие.&lt;br /&gt;
* &#039;&#039;&#039;URI формат&#039;&#039;&#039; соответствует стандарту Hysteria2 и принимается всеми клиентами: NekoBox, husi, Exclave, podkop.&lt;br /&gt;
&lt;br /&gt;
=== 3.2 Установка скрипта ===&lt;br /&gt;
&lt;br /&gt;
Скрипт хранится в репозитории по пути &amp;lt;code&amp;gt;scripts/hy2-users.sh&amp;lt;/code&amp;gt;. Установка на сервер:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Скопировать скрипт на сервер&lt;br /&gt;
scp scripts/hy2-users.sh root@YOUR_RU_SERVER_IP:/usr/local/bin/hy2-users.sh&lt;br /&gt;
&lt;br /&gt;
# Сделать исполняемым&lt;br /&gt;
ssh root@YOUR_RU_SERVER_IP &amp;quot;chmod +x /usr/local/bin/hy2-users.sh&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или выполнить непосредственно на RU сервере (если скрипт уже там):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x /usr/local/bin/hy2-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка переменных в начале скрипта.&#039;&#039;&#039; Открой скрипт и убедись, что следующие переменные указывают на правильные значения:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
head -15 /usr/local/bin/hy2-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Должны быть:&lt;br /&gt;
* &amp;lt;code&amp;gt;USERS_FILE=&amp;quot;/opt/hysteria-ru/users/users.txt&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DOMAIN=&amp;quot;your-hy2-ru-domain.example.com&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;PORT=&amp;quot;2053&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если домен указан неверно — исправь:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sed -i &#039;s|DOMAIN=.*|DOMAIN=&amp;quot;your-hy2-ru-domain.example.com&amp;quot;|&#039; /usr/local/bin/hy2-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3.3 Использование ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo bash /usr/local/bin/hy2-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скрипт показывает меню:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
┌─────────────────────────────────────────────┐&lt;br /&gt;
│  Hysteria2 — управление пользователями RU   │&lt;br /&gt;
└─────────────────────────────────────────────┘&lt;br /&gt;
&lt;br /&gt;
  1. Список пользователей&lt;br /&gt;
  2. Добавить пользователя&lt;br /&gt;
  3. Удалить пользователя&lt;br /&gt;
  4. Показать конфиг клиента&lt;br /&gt;
&lt;br /&gt;
  0. Выход&lt;br /&gt;
&lt;br /&gt;
Выбери действие:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При добавлении нового пользователя скрипт выводит готовый URI:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hysteria2://СГЕНЕРИРОВАННЫЙ_ПАРОЛЬ@your-hy2-ru-domain.example.com:2053&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот URI вставляется напрямую в клиентское приложение (см. Часть 4).&lt;br /&gt;
&lt;br /&gt;
=== 3.4 Исходный код скрипта ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight:bold; padding:4px 0;&amp;quot;&amp;gt;▶ Показать исходный код hy2-users.sh&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# --- ИСХОДНЫЙ КОД СКРИПТА hy2-users.sh ---&lt;br /&gt;
# (вставить содержимое файла scripts/hy2-users.sh)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 4: Настройка клиентов ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1 Формат URI Hysteria2 ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 использует стандартизированный URI для передачи параметров подключения клиентам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hysteria2://ПАРОЛЬ@ДОМЕН:ПОРТ&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hysteria2://aBcDeFgHiJkLmNoPqRsT@your-hy2-ru-domain.example.com:2053&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
URI можно получить через скрипт &amp;lt;code&amp;gt;hy2-users.sh&amp;lt;/code&amp;gt; (пункт 4 меню — «Показать конфиг клиента»).&lt;br /&gt;
&lt;br /&gt;
=== 4.2 Мобильные клиенты (iOS / Android) ===&lt;br /&gt;
&lt;br /&gt;
Рекомендуемые приложения с нативной поддержкой Hysteria2:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Приложение !! Платформа !! Как импортировать URI&lt;br /&gt;
|-&lt;br /&gt;
|| NekoBox || Android || Главный экран → + → Add → Hysteria2 → вставить URI&lt;br /&gt;
|-&lt;br /&gt;
|| husi || Android || Профили → + → Hysteria2 → вставить URI&lt;br /&gt;
|-&lt;br /&gt;
|| Exclave || iOS || Конфигурации → + → Hysteria2 → вставить URI&lt;br /&gt;
|-&lt;br /&gt;
|| Shadowrocket || iOS || Главная → + → Тип: Hysteria2 → вставить URI&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Все эти приложения принимают URI в формате &amp;lt;code&amp;gt;hysteria2://...&amp;lt;/code&amp;gt; напрямую — через кнопку импорта, QR-код или буфер обмена.&lt;br /&gt;
&lt;br /&gt;
=== 4.3 ПК-клиенты (Windows / macOS / Linux) ===&lt;br /&gt;
&lt;br /&gt;
==== Вариант А: официальный бинарь Hysteria2 ====&lt;br /&gt;
&lt;br /&gt;
Скачать бинарь с официального репозитория: https://github.com/apernet/hysteria/releases&lt;br /&gt;
&lt;br /&gt;
Создать файл конфигурации &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
server: your-hy2-ru-domain.example.com:2053&lt;br /&gt;
&lt;br /&gt;
auth: ВАШ_ПАРОЛЬ&lt;br /&gt;
&lt;br /&gt;
socks5:&lt;br /&gt;
  listen: 127.0.0.1:1080&lt;br /&gt;
&lt;br /&gt;
http:&lt;br /&gt;
  listen: 127.0.0.1:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Запустить:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Linux / macOS&lt;br /&gt;
./hysteria client --config config.yaml&lt;br /&gt;
&lt;br /&gt;
# Windows (PowerShell)&lt;br /&gt;
.\hysteria.exe client --config config.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После запуска:&lt;br /&gt;
* SOCKS5 прокси доступен на &amp;lt;code&amp;gt;127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
* HTTP прокси доступен на &amp;lt;code&amp;gt;127.0.0.1:8080&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Вариант Б: через NekoRay / Hiddify Next (Windows / Linux) ====&lt;br /&gt;
&lt;br /&gt;
Приложения NekoRay и Hiddify Next принимают Hysteria2 URI — импорт через меню или буфер обмена. Автоматически управляют запуском клиентского процесса.&lt;br /&gt;
&lt;br /&gt;
=== 4.4 OpenWrt / podkop ===&lt;br /&gt;
&lt;br /&gt;
podkop (реализация на базе sing-box) нативно поддерживает Hysteria2 URI. Никакой дополнительной установки бинарей не требуется.&lt;br /&gt;
&lt;br /&gt;
В интерфейсе podkop (LuCI → Network → podkop → Outbound):&lt;br /&gt;
* Тип: &amp;lt;code&amp;gt;Hysteria2&amp;lt;/code&amp;gt;&lt;br /&gt;
* URI: &amp;lt;code&amp;gt;hysteria2://ПАРОЛЬ@your-hy2-ru-domain.example.com:2053&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или через UCI:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
uci set podkop.main.proxy=&#039;hysteria2://ПАРОЛЬ@your-hy2-ru-domain.example.com:2053&#039;&lt;br /&gt;
uci commit podkop&lt;br /&gt;
/etc/init.d/podkop restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После сохранения все устройства домашней сети автоматически получают обход без дополнительной настройки.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 5: Проверка всей цепочки ==&lt;br /&gt;
&lt;br /&gt;
=== 5.1 Тест RU сервера: цепочка RU → EU → WARP ===&lt;br /&gt;
&lt;br /&gt;
Выполнить на RU сервере — проверяет, что трафик выходит через WARP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# SOCKS5 порт 10810 — это точка выхода RU клиента (= вход в EU сервер → WARP)&lt;br /&gt;
curl -s --max-time 20 -x socks5h://127.0.0.1:10810 https://ifconfig.me&lt;br /&gt;
echo &amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результат должен быть &#039;&#039;&#039;IP Cloudflare WARP&#039;&#039;&#039; — например, начинается с &amp;lt;code&amp;gt;2a09:&amp;lt;/code&amp;gt; (IPv6) или принадлежит AS13335 (Cloudflare).&lt;br /&gt;
&lt;br /&gt;
Проверить AS:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
IP=$(curl -s --max-time 20 -x socks5h://127.0.0.1:10810 https://ifconfig.me)&lt;br /&gt;
curl -s &amp;quot;https://ipinfo.io/${IP}/org&amp;quot;&lt;br /&gt;
echo &amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод: строка содержит &amp;lt;code&amp;gt;Cloudflare&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 5.2 Тест с реального клиента ===&lt;br /&gt;
&lt;br /&gt;
После добавления пользователя через &amp;lt;code&amp;gt;hy2-users.sh&amp;lt;/code&amp;gt; и получения URI:&lt;br /&gt;
&lt;br /&gt;
# Вставь URI в клиентское приложение (NekoBox, husi, Shadowrocket).&lt;br /&gt;
# Активируй профиль.&lt;br /&gt;
# Открой &amp;lt;code&amp;gt;https://ifconfig.me&amp;lt;/code&amp;gt; в браузере — должен отображаться IP Cloudflare WARP.&lt;br /&gt;
# Открой &amp;lt;code&amp;gt;https://www.whatismybrowser.com/detect/what-is-my-ip-address&amp;lt;/code&amp;gt; для проверки отсутствия WebRTC утечки.&lt;br /&gt;
&lt;br /&gt;
=== 5.3 Диагностика проблем ===&lt;br /&gt;
&lt;br /&gt;
==== Проблема: hysteria-eu не запускается — ошибка TLS ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/hysteria-eu/docker-compose.yml logs hysteria-eu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Возможные причины:&lt;br /&gt;
* Путь к сертификату неверен → проверь &amp;lt;code&amp;gt;ls&amp;lt;/code&amp;gt; по пути, указанному в volumes.&lt;br /&gt;
* Сертификат ещё не был получен Caddy → проверь, что caddy-naive запущен и прошёл ACME-проверку.&lt;br /&gt;
* Caddy хранит сертификат под другим именем → выполни &amp;lt;code&amp;gt;find /var/lib/docker/volumes/caddy-naive_caddy_data/_data -name &amp;quot;*.crt&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Проблема: hysteria-ru-server выдаёт auth error ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/hysteria-ru/docker-compose.yml logs hysteria-ru-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверить вручную (на RU сервере):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Проверить, что скрипт находится на месте внутри контейнера&lt;br /&gt;
docker exec hysteria-ru-server ls -la /etc/hysteria/users/&lt;br /&gt;
&lt;br /&gt;
# Запустить скрипт вручную с тестовым паролем&lt;br /&gt;
docker exec hysteria-ru-server /etc/hysteria/users/check-auth.sh addr ТЕСТОВЫЙ_ПАРОЛЬ 0&lt;br /&gt;
echo &amp;quot;Exit code: $?&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;code&amp;gt;Exit code: 0&amp;lt;/code&amp;gt; — скрипт работает. Если &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; — пароль не найден в &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Проблема: hysteria-ru-client не подключается к EU ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/hysteria-ru/docker-compose.yml logs hysteria-ru-client&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Возможные причины:&lt;br /&gt;
* &amp;lt;code&amp;gt;EU_HY2_PASSWORD&amp;lt;/code&amp;gt; в &amp;lt;code&amp;gt;client.yaml&amp;lt;/code&amp;gt; не совпадает с паролем в EU &amp;lt;code&amp;gt;server.yaml&amp;lt;/code&amp;gt;.&lt;br /&gt;
* UDP порт 2053 заблокирован на EU сервере (firewall) → проверь &amp;lt;code&amp;gt;ss -ulnp | grep 2053&amp;lt;/code&amp;gt; на EU сервере.&lt;br /&gt;
* EU сервер ещё не запущен.&lt;br /&gt;
&lt;br /&gt;
==== Проблема: ACL ошибка при запуске ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FATAL failed to load server config: invalid config: acl.inline: invalid syntax at line 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неверный синтаксис ACL. Правильный формат: &amp;lt;code&amp;gt;&amp;quot;outbound_name(address)&amp;quot;&amp;lt;/code&amp;gt;:&lt;br /&gt;
* ✅ &amp;lt;code&amp;gt;&amp;quot;warp(all)&amp;quot;&amp;lt;/code&amp;gt; — направить всё в outbound &amp;quot;warp&amp;quot;&lt;br /&gt;
* ✅ &amp;lt;code&amp;gt;&amp;quot;chain(all)&amp;quot;&amp;lt;/code&amp;gt; — направить всё в outbound &amp;quot;chain&amp;quot;&lt;br /&gt;
* ❌ &amp;lt;code&amp;gt;&amp;quot;outbound(warp) all&amp;quot;&amp;lt;/code&amp;gt; — неверно&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 6: Обслуживание ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1 Управление контейнерами ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# EU сервер&lt;br /&gt;
cd /opt/hysteria-eu&lt;br /&gt;
docker compose up -d         # запустить&lt;br /&gt;
docker compose down          # остановить&lt;br /&gt;
docker compose restart       # перезапустить&lt;br /&gt;
docker compose logs -f       # следить за логами в реальном времени&lt;br /&gt;
docker compose ps            # статус&lt;br /&gt;
&lt;br /&gt;
# RU сервер (оба контейнера)&lt;br /&gt;
cd /opt/hysteria-ru&lt;br /&gt;
docker compose up -d&lt;br /&gt;
docker compose down&lt;br /&gt;
docker compose restart&lt;br /&gt;
docker compose logs -f&lt;br /&gt;
&lt;br /&gt;
# RU сервер (по отдельности)&lt;br /&gt;
docker compose restart hysteria-ru-server   # только сервер&lt;br /&gt;
docker compose restart hysteria-ru-client   # только клиент&lt;br /&gt;
docker compose logs -f hysteria-ru-server   # логи только сервера&lt;br /&gt;
docker compose logs -f hysteria-ru-client   # логи только клиента&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 6.2 Обновление сертификатов ===&lt;br /&gt;
&lt;br /&gt;
TLS-сертификаты обновляются Caddy автоматически (за 30 дней до истечения). После автообновления Hysteria2 начнёт использовать новый сертификат при следующем перезапуске.&lt;br /&gt;
&lt;br /&gt;
Для принудительного применения нового сертификата:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# EU сервер&lt;br /&gt;
cd /opt/hysteria-eu &amp;amp;&amp;amp; docker compose restart&lt;br /&gt;
&lt;br /&gt;
# RU сервер&lt;br /&gt;
cd /opt/hysteria-ru &amp;amp;&amp;amp; docker compose restart hysteria-ru-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверить дату истечения текущего сертификата:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# EU сервер&lt;br /&gt;
DOMAIN=&amp;quot;your-hy2-eu-domain.example.com&amp;quot;&lt;br /&gt;
CERT=&amp;quot;/var/lib/docker/volumes/caddy-naive_caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${DOMAIN}/${DOMAIN}.crt&amp;quot;&lt;br /&gt;
openssl x509 -in &amp;quot;${CERT}&amp;quot; -noout -enddate&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 6.3 Обновление Docker-образа ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 активно развивается. Для обновления до последней версии:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# EU сервер&lt;br /&gt;
cd /opt/hysteria-eu&lt;br /&gt;
docker compose pull           # скачать новый образ&lt;br /&gt;
docker compose up -d          # перезапустить с новым образом&lt;br /&gt;
docker compose logs --tail=5  # проверить старт&lt;br /&gt;
&lt;br /&gt;
# RU сервер&lt;br /&gt;
cd /opt/hysteria-ru&lt;br /&gt;
docker compose pull&lt;br /&gt;
docker compose up -d&lt;br /&gt;
docker compose logs --tail=5&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Старые неиспользуемые образы можно удалить:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker image prune -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 6.4 Мониторинг логов ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 пишет структурированные JSON-логи. Полезные паттерны для мониторинга:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Смотреть все подключения на RU сервере&lt;br /&gt;
docker logs hysteria-ru-server 2&amp;gt;&amp;amp;1 | grep -E &amp;quot;connected|disconnected|auth&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Смотреть ошибки&lt;br /&gt;
docker logs hysteria-ru-server 2&amp;gt;&amp;amp;1 | grep -i &amp;quot;error\|fatal\|warn&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Считать количество уникальных пользователей (поле &amp;quot;id&amp;quot;)&lt;br /&gt;
docker logs hysteria-ru-server 2&amp;gt;&amp;amp;1 | grep &#039;&amp;quot;id&amp;quot;&#039; | grep -oP &#039;&amp;quot;id&amp;quot;: &amp;quot;\K[^&amp;quot;]+&#039; | sort -u&lt;br /&gt;
&lt;br /&gt;
# Следить за логами EU сервера в реальном времени&lt;br /&gt;
docker logs -f hysteria-eu 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример нормального лога RU сервера при входящем подключении:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
INFO  client connected     {&amp;quot;addr&amp;quot;: &amp;quot;CLIENT_IP:PORT&amp;quot;, &amp;quot;id&amp;quot;: &amp;quot;username&amp;quot;}&lt;br /&gt;
INFO  TCP request          {&amp;quot;addr&amp;quot;: &amp;quot;CLIENT_IP:PORT&amp;quot;, &amp;quot;id&amp;quot;: &amp;quot;username&amp;quot;, &amp;quot;reqAddr&amp;quot;: &amp;quot;example.com:443&amp;quot;}&lt;br /&gt;
INFO  client disconnected  {&amp;quot;addr&amp;quot;: &amp;quot;CLIENT_IP:PORT&amp;quot;, &amp;quot;id&amp;quot;: &amp;quot;username&amp;quot;, &amp;quot;error&amp;quot;: &amp;quot;...&amp;quot;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Поле &amp;lt;code&amp;gt;&amp;quot;id&amp;quot;&amp;lt;/code&amp;gt; — это имя пользователя, возвращённое скриптом &amp;lt;code&amp;gt;check-auth.sh&amp;lt;/code&amp;gt;. Это позволяет отслеживать активность конкретных пользователей в логах без хранения паролей.&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Hysteria2-chain-traffic-flow.png&amp;diff=957</id>
		<title>Файл:Hysteria2-chain-traffic-flow.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Hysteria2-chain-traffic-flow.png&amp;diff=957"/>
		<updated>2026-04-26T10:12:03Z</updated>

		<summary type="html">&lt;p&gt;Владимир: Владимир загрузил новую версию Файл:Hysteria2-chain-traffic-flow.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=Hysteria_2_%D0%BA%D0%B0%D1%81%D0%BA%D0%B0%D0%B4&amp;diff=956</id>
		<title>Hysteria 2 каскад</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=Hysteria_2_%D0%BA%D0%B0%D1%81%D0%BA%D0%B0%D0%B4&amp;diff=956"/>
		<updated>2026-04-26T10:01:45Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Hysteria2: установка каскадной цепочки Entry Node → Exit Node → WARP =&lt;br /&gt;
&lt;br /&gt;
== Что такое Hysteria2 и зачем он нужен ==&lt;br /&gt;
&lt;br /&gt;
=== Проблема: ограничения традиционных прокси-протоколов ===&lt;br /&gt;
&lt;br /&gt;
Современные системы глубокой инспекции пакетов (DPI — Deep Packet Inspection), применяемые интернет-провайдерами и регуляторами по всему миру, умеют анализировать не только адреса назначения, но и &#039;&#039;&#039;характер самого трафика&#039;&#039;&#039;. Даже зашифрованное соединение можно идентифицировать — по поведению, по паузам между пакетами, по размерам передаваемых блоков данных, по TLS-fingerprint.&lt;br /&gt;
&lt;br /&gt;
Большинство прокси-протоколов работают поверх &#039;&#039;&#039;TCP&#039;&#039;&#039;. Это означает:&lt;br /&gt;
* Все потери пакетов обрабатываются дважды — сначала на уровне транспорта, затем внутри туннеля (head-of-line blocking).&lt;br /&gt;
* При нестабильном канале (мобильная сеть, спутник, VPN на слабом железе) скорость резко падает.&lt;br /&gt;
* TCP-fingerprint легче распознаётся и блокируется.&lt;br /&gt;
&lt;br /&gt;
Hysteria2 решает эту проблему фундаментально иначе: он работает поверх &#039;&#039;&#039;QUIC&#039;&#039;&#039; — транспортного протокола на базе UDP, разработанного в Google и стандартизированного в RFC 9000.&lt;br /&gt;
&lt;br /&gt;
=== Решение: QUIC/UDP с маскировкой под HTTPS ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 строит зашифрованный туннель поверх UDP, используя QUIC:&lt;br /&gt;
* &#039;&#039;&#039;Нет head-of-line blocking:&#039;&#039;&#039; потеря одного пакета не блокирует остальные потоки.&lt;br /&gt;
* &#039;&#039;&#039;Быстрое восстановление соединения:&#039;&#039;&#039; QUIC переподключается за 0-RTT (без дополнительного round-trip).&lt;br /&gt;
* &#039;&#039;&#039;Маскировка под HTTPS:&#039;&#039;&#039; снаружи трафик Hysteria2 выглядит как обычный QUIC/HTTP3 браузерный трафик — сервер «притворяется» обычным HTTPS-сайтом и возвращает реальный веб-контент при неавторизованных запросах.&lt;br /&gt;
* &#039;&#039;&#039;Congestion control:&#039;&#039;&#039; поддерживает несколько алгоритмов управления перегрузкой, включая BBR.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Протокол !! Транспорт !! Как выглядит для DPI !! Устойчивость к блокировке !! Скорость при потерях&lt;br /&gt;
|-&lt;br /&gt;
|| Обычный VPN (WireGuard, OpenVPN) || UDP / TCP || Характерный шаблон || Низкая — fingerprint легко детектируется || Высокая (WG) / Низкая (OpenVPN)&lt;br /&gt;
|-&lt;br /&gt;
|| Shadowsocks || TCP || Случайный зашифрованный поток || Средняя — выявляется по энтропии || Средняя&lt;br /&gt;
|-&lt;br /&gt;
|| VLESS + REALITY || TCP (TLS) || TLS с реальным сертификатом стороннего сайта || Высокая || Средняя&lt;br /&gt;
|-&lt;br /&gt;
|| NaïveProxy || TCP (HTTP/2 TLS) || Неотличим от Chrome HTTPS || Очень высокая || Средняя (TCP Head-of-Line)&lt;br /&gt;
|-&lt;br /&gt;
|| &#039;&#039;&#039;Hysteria2&#039;&#039;&#039; || &#039;&#039;&#039;UDP (QUIC/TLS)&#039;&#039;&#039; || &#039;&#039;&#039;QUIC/HTTP3, маскировка под HTTPS&#039;&#039;&#039; || &#039;&#039;&#039;Очень высокая&#039;&#039;&#039; || &#039;&#039;&#039;Высокая — устойчив к потерям&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Как работает Hysteria2 технически ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 использует протокол QUIC в качестве транспорта:&lt;br /&gt;
&lt;br /&gt;
# Клиент устанавливает QUIC-соединение с сервером — это TLS 1.3 поверх UDP.&lt;br /&gt;
# Внутри QUIC-соединения открываются независимые потоки (streams) для каждого проксируемого соединения.&lt;br /&gt;
# Сервер обрабатывает входящий трафик: авторизует клиента (по паролю или через внешний скрипт), затем перенаправляет трафик через указанный outbound.&lt;br /&gt;
# Если к серверу обращаются без правильного пароля — сервер ведёт себя как обычный HTTPS-сайт (&#039;&#039;&#039;masquerade&#039;&#039;&#039;) и возвращает реальный контент с заданного URL.&lt;br /&gt;
&lt;br /&gt;
Особенности аутентификации в данной схеме:&lt;br /&gt;
* &#039;&#039;&#039;EU сервер:&#039;&#039;&#039; использует одиночный пароль — только для входящих соединений от RU клиента (не клиентских устройств).&lt;br /&gt;
* &#039;&#039;&#039;RU сервер:&#039;&#039;&#039; использует &#039;&#039;&#039;command-аутентификацию&#039;&#039;&#039; — при каждом подключении вызывается внешний bash-скрипт, который проверяет пароль по файлу &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt;. Это позволяет добавлять и удалять пользователей &#039;&#039;&#039;без перезапуска сервера&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Каскадная цепочка: зачем два сервера ===&lt;br /&gt;
&lt;br /&gt;
В данном решении используется &#039;&#039;&#039;каскад из двух серверов&#039;&#039;&#039;: Entry Node (ближайший к клиентам сервер-вход) и Exit Node (сервер-выход в интернет). Это архитектурное решение принято намеренно по нескольким причинам:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Снижение риска для клиента:&#039;&#039;&#039; клиентские устройства подключаются только к ближайшему серверу. Соединение с соседним узлом менее заметно, чем прямое соединение с зарубежным сервером.&lt;br /&gt;
* &#039;&#039;&#039;Раздельная аутентификация:&#039;&#039;&#039; пароль «клиент → Entry Node» знают только конечные пользователи. Пароль «Entry Node → Exit Node» знают только серверы. Компрометация клиентского пароля не раскрывает пароль соединения между серверами.&lt;br /&gt;
* &#039;&#039;&#039;Анонимизация выхода:&#039;&#039;&#039; Exit Node передаёт трафик через Cloudflare WARP. Конечные сайты видят IP Cloudflare, а не IP ваших серверов.&lt;br /&gt;
* &#039;&#039;&#039;Параллельные независимые каналы:&#039;&#039;&#039; Hysteria2 работает рядом с NaïveProxy и 3x-ui на тех же серверах, не конфликтуя с ними. Падение одного канала не блокирует другие.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Схема конкретного решения ==&lt;br /&gt;
&lt;br /&gt;
=== Компоненты инфраструктуры ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Компонент !! Роль !! Адрес / Домен !! ОС&lt;br /&gt;
|-&lt;br /&gt;
|| Клиентские устройства || Конечные пользователи || — || iOS, Android, Windows, macOS, Linux&lt;br /&gt;
|-&lt;br /&gt;
|| OpenWrt роутер || Прозрачный обход для всей домашней сети || — || OpenWrt 24.10 (podkop нативно поддерживает hy2 URI)&lt;br /&gt;
|-&lt;br /&gt;
|| RU сервер (&#039;&#039;&#039;Entry Node&#039;&#039;&#039;) || Точка входа клиентов || &amp;lt;code&amp;gt;YOUR_RU_SERVER_IP&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;your-hy2-ru-domain.example.com&amp;lt;/code&amp;gt; || Ubuntu 24.04&lt;br /&gt;
|-&lt;br /&gt;
|| EU сервер (&#039;&#039;&#039;Exit Node&#039;&#039;&#039;) || Точка выхода в интернет || &amp;lt;code&amp;gt;YOUR_EU_SERVER_IP&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;your-hy2-eu-domain.example.com&amp;lt;/code&amp;gt; || Ubuntu 24.04&lt;br /&gt;
|-&lt;br /&gt;
|| Cloudflare WARP || Финальный выход в интернет || IP Cloudflare || —&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Полная схема прохождения трафика ===&lt;br /&gt;
&lt;br /&gt;
[[File:hysteria2-chain-traffic-flow.png|center|900px|Схема трафика Hysteria2: Клиенты → RU Entry Node → EU Exit Node → WARP → Интернет]]&lt;br /&gt;
&lt;br /&gt;
=== Протоколы на каждом участке цепочки ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Участок !! Протокол !! Шифрование !! Что видит наблюдатель&lt;br /&gt;
|-&lt;br /&gt;
|| Устройство → Роутер || Обычный TCP/UDP || Нет (локальная сеть) || Локальный трафик&lt;br /&gt;
|-&lt;br /&gt;
|| Роутер / ПК → RU сервер || QUIC / UDP (Hysteria2) || TLS 1.3 (Let&#039;s Encrypt) || HTTPS/HTTP3 трафик к обычному сайту&lt;br /&gt;
|-&lt;br /&gt;
|| RU клиент → EU сервер || QUIC / UDP (Hysteria2) || TLS 1.3 (Let&#039;s Encrypt) || HTTPS/HTTP3 трафик к обычному сайту&lt;br /&gt;
|-&lt;br /&gt;
|| EU сервер → 3x-ui inbound || SOCKS5 (localhost) || — (только на EU сервере) || Только локально&lt;br /&gt;
|-&lt;br /&gt;
|| EU 3x-ui → WARP || WireGuard (gVisor TUN) || WireGuard || Зашифрованный WireGuard к Cloudflare&lt;br /&gt;
|-&lt;br /&gt;
|| WARP → Интернет || Обычный TCP/UDP || — || IP Cloudflare&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Дополнительные каналы (параллельно Hysteria2) ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 работает &#039;&#039;&#039;независимо&#039;&#039;&#039; от NaïveProxy и 3x-ui. Все три канала активны одновременно:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Канал !! Протокол !! Маршрут !! Статус&lt;br /&gt;
|-&lt;br /&gt;
|| 3x-ui каскад (основной) || VLESS / REALITY || Клиенты → RU 3x-ui → EU 3x-ui → Интернет || ✅ Активен&lt;br /&gt;
|-&lt;br /&gt;
|| NaïveProxy каскад || HTTP/2 naïve || Роутер/ПК → RU Caddy → EU Caddy → WARP || ✅ Активен&lt;br /&gt;
|-&lt;br /&gt;
|| &#039;&#039;&#039;Hysteria2 каскад (этот гайд)&#039;&#039;&#039; || &#039;&#039;&#039;QUIC/UDP hy2&#039;&#039;&#039; || &#039;&#039;&#039;Клиенты → RU hy2 → EU hy2 → WARP&#039;&#039;&#039; || &#039;&#039;&#039;✅ Активен&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|| MTProto (Telegram) || MTProto || Клиенты Telegram → EU :8443, :2443 || ✅ Активен&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
=== Инфраструктура ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Компонент !! Требования&lt;br /&gt;
|-&lt;br /&gt;
|| EU сервер || Ubuntu 24.04, публичный IP, домен с A-записью → IP сервера&lt;br /&gt;
|-&lt;br /&gt;
|| RU сервер || Ubuntu 24.04, публичный IP, домен с A-записью → IP сервера&lt;br /&gt;
|-&lt;br /&gt;
|| 3x-ui на EU сервере || Уже установлен и работает; настроен outbound WARP&lt;br /&gt;
|-&lt;br /&gt;
|| Docker || Установлен на обоих серверах&lt;br /&gt;
|-&lt;br /&gt;
|| Порт 2053 UDP || Должен быть свободен на обоих серверах&lt;br /&gt;
|-&lt;br /&gt;
|| TLS-сертификат || Получается через Caddy (caddy-naive), либо через certbot — описано в разделе ниже&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DNS-записи (создать заранее, до установки) ===&lt;br /&gt;
&lt;br /&gt;
Let&#039;s Encrypt проверяет доступность домена по HTTP (порт 80) перед выдачей сертификата. DNS-записи должны быть созданы и распространены (propagated) до первого запуска Caddy.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Запись !! Тип !! Значение !! Примечание&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;your-hy2-ru-domain.example.com&amp;lt;/code&amp;gt; || A || IP RU сервера || Используется Hysteria2 сервером на RU&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;your-hy2-eu-domain.example.com&amp;lt;/code&amp;gt; || A || IP EU сервера || Используется Hysteria2 сервером на EU&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Примечание:&#039;&#039;&#039; если NaïveProxy (Caddy) уже настроен на тех же серверах с теми же доменами, отдельные DNS-записи для Hysteria2 не нужны — используется тот же домен и тот же сертификат.&lt;br /&gt;
&lt;br /&gt;
=== Используемые заглушки ===&lt;br /&gt;
&lt;br /&gt;
В данном руководстве применяются следующие заглушки. Замени их реальными значениями перед использованием:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Заглушка !! Описание&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;YOUR_RU_SERVER_IP&amp;lt;/code&amp;gt; || Публичный IP RU сервера&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;YOUR_EU_SERVER_IP&amp;lt;/code&amp;gt; || Публичный IP EU сервера&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;your-hy2-ru-domain.example.com&amp;lt;/code&amp;gt; || Домен для RU сервера (для TLS-сертификата)&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;your-hy2-eu-domain.example.com&amp;lt;/code&amp;gt; || Домен для EU сервера (для TLS-сертификата)&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;YOUR_EMAIL@example.com&amp;lt;/code&amp;gt; || Email для Let&#039;s Encrypt (уведомления об истечении сертификата)&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;EU_HY2_PASSWORD&amp;lt;/code&amp;gt; || Пароль соединения RU клиент → EU сервер (генерируется один раз)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Для генерации пароля EU_HY2_PASSWORD используй:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl rand -base64 18&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Сохрани результат — он понадобится в конфигах обоих серверов.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 1: EU сервер (Exit Node) ==&lt;br /&gt;
&lt;br /&gt;
Цель: развернуть Hysteria2 сервер в Docker, который принимает соединения от RU клиента и перенаправляет трафик через 3x-ui → Cloudflare WARP.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Все команды в этом разделе выполняются на EU сервере под root.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== 1.1 Установка Docker ===&lt;br /&gt;
&lt;br /&gt;
Если Docker уже установлен (проверить: &amp;lt;code&amp;gt;docker --version&amp;lt;/code&amp;gt;) — пропусти этот шаг.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Обновить пакеты&lt;br /&gt;
apt-get update &amp;amp;&amp;amp; apt-get upgrade -y&lt;br /&gt;
&lt;br /&gt;
# Установить зависимости&lt;br /&gt;
apt-get install -y ca-certificates curl gnupg lsb-release&lt;br /&gt;
&lt;br /&gt;
# Добавить GPG-ключ Docker&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \&lt;br /&gt;
  -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
# Добавить репозиторий Docker&lt;br /&gt;
echo &amp;quot;deb [arch=$(dpkg --print-architecture) \&lt;br /&gt;
  signed-by=/etc/apt/keyrings/docker.asc] \&lt;br /&gt;
  https://download.docker.com/linux/ubuntu \&lt;br /&gt;
  $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;$VERSION_CODENAME&amp;quot;) stable&amp;quot; \&lt;br /&gt;
  &amp;gt; /etc/apt/sources.list.d/docker.list&lt;br /&gt;
&lt;br /&gt;
# Установить Docker Engine&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin&lt;br /&gt;
&lt;br /&gt;
# Включить автозапуск&lt;br /&gt;
systemctl enable docker&lt;br /&gt;
systemctl start docker&lt;br /&gt;
&lt;br /&gt;
# Проверить&lt;br /&gt;
docker --version&lt;br /&gt;
docker compose version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Docker version 27.x.x, build ...&lt;br /&gt;
Docker Compose version v2.x.x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 1.2 Настройка 3x-ui: создание inbound hy2-out → WARP ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 Exit Node направляет трафик через 3x-ui SOCKS5 inbound, который в свою очередь маршрутизирует его в Cloudflare WARP. Этот шаг выполняется в веб-интерфейсе 3x-ui &#039;&#039;&#039;до&#039;&#039;&#039; запуска Hysteria2.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Условие:&#039;&#039;&#039; в 3x-ui должен быть настроен outbound WARP (WireGuard/gVisor).&lt;br /&gt;
&lt;br /&gt;
==== 1.2.1 Создать новый inbound в 3x-ui ====&lt;br /&gt;
&lt;br /&gt;
В веб-интерфейсе 3x-ui (EU сервер) перейди в &#039;&#039;&#039;Inbounds → Add Inbound&#039;&#039;&#039; и заполни следующие поля:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Параметр !! Значение !! Пояснение&lt;br /&gt;
|-&lt;br /&gt;
|| Примечание (Remark) || &amp;lt;code&amp;gt;hy2-out&amp;lt;/code&amp;gt; || Произвольное имя для идентификации в правилах маршрутизации&lt;br /&gt;
|-&lt;br /&gt;
|| Протокол || &amp;lt;code&amp;gt;mixed&amp;lt;/code&amp;gt; || Поддерживает SOCKS5 и HTTP одновременно&lt;br /&gt;
|-&lt;br /&gt;
|| Listen IP || &amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt; || Только localhost — недоступен извне&lt;br /&gt;
|-&lt;br /&gt;
|| Порт || &amp;lt;code&amp;gt;24364&amp;lt;/code&amp;gt; || Должен быть свободен; проверить: &amp;lt;code&amp;gt;ss -tlnp | grep 24364&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|| Аутентификация || Выключена || Hysteria2 сам отвечает за авторизацию клиентов&lt;br /&gt;
|-&lt;br /&gt;
|| UDP || Включён || Требуется для DNS-запросов через туннель&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Нажми &#039;&#039;&#039;Save&#039;&#039;&#039; — inbound немедленно активируется.&lt;br /&gt;
&lt;br /&gt;
==== 1.2.2 Создать правило маршрутизации ====&lt;br /&gt;
&lt;br /&gt;
В 3x-ui перейди в &#039;&#039;&#039;Routing → Add Rule&#039;&#039;&#039; (или Settings → Routing Rules):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
|| Inbound Tag || &amp;lt;code&amp;gt;hy2-out&amp;lt;/code&amp;gt; (тег созданного выше inbound)&lt;br /&gt;
|-&lt;br /&gt;
|| Outbound Tag || &amp;lt;code&amp;gt;warp&amp;lt;/code&amp;gt; (или название твоего WARP outbound в 3x-ui)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сохрани и перезапусти Xray внутри 3x-ui.&lt;br /&gt;
&lt;br /&gt;
==== 1.2.3 Проверить, что порт 24364 слушает ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -tlnp | grep 24364&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LISTEN  0  128  127.0.0.1:24364  0.0.0.0:*  users:((&amp;quot;xray&amp;quot;,...))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 1.3 TLS-сертификат для Hysteria2 ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 требует действующий TLS-сертификат (самоподписанный не рекомендуется — клиентам потребуется флаг &amp;lt;code&amp;gt;insecure: true&amp;lt;/code&amp;gt;). В нашей схеме используется &#039;&#039;&#039;Let&#039;s Encrypt сертификат&#039;&#039;&#039;, получаемый и автоматически обновляемый через Caddy (caddy-naive стек).&lt;br /&gt;
&lt;br /&gt;
Caddy хранит сертификаты в именованном Docker volume &amp;lt;code&amp;gt;caddy-naive_caddy_data&amp;lt;/code&amp;gt;, и Hysteria2 подключает их через bind mount (read-only) — никаких лишних сервисов, никакого дублирования.&lt;br /&gt;
&lt;br /&gt;
==== Вариант А: Caddy (caddy-naive) уже установлен — рекомендуется ====&lt;br /&gt;
&lt;br /&gt;
Если NaïveProxy (caddy-naive) уже настроен и работает, сертификат уже получен. Проверь:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Найти путь к сертификату в Docker volume&lt;br /&gt;
DOMAIN=&amp;quot;your-hy2-eu-domain.example.com&amp;quot;&lt;br /&gt;
CERT_DIR=&amp;quot;/var/lib/docker/volumes/caddy-naive_caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${DOMAIN}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ls -la &amp;quot;${CERT_DIR}/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод — два файла:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
your-hy2-eu-domain.example.com.crt&lt;br /&gt;
your-hy2-eu-domain.example.com.key&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если файлы есть — переходи к разделу &#039;&#039;&#039;1.4&#039;&#039;&#039;. Если volume или папка не существуют — сначала установи caddy-naive (NaïveProxy) или воспользуйся Вариантом Б.&lt;br /&gt;
&lt;br /&gt;
==== Вариант Б: получить сертификат через certbot (если Caddy не установлен) ====&lt;br /&gt;
&lt;br /&gt;
Этот вариант используется, если caddy-naive &#039;&#039;&#039;не установлен&#039;&#039;&#039; и на серверах нет другого HTTP-сервера на портах 80/443.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Установить certbot&lt;br /&gt;
apt-get install -y certbot&lt;br /&gt;
&lt;br /&gt;
# Получить сертификат (standalone — Certbot запустит временный HTTP-сервер на :80)&lt;br /&gt;
certbot certonly --standalone \&lt;br /&gt;
  -d your-hy2-eu-domain.example.com \&lt;br /&gt;
  --email YOUR_EMAIL@example.com \&lt;br /&gt;
  --agree-tos --non-interactive&lt;br /&gt;
&lt;br /&gt;
# Проверить&lt;br /&gt;
ls /etc/letsencrypt/live/your-hy2-eu-domain.example.com/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сертификаты будут по пути &amp;lt;code&amp;gt;/etc/letsencrypt/live/your-hy2-eu-domain.example.com/&amp;lt;/code&amp;gt;. В этом случае в &amp;lt;code&amp;gt;docker-compose.yml&amp;lt;/code&amp;gt; (раздел 1.6) замени volume на:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
- /etc/letsencrypt/live/your-hy2-eu-domain.example.com:/etc/hysteria/certs:ro&lt;br /&gt;
- /etc/letsencrypt/archive/your-hy2-eu-domain.example.com:/etc/letsencrypt/archive/your-hy2-eu-domain.example.com:ro&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И в &amp;lt;code&amp;gt;server.yaml&amp;lt;/code&amp;gt; пути к файлам:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
tls:&lt;br /&gt;
  cert: /etc/hysteria/certs/fullchain.pem&lt;br /&gt;
  key: /etc/hysteria/certs/privkey.pem&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 1.4 Создание структуры проекта ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/hysteria-eu&lt;br /&gt;
cd /opt/hysteria-eu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итоговая структура:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/hysteria-eu/&lt;br /&gt;
├── docker-compose.yml&lt;br /&gt;
└── server.yaml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 1.5 Конфигурация сервера: server.yaml ===&lt;br /&gt;
&lt;br /&gt;
Создай файл конфигурации. Замени &amp;lt;code&amp;gt;EU_HY2_PASSWORD&amp;lt;/code&amp;gt; сгенерированным паролем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-eu/server.yaml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
listen: :2053&lt;br /&gt;
&lt;br /&gt;
tls:&lt;br /&gt;
  cert: /etc/hysteria/certs/your-hy2-eu-domain.example.com.crt&lt;br /&gt;
  key: /etc/hysteria/certs/your-hy2-eu-domain.example.com.key&lt;br /&gt;
&lt;br /&gt;
auth:&lt;br /&gt;
  type: password&lt;br /&gt;
  password: EU_HY2_PASSWORD&lt;br /&gt;
&lt;br /&gt;
ignoreClientBandwidth: true&lt;br /&gt;
&lt;br /&gt;
masquerade:&lt;br /&gt;
  type: proxy&lt;br /&gt;
  proxy:&lt;br /&gt;
    url: https://news.ycombinator.com/&lt;br /&gt;
    rewriteHost: true&lt;br /&gt;
&lt;br /&gt;
outbounds:&lt;br /&gt;
  - name: warp&lt;br /&gt;
    type: socks5&lt;br /&gt;
    socks5:&lt;br /&gt;
      addr: 127.0.0.1:24364&lt;br /&gt;
&lt;br /&gt;
acl:&lt;br /&gt;
  inline:&lt;br /&gt;
    - &amp;quot;warp(all)&amp;quot;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Описание ключевых параметров:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Параметр !! Значение !! Пояснение&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;listen: :2053&amp;lt;/code&amp;gt; || UDP порт 2053 || Hysteria2 слушает на всех интерфейсах&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;tls.cert / tls.key&amp;lt;/code&amp;gt; || Пути к сертификату || Берутся из caddy-naive Docker volume (bind mount)&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;auth.type: password&amp;lt;/code&amp;gt; || Одиночный пароль || Для соединения RU клиент → EU сервер (клиентские устройства этот пароль не знают)&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;ignoreClientBandwidth: true&amp;lt;/code&amp;gt; || Игнорировать лимит клиента || Серверная сторона управляет congestion control самостоятельно&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;masquerade.type: proxy&amp;lt;/code&amp;gt; || Проксировать реальный сайт || Неавторизованные запросы получают реальный контент ycombinator.com — сервер выглядит как обычный HTTPS-сайт&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;outbounds.warp&amp;lt;/code&amp;gt; || SOCKS5 на 127.0.0.1:24364 || Исходящий трафик → 3x-ui inbound &amp;quot;hy2-out&amp;quot; → WARP&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;acl: warp(all)&amp;lt;/code&amp;gt; || Направить весь трафик в warp || Синтаксис: имя outbound в скобках, адрес/маска после&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 1.6 Конфигурация Docker Compose: docker-compose.yml ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-eu/docker-compose.yml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
services:&lt;br /&gt;
  hysteria-eu:&lt;br /&gt;
    image: tobyxdd/hysteria:latest&lt;br /&gt;
    container_name: hysteria-eu&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    command: server --config /etc/hysteria/server.yaml&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./server.yaml:/etc/hysteria/server.yaml:ro&lt;br /&gt;
      - /var/lib/docker/volumes/caddy-naive_caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/your-hy2-eu-domain.example.com:/etc/hysteria/certs:ro&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важные моменты:&lt;br /&gt;
* &amp;lt;code&amp;gt;network_mode: host&amp;lt;/code&amp;gt; — обязателен, чтобы контейнер видел &amp;lt;code&amp;gt;127.0.0.1:24364&amp;lt;/code&amp;gt; (3x-ui inbound).&lt;br /&gt;
* &amp;lt;code&amp;gt;:ro&amp;lt;/code&amp;gt; — сертификаты подключены только для чтения, Hysteria2 их не изменяет.&lt;br /&gt;
* Путь к сертификату — bind mount из Docker volume caddy-naive. Если используется certbot (Вариант Б) — замени путь согласно инструкции раздела 1.3.&lt;br /&gt;
&lt;br /&gt;
=== 1.7 Первый запуск ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/hysteria-eu&lt;br /&gt;
&lt;br /&gt;
# Скачать образ и запустить&lt;br /&gt;
docker compose pull&lt;br /&gt;
docker compose up -d&lt;br /&gt;
&lt;br /&gt;
# Подождать 3 секунды и проверить логи&lt;br /&gt;
sleep 3 &amp;amp;&amp;amp; docker compose logs&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод в логах:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
INFO  server mode&lt;br /&gt;
INFO  server up and running   {&amp;quot;listen&amp;quot;: &amp;quot;:2053&amp;quot;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если в логах ошибка — см. раздел «Диагностика проблем» (Часть 5).&lt;br /&gt;
&lt;br /&gt;
=== 1.8 Проверка: порт и соединение ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Проверить, что Hysteria2 слушает на UDP :2053&lt;br /&gt;
ss -ulnp | grep &#039;:2053&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UNCONN  0  0  0.0.0.0:2053  0.0.0.0:*  users:((&amp;quot;hysteria&amp;quot;,...))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Статус контейнера&lt;br /&gt;
docker compose ps&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NAME          IMAGE                     STATUS&lt;br /&gt;
hysteria-eu   tobyxdd/hysteria:latest   Up X minutes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 2: RU сервер (Entry Node) ==&lt;br /&gt;
&lt;br /&gt;
Цель: развернуть два Docker-контейнера:&lt;br /&gt;
* &amp;lt;code&amp;gt;hysteria-ru-server&amp;lt;/code&amp;gt; — принимает соединения от клиентов, аутентифицирует по &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;hysteria-ru-client&amp;lt;/code&amp;gt; — подключается к EU серверу, слушает SOCKS5 на &amp;lt;code&amp;gt;127.0.0.1:10810&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Между ними: hysteria-ru-server направляет трафик через SOCKS5 → hysteria-ru-client → EU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Все команды в этом разделе выполняются на RU сервере под root.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== 2.1 Установка Docker ===&lt;br /&gt;
&lt;br /&gt;
Аналогично EU серверу (раздел 1.1). Если Docker уже установлен — пропусти.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt-get update &amp;amp;&amp;amp; apt-get upgrade -y&lt;br /&gt;
apt-get install -y ca-certificates curl gnupg lsb-release&lt;br /&gt;
&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \&lt;br /&gt;
  -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;deb [arch=$(dpkg --print-architecture) \&lt;br /&gt;
  signed-by=/etc/apt/keyrings/docker.asc] \&lt;br /&gt;
  https://download.docker.com/linux/ubuntu \&lt;br /&gt;
  $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;$VERSION_CODENAME&amp;quot;) stable&amp;quot; \&lt;br /&gt;
  &amp;gt; /etc/apt/sources.list.d/docker.list&lt;br /&gt;
&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin&lt;br /&gt;
systemctl enable docker &amp;amp;&amp;amp; systemctl start docker&lt;br /&gt;
&lt;br /&gt;
docker --version &amp;amp;&amp;amp; docker compose version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2.2 TLS-сертификат для RU сервера ===&lt;br /&gt;
&lt;br /&gt;
Аналогично EU серверу. На RU сервере также используется сертификат от Caddy (caddy-naive), если NaïveProxy настроен.&lt;br /&gt;
&lt;br /&gt;
==== Вариант А: через Caddy (caddy-naive) — рекомендуется ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
DOMAIN=&amp;quot;your-hy2-ru-domain.example.com&amp;quot;&lt;br /&gt;
CERT_DIR=&amp;quot;/var/lib/docker/volumes/caddy-naive_caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${DOMAIN}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ls -la &amp;quot;${CERT_DIR}/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если файлы &amp;lt;code&amp;gt;.crt&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;.key&amp;lt;/code&amp;gt; присутствуют — всё готово, переходи к разделу 2.3.&lt;br /&gt;
&lt;br /&gt;
==== Вариант Б: через certbot (если Caddy не установлен) ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt-get install -y certbot&lt;br /&gt;
&lt;br /&gt;
certbot certonly --standalone \&lt;br /&gt;
  -d your-hy2-ru-domain.example.com \&lt;br /&gt;
  --email YOUR_EMAIL@example.com \&lt;br /&gt;
  --agree-tos --non-interactive&lt;br /&gt;
&lt;br /&gt;
ls /etc/letsencrypt/live/your-hy2-ru-domain.example.com/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2.3 Создание структуры проекта ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/hysteria-ru/users&lt;br /&gt;
cd /opt/hysteria-ru&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итоговая структура:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/hysteria-ru/&lt;br /&gt;
├── docker-compose.yml&lt;br /&gt;
├── server.yaml&lt;br /&gt;
├── client.yaml&lt;br /&gt;
└── users/&lt;br /&gt;
    ├── users.txt        ← список пользователей (username password)&lt;br /&gt;
    └── check-auth.sh    ← скрипт авторизации, вызывается при каждом подключении&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2.4 Система аутентификации пользователей ===&lt;br /&gt;
&lt;br /&gt;
RU сервер использует &amp;lt;code&amp;gt;auth.type: command&amp;lt;/code&amp;gt; — при каждом входящем подключении Hysteria2 вызывает внешний скрипт и передаёт ему пароль клиента в аргументах. Скрипт ищет пароль в файле &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt;: если совпадение найдено — выводит имя пользователя (оно попадает в логи) и завершается с кодом 0. Если нет — завершается с кодом 1 (отказ в подключении).&lt;br /&gt;
&lt;br /&gt;
Преимущество этого подхода: &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt; можно редактировать в любой момент без перезапуска контейнера. Изменения применяются немедленно.&lt;br /&gt;
&lt;br /&gt;
==== 2.4.1 Файл пользователей: users/users.txt ====&lt;br /&gt;
&lt;br /&gt;
Формат: одна строка на пользователя — имя пользователя и пароль, разделённые пробелом.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Сгенерировать первого пользователя (пример: &amp;quot;default&amp;quot;)&lt;br /&gt;
PASS=$(openssl rand -base64 18)&lt;br /&gt;
echo &amp;quot;default $PASS&amp;quot; &amp;gt; /opt/hysteria-ru/users/users.txt&lt;br /&gt;
echo &amp;quot;Пароль пользователя default: $PASS&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Формат файла:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
username1 пароль1&lt;br /&gt;
username2 пароль2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Важно:&#039;&#039;&#039; не используй пробелы внутри пароля — пароль считывается по второму полю строки.&lt;br /&gt;
&lt;br /&gt;
==== 2.4.2 Скрипт авторизации: users/check-auth.sh ====&lt;br /&gt;
&lt;br /&gt;
Hysteria2 вызывает скрипт с тремя аргументами: &amp;lt;code&amp;gt;$1&amp;lt;/code&amp;gt; — адрес клиента, &amp;lt;code&amp;gt;$2&amp;lt;/code&amp;gt; — пароль, &amp;lt;code&amp;gt;$3&amp;lt;/code&amp;gt; — tx bandwidth.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-ru/users/check-auth.sh &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
AUTH_PAYLOAD=&amp;quot;$2&amp;quot;&lt;br /&gt;
USERS_FILE=&amp;quot;/etc/hysteria/users/users.txt&amp;quot;&lt;br /&gt;
&lt;br /&gt;
USERNAME=$(awk -v pwd=&amp;quot;$AUTH_PAYLOAD&amp;quot; &#039;$2 == pwd {print $1; exit}&#039; &amp;quot;$USERS_FILE&amp;quot; 2&amp;gt;/dev/null)&lt;br /&gt;
&lt;br /&gt;
if [ -n &amp;quot;$USERNAME&amp;quot; ]; then&lt;br /&gt;
    echo &amp;quot;$USERNAME&amp;quot;&lt;br /&gt;
    exit 0&lt;br /&gt;
fi&lt;br /&gt;
exit 1&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
chmod +x /opt/hysteria-ru/users/check-auth.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Почему используется &amp;lt;code&amp;gt;awk&amp;lt;/code&amp;gt;, а не &amp;lt;code&amp;gt;grep&amp;lt;/code&amp;gt;:&lt;br /&gt;
* Hysteria2 использует Docker-образ на базе Alpine Linux с BusyBox.&lt;br /&gt;
* BusyBox &amp;lt;code&amp;gt;grep&amp;lt;/code&amp;gt; не поддерживает флаг &amp;lt;code&amp;gt;-P&amp;lt;/code&amp;gt; (Perl-совместимые регулярки).&lt;br /&gt;
* &amp;lt;code&amp;gt;awk&amp;lt;/code&amp;gt; доступен во всех Unix/Linux окружениях и работает стабильно.&lt;br /&gt;
&lt;br /&gt;
=== 2.5 Конфигурация сервера: server.yaml ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-ru/server.yaml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
listen: :2053&lt;br /&gt;
&lt;br /&gt;
tls:&lt;br /&gt;
  cert: /etc/hysteria/certs/your-hy2-ru-domain.example.com.crt&lt;br /&gt;
  key: /etc/hysteria/certs/your-hy2-ru-domain.example.com.key&lt;br /&gt;
&lt;br /&gt;
auth:&lt;br /&gt;
  type: command&lt;br /&gt;
  command: /etc/hysteria/users/check-auth.sh&lt;br /&gt;
&lt;br /&gt;
ignoreClientBandwidth: true&lt;br /&gt;
&lt;br /&gt;
masquerade:&lt;br /&gt;
  type: proxy&lt;br /&gt;
  proxy:&lt;br /&gt;
    url: https://news.ycombinator.com/&lt;br /&gt;
    rewriteHost: true&lt;br /&gt;
&lt;br /&gt;
outbounds:&lt;br /&gt;
  - name: chain&lt;br /&gt;
    type: socks5&lt;br /&gt;
    socks5:&lt;br /&gt;
      addr: 127.0.0.1:10810&lt;br /&gt;
&lt;br /&gt;
acl:&lt;br /&gt;
  inline:&lt;br /&gt;
    - &amp;quot;chain(all)&amp;quot;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Описание ключевых параметров:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Параметр !! Значение !! Пояснение&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;auth.type: command&amp;lt;/code&amp;gt; || Внешний скрипт || При каждом подключении вызывается &amp;lt;code&amp;gt;check-auth.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;auth.command&amp;lt;/code&amp;gt; || Путь внутри контейнера || Скрипт смонтирован через volume: &amp;lt;code&amp;gt;./users:/etc/hysteria/users&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;outbounds.chain&amp;lt;/code&amp;gt; || SOCKS5 на 127.0.0.1:10810 || Трафик → hysteria-ru-client → EU&lt;br /&gt;
|-&lt;br /&gt;
|| &amp;lt;code&amp;gt;acl: chain(all)&amp;lt;/code&amp;gt; || Весь трафик через chain || Синтаксис: имя outbound, затем адрес в скобках&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 2.6 Конфигурация клиента: client.yaml ===&lt;br /&gt;
&lt;br /&gt;
RU клиент подключается к EU серверу и поднимает SOCKS5 на &amp;lt;code&amp;gt;127.0.0.1:10810&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-ru/client.yaml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
server: your-hy2-eu-domain.example.com:2053&lt;br /&gt;
&lt;br /&gt;
auth: EU_HY2_PASSWORD&lt;br /&gt;
&lt;br /&gt;
socks5:&lt;br /&gt;
  listen: 127.0.0.1:10810&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Замени &amp;lt;code&amp;gt;EU_HY2_PASSWORD&amp;lt;/code&amp;gt; на тот же пароль, который указан в &amp;lt;code&amp;gt;server.yaml&amp;lt;/code&amp;gt; EU сервера.&lt;br /&gt;
&lt;br /&gt;
=== 2.7 Конфигурация Docker Compose: docker-compose.yml ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/hysteria-ru/docker-compose.yml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
services:&lt;br /&gt;
  hysteria-ru-server:&lt;br /&gt;
    image: tobyxdd/hysteria:latest&lt;br /&gt;
    container_name: hysteria-ru-server&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    command: server --config /etc/hysteria/server.yaml&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./server.yaml:/etc/hysteria/server.yaml:ro&lt;br /&gt;
      - ./users:/etc/hysteria/users:ro&lt;br /&gt;
      - /var/lib/docker/volumes/caddy-naive_caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/your-hy2-ru-domain.example.com:/etc/hysteria/certs:ro&lt;br /&gt;
&lt;br /&gt;
  hysteria-ru-client:&lt;br /&gt;
    image: tobyxdd/hysteria:latest&lt;br /&gt;
    container_name: hysteria-ru-client&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    network_mode: host&lt;br /&gt;
    command: client --config /etc/hysteria/client.yaml&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./client.yaml:/etc/hysteria/client.yaml:ro&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Критически важные моменты:&#039;&#039;&#039;&lt;br /&gt;
* Директория &amp;lt;code&amp;gt;./users&amp;lt;/code&amp;gt; монтируется в оба контейнера... нет, только в &amp;lt;code&amp;gt;hysteria-ru-server&amp;lt;/code&amp;gt;. Клиентский контейнер видит только свой &amp;lt;code&amp;gt;client.yaml&amp;lt;/code&amp;gt;.&lt;br /&gt;
* При изменении &amp;lt;code&amp;gt;docker-compose.yml&amp;lt;/code&amp;gt; (добавлении volume) нужен пересоздать контейнер: &amp;lt;code&amp;gt;docker compose down &amp;amp;&amp;amp; docker compose up -d&amp;lt;/code&amp;gt;. Простой &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt; не применяет изменения volumes.&lt;br /&gt;
&lt;br /&gt;
=== 2.8 Первый запуск ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/hysteria-ru&lt;br /&gt;
&lt;br /&gt;
# Скачать образ&lt;br /&gt;
docker compose pull&lt;br /&gt;
&lt;br /&gt;
# Запустить оба контейнера&lt;br /&gt;
docker compose up -d&lt;br /&gt;
&lt;br /&gt;
# Подождать и проверить логи&lt;br /&gt;
sleep 3 &amp;amp;&amp;amp; docker compose logs&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hysteria-ru-server  | INFO  server mode&lt;br /&gt;
hysteria-ru-server  | INFO  server up and running  {&amp;quot;listen&amp;quot;: &amp;quot;:2053&amp;quot;}&lt;br /&gt;
hysteria-ru-client  | INFO  client mode&lt;br /&gt;
hysteria-ru-client  | INFO  connected to server  {&amp;quot;udpEnabled&amp;quot;: true, &amp;quot;count&amp;quot;: 1}&lt;br /&gt;
hysteria-ru-client  | INFO  SOCKS5 server listening  {&amp;quot;addr&amp;quot;: &amp;quot;127.0.0.1:10810&amp;quot;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2.9 Проверка цепочки с RU сервера ===&lt;br /&gt;
&lt;br /&gt;
Тест: запустить временный Hysteria2 клиент на RU сервере и проверить, что трафик выходит через WARP (IP Cloudflare):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Создать временный конфиг тест-клиента&lt;br /&gt;
cat &amp;gt; /tmp/hy2-test.yaml &amp;lt;&amp;lt; EOF&lt;br /&gt;
server: 127.0.0.1:2053&lt;br /&gt;
auth: $(awk &#039;NR==1{print $2}&#039; /opt/hysteria-ru/users/users.txt)&lt;br /&gt;
tls:&lt;br /&gt;
  insecure: true&lt;br /&gt;
  sni: your-hy2-ru-domain.example.com&lt;br /&gt;
socks5:&lt;br /&gt;
  listen: 127.0.0.1:11080&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
# Запустить тест-клиент&lt;br /&gt;
docker run -d --name hy2-test --network host \&lt;br /&gt;
  -v /tmp/hy2-test.yaml:/etc/hysteria/client.yaml:ro \&lt;br /&gt;
  tobyxdd/hysteria:latest client --config /etc/hysteria/client.yaml&lt;br /&gt;
&lt;br /&gt;
# Ждать 3 секунды&lt;br /&gt;
sleep 3&lt;br /&gt;
&lt;br /&gt;
# Проверить IP выхода — должен быть Cloudflare WARP IP&lt;br /&gt;
echo &amp;quot;IP через цепочку:&amp;quot;&lt;br /&gt;
curl -s --max-time 15 -x socks5h://127.0.0.1:11080 https://ifconfig.me&lt;br /&gt;
&lt;br /&gt;
# Очистить&lt;br /&gt;
docker rm -f hy2-test&lt;br /&gt;
rm -f /tmp/hy2-test.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если IP вывода принадлежит Cloudflare (начинается с &amp;lt;code&amp;gt;2a09:&amp;lt;/code&amp;gt; для IPv6 или относится к диапазонам WARP) — цепочка RU → EU → WARP работает корректно.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Примечание:&#039;&#039;&#039; параметр &amp;lt;code&amp;gt;insecure: true&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;sni&amp;lt;/code&amp;gt; нужны в тест-клиенте, потому что он подключается по IP (&amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt;), а сертификат выдан на домен. Реальные клиенты подключаются по домену и такие параметры не требуются.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 3: Управление пользователями (hy2-users.sh) ==&lt;br /&gt;
&lt;br /&gt;
=== 3.1 Что это и зачем ===&lt;br /&gt;
&lt;br /&gt;
Для управления пользователями Hysteria2 на RU сервере предназначен скрипт &amp;lt;code&amp;gt;hy2-users.sh&amp;lt;/code&amp;gt;. Он предоставляет интерактивное меню с набором операций над файлом &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Скрипт решает следующие задачи:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Операция !! Описание&lt;br /&gt;
|-&lt;br /&gt;
|| Список пользователей || Показывает всех пользователей из users.txt с маскированными паролями&lt;br /&gt;
|-&lt;br /&gt;
|| Добавить пользователя || Запрашивает имя, автоматически генерирует криптостойкий пароль, сохраняет в users.txt, показывает готовый Hysteria2 URI&lt;br /&gt;
|-&lt;br /&gt;
|| Удалить пользователя || Интерактивный выбор из списка, удаление строки из users.txt&lt;br /&gt;
|-&lt;br /&gt;
|| Показать конфиг || Генерирует и показывает Hysteria2 URI для выбранного пользователя&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Ключевые особенности:&lt;br /&gt;
* &#039;&#039;&#039;Нет перезапуска контейнера.&#039;&#039;&#039; Hysteria2 с &amp;lt;code&amp;gt;auth.type: command&amp;lt;/code&amp;gt; читает файл при каждом подключении — изменения в &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt; применяются мгновенно.&lt;br /&gt;
* &#039;&#039;&#039;Пароли генерируются автоматически&#039;&#039;&#039; через &amp;lt;code&amp;gt;openssl rand&amp;lt;/code&amp;gt; — случайные, криптостойкие.&lt;br /&gt;
* &#039;&#039;&#039;URI формат&#039;&#039;&#039; соответствует стандарту Hysteria2 и принимается всеми клиентами: NekoBox, husi, Exclave, podkop.&lt;br /&gt;
&lt;br /&gt;
=== 3.2 Установка скрипта ===&lt;br /&gt;
&lt;br /&gt;
Скрипт хранится в репозитории по пути &amp;lt;code&amp;gt;scripts/hy2-users.sh&amp;lt;/code&amp;gt;. Установка на сервер:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Скопировать скрипт на сервер&lt;br /&gt;
scp scripts/hy2-users.sh root@YOUR_RU_SERVER_IP:/usr/local/bin/hy2-users.sh&lt;br /&gt;
&lt;br /&gt;
# Сделать исполняемым&lt;br /&gt;
ssh root@YOUR_RU_SERVER_IP &amp;quot;chmod +x /usr/local/bin/hy2-users.sh&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или выполнить непосредственно на RU сервере (если скрипт уже там):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x /usr/local/bin/hy2-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка переменных в начале скрипта.&#039;&#039;&#039; Открой скрипт и убедись, что следующие переменные указывают на правильные значения:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
head -15 /usr/local/bin/hy2-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Должны быть:&lt;br /&gt;
* &amp;lt;code&amp;gt;USERS_FILE=&amp;quot;/opt/hysteria-ru/users/users.txt&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DOMAIN=&amp;quot;your-hy2-ru-domain.example.com&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;PORT=&amp;quot;2053&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если домен указан неверно — исправь:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sed -i &#039;s|DOMAIN=.*|DOMAIN=&amp;quot;your-hy2-ru-domain.example.com&amp;quot;|&#039; /usr/local/bin/hy2-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3.3 Использование ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo bash /usr/local/bin/hy2-users.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скрипт показывает меню:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
┌─────────────────────────────────────────────┐&lt;br /&gt;
│  Hysteria2 — управление пользователями RU   │&lt;br /&gt;
└─────────────────────────────────────────────┘&lt;br /&gt;
&lt;br /&gt;
  1. Список пользователей&lt;br /&gt;
  2. Добавить пользователя&lt;br /&gt;
  3. Удалить пользователя&lt;br /&gt;
  4. Показать конфиг клиента&lt;br /&gt;
&lt;br /&gt;
  0. Выход&lt;br /&gt;
&lt;br /&gt;
Выбери действие:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При добавлении нового пользователя скрипт выводит готовый URI:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hysteria2://СГЕНЕРИРОВАННЫЙ_ПАРОЛЬ@your-hy2-ru-domain.example.com:2053&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот URI вставляется напрямую в клиентское приложение (см. Часть 4).&lt;br /&gt;
&lt;br /&gt;
=== 3.4 Исходный код скрипта ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight:bold; padding:4px 0;&amp;quot;&amp;gt;▶ Показать исходный код hy2-users.sh&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# --- ИСХОДНЫЙ КОД СКРИПТА hy2-users.sh ---&lt;br /&gt;
# (вставить содержимое файла scripts/hy2-users.sh)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 4: Настройка клиентов ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1 Формат URI Hysteria2 ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 использует стандартизированный URI для передачи параметров подключения клиентам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hysteria2://ПАРОЛЬ@ДОМЕН:ПОРТ&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hysteria2://aBcDeFgHiJkLmNoPqRsT@your-hy2-ru-domain.example.com:2053&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
URI можно получить через скрипт &amp;lt;code&amp;gt;hy2-users.sh&amp;lt;/code&amp;gt; (пункт 4 меню — «Показать конфиг клиента»).&lt;br /&gt;
&lt;br /&gt;
=== 4.2 Мобильные клиенты (iOS / Android) ===&lt;br /&gt;
&lt;br /&gt;
Рекомендуемые приложения с нативной поддержкой Hysteria2:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Приложение !! Платформа !! Как импортировать URI&lt;br /&gt;
|-&lt;br /&gt;
|| NekoBox || Android || Главный экран → + → Add → Hysteria2 → вставить URI&lt;br /&gt;
|-&lt;br /&gt;
|| husi || Android || Профили → + → Hysteria2 → вставить URI&lt;br /&gt;
|-&lt;br /&gt;
|| Exclave || iOS || Конфигурации → + → Hysteria2 → вставить URI&lt;br /&gt;
|-&lt;br /&gt;
|| Shadowrocket || iOS || Главная → + → Тип: Hysteria2 → вставить URI&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Все эти приложения принимают URI в формате &amp;lt;code&amp;gt;hysteria2://...&amp;lt;/code&amp;gt; напрямую — через кнопку импорта, QR-код или буфер обмена.&lt;br /&gt;
&lt;br /&gt;
=== 4.3 ПК-клиенты (Windows / macOS / Linux) ===&lt;br /&gt;
&lt;br /&gt;
==== Вариант А: официальный бинарь Hysteria2 ====&lt;br /&gt;
&lt;br /&gt;
Скачать бинарь с официального репозитория: https://github.com/apernet/hysteria/releases&lt;br /&gt;
&lt;br /&gt;
Создать файл конфигурации &amp;lt;code&amp;gt;config.yaml&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
server: your-hy2-ru-domain.example.com:2053&lt;br /&gt;
&lt;br /&gt;
auth: ВАШ_ПАРОЛЬ&lt;br /&gt;
&lt;br /&gt;
socks5:&lt;br /&gt;
  listen: 127.0.0.1:1080&lt;br /&gt;
&lt;br /&gt;
http:&lt;br /&gt;
  listen: 127.0.0.1:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Запустить:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Linux / macOS&lt;br /&gt;
./hysteria client --config config.yaml&lt;br /&gt;
&lt;br /&gt;
# Windows (PowerShell)&lt;br /&gt;
.\hysteria.exe client --config config.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После запуска:&lt;br /&gt;
* SOCKS5 прокси доступен на &amp;lt;code&amp;gt;127.0.0.1:1080&amp;lt;/code&amp;gt;&lt;br /&gt;
* HTTP прокси доступен на &amp;lt;code&amp;gt;127.0.0.1:8080&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Вариант Б: через NekoRay / Hiddify Next (Windows / Linux) ====&lt;br /&gt;
&lt;br /&gt;
Приложения NekoRay и Hiddify Next принимают Hysteria2 URI — импорт через меню или буфер обмена. Автоматически управляют запуском клиентского процесса.&lt;br /&gt;
&lt;br /&gt;
=== 4.4 OpenWrt / podkop ===&lt;br /&gt;
&lt;br /&gt;
podkop (реализация на базе sing-box) нативно поддерживает Hysteria2 URI. Никакой дополнительной установки бинарей не требуется.&lt;br /&gt;
&lt;br /&gt;
В интерфейсе podkop (LuCI → Network → podkop → Outbound):&lt;br /&gt;
* Тип: &amp;lt;code&amp;gt;Hysteria2&amp;lt;/code&amp;gt;&lt;br /&gt;
* URI: &amp;lt;code&amp;gt;hysteria2://ПАРОЛЬ@your-hy2-ru-domain.example.com:2053&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или через UCI:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
uci set podkop.main.proxy=&#039;hysteria2://ПАРОЛЬ@your-hy2-ru-domain.example.com:2053&#039;&lt;br /&gt;
uci commit podkop&lt;br /&gt;
/etc/init.d/podkop restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После сохранения все устройства домашней сети автоматически получают обход без дополнительной настройки.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 5: Проверка всей цепочки ==&lt;br /&gt;
&lt;br /&gt;
=== 5.1 Тест RU сервера: цепочка RU → EU → WARP ===&lt;br /&gt;
&lt;br /&gt;
Выполнить на RU сервере — проверяет, что трафик выходит через WARP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# SOCKS5 порт 10810 — это точка выхода RU клиента (= вход в EU сервер → WARP)&lt;br /&gt;
curl -s --max-time 20 -x socks5h://127.0.0.1:10810 https://ifconfig.me&lt;br /&gt;
echo &amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результат должен быть &#039;&#039;&#039;IP Cloudflare WARP&#039;&#039;&#039; — например, начинается с &amp;lt;code&amp;gt;2a09:&amp;lt;/code&amp;gt; (IPv6) или принадлежит AS13335 (Cloudflare).&lt;br /&gt;
&lt;br /&gt;
Проверить AS:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
IP=$(curl -s --max-time 20 -x socks5h://127.0.0.1:10810 https://ifconfig.me)&lt;br /&gt;
curl -s &amp;quot;https://ipinfo.io/${IP}/org&amp;quot;&lt;br /&gt;
echo &amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ожидаемый вывод: строка содержит &amp;lt;code&amp;gt;Cloudflare&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 5.2 Тест с реального клиента ===&lt;br /&gt;
&lt;br /&gt;
После добавления пользователя через &amp;lt;code&amp;gt;hy2-users.sh&amp;lt;/code&amp;gt; и получения URI:&lt;br /&gt;
&lt;br /&gt;
# Вставь URI в клиентское приложение (NekoBox, husi, Shadowrocket).&lt;br /&gt;
# Активируй профиль.&lt;br /&gt;
# Открой &amp;lt;code&amp;gt;https://ifconfig.me&amp;lt;/code&amp;gt; в браузере — должен отображаться IP Cloudflare WARP.&lt;br /&gt;
# Открой &amp;lt;code&amp;gt;https://www.whatismybrowser.com/detect/what-is-my-ip-address&amp;lt;/code&amp;gt; для проверки отсутствия WebRTC утечки.&lt;br /&gt;
&lt;br /&gt;
=== 5.3 Диагностика проблем ===&lt;br /&gt;
&lt;br /&gt;
==== Проблема: hysteria-eu не запускается — ошибка TLS ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/hysteria-eu/docker-compose.yml logs hysteria-eu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Возможные причины:&lt;br /&gt;
* Путь к сертификату неверен → проверь &amp;lt;code&amp;gt;ls&amp;lt;/code&amp;gt; по пути, указанному в volumes.&lt;br /&gt;
* Сертификат ещё не был получен Caddy → проверь, что caddy-naive запущен и прошёл ACME-проверку.&lt;br /&gt;
* Caddy хранит сертификат под другим именем → выполни &amp;lt;code&amp;gt;find /var/lib/docker/volumes/caddy-naive_caddy_data/_data -name &amp;quot;*.crt&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Проблема: hysteria-ru-server выдаёт auth error ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/hysteria-ru/docker-compose.yml logs hysteria-ru-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверить вручную (на RU сервере):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Проверить, что скрипт находится на месте внутри контейнера&lt;br /&gt;
docker exec hysteria-ru-server ls -la /etc/hysteria/users/&lt;br /&gt;
&lt;br /&gt;
# Запустить скрипт вручную с тестовым паролем&lt;br /&gt;
docker exec hysteria-ru-server /etc/hysteria/users/check-auth.sh addr ТЕСТОВЫЙ_ПАРОЛЬ 0&lt;br /&gt;
echo &amp;quot;Exit code: $?&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;code&amp;gt;Exit code: 0&amp;lt;/code&amp;gt; — скрипт работает. Если &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; — пароль не найден в &amp;lt;code&amp;gt;users.txt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Проблема: hysteria-ru-client не подключается к EU ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose -f /opt/hysteria-ru/docker-compose.yml logs hysteria-ru-client&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Возможные причины:&lt;br /&gt;
* &amp;lt;code&amp;gt;EU_HY2_PASSWORD&amp;lt;/code&amp;gt; в &amp;lt;code&amp;gt;client.yaml&amp;lt;/code&amp;gt; не совпадает с паролем в EU &amp;lt;code&amp;gt;server.yaml&amp;lt;/code&amp;gt;.&lt;br /&gt;
* UDP порт 2053 заблокирован на EU сервере (firewall) → проверь &amp;lt;code&amp;gt;ss -ulnp | grep 2053&amp;lt;/code&amp;gt; на EU сервере.&lt;br /&gt;
* EU сервер ещё не запущен.&lt;br /&gt;
&lt;br /&gt;
==== Проблема: ACL ошибка при запуске ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FATAL failed to load server config: invalid config: acl.inline: invalid syntax at line 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неверный синтаксис ACL. Правильный формат: &amp;lt;code&amp;gt;&amp;quot;outbound_name(address)&amp;quot;&amp;lt;/code&amp;gt;:&lt;br /&gt;
* ✅ &amp;lt;code&amp;gt;&amp;quot;warp(all)&amp;quot;&amp;lt;/code&amp;gt; — направить всё в outbound &amp;quot;warp&amp;quot;&lt;br /&gt;
* ✅ &amp;lt;code&amp;gt;&amp;quot;chain(all)&amp;quot;&amp;lt;/code&amp;gt; — направить всё в outbound &amp;quot;chain&amp;quot;&lt;br /&gt;
* ❌ &amp;lt;code&amp;gt;&amp;quot;outbound(warp) all&amp;quot;&amp;lt;/code&amp;gt; — неверно&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Часть 6: Обслуживание ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1 Управление контейнерами ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# EU сервер&lt;br /&gt;
cd /opt/hysteria-eu&lt;br /&gt;
docker compose up -d         # запустить&lt;br /&gt;
docker compose down          # остановить&lt;br /&gt;
docker compose restart       # перезапустить&lt;br /&gt;
docker compose logs -f       # следить за логами в реальном времени&lt;br /&gt;
docker compose ps            # статус&lt;br /&gt;
&lt;br /&gt;
# RU сервер (оба контейнера)&lt;br /&gt;
cd /opt/hysteria-ru&lt;br /&gt;
docker compose up -d&lt;br /&gt;
docker compose down&lt;br /&gt;
docker compose restart&lt;br /&gt;
docker compose logs -f&lt;br /&gt;
&lt;br /&gt;
# RU сервер (по отдельности)&lt;br /&gt;
docker compose restart hysteria-ru-server   # только сервер&lt;br /&gt;
docker compose restart hysteria-ru-client   # только клиент&lt;br /&gt;
docker compose logs -f hysteria-ru-server   # логи только сервера&lt;br /&gt;
docker compose logs -f hysteria-ru-client   # логи только клиента&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 6.2 Обновление сертификатов ===&lt;br /&gt;
&lt;br /&gt;
TLS-сертификаты обновляются Caddy автоматически (за 30 дней до истечения). После автообновления Hysteria2 начнёт использовать новый сертификат при следующем перезапуске.&lt;br /&gt;
&lt;br /&gt;
Для принудительного применения нового сертификата:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# EU сервер&lt;br /&gt;
cd /opt/hysteria-eu &amp;amp;&amp;amp; docker compose restart&lt;br /&gt;
&lt;br /&gt;
# RU сервер&lt;br /&gt;
cd /opt/hysteria-ru &amp;amp;&amp;amp; docker compose restart hysteria-ru-server&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверить дату истечения текущего сертификата:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# EU сервер&lt;br /&gt;
DOMAIN=&amp;quot;your-hy2-eu-domain.example.com&amp;quot;&lt;br /&gt;
CERT=&amp;quot;/var/lib/docker/volumes/caddy-naive_caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${DOMAIN}/${DOMAIN}.crt&amp;quot;&lt;br /&gt;
openssl x509 -in &amp;quot;${CERT}&amp;quot; -noout -enddate&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 6.3 Обновление Docker-образа ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 активно развивается. Для обновления до последней версии:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# EU сервер&lt;br /&gt;
cd /opt/hysteria-eu&lt;br /&gt;
docker compose pull           # скачать новый образ&lt;br /&gt;
docker compose up -d          # перезапустить с новым образом&lt;br /&gt;
docker compose logs --tail=5  # проверить старт&lt;br /&gt;
&lt;br /&gt;
# RU сервер&lt;br /&gt;
cd /opt/hysteria-ru&lt;br /&gt;
docker compose pull&lt;br /&gt;
docker compose up -d&lt;br /&gt;
docker compose logs --tail=5&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Старые неиспользуемые образы можно удалить:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker image prune -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 6.4 Мониторинг логов ===&lt;br /&gt;
&lt;br /&gt;
Hysteria2 пишет структурированные JSON-логи. Полезные паттерны для мониторинга:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Смотреть все подключения на RU сервере&lt;br /&gt;
docker logs hysteria-ru-server 2&amp;gt;&amp;amp;1 | grep -E &amp;quot;connected|disconnected|auth&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Смотреть ошибки&lt;br /&gt;
docker logs hysteria-ru-server 2&amp;gt;&amp;amp;1 | grep -i &amp;quot;error\|fatal\|warn&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Считать количество уникальных пользователей (поле &amp;quot;id&amp;quot;)&lt;br /&gt;
docker logs hysteria-ru-server 2&amp;gt;&amp;amp;1 | grep &#039;&amp;quot;id&amp;quot;&#039; | grep -oP &#039;&amp;quot;id&amp;quot;: &amp;quot;\K[^&amp;quot;]+&#039; | sort -u&lt;br /&gt;
&lt;br /&gt;
# Следить за логами EU сервера в реальном времени&lt;br /&gt;
docker logs -f hysteria-eu 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример нормального лога RU сервера при входящем подключении:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
INFO  client connected     {&amp;quot;addr&amp;quot;: &amp;quot;CLIENT_IP:PORT&amp;quot;, &amp;quot;id&amp;quot;: &amp;quot;username&amp;quot;}&lt;br /&gt;
INFO  TCP request          {&amp;quot;addr&amp;quot;: &amp;quot;CLIENT_IP:PORT&amp;quot;, &amp;quot;id&amp;quot;: &amp;quot;username&amp;quot;, &amp;quot;reqAddr&amp;quot;: &amp;quot;example.com:443&amp;quot;}&lt;br /&gt;
INFO  client disconnected  {&amp;quot;addr&amp;quot;: &amp;quot;CLIENT_IP:PORT&amp;quot;, &amp;quot;id&amp;quot;: &amp;quot;username&amp;quot;, &amp;quot;error&amp;quot;: &amp;quot;...&amp;quot;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Поле &amp;lt;code&amp;gt;&amp;quot;id&amp;quot;&amp;lt;/code&amp;gt; — это имя пользователя, возвращённое скриптом &amp;lt;code&amp;gt;check-auth.sh&amp;lt;/code&amp;gt;. Это позволяет отслеживать активность конкретных пользователей в логах без хранения паролей.&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
	<entry>
		<id>https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Hysteria2-chain-traffic-flow.png&amp;diff=955</id>
		<title>Файл:Hysteria2-chain-traffic-flow.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.mywolfram.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Hysteria2-chain-traffic-flow.png&amp;diff=955"/>
		<updated>2026-04-26T10:00:57Z</updated>

		<summary type="html">&lt;p&gt;Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Владимир</name></author>
	</entry>
</feed>