# Keenetic DNS Routes Один список доменов в браузере — и он уезжает на все твои Keenetic сразу. Без HydraRoute Neo, без SSH: только встроенные **«Маршруты DNS»** и RCI API. > **Поддержать проект:** [Boosty](https://boosty.to/andrey27/donate) · [СБП / Ozon Bank](https://finance.ozon.ru/apps/sbp/ozonbankpay/019dc200-2a5d-7931-a619-782d285f6798) · Telegram: [@PCAdministration](https://t.me/PCAdministration) --- ## 1. Зачем это нужно На Keenetic можно отправить, скажем, YouTube и Netflix через VPN, а остальное — мимо. В веб-морде роутера домены добавляются по одному; на пяти роутерах это быстро надоедает. Здесь ты правишь **US** и **RU** списки на VPS, жмёшь «Применить» — и все роутеры получают одинаковый набор. ``` ┌───────────────────────────────┐ │ Браузер → http://VPS:8001 │ ← ты работаешь здесь └──────────────┬────────────────┘ │ API ┌──────────────▼────────────────┐ │ keenetic-dns-routes на VPS │ ← этот сервис └──────────┬──────────┬─────────┘ │ RCI │ RCI ┌──────▼──┐ ┌────▼──────┐ │Роутер 1 │ │ Роутер 2 │ ← роутеры дома └─────────┘ └───────────┘ ``` **Что умеет:** - Два независимых списка доменов/IP: **US** (под VPN) и **RU** (локальный трафик, если нужен второй туннель). - Применяет списки сразу на несколько роутеров одной кнопкой. - Для роутеров **без белого IP** (за провайдерским NAT) — встроенный мастер настройки обратного туннеля. - Не требует Neo / HydraRoute — только встроенная DNS-маршрутизация KeeneticOS. **Требования к роутеру:** - KeeneticOS **5.0.1** или новее. - Включены: **KeenDNS** + **HTTP Proxy для API** (порт 79). - У пользователя роутера есть права на HTTP Proxy. --- ## 2. Быстрая установка Вставляй команды по одной на сервере (VPS), где будет работать панель. ### Шаг 1 — клонируй и запусти установщик ```bash git clone https://github.com/andrey271192/keenetic-dns-routes.git /opt/keenetic-dns-routes cd /opt/keenetic-dns-routes sudo bash install.sh ``` Установщик сам создаст Python-окружение, пропишет systemd-сервис и запустит его. ### Шаг 2 — задай пароль и адрес VPS ```bash nano /opt/keenetic-dns-routes/.env ``` Минимум что нужно поменять: ``` ADMIN_PASSWORD=твой-пароль-для-панели # Если у всех роутеров одинаковый логин/пароль Keenetic: KEENETIC_LOGIN=admin KEENETIC_PASSWORD=пароль-роутера ``` Если планируешь использовать **туннель** (для роутеров без белого IP) — добавь сюда же: ``` VPS_SSH_HOST=IP_или_домен_твоего_VPS ``` Остальные поля туннеля — см. раздел 3. ### Шаг 3 — перезапусти сервис ```bash sudo systemctl restart keenetic-dns-routes ``` ### Шаг 4 — открой панель ``` http://IP_ТВОЕГО_VPS:8001 ``` Введи пароль из `ADMIN_PASSWORD`. ### Обновление ```bash cd /opt/keenetic-dns-routes && sudo bash update.sh ``` ### Удаление ```bash curl -fsSL https://raw.githubusercontent.com/andrey271192/keenetic-dns-routes/main/uninstall.sh | sudo bash ``` --- ## 3. Туннель — для роутеров без белого IP ### Что такое «белый IP» и почему он нужен Обычно сервис (VPS) подключается к роутеру напрямую по сети. Для этого нужно знать IP-адрес роутера, и он должен быть **публичным** («белым») — то есть доступным из интернета. Если твой провайдер выдаёт **серый IP** (роутер за NAT оператора — очень частая ситуация в России), то с VPS до роутера «достучаться» невозможно. Роутер сам должен инициировать соединение. ### Как работает туннель Роутер сам устанавливает зашифрованное SSH-соединение на VPS и говорит ему: «слушай у себя порт 20100 — всё что придёт туда, перешли мне на порт 81». ``` Роутер (серый IP) ──SSH──▶ VPS :20100 │ VPS → keenetic-dns-routes ──────▶│──▶ Порт 81 роутера (RCI API) ``` В итоге сервис обращается не напрямую к роутеру, а к `localhost:20100` на самом же VPS — и это работает даже если у роутера серый IP. ### Что понадобится - Публичный IP/домен VPS (он у тебя уже есть, раз ставишь сервис). - SSH-доступ к VPS (тоже есть). - Роутер с установленным **Entware** (нужен для `autossh`). ### Установка Entware на роутер > Entware — пакетный менеджер для роутеров, позволяет устанавливать дополнительные программы. С KeeneticOS 4.2+ можно прямо через браузер: открой `192.168.1.1/a` и следуй инструкциям. Или через SSH на роутере (логин `root`, пароль `keenetic`, порт 22): ```sh # Определи свою архитектуру: # MT7628/MT7621 → mipsel: opkg disk storage:/ https://bin.entware.net/mipselsf-k3.4/installer/mipsel-installer.tar.gz # MT7622/MT7981/MT7988 (ARM) → aarch64: opkg disk storage:/ https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz ``` Дождись окончания (~2 минуты), потом проверь: `opkg update` должен отработать без ошибок. ### Шаг 1 — настрой .env на VPS ```bash nano /opt/keenetic-dns-routes/.env ``` Добавь или заполни строки: ``` VPS_SSH_HOST=IP_или_домен_VPS # публичный адрес, куда роутер будет коннектиться VPS_SSH_PORT=22 # SSH-порт VPS (обычно 22) VPS_SSH_USER=root # пользователь VPS ``` `VPS_SSH_PASS` оставь **пустым** — туннель использует SSH-ключи, пароль не нужен. Перезапусти сервис: ```bash sudo systemctl restart keenetic-dns-routes ``` ### Шаг 2 — добавь роутер в панель Открой `http://VPS:8001`. Нажми кнопку **«⇄ Тоннель»** рядом с «+ Добавить». Введи имя роутера и пароль веб-интерфейса роутера (для Keenetic API). Нажми **«Создать»**. > Если кнопки «⇄ Тоннель» нет — проверь, что `VPS_SSH_HOST` в `.env` не пустой и сервис перезапущен. ### Шаг 3 — скопируй и выполни команду на роутере В открывшемся окне ты увидишь одну команду вида: ``` curl -fsS 'http://VPS:8001/api/routers/abc/tunnel-script?token=XXX' | sh ``` Нажми кнопку **«Скопировать»** (если не сработала — выдели текст и Cmd/Ctrl+C). Открой SSH-сессию на **роутер** (не на VPS!) и вставь команду. > **Как отличить терминал роутера от VPS:** > - Роутер: приглашение выглядит как `~ #` или `(none) ~ #` > - VPS: выглядит как `root@имя-сервера:~#` > > Команда для роутера — это та, что начинается с `curl -fsS`. Её надо вводить там, где `~ #`. Скрипт автоматически: 1. Установит `autossh` через opkg. 2. Запишет SSH-ключ в `/opt/etc/kdns_tk`. 3. Создаст скрипт тоннеля `/opt/bin/kdns_tun`. 4. Пропишет автозапуск при старте роутера. 5. Запустит туннель в фоне. В конце ты увидишь: ``` === OK === Тоннель: localhost:81 (роутер) -> VPS:20100 ``` ### Шаг 4 — проверь связь Вернись в браузер и нажми кнопку **«⟳ Проверить связь»** в окне туннеля. Если всё хорошо — статус изменится на «Активен». После этого можно нажать «Применить маршруты». ### Ручной запуск и диагностика Если автоматический запуск не сработал (написало «ОШИБКА»): ```sh # На роутере — запусти туннель вручную (ты увидишь вывод): /opt/bin/kdns_tun # Если работает вручную, но не в фоне — запусти через init.d: /opt/etc/init.d/S99kdns_tun restart # Проверить лог: cat /tmp/kdns_tun.log # Перезапустить автоматически: killall autossh 2>/dev/null; sleep 1; /opt/etc/init.d/S99kdns_tun start ``` Если `/opt/bin/kdns_tun` работает вручную — туннель настроен правильно, вопрос только в фоновом запуске. Попробуй перезагрузить роутер — при старте Entware сам запустит `/opt/etc/init.d/S99kdns_tun start`. ### Проверка на VPS На VPS можно посмотреть, слушается ли порт туннеля: ```bash ss -tlnp | grep 20100 ``` Должна быть строка с `127.0.0.1:20100`. Если есть — туннель работает. --- ## 4. Логины и пароли Здесь два совершенно разных набора учётных данных. Не перепутай. ### Пароль веб-панели (`ADMIN_PASSWORD`) Это пароль для входа на `http://VPS:8001`. Задаётся один раз в `.env` на VPS. Никак не связан с паролями роутеров. ``` ADMIN_PASSWORD=твой-секретный-пароль ``` ### Логин/пароль Keenetic (для RCI API) Это логин и пароль **веб-интерфейса роутера** (`192.168.1.1`). Нужны сервису для того, чтобы применять маршруты через RCI API. **Вариант 1 — один дефолт для всех роутеров** (удобно, если у всех один и тот же): ``` KEENETIC_LOGIN=admin KEENETIC_PASSWORD=пароль-от-192.168.1.1 ``` **Вариант 2 — у каждого роутера свой** (заполняется в веб-панели при добавлении роутера): - Поле «Логин» и «Пароль» в форме добавления роутера. - Или URL вида `http://логин:пароль@rci.ваш-роутер.keenetic.pro:79`. **Вариант 3 — прямо в URL** (если вставил URL с `логин:пароль@` — сервис сам перенесёт это в поля): ``` http://admin:пароль@rci.xxx.keenetic.pro:79 ``` Приоритет (что важнее): поля роутера → user:pass@ в URL → `.env` дефолт. ### SSH-ключи для туннеля Это отдельная история, и **тебе ничего делать не нужно**. Ключи генерируются автоматически на VPS при нажатии кнопки «⇄ Тоннель». Приватный ключ уходит на роутер через одноразовую ссылку (действует 10 минут). Публичный ключ добавляется в `~/.ssh/authorized_keys` на VPS. Никакого пароля SSH нет. --- ## 5. Как добавлять маршруты ### Где настроить интерфейс (куда направлять трафик) В панели вверху есть поля **Interface ID** для групп US и RU. Это имя VPN-туннеля на роутере, через который пойдёт трафик: `Wireguard0`, `PPPoE0`, `SSTP0` и т.д. Нажми **«Сканировать…»** рядом с полем — панель сама загрузит список интерфейсов с роутера. Или включи «Только WireGuard» чтобы видеть только VPN-туннели. ### Как добавить домены В большие текстовые поля вводи по одному на строке: ``` youtube.com netflix.com spotify.com # комментарий — эти строки игнорируются 1.2.3.4 192.168.100.0/24 ``` Поддерживаются: домены, IP-адреса, CIDR-подсети. Пустые строки и строки с `#` игнорируются. > **Лимит:** Keenetic держит примерно **~300 доменов** в одном списке. Если превысишь — роутер вернёт ошибку. ### Применение - **«Сохранить на сервер»** — сохраняет список только на VPS (не применяет на роутеры). - **«Применить на всех»** — применяет на все роутеры сразу. - Чтобы применить только на некоторые — поставь галочки у нужных роутеров и нажми **«Только на выбранных»**. При применении сервис делает «умный дифф»: добавляет только новые домены, удаляет убранные, не трогает остальные. В конце отправляет `system configuration save`. --- ## 6. Частые ошибки и решения ### `Connection refused` при применении маршрутов **Причина:** RCI API роутера недоступен с VPS. **Что проверить:** 1. В Keenetic включён **HTTP Proxy для API** — порт **79** (не 81, не 80). 2. У пользователя роутера есть права на HTTP Proxy (в веб-интерфейсе роутера → «Управление» → «Пользователи»). 3. Правильный URL прокси: `http://rci.твой.keenetic.pro:79` (или аналогичный). ### Туннель пишет «autossh не запустился в фоне» **Причина:** BusyBox на роутере не полностью «отвязывает» фоновый процесс от терминала. **Решение:** ```sh # На роутере — проверь вручную: /opt/bin/kdns_tun # Если работает (есть вывод и не падает с ошибкой) — перезагрузи роутер. # После перезагрузки Entware сам запустит туннель через init.d. ``` Если падает и вручную — смотри лог: ```sh cat /tmp/kdns_tun.log ``` Там будет конкретная ошибка SSH. ### `Host key verification failed` в логе autossh **Причина:** Старый ключ VPS не совпадает с сохранённым. **Решение:** Скрипт уже ставит `-o StrictHostKeyChecking=no` — этой ошибки быть не должно. Если всё же есть: ```sh rm /opt/etc/ssh/ssh_known_hosts 2>/dev/null; /opt/bin/kdns_tun ``` ### Кнопка «Скопировать» не работает **Причина:** `navigator.clipboard` требует HTTPS. Панель работает по HTTP. **Решение встроено:** при ошибке кнопка автоматически выделяет текст — просто нажми Cmd+C (Mac) или Ctrl+C (Windows/Linux). ### Токен истёк (10 мин) **Причина:** Одноразовая ссылка для установки туннеля действует 10 минут. **Решение:** Нажми «Получить команду» заново — сформируется новая ссылка. ### `opkg: не найдена команда` на роутере **Причина:** Entware не установлен или не инициализирован. **Решение:** Установи Entware (см. раздел 3), дождись окончания и выполни `opkg update`. ### Панель не открывается (`http://VPS:8001`) **Причина:** Порт заблокирован файрволом VPS. **Решение:** ```bash # На VPS: sudo ufw allow 8001/tcp # или через iptables, в зависимости от дистрибутива ``` --- ## 7. Полезные советы **Как зайти на роутер по SSH:** ``` Адрес: 192.168.1.1 (или IP роутера в сети) Логин: root Пароль: keenetic (стандартный, если не менял) Порт: 222 (в некоторых моделях вместо 22) ``` Используй Termius, PuTTY или команду `ssh root@192.168.1.1` в терминале. **Сервис запускается автоматически при старте VPS** — systemd следит за ним. Если упал: ```bash sudo systemctl status keenetic-dns-routes # посмотреть состояние sudo systemctl restart keenetic-dns-routes # перезапустить sudo journalctl -u keenetic-dns-routes -n 50 # последние 50 строк лога ``` **Обновить сервис:** ```bash cd /opt/keenetic-dns-routes && sudo bash update.sh ``` **Проверить, что туннельный порт слушается на VPS:** ```bash ss -tlnp | grep 20100 ``` **Применять маршруты по расписанию** (через cron на VPS): ```bash crontab -e # Добавь строку — применять каждую ночь в 3:00: 0 3 * * * curl -s -X POST http://localhost:8001/api/apply \ -H "X-Admin-Password: твой-пароль" \ -H "Content-Type: application/json" \ -d '{"mode":"all"}' ``` **Список доменов через API** (без браузера): ```bash # Получить текущий список US: curl -s http://localhost:8001/api/data \ -H "X-Admin-Password: твой-пароль" | python3 -m json.tool # Добавить домен в список US: curl -s -X POST http://localhost:8001/api/groups/US/lines \ -H "X-Admin-Password: твой-пароль" \ -H "Content-Type: application/json" \ -d '{"add":["newdomain.com"],"remove":[]}' ``` --- ## Что изменено в репозитории (кратко) | Файл | Что добавлено / исправлено | |------|---------------------------| | `app/main.py` | Генерация ed25519-keypair на VPS через `ssh-keygen`; добавление pubkey в `~/.ssh/authorized_keys`; эндпоинты `/tunnel-cmd`, `/tunnel-script` (одноразовый токен, 10 мин), `/tunnel-status` (проверка порта), `DELETE /tunnel` | | `app/config.py` | Переменные `VPS_SSH_HOST`, `VPS_SSH_PORT`, `VPS_SSH_USER`, `VPS_SSH_PASS`, `TUNNEL_PORT_START` | | `.env.example` | Секция `Reverse SSH tunnel` с объяснениями | | `templates/index.html` | Кнопка «⇄ Тоннель» рядом с «+ Добавить»; модалка с curl-командой; кнопка «⟳ Проверить связь»; fallback-копирование (execCommand) для HTTP без HTTPS | | `tunnel/kssh-tun` | Отдельный скрипт управления WireGuard-пирами на VPS-стороне (для альтернативной WG-топологии) | **Что было исправлено в процессе разработки:** - `sshpass` и `cronie` недоступны в Entware aarch64-k3.10 → заменены на keypair-аутентификацию и `init.d`-автозапуск. - `openssh-keygen` нет на роутере → генерация keypair перенесена на VPS. - `navigator.clipboard` не работает по HTTP → fallback через `execCommand('copy')`. - autossh умирал при фоновом запуске → добавлены `AUTOSSH_GATETIME=0`, `