Новые возможности
-
Автоматическая установка обновлений по расписанию (#559) — в настройках (продвинутый режим) появился блок «Автоматическая установка»: тумблер, интервал «каждые N дней» (1–30) и время «HH:MM». По расписанию демон проверяет и ставит обновление awg-manager, а sing-box догоняется до закреплённой версии (в том числе разовой сверкой через несколько минут после старта, если он отстал). Результат каждой автоустановки пишется в журнал приложения, а после самообновления причина перезапуска восстанавливается из метки на диске. Отдельная страховка: когда обновлений нет, слот не опрашивает репозиторий на каждом тике. Время слота считается в локальной зоне роутера (заодно это чинит и ежедневное обновление DNS-списков по времени, раньше работавшее в UTC). Отката при неудаче нет (будьте внимательны!).
-
Массовая смена выхода и download detour в sb-router (#558) — режим выделения на страницах правил sing-box роутера (tproxy и FakeIP): чекбоксы на карточках правил и «Выбрать все», нижняя панель «N выбрано → выбрать выход → Применить» меняет outbound сразу у всех отмеченных правил одним запросом (в tproxy правки уходят в общий черновик и применяются кнопкой «Применить», в FakeIP — сразу, одной перезагрузкой движка вместо гонки по одному). То же для download detour у наборов правил: массовая смена detour у выбранных remote-наборов. Выбираются только правила с реальным выходом-туннелем — системные (sniff/hijack-dns) и правила «Напрямую»/«Блокировать» из массовой операции исключены. Валидация серверная и строгая: неизвестный тег выхода, не-маршрутное правило, не-remote набор или пустой выбор отклоняются целиком (то есть весь пакет изменений).
-
Соединения: редизайн страницы — "бублики" по туннелям/назначению/клиентам, фильтры с чипами, группировка по клиенту/хосту, панель деталей и сброс отдельного соединения. Дополнительно видно вообще все соединения на роутере.
-
Интеграция FreeTurn — TURN-туннель для обхода блокировок (free-turn-proxy): управление из веб-панели (новый пункт меню FreeTurn, вкладки «Клиент»/«Сервер»). Полный набор флагов, живые логи процессов прямо в панели, генератор и декодер share-ссылок
freeturn://(с опциональным вложением WireGuard-конфига и автосозданием туннеля при импорте). Бинари freeturn НЕ поставляются в пакете awg-manager — панель предлагает установку в один клик: загрузка закреплённой в билде версии из релизов апстрима с проверкой SHA256 (та же модель доверия, что у managed sing-box); для архитектур без закреплённой сборки остаётся подсказка по ручной установке. -
IPv6 endpoint для NativeWG-туннелей через awg_proxy — сервер AmneziaWG за IPv6-адресом теперь работает в проксирующем режиме (прошивки без нативного ASC). Модуль
awg_proxy.koпонимает бракетированную форму эндпоинта[2001:db8::1]:51820в/proc/awg_proxy/{add,del,list}, создаёт per-family UDP-сокет и отправляет трафик черезudp_tunnel6_xmit_skb(обязательная UDP-контрольная сумма, hoplimit из маршрута; DF-бита в IPv6 нет). Локальная сторона (клиент WireGuard →127.0.0.1:порт) по-прежнему IPv4-loopback. Двухстековые хосты по-прежнему предпочитают IPv4 (стабильность), IPv6-only домены резолвятся в IPv6. В форме туннеля IPv6-литерал указывается в квадратных скобках (подсказка в поле Endpoint; голый2001:db8::1:51820отклоняется с ошибкой). -
Эксперт-редактор конфигурации sing-box — пользовательский слот
90-user.jsonс черновиками, валидацией (кросс-слот проверка тегов +sing-box checkнад снапшотом «как если бы применили») и подсветкой синтаксиса; правки не перезаписываются генераторами. В эксперт-режиме sb-router появилась кнопка «Редактор»: обзор всех слотов config.d с бейджами владельца («генерируется автоматически» / «пользовательский»), read-only просмотр системных слотов с подсветкой и копированием, для user-слота — полноценный редактор (номера строк, маркер строки с ошибкой JSON, Tab-отступы): Сохранить черновик → Проверить → Применить (debounced SIGHUP; изменение tun-inbound перезапустит движок) / Отменить черновик, плюс выключатель слота целиком без удаления содержимого. Массивы user-слота (outbounds/inbounds/правила) дополняют merged-конфиг последними; скаляры dns/route (final, strategy) отсюда не переопределяются (first-file-wins). Если применённый user-конфиг после удаления чужого outbound начинает ссылаться на несуществующий тег, reload пропускается (движок работает на старом конфиге), а причина всплывает в статусе роутера: «Пользовательский конфиг (90-user.json) ссылается на несуществующий тег … — правьте в редакторе конфигурации». -
Импорт настроек VPN через JSON-файл mieru (#449) — панели (RIXXX / Panel-Naive-Mieru) экспортируют настройки mieru каноническим JSON-конфигом клиента (формат
mieru apply config), который раньше отклонялся всеми путями импорта. Теперь такой JSON принимается целиком — вставкой и загрузкой файла: в мастере добавления («Один сервер» и «Группа серверов» получили дроп-зону для .json/.txt/.yaml файлов) и в подписках (inline и по URL, включая превью выбора серверов). УчитываетсяactiveProfile, лишние клиентские поля (rpcPort, socks5Port, loggingLevel и добавки панелей) игнорируются; TCP/UDP-привязки портов и portRange профиля дают те же outbounds, что и ссылкаmieru://. -
Панель Inbounds показывает все inbound'ы merged-конфига — раньше вкладка «Inbounds» (fakeip) и панель «Inbounds» (tproxy expert) отражали только tun-in и device-proxy, хотя merged-конфиг содержит также mixed-входы подписок (
sub-*-in), сводных групп (agg-*-in), туннелей и tproxy-входы QoS — в config-preview они были видны, но ни одна вкладка их не объясняла. Новый endpointGET /api/singbox/inboundsчитает слоты config.d по одному и атрибутирует каждый inbound источнику (подписка/группа/туннель/device-proxy/QoS/движок) с именем владельца; обе панели показывают полный сгруппированный список (управление device-proxy не изменилось), а входы, которые никто не питает (NDMS-прокси выключен или объект отключён), помечаются бейджем «резерв порта» с пояснением — порт сохраняется, чтобы при включении номера портов не менялись. -
Regex-фильтры серверов подписки и сводные группы (#372) — у подписки появились фильтры в стиле mihomo
filter:: «включать только» и «исключать» (Go RE2, матч по имени сервера; lookahead не поддерживается — вместо(?i)^(?!.*(RU)).*$используется поле «исключать» с(?i)(RU)). Скрытые фильтром серверы не материализуются в sing-box и показаны отдельным блоком «Скрыто фильтром»; фильтры компонуются с ручным исключением, смена фильтра сразу пере-применяет подписку (для inline — повторный разбор сохранённого списка). Плюс сводные группы: один selector/urltest-туннель поверх серверов НЕСКОЛЬКИХ подписок с собственным фильтром, режимом (по умолчанию — авто-выбор быстрейшего), портом и NDMS Proxy; группы пересобираются в том же reload, что и любое изменение подписок, управление — в секции «Сводные группы» на вкладке подписок. Надёжность: стадия батч-коммита конфига сериализована между конкурентными операциями (плановый refresh больше не смешивается с CRUD подписок/групп в общем батче), тела запросов subscription-эндпоинтов ограничены 1 МБ через общий helper, сторы подписок и групп пишутся copy-on-write — при ошибке записи на диск память не расходится с файлом. -
Настраиваемое время жизни сессии и вход по учётным данным Entware (#441) — время жизни auth-сессии задаётся в настройках (
sessionTtlHours, 1-720 часов, по умолчанию 24; скользящее окно, укорочение действует сразу на уже выданные сессии). Опциональный вход по системным учётным данным Entware (entwareAuthEnabled): пароль проверяется локально по/opt/etc/shadow(MD5-crypt/SHA-256/SHA-512-crypt, только stdlib) без обращения к NDMS/auth— роутер больше не шлёт уведомления о входе; при неудаче локальной проверки выполняется прежний вход через Keenetic. Защита от перебора: локальная проверка Entware добавляет поверхность офлайн-подбора, поэтому учитывается каждая неудачная попытка, в которой проверялись учётные данные (в том числе локальная Entware-проверка при недоступном роутере) — на каждую такую попытку начисляется задержка 300 мс, а после 5 с одного IP endpoint отвечает 429 в течение 30 секунд; учёт атомарный, параллельные запросы не обходят лимит. Недоступность роутера без проверки учётных данных не учитывается; ответы «пользователь не найден/заблокирован» выровнены по времени с неверным паролем (защита от перечисления пользователей). -
QoS-классы по DSCP в sb-router (#371) — трафик, помеченный DSCP-кодами (0-63, до 8 классов), направляется в отдельные выходы sing-box: классификация через iptables
-m dscpв цепочках AWGM (per-class TPROXY/REDIRECT-порты 51281+/51301+), пары inbound'овtproxy-qos-N/redirect-qos-Nи управляемые правила маршрутизации поinbound. Классы редактируются в настройках sb-router (qosClasses); доступность xt_dscp отражается в статусе (xtDscpAvailable), при отсутствии модуля ядра или расширения iptables функция мягко отключается, не ломая движок.
Улучшения
-
Карточка Inbounds (прокси для LAN-устройств) показывает человеческие имена выходов — бейдж целевого выхода и пометка «сейчас: …» отображали сырые теги (
awg-sys-Wireguard1), тогда как выпадающий список настроек — понятные подписи («Veesp SE · nwg1»). Теперь бейджи резолвятся через тот же каталог выходов и показывают те же имена; формат подписи сведён в один хелпер для списка и бейджей. -
Рестарт и обновление awg-manager больше не перезапускают sing-box — демон «переподключается» к уже работающему процессу: логи sing-box переезжают с пайпов на файлы в tmpfs (осиротевший процесс больше не умирает от SIGPIPE при первой записи в лог), а сверка конфигурации пропускает перезагрузку, когда применённый конфиг не изменился (раньше рестарт демона всегда дёргал sing-box, в режиме FakeIP — с полным перезапуском туннеля). Если конфиг изменился (например, после обновления) — выполняется обычная перезагрузка. VPN-соединения при рестарте/апгрейде панели больше не мигают.
-
Страницы «Туннели» и «Серверы» загружаются со скелетоном — вместо спиннера на холодной загрузке сразу рисуется структура будущего контента (правильный режим отображения и число карточек с прошлого визита), которая заполняется данными по мере ответа роутера. Анимация уважает prefers-reduced-motion; скелет списка соединений в диагностике переведён на тот же общий стиль.
-
Страница соединений больше не грузит роутер на каждый опрос — атрибуция правил (badge DNS-списков) читала у NDMS весь runtime-кэш object-group (сотни килобайт JSON, ~1 секунда работы ndm) на каждое обновление списка соединений: под открытой страницей это давало ~40% CPU awg-manager и постоянную фоновую нагрузку на RCI роутера. Теперь результат кэшируется на 30 секунд (данные меняются только когда DNS-правила резолвят новые IP — на свежести бейджей это не сказывается). Заодно ускорен разбор всех ответов RCI: проверка на конверт ошибки больше не парсит целиком большие успешные ответы.
-
Каталог наборов sb-router: пометки про композитные списки и наборы без правил (#450) — сервисы, уже входящие в добавленный композитный список (например, Anthropic при добавленном «Все AI сервисы»), помечаются в каталоге угловым знаком и подписью «в {название}» с подсказкой «Уже входит в добавленный композитный список … Можно добавить и отдельно» — плитка при этом остаётся кликабельной (отдельный набор добавить по-прежнему можно). Задизейбленные плитки стали внятнее: «добавлено» теперь различает набор, на который ссылается хотя бы одно правило (route или DNS), и «добавлено, без правил» (добавлен как набор — не используется ни одним правилом); работает и в каталоге tproxy-эксперта, и на вкладке Rule sets режима FakeIP. В мастере правил (каталог сервисов) пресеты, чьи наборы уже есть в конфиге, получают недизейблящую пометку «набор уже есть — будет создано только правило»: мастер переиспользует существующий набор и дублей не создаёт.
Прочее
- sing-box — бамп до 1.14.0-alpha.42 (совместимость с обновлённым mieru-патчем из #459; xhttp-патч применяется без изменений). Смоук сгенерированных конфигов (tproxy и fakeip-tun, все слоты config.d) против нового бинаря:
sing-box checkи полный старт проходят чисто; наши генераторы НЕ используют конструкции, удалённые в 1.14 (legacy address filter в DNS-правилах, outbound DNS rule item,store_rdrc,independent_cacheне эмитятся). Осталось два деприкейшена с удалением в 1.16 (только WARN в логе, миграция отдельным issue):download_detourу remote rule-set (→http_client) и неявный HTTP-клиент через default outbound у remote rule-set без detour.
Исправления
-
FakeIP не валится «unknown-outbound» из-за протухших членов композита (#567) — пересоздание или переименование туннеля меняло его тег, а ссылки в fakeip-слоте (члены композитов, правила) никто не чинил и не охранял: включение FakeIP падало кросс-слот валидацией с откатом в «Выключен», и пересоздание выхода не помогало. Теперь: сохранение композита проверяет member-теги и называет несуществующие (в обоих режимах — FakeIP и TProxy); переименование туннеля переписывает ссылки и в fakeip-слоте (включая припаркованный); удаление туннеля, на который ссылается fakeip-конфиг, отклоняется с перечислением мест; перед включением FakeIP каталог AWG-выходов (15-awg.json) освежается, чтобы живой туннель не считался неизвестным из-за устаревшего файла.
-
Селективный перехват больше не «воскресает» в режиме FakeIP (#564) — выключенный слот
19-selective-routes.jsonсамовольно возвращался изdisabled/вconfig.d/, и его правила мерджились в работающий fakeip-конфиг. Причина: завершившаяся пересборка ipset включала слот по одному лишь наличию правил, а сами пересборки не проверяли режим — их запускали и API-ручка, и фоновое CDN-обновление, и применение правил при «спящем» (унаследованном из tproxy) флаге селектива. Теперь включённость слота и все точки запуска пересборки сверяются с реальной активностью селектива (движок включён + режим tproxy + флаг взведён); ручной запуск пересборки вне tproxy отклоняется с честной ошибкой. -
Страховочный потолок памяти демона на 1ГБ-роутерах (#562) — модели с ≥700МБ ОЗУ работали вообще без GOMEMLIMIT (тюнинг GC был только у 128-512МБ), поэтому любой аллокационный всплеск беспрепятственно доезжал до 90%+ памяти роутера. Теперь и им ставится мягкий потолок 256MiB (сильно выше рабочих пиков — на обычной нагрузке GC не напрягается); явные переменные окружения GOGC/GOMEMLIMIT по-прежнему в приоритете.
-
Демон больше не раздувает ОЗУ после ротации логов sing-box (#562) — файл процесс-лога sing-box открывался при спавне без O_APPEND: после самоусечения лога на 4 МБ писатель продолжал с прежнего смещения, файл становился разреженным, и tail демона бесконечно перечитывал «дыру» из NUL-байтов, экранируя каждый байт в журнал — CPU до 50% и рост памяти до OOM (ускоряющийся, так как дыра растёт). Исправлено открытие (O_APPEND сохраняется при truncate) и добавлен фильтр NUL-байтов в tail — он же защищает уже запущенные sing-box со старым позиционным fd, живущие через адопцию после обновления.
-
TProxy: смена «UDP-таймаут сессии» применяется без перевключения движка (#554) — новое значение доезжало до inbound'а, но системное правило
route-options(перекрывающее короткие сниф-таймауты sing-box, #469) перегенерировалось только при включении движка: в конфиге оставался старыйudp_timeout, и не помогал даже «Перезапустить». Теперь сверка доводит правило до нужного значения сразу после сохранения настроек (и лечит его при ручном дрейфе). Для режима FakeIP то же самое было исправлено ранее в этом релизе. -
FakeIP: правило маршрутизации без явного
actionполучает CIDR-маршруты в туннель — правило, добавленное через API без поля"action": "route"(веб-интерфейс его всегда шлёт), sing-box исполняет как route, но защита от петель считала его «не-маршрутом»: IP-адреса из его rule-set'ов не получали маршруты в tun и шли мимо туннеля молча. Теперь пустойactionтрактуется как route везде, где это делает sing-box — заодно у таких правил заработало предупреждение о несуществующем outbound. -
Карточки sing-box-подписок больше не перемешиваются (#525) — список подписок отдавался в случайном порядке (итерация по map), и карточки на странице «Туннели» перепрыгивали при каждом фоновом обновлении (~раз в 30 секунд) и при перезагрузке страницы — можно было удалить не ту подписку. Теперь порядок стабильный: по названию без учёта регистра.
-
DNS-маршрутизация: включение NDMS-списка снова доезжает до роутера (#489) — у списков с фолбэком «авто» выключение срабатывало, а включение оставалось только в интерфейсе AWG Manager: маршрут в прошивке продолжал висеть выключенным. Причин было две. Значение «авто» не восстанавливается из состояния роутера (NDMS не отличает его от «нет фолбэка»), из-за чего сверка считала такие маршруты вечно изменёнными и на каждом цикле пересоздавала их вместо штатного переключения флага — теперь «авто» нормализуется при сравнении, и включение/выключение идёт нативным
dns-proxy route disableпо index. Вторая: NDMS при пересоздании существующего маршрута сохраняет его флаг disable (проверено на 5.1.1) — теперь после любого пересоздания сверка перечитывает состояние и явно доводит флаг до нужного в обе стороны. -
FakeIP: смена DNS-сервера, стека и UDP-таймаута применяется сразу — сохранение этих полей в настройках sb-router на включённом режиме FakeIP не доезжало до движка (даже после рестарта демона) и срабатывало только при выключении/включении режима. Теперь сохранение перегенерирует fakeip-конфигурацию и перезагружает движок. Пулы адресов и MTU по-прежнему применяются при перевключении режима — они требуют пересоздания интерфейса и маршрутов.
-
Ошибки старта sing-box видны в журнале приложения — FATAL-строки из stderr sing-box (ошибки старта, когда Clash API ещё не поднялся и штатный пересыл логов их не застаёт) теперь попадают в журнал (
/logs, раздел sing-box), а не только в stderr самого демона. -
Файловые логи процесса sing-box не растут бесконечно — лог-файлы на tmpfs (
/var/run/awg-manager/sing-box.*.log) усекаются при достижении 4 МБ; на debug-уровне при месяцах аптайма они больше не съедают tmpfs роутера. -
FakeIP: восстановлено разрешение трафика в tun-интерфейс средствами NDMS — при интеграции режима FakeIP из прототипа потерялась настройка firewall на OpkgTun-интерфейсе: там, где межсегментный трафик режется файрволом роутера (isolate-private и подобные политики), клиентский трафик и DNS-запросы не доходили до fakeip-интерфейса. Теперь при включении режима создаётся permit-all access-list
_WEBADMIN_OpkgTunNс привязкойip access-group … inи флагом auto-delete — ровно та же форма, которую генерирует веб-интерфейс Keenetic при разрешении доступа к интерфейсу (проверено вживую: permit → bind → auto-delete, каскадное удаление списка вместе с интерфейсом). Список снимается при выключении режима, откате неудачного включения и уборке сирот; после обновления awg-manager поверх уже включённого FakeIP список доставляется автоматически первой сверкой. ACL-команды сведены в единые NDMS-примитивы (ими же пользуется межсегментный доступ managed-серверов) — заодно ошибки этих операций, которые NDMS кладёт внутрь ответа, перестали молча проглатываться: неудачное правило доступа теперь честно всплывает, а не выглядит применённым. -
Осиротевший интерфейс FakeIP больше не вгоняет роутер в вечный цикл перезапуска nginx — если NDMS-интерфейс OpkgTun с настроенным
ip addressоставался после выключения FakeIP (сбой удаления, крэш посреди включения, fail-safe выключение), ndm ежесекундно пересобирал конфигурацию nginx (bind на несуществующий адрес → ошибка → регенерация → снова ошибка), постоянно съедая ~20% ядра и подвешивая ВЕСЬ RCI на секунды — веб-панель и все операции awg-manager начинали спорадически тормозить на 1–9 секунд (частая причина «awg-manager стал очень медленным» и warn'овperf: slow rci). Теперь на всех путях отключения (штатное выключение, откат неудачного включения, reap) при провале удаления интерфейса его IP-адреса снимаются отдельным шагом — неудалённый интерфейс больше не оставляет опасный адрес; reap дополнен сканом по описанию (убирает осиротевшие OpkgTun'ы FakeIP, потерявшие учётную запись, вместе с их маршрутом пула) и выполняется не только на старте, но и на каждом цикле сверки — runtime-сирота лечится за полминуты без перезагрузки. Откат неудачного включения FakeIP доезжает до NDMS даже при обрыве клиента посреди операции. -
Соединения: исправлены двойные badge DNS-списка и потеря соединений без исходящего интерфейса — записи sing-box/tproxy (в том числе IPv6) без исходящего интерфейса в conntrack раньше терялись из списка вместо атрибуции по маршруту.
-
Rule-set'ы каталога переехали на зеркало repo.hoaxisr.ru — списки vernette/rulesets раздавались через raw.githubusercontent.com, заблокированный у части российских провайдеров: sing-box молча не мог скачать remote-набор, и правила маршрутизации/DNS с ним не работали (частая причина «каталог не работает», в т.ч. по мотивам #534). Теперь 19 URL каталога указывают на зеркало
repo.hoaxisr.ru/rulesets(источник — форк hoaxisr/rulesets с ежедневным синком upstream), существующие установки мигрируются автоматически при старте: URL в применённых sing-box-конфигах (все слоты) и DNS-подписках переписываются на зеркало без переприменения пресетов. В данные Discord добавлены подсеть104.29.0.0/16и голосовые порты19200:19400(в применённые DNS-списки Discord подсеть дописывается той же стартовой миграцией). -
NativeWG: маска подсети из адреса интерфейса больше не заменяется на /32 (#531) — указанный в туннеле CIDR (например
172.25.1.2/24) молча превращался в/32: при создании интерфейса маска была захардкожена, а при каждом старте синк адреса срезал суффикс до разбора маски — и перетирал даже ручную правку в веб-интерфейсе Keenetic. Теперь маска пользователя доезжает до NDMS (connected-маршрут на туннельную подсеть для LAN-to-LAN работает); адрес без маски по-прежнему получает/32. Помните: маска интерфейса задаёт только маршрут — что пропустит WireGuard, решает AllowedIPs пира. -
Движок маршрутизации больше не выключается сам из-за недоступного RCI (#523) — периодическая сверка трактовала ЛЮБУЮ ошибку чтения метки политики (включая транзиентную недоступность RCI при ранней загрузке или shutdown-гонке во время перезагрузки роутера) как «политика удалена» и молча делала fail-safe выключение: снос перехвата, парковка слота,
enabled=falseбез записи в журнал и без авто-восстановления — после перезагрузки тумблер оказывался в «выключено». Теперь fail-safe срабатывает только когда NDMS ответил и политики действительно нет; транзиентная ошибка оставляет состояние нетронутым и ретраится следующим тиком. Причина fail-safe пишется в журнал, а каждое выключение движка (включая по кнопке) оставляет запись в журнале. Закрыт и смежный тупик: если слот конфигурации движка запаркован (rollback неудачного включения), а цепочки перехвата живы (netfilter.d-hook восстановил их из сохранённых правил), сверка считала состояние здоровым «installed» и бесконечно ждала watchdog, которому нечего чинить — теперь запаркованный слот распознаётся как дрейф и лечится полным включением (перепромоут слота + переустановка перехвата); при мёртвом процессе лечение откладывается на тик после его оживления watchdog'ом, чтобы не задерживать fail-closed блокировку. Тот же дрейф закрыт и в режиме FakeIP: запаркованный слот конфигурации возвращается в merged-конфиг и при живом движке (раньше — только при мёртвом). -
Импорт mierus://-ссылок с дополнительными портами/диапазонами (#516) — ссылка вида
...&port=2012&port=2012-2022&protocol=TCP(одинprotocolна несколькоport, так экспортируют панели) отклонялась с ошибкой «mismatched number of port and protocol parameters»; теперь единственныйprotocolприменяется ко всем портам. Заодно исправлен собственный экспорт «Копировать ссылку»: он генерировал именно такой неканоничный формат, и ссылка не импортировалась обратно — теперьprotocolпишется парой к каждомуport, как в эталонном клиенте mieru. -
NativeWG-туннели больше не делят лимит 7 ID с kernel-AWG туннелями — раньше оба backend'а получали ID из общего пула
awg10..awg16(7 слотов), хотя потолок 16 — прошивочное ограничение индекса OpkgTun и к NativeWG отношения не имеет (его NDMS-интерфейс —WireguardN, в OpkgTun не отображается). NativeWG-туннели вымещали kernel-AWG из дефицитного диапазона и сами не могли превысить 7 даже в одиночку. Теперь у NativeWG собственный неограниченный сверху диапазон ID (awg20+), а реальную ёмкость задают честные пределы: до 100 интерфейсов Wireguard в NDMS (индексыWireguard0..99, ранее искусственно ограничивались десятью) и до 16 одновременных туннелей с обфускацией через awg_proxy (слоты kmod; предел срабатывает при СТАРТЕ туннеля на прошивках без нативного ASC и сопровождается понятным сообщением, создание интерфейсов он не ограничивает). Лимит kernel-AWG (7 туннелей,OpkgTun10..16) — прошивочный, без изменений. Существующие NativeWG-туннели со старыми IDawg10..awg16продолжают работать без миграции — kernel-аллокатор просто пропускает занятые ими номера. -
Прокси устройств с выходом через композит роутера (vpn/vpn2) при выключенном движке маршрутизации (#465) — ломались и маршрутизация, и отображение. При выключении движка слот 20-router паркуется, композиты пропадают из merged-конфига, и авточистка висячих ссылок перед каждым reload молча вырезала vpn/vpn2 из селекторов device-proxy вместе с их
default— sing-box уводил трафик в произвольный выживший член селектора, а карточка инбаунда показывала этот runtime-тег как якобы настроенный выход (последний переключённый инстанс выглядел «правильным» лишь до следующего reload). Теперь: (1) генерация слота 30 сама не эмитит ссылки на теги выключенных слотов — при недоступном композите селектор получает его default-член (нет default'а/недоступен → первый член → direct), т.е. трафик идёт по намерению пользователя, а сохранённый выбор не трогается и восстанавливается при включении движка; (2) включение/выключение движка (и смена режима tproxy/fakeip) синхронно перегенерируют слот device-proxy ДО reload, так что авточистке нечего вырезать, а если она всё же что-то режет — пишет warn, а не молчит; (3) карточки инбаундов показывают НАСТРОЕННЫЙ выход (как «О устройстве»), живой selector.now — отдельной пометкой «сейчас: …», деградация — явной пометкой «выход недоступен — через …» (новые поляdegradedOutbound/fallbackTagв runtime-ответах прокси). Попутно: стартовый reconcile device-proxy перенесён после подключения каталога выходов роутера — раньше на каждой загрузке он считал композиты удалёнными и выключал ссылающиеся на них инстансы, стирая выбранный выход. -
Валидация «как будто применён» для выключенного целевого слота — CheckMerged/ApplyDraft теперь всегда включают целевой слот в снапшот
sing-box check, даже если он в данный момент выключен: черновик валидируется «как будто применён и включён», в согласии с кросс-слот проверкой. Раньше применение черновика к выключенному слоту проходило мимоsing-box check(затрагивало и staging роутера на выключенном слоте, и user-слот эксперт-редактора). Порядок apply у user-слота изменён на «применить, потом включить»: провал валидации оставляет припаркованный слот выключенным, а его старый конфиг — нетронутым. Попутно: конфликт тега подписки с пользовательским слотом при обновлении подписки падает сразу с честной причиной («конфликт с пользовательским слотом 90-user.json: тег … уже занят — переименуйте outbound в редакторе конфигурации») вместо непрозрачной ошибки изоляции; advisory-предупреждения валидации (например, route.final задан несколькими слотами — sing-box молча оставит первый) доезжают до ответов check/apply эксперт-редактора и показываются отдельным жёлтым блоком; включённый, но содержательно пустой 90-user.json больше не удерживает и не запускает процесс sing-box. -
sing-box в режиме маршрутизации теперь перезапускается автоматически после падения (#456) — вотчдог проверял только легаси-туннели (10-tunnels.json) и при пустом списке выходил до liveness-проверки, поэтому упавший (например, убитый OOM-killer'ом) процесс в tproxy/fakeip-режиме оставался лежать до ручного «Перезагрузить». Теперь предикат перезапуска — активная работа оркестратора (router / device-proxy / подписки / туннели), а reconcile самих режимов (tproxy и fakeip) дополнительно поднимает мёртвый процесс сам (defense in depth). Против crash-loop добавлен backoff: 3 быстрых перезапуска за 10 минут — сразу, дальше экспоненциальная пауза (1→2→4 мин, кап 15 мин); сброс после «здорового» аптайма ≥5 мин или ручного управления, ручной «Перезапустить» не подавляется. Backoff применяется и к легаси-туннелям — раньше вотчдог перезапускал упавший процесс каждые 30 секунд без ограничений. Наблюдаемость: SIGKILL без stderr классифицируется по dmesg как OOM-kill с понятной причиной («роутеру не хватило памяти…»); панель движка показывает «Падений за 10 мин», причину последнего падения и до какого времени приостановлен автоперезапуск. Попутно закрыт пробел fakeip-реконсайла: drift-heal больше не воскрешает движок, остановленный пользователем вручную.
-
Пересборка selective-ipset больше не падает по фиксированному таймауту при медленной, но идущей работе, а «живую», но затянувшуюся пересборку теперь можно отменить из UI — раньше фоновую пересборку (API
POST /rebuildи авто-запуск при старте/reconcile) обрывал настенный дедлайн 10 минут, хотя на медленном MIPS-роутере с большим списком доменов работа честно продолжалась. Теперь продолжительность ограничивает stall-guard по прогрессу: отмена — только если 4 минуты подряд нет ни одного сигнала прогресса (смена фазы, собранный CIDR, завершённый DNS-резолв хоста/матчера, каждая ipset-команда и restore-чанк, материализация rule-set'ов и периодический тик geosite/geoip-скана), плюс абсолютный предохранитель 2 часа от «вечно живой» пересборки. Сигналы прогресса и время простоя считаются по монотонным часам — NTP-скачок посреди boot-пересборки не даёт ни ложного «нет прогресса», ни подавленного срабатывания. Сообщение об остановке различает причины и несёт последний прогресс («нет прогресса 4 мин подряд (фаза resolving, последний матчер …)»). Отмена пересборки из UI: в модальном окне пересборки появилась кнопка «Отменить пересборку» (POST /api/singbox/router/selective/rebuild/cancel) — ограниченный ручной выход из медленной, но живой пересборки, которую stall-guard легально не трогает; отменённый прогон завершается событием «пересборка отменена пользователем», staging-набор не подменяет живой. Попутно: подняты тесные exec-таймауты ipset-команд (restore одного чанка 60 с → 180 с, управляющие команды create/flush/swap/destroy/list 30 с → 120 с — нагруженный роутер с maxelem=262144 в них не укладывался); decompile .srs подчинён контексту пересборки и собственному таймауту 5 минут (зависший decompile больше не переживает и stall-guard, и 2-часовой предохранитель, вечно удерживая heavyop-гейт); сбой счётчика записей после успешного swap больше не рисует ложное «ipset пустой — весь трафик в WAN» (честное «записей: н/д»); пост-обработка успешной пересборки (синхронизация маршрутов + перезапуск sing-box) ограничена 10 минутами, чтобы заклинившая другая тяжёлая операция не удерживала флаг rebuilding бесконечно. -
Rule-set'ы из geosite.dat не срабатывали на домен верхнего уровня (#448) — при создании набора правил из .dat-файла все записи geosite конвертировались в
domain_suffixс ведущей точкой (.chatgpt.com), который в sing-box матчит только поддомены — самchatgpt.comмимо правила уходил вfinal. Конвертация переведена на типизированное извлечение v2ray-типов: RootDomain теперь даётdomain_suffix+ точноеdomainдля апекса (как в официальных конвертерах geosite→srs), Full — точныйdomain, Plain —domain_keyword, Regex —domain_regex. Скомпилированные старым кодом .srs-кэши инвалидируются автоматически (версия формата в meta.json); просмотр geo-файлов не затронут. -
Файлы rule-set'ов не удалялись с диска (#448) — удаление или переименование набора правил оставляло его артефакты (
rule-sets/inline/*.json|.srs,rule-sets/dat/*.json|.srs|.meta.json) на диске навсегда. Теперь после успешного «Применить» и один раз на старте демона выполняется сборка мусора: удаляются файлы, на которые не ссылается ни активная конфигурация, ни pending-черновик (router и fakeip-слоты); отложенное удаление в черновике по-прежнему сохраняет файлы до применения, токен dat-эндпоинта и незавершённые компиляции не трогаются. -
Клик по названию rule-set удалял первый чип (#446) — в модалке DNS-правила поле «Rule sets» было обёрнуто в
<label>: клик по любой не-интерактивной части (названию набора) браузер форвардил в первый labelable-элемент — крестик первого чипа, «случайно» удаляя его. Обёртка заменена наdiv, а ChipMultiSelect дополнительно гасит дефолтный label-форвардинг. -
Панель дашборда туннелей на мобильных — переключатель «Сплошной/Разделы» рисовался с наезжающими друг на друга подписями («СплошнРазделы»): кнопки сегмент-контрола сжимались ниже ширины текста без обрезки, и текст выползал на соседнюю кнопку — теперь подписи обрезаются с многоточием. Контролы панели скомпонованы компактнее (≤4 строк): тег-фильтр и действия (Экспорт) делят одну строку 50/50 вместо двух полноширинных.
-
OOM при пересборке selective-ipset на больших списках — импорт geosite-масштаба (сотни тысяч матчеров) убивал демон по памяти: резолвер запускал по горутине на каждый матчер, а весь список доменов и IP материализовался в RAM. Пересборка переведена на потоковый конвейер (сбор правил → ограниченная очередь → фиксированный пул DNS-воркеров) — пиковое число горутин теперь ~14 вместо сотен тысяч (бенчмарк 80k матчеров: суммарные аллокации ~44MB, 200k: ~53MB, пик горутин неизменен). Введены лимиты: 100 000 уникальных доменных матчеров на пересборку и 65 536 host-маршрутов в оверлее 19-selective-routes.json — при превышении список усекается с явной пометкой «список усечён» в итоговом сообщении и в снапшоте (
truncatedMatchers/truncatedRoutes), а не валит демон. Для роутеров с 200–700MB RAM (256/512MB-модели) добавлен GC-тюнинг: мягкийGOMEMLIMIT=96MiB+GOGC=50(ранее — никакого лимита;/system/infoтеперь показывает лимит вместо «Unlimited»); явно заданные переменные окружения GOGC/GOMEMLIMIT по-прежнему имеют приоритет.