Skip to content

Несколько доработок: резервная политика XKeenFull, расширенное предупреждение по DNS, закрепление yq#32

Closed
kittylabassistant wants to merge 19 commits into
jameszeroX:mainfrom
kittylabassistant:main

Conversation

@kittylabassistant
Copy link
Copy Markdown

Мелкие правки, каждая закрывает открытый/закрытый issue. Коммиты атомарны — можно принимать выборочно. Изменения протестированы на mipsle (KN-2910) и arm64 (KN-3811) с ядрами xray и mihomo.


1. Резервная политика XKeenFull + предупреждение о CPU — closes #17

Проблема. Сейчас для полного проксирования клиента требуется либо оставлять port_proxying.lst пустым (тогда проксируется всё у всех клиентов политики xkeen), либо ручками писать пользовательскую политику в xkeen.json. Для use-case «полностью прокси для одного устройства» оба варианта неудобны.

Решение. Добавлено зарезервированное имя политики XKeenFull (переменная name_policy_full в S05xkeen, по умолчанию XKeenFull). Если пользователь создаёт в веб-интерфейсе Keenetic политику с этим именем и назначает туда клиентов, они автоматически проксируются на всех портах — без правок xkeen.json. Работает одновременно с базовой политикой xkeen и пользовательскими политиками.

Реализовано переиспользованием существующего механизма resolve_user_policies() + итерации по $user_policies в configure_firewall(): XKeenFull вкрывается в поток как виртуальная запись XKeenFull|<mark>|all|. Новых ipt-веток не появилось.

При активном полном проксировании (пустая xkeen, XKeenFull, или пользовательская политика в режиме all) XKeen выводит предупреждение о повышенной нагрузке на CPU в консоль и syslog (logread -t | grep XKeen). Не блокирующее — просто информационное.

Защита от конфликта имён: check_policy_name_conflict() расширена — если пользователь попытается завести политику с именем XKeenFull в xkeen.json, старт прерывается с понятной ошибкой.

Файлы:

  • scripts/_xkeen/02_install/07_install_register/04_register_init.sh — функции get_policy_mark_full, warn_full_proxy_cpu, расширения print_policy_info / check_policy_name_conflict / proxy_start, переменная
    name_policy_full
  • scripts/_xkeen/02_install/07_install_register/02_register_xkeen.sh:50name_policy_full добавлен в variables_to_extract, чтобы пользовательское переопределение переживало обновления XKeen

2. Предупреждение о несовместимости перехвата DNS с модулями фильтрации — addresses #19

Проблема. Связка «перехват DNS XKeen + модуль фильтрации Keenetic (NextDNS/SafeDNS/AdGuard DNS)» работает нестабильно: перехват на iptables PREROUTING уводит DNS-пакеты в прокси раньше, чем их обрабатывает модуль. Несколько пользователей в #19 столкнулись с этим; рабочий обходной путь — включить «Разрешить транзит запросов» в настройках модуля, либо использовать сервис как обычный DoH/DoT, либо xkeen -dns off.

Решение. Расширена существующая функция warn_proxy_dns() (она уже предупреждает про DNS-Based Routes KeeneticOS 5+). Добавлен абзац про модули фильтрации DNS с указанием трёх вариантов решения. Кода в рантайме не добавлено — XKeen не может надёжно отличить активный NextDNS-модуль от обычного DNS, поэтому ограничились предупреждением при xkeen -dns on.

Сопутствующе в configuration.md добавлен раздел «Перехват DNS и модули фильтрации Keenetic» с тремя опциями (транзит / DoH-DoT / отключить перехват) и указанием, что те же варианты применимы к DNS-Based Routes.

Файлы:

  • scripts/_xkeen/04_tools/05_tools_choice/02_choice_xkeen.sh:181-195 — расширение warn_proxy_dns
  • configuration.md — новый раздел

3. Заметка про #20 (DNS-маршруты в политике по умолчанию) — already fixed

Upstream-фикс #20 (коммит 27619b9) закомментировал iptables -I PREROUTING 1 -j CONNMARK --restore-mark. Форк levmnkv/XKeen исторически не ставит эту метку глобально в PREROUTINGCONNMARK --restore-mark применяется только внутри $name_chain, куда попадает лишь проксируемый трафик (не клиенты default-политики). Так что баг #20 здесь не воспроизводился и в нашем коде.


4. Закрепление тега yq и post-download self-test — closes #23

Проблема. releases/latest/download форка jameszeroX/yq прокатывается через latest, которое может дрейфовать. Плюс upstream mikefarah/yq 4.52.4 сегфолтится на mipsle
(mikefarah/yq#2609), а детекция этой ситуации в инсталляторе отсутствует: скачивание завершается «успешно», а при старте Mihomo получаем mode_proxy=Other и молчаливое отсутствие прозрачного прокси — та самая симптоматика #23.

Пин через фиксированный тег предлагался в #23 самим автором ишью. Альтернатива — миграция на tomwright/dasel — рассмотрена и отвергнута: за всю историю dasel (99 релизов) ни одного MIPS/MIPSLE бинарника не публиковалось, миграция убила бы поддержку Mediatek-линейки Keenetic (~половина юзербазы).

Решение.

(a) Вводится переменная yq_workaround_tag="260312". URL рабочего yq собирается как https://github.com/jameszeroX/yq/releases/download/$yq_workaround_tag/... вместо releases/latest/download/.... Тумблер
yq_use_workaround="false" по-прежнему возвращает к upstream mikefarah/yq/releases/latest.

(b) В 01_downloaders_mihomo.sh добавлен post-download smoke-test yq -V. Если бинарь не запускается (сегфолт от регрессии upstream или неправильная архитектура при OffLine-установке), инсталлятор прерывается с понятной ошибкой
и ссылкой на mikefarah/yq#2609. Аналогичный чек добавлен в fallback-ветку, использующую уже установленный yq.

(c) Синхронизирован корневой 01_info_variable.sh со скриптовой версией: текущий install.sh:74 поверх свежераспакованного файла накатывает корневой из main, и до правки корневой не содержал get_yq_dist_url()
mihomo-загрузчик получал пустой URL.

Файлы:

  • 01_info_variable.sh — синхронизация + пин
  • scripts/_xkeen/01_info/01_info_variable.sh:78-92 — пин + переменная yq_workaround_tag
  • scripts/_xkeen/04_tools/07_tools_downloaders/01_downloaders_mihomo.sh:199-233 — self-test в двух ветках (свежая загрузка + fallback на установленный)

Test plan

  • sh -n на всех изменённых скриптах — OK
  • Синтетические jq-тесты для get_policy_mark_full и check_policy_name_conflict на искусственном api_policy_json — возвращают ожидаемые метки / конфликты
  • HEAD 200 на https://github.com/jameszeroX/yq/releases/download/260312/yq_linux_{arm64,mips,mipsle} — все три ассета на месте
  • Смоук-тест self-test'а: искусственный битый бинарник exit 1 корректно отвергается, ветка ошибки печатается
  • KN-3811 (arm64, TProxy, xray): создана политика XKeenFull, назначено устройство, xkeen -restart → в терминале жёлтое предупреждение Активен режим полного проксирования, в logread аналогичный warning; iptables -t mangle -S PREROUTING | grep <mark> показывает правило с -j xkeen без multiport; устройство проксируется на произвольных портах
  • KN-2910 (mipsle, Hybrid, mihomo): установка с нуля через install.sh, выбор mihomo — Yq успешно загружен и установлен, mode_proxy=TProxy, yq -V возвращает v4.52.2
  • Негативный тест на KN-2910: вручную подменён /opt/sbin/yq на yq_linux_arm64xkeen -rm валится с ошибкой «Yq не запускается», ссылка на #2609 присутствует
  • Регрессия: политика «Без доступа в интернет» при активных xkeen и XKeenFull — клиенты без интернета штатно не получают интернет; xkeen -dns on показывает оба предупреждения (DNS-маршрутизация + модули фильтрации)

Что НЕ вошло

  • Миграция yq → dasel — отвергнута (отсутствуют MIPS-бинарники, см. секцию 4)
  • Зеркалирование yq-бинарников в собственные релизы — избыточно, пока jameszeroX/yq жив; пин на тег даёт достаточный детерминизм

Документация

  • forkinfo.md — записи по каждому из четырёх пунктов
  • configuration.md — новые разделы «Политика доступа XKeenFull (полное проксирование устройств)» и «Перехват DNS и модули фильтрации Keenetic»

Честно - текст для PR писала нейроночка, по коду только мелкие нюансы уточнял, особенно по совместимости yq

@jameszeroX
Copy link
Copy Markdown
Owner

Спасибо за доработки, рассмотрю PR позже. В настоящее время GitHub заблокировал использование Action во всех моих репозиториях. До прояснения ситуации разработка и обновление всех проектов мной приостановлены.

@kittylabassistant
Copy link
Copy Markdown
Author

@jameszeroX можем переехать на gitlab либо могу помочь оформить self-hosted gitlab/любой другой scm

@kittylabassistant
Copy link
Copy Markdown
Author

Добавил ещё кучу изменений, в основном для безопасности. Все изменения в changed.md прописаны

@kittylabassistant
Copy link
Copy Markdown
Author

По нюансам
Перенос mktemp - флешки пользователей будут быстрее умирать из-за того, что на них будут храниться/перезаписываться те данные, которые раньше в tmp хранились

@jameszeroX
Copy link
Copy Markdown
Owner

jameszeroX commented Apr 24, 2026

Предварительный визуальный анализ доработок (тестирование пока не проводил)

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

  • Модификация шаблона конфигурации Mihomo не требуется. Используемое указание портов tproxy-port и redir-port валидно.

  • Упоминание при регистрации компонентов двойного ника (jameszero / jameszeroX) не понятно. В файле about.sh ник jameszeroX добавлен, как отдельный разработчик, это не так.

  • Скрипт диагностики не копирует в отчёт файл outbounds.json c чувствительными данными, но учитывая, что подключение к серверу пользователь может указать в любом из конфигурационных файлов, рассмотрю предложенную идею по обезличиванию чувствительных данных, случайно попавших в отчёт.

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

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

@kittylabassistant
Copy link
Copy Markdown
Author

kittylabassistant commented Apr 24, 2026

  1. имхо - ставить на flash-память самого роутера моветон. Только если какой-то крутой на arm чипе

  2. Удалим, не страшно

  3. ошибся когда откатывал изменения, не планировал PR делать изначально и делал только для себя форк

  4. Безопасноть должна быть безопасной :) Пару строк кода на маскирование не повредит

  5. Шикарно

Всегда можно те коммиты, где изменения не нужны/не требуются можем отменить и оставить только самый сок

Про ИИ да, я использовал репозиторий скорее как leetcode для практики и сохранил ответы нейронки для сравнения. Подумал чего добру пропадать, всё-равно уже токены потрачены
Проблема с GitHub Actions_ причины отключения.pdf

Про GH Actions мне Gemini составила какой-то конский отчёт, но там без конкретных причин блокировки - приложу, может пригодится

@jameszeroX
Copy link
Copy Markdown
Owner

  1. Согласен, и в XKeen даже выводится предупреждение при попытке установки на внутреннюю память, но повлиять на сторонников такой установки я не могу, они существуют и скрипты XKeen должны это учитывать.

@kittylabassistant
Copy link
Copy Markdown
Author

Мейби тогда сделать отдельный флаг для установки на внутреннюю память с выводом предупреждения повторным? Большинство не должно зависеть от меньшинства, но мнение меньшинства тоже можно учитывать и удовлетворять - я согласен

@jameszeroX
Copy link
Copy Markdown
Owner

Думаю, нужно оставить, как сейчас. Вариант загрузки в оперативную память выработан пользовательским опытом. Этой памяти достаточно для скачивания любого компонента XKeen при установке на любой тип носителя. Жалоб на сбои при такой загрузке не было, в отличие от загрузки в /opt/tmp/xkeen/ на ранних версиях форка и в оригинальном XKeen.

@kittylabassistant
Copy link
Copy Markdown
Author

Откатил замечания

Может тогда сделать флаг а-ля -usbinstall (нейминг без разницы) с установкой на флешку? Чтобы те кто хотели устанавливали всё на флешку, а кто нет в /tmp?

@jameszeroX
Copy link
Copy Markdown
Owner

Зачем усложнять) Всё же работает без ошибок независимо от используемого накопителя. Лучше проясните зачем в стартовом скрипте обрабатываются политики без доступа в интернет? Не совсем понимаю эту доработку. Есть у меня в роутере политики с подключениями WARP и OpenVPN, они настроены, но отключены, и как-либо использовать их в XKeen я не планирую, но их политики зачем-то учитываются скриптом.

@kittylabassistant
Copy link
Copy Markdown
Author

Цитирую knowissues.md: "При включенном проксировании, во встроенной политике "Без доступа в интернет" интернет продолжает работать, решения нет" - решение есть и оно как раз выполнено в скрипте

@kittylabassistant
Copy link
Copy Markdown
Author

Просто без перебора политик понять какие из них блэкхолят трафик и выставлены как "без доступа в интернет" - нельзя, либо я не нашел этот способ пока гуглил логику/нейронка тоже не предлага других вариантов

@kittylabassistant
Copy link
Copy Markdown
Author

"Зачем усложнять) Всё же работает без ошибок независимо от используемого накопителя" - прозвучу как llm - вы правы, но отчасти
Усложнение логики оправдывается тем, что освобождается ОЗУ - в среднем же на роутерах что-то около 128/ 256 МБ ОЗУ, и некоторые люди хотят ещё разные утилиты держать поднятыми (smb, ftp, transmission например). У меня на 1810 на xray 26.3.27 по oom падало уже не в самые лучшие моменты - поэтому и пришел форк делать :)

@kittylabassistant
Copy link
Copy Markdown
Author

Ещё дополню:
"При проксировании DNS с помощью XKeen, в профиле "Политика по умолчанию" отсутствует интернет, создайте пользовательсую политкику вместо этого профиля" - коммит e0519ad добавил фолбэк на мейн, оно же "Политика по умолчанию"

@jameszeroX
Copy link
Copy Markdown
Owner

Цитирую knowissues.md: "При включенном проксировании, во встроенной политике "Без доступа в интернет" интернет продолжает работать, решения нет" - решение есть и оно как раз выполнено в скрипте

С кастомными политиками и так проблем нет. Речь идет о встроенной политике, и предложенная доработка не закрывает баг
Screenshot_1

@jameszeroX
Copy link
Copy Markdown
Owner

jameszeroX commented Apr 25, 2026

У меня на 1810 на xray 26.3.27 по oom падало уже не в самые лучшие моменты

Падало именно в момент установки XKeen? Остальные кейсы падения не имеют отношения к скрипту установки. Ещё раз повторю, оперативной памяти в роутерах даже младших моделей достаточно для загрузки в неё любого компонента XKeen. Впрочем, вы можете сделать дополнительный флаг, например xkeen -i -usbtmp, чтобы реализовать задуманное, но основная логика установки должна остаться прежней.

@jameszeroX
Copy link
Copy Markdown
Owner

Ещё дополню: "При проксировании DNS с помощью XKeen, в профиле "Политика по умолчанию" отсутствует интернет, создайте пользовательсую политкику вместо этого профиля" - коммит e0519ad добавил фолбэк на мейн, оно же "Политика по умолчанию"

Это не работает. У Полититки по умолчанию проблема не в маршрутизации, а в доступе к DNS

@kittylabassistant
Copy link
Copy Markdown
Author

  • url_hotspot="rci/show/ip/hotspot" + api_hotspot_json в api_cache_init
  • Новая get_no_internet_macs() — берёт MAC-и из hotspot API где access == "deny"
  • Старая get_no_internet_marks() оставлена — закрывает редкий кейс кастомных политик «без интернета»
  • В add_prerouting() MAC-bypass идёт первым в xkeen-секции PREROUTING (до connmark-bypass и до основного -j xkeen-jump). Pattern: -m mac --mac-source -j RETURN
  • inject_var no_internet_macs + установка переменной в proxy_start

Короче кинетик в дефолтном без доступа в интернет по маку и ndm hotspot блокирует трафик

@kittylabassistant
Copy link
Copy Markdown
Author

Про "Это не работает. У Полититки по умолчанию проблема не в маршрутизации, а в доступе к DNS" - откатил knowissues.md - у меня не воспроизводится, не могу логи/фактуру проблемы собрать

@jameszeroX
Copy link
Copy Markdown
Owner

не воспроизводится, не могу логи/фактуру проблемы собрать

Для воспроизведения необходимо настроить проксирование DNS, например, по этой инструкции DNS-over-VLESS и включить перехват DNS в XKeen. При этом устройства в политике по умолчанию теряют доступ к DNS, а кроме того, если в "Интернет фильтрах" прописаны только шифрованные DNS, то так же перестаёт работать ping по доменным именам в самом Кинетике на странице диагностики. Для исправления, необходимо добавить любой не шифрованный DNS и переместить устройства в кастомную политику.

@kittylabassistant
Copy link
Copy Markdown
Author

Окей, я учту этот момент. Пока предлагаю ПР больше не заполнять - и так большой получается

@kittylabassistant
Copy link
Copy Markdown
Author

Добавите ещё, пожалуйста, LICENSE - любую на ваше усмотрение в репу

@jameszeroX
Copy link
Copy Markdown
Owner

кинетик в дефолтном без доступа в интернет по маку и ndm hotspot блокирует трафик

Да, это так. Только предложенная доработка не динамическая, она фиксирует mac в переменной и если устройство убрать из политики без интернета, то без xkeen -restart оно не пойдет в через прокси. Политика без интернета часто используется пользователями в шедуле Кинетика, когда нужно ограничивать время использования интернетом, например, для родительского контроля, и состояние доступа в интернет должно меняться автоматически.

Вы бы разбили данный PR на несколько. Каждая доработка - отдельный PR. Часть доработок я могу принять, часть под вопросом, но из-за того, что они все в одной куче, принятие всего PR под вопросом. Если разбиение слишком трудозатратно, я могу это понять и внесу предложенные доработки вручную. В контрибьюторах проекта вы будете указаны в любом случае.

@kittylabassistant
Copy link
Copy Markdown
Author

kittylabassistant commented Apr 26, 2026

У меня skill-issue по переделыванию PR и делению коммитов на разные - если есть возможность взять изменения и применить их вручную - будет идеально.
Это мой первый опыт работы с PR в Open Source репозиториями - поэтому все изменения делал у себя в main, а не в feature ветках. Ошибки учёл и в будущем сделаю по-другому

@kittylabassistant
Copy link
Copy Markdown
Author

kittylabassistant commented Apr 26, 2026

Просто в комментах перед закрытием PR прошу указать какие наработки были взяты, какие требуют исправления, а в каких отказано - чтобы всё было в одном сообщении. Мне так будет легче работать над будущим PR

@jameszeroX
Copy link
Copy Markdown
Owner

Следующие доработки были учтены и применены вручную к скриптам форка:

Функция init_directories в 01_info_variable.sh и её вызов в файле xkeen

Код следующих файлов применён полностью:
03_install_xkeen.sh
04_install_geofile.sh
00_register_common.sh
01_backups_xkeen.sh
01_downloaders_mihomo.sh
01_downloaders_xray.sh
02_donwloaders_xkeen.sh
00_tools_import.sh
01_tests_connected.sh

03_tools_diagnostic.sh (с правками)

04_register_init.sh (частично)

Применены:
Доработка парсинга redirect и tproxy портов конфигурации Mihomo
Геренерация proxy.sh
Мягкое завершение процесса прокси-клиента вместо killall -9

Не применены:
Политика XKeenFull - избыточно при наличии пользовательских политик
Попытки доработать политику без доступа в интернет - нет ожидаемого результата
Предупреждения о повышенной нагрузке на CPU и особенностях работы DNS при включенном перехвате - перегружает интерфейс, эту информацию лучше указать в инструкции или в FAQ

Функцию acquire_lock приму, когда согласуете совместимость с #33
Обратите внимание на висящую в воздухе функцию release_lock

Результирующий код доступен в папке scripts, установочный архив /temp/zkeen.tar.gz не пересобирал, жду ответа GitHub о причинах блокировки Action.

@jameszeroX jameszeroX closed this Apr 27, 2026
kittylabassistant added a commit to kittylabassistant/XKeen that referenced this pull request May 13, 2026
Built-in Keenetic policy drops via _NDM_HOTSPOT_FWD in FORWARD, but
XKeen TPROXY/REDIRECT/MARK intercepts in PREROUTING before FORWARD
runs, bypassing the drop. Custom policies work via routing mark from
rci/show/ip/policy; built-in has none.

Fix: ipset xkeen_deny_mac (hash:mac) + RETURN rule in PREROUTING
position 1 ahead of xkeen-jumps. Sync triggers:
  1. xkeen -start/-restart — sync_deny_mac_ipset post api_cache_init
  2. /opt/etc/ndm/netfilter.d/proxy.sh — _xkeen_sync_deny_mac_ipset
     baked into template, runs on every NDM netfilter rewrite
  3. /opt/etc/ndm/schedule.d/00-xkeen-hotspot-sync.sh — generated by
     configure_firewall, fires on schedule start/stop

Dynamic refresh closes maintainer's objection on PR jameszeroX#32 (static
mac list required xkeen -restart on schedule transitions, breaking
parental-control use case). MAC bypass limited to L2-visible hosts
(LAN/Wi-Fi/guest-bridge); inert behind L3-VLAN — documented in
knownissues.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
jameszeroX pushed a commit that referenced this pull request May 13, 2026
Built-in Keenetic policy drops via _NDM_HOTSPOT_FWD in FORWARD, but
XKeen TPROXY/REDIRECT/MARK intercepts in PREROUTING before FORWARD
runs, bypassing the drop. Custom policies work via routing mark from
rci/show/ip/policy; built-in has none.

Fix: ipset xkeen_deny_mac (hash:mac) + RETURN rule in PREROUTING
position 1 ahead of xkeen-jumps. Sync triggers:
  1. xkeen -start/-restart — sync_deny_mac_ipset post api_cache_init
  2. /opt/etc/ndm/netfilter.d/proxy.sh — _xkeen_sync_deny_mac_ipset
     baked into template, runs on every NDM netfilter rewrite
  3. /opt/etc/ndm/schedule.d/00-xkeen-hotspot-sync.sh — generated by
     configure_firewall, fires on schedule start/stop

Dynamic refresh closes maintainer's objection on PR #32 (static
mac list required xkeen -restart on schedule transitions, breaking
parental-control use case). MAC bypass limited to L2-visible hosts
(LAN/Wi-Fi/guest-bridge); inert behind L3-VLAN — documented in
knownissues.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants