Releases: LackyCraft/xkeen-smartroute
Release list
XKeen SmartRoute v2.2.0
Исправлено
-
install.shбольше не падает на свежем OpenWrt 25.12.5 при установке
entware-сборки Xray. Обнаружено вживую (GitHub issue #1) и
воспроизведено на реальном роутере (Netis N6, свежепрошитый на
OpenWrt 25.12.5): текущая версия установщика xkeen (Skrill0/XKeen)
сама регистрирует фиктивный пакетxray_sпрямо в статус-базе opkg —
чтобы отслеживать файлы, которые сама же записала (бинарник xray, его
конфиг-шаблоны, geoip/geosite.dat, логи). На OpenWrtxray_s
никогда не был настоящим, скачиваемым пакетом Entware, но opkg об
этом не знает: обычныйopkg install xray-coreкорректно отказывает
из-за конфликта на/opt/sbin/xray(«уже предоставлен пакетом
xray_s») — так же, как отказал бы для двух по-настоящему
конфликтующих пакетов.Пробовал сначала удалять
xray_s— тот же приём, что уже
используется веткой для KeeneticOS чуть выше по коду для похожего,
но другого конфликта — подтверждено вживую, что это неверный ход
именно здесь:opkg removeудаляет все пути из списка файлов этого
пакета, включая собственный каталог шаблонов xkeen
/opt/etc/xray/configs, который ничто дальше по скрипту не
восстанавливает.opkg install --force-overwrite xray-coreвместо
этого просто отдаёт настоящим файлам xray-core тот один путь, на
который претендуют оба, не трогая ни статус-записьxray_s, ни что-либо
ещё, что она заявляет — подтверждено вживую, что каталог шаблонов
остаётся нетронутым, а Xray после этого запускается и реально
маршрутизирует трафик.Попутно найден и исправлен второй, независимый баг устойчивости:
интерактивные запросы пароля (xkeen-UI, панель SmartRoute) могли
уронить всю установку подset -eu, еслиinstall.shзапущен не из
живого терминала (например,ssh роутер 'sh install.sh'— реальный
сценарий, не только особенность тестового стенда): проверка
[ -r /dev/tty ]может пройти, а сама попытка открыть/dev/ttyдля
read— упасть.Проверено вживую end-to-end: чистая установка на OpenWrt 25.12.5
проходит все 6 шагов,check.sh— везде [OK], реальная
подписка/профиль/маршрутизация работают.
XKeen SmartRoute v2.1.0
Добавлено
- Жёсткий (per-профильный) kill-switch теперь работает на KeeneticOS.
Последний оставшийся пробел платформенного паритета из релиза 2.0.0.
KeeneticOS не имеет системного dnsmasq вообще (DNS роутера — NDM'овский
ndnproxy, уже занявший порт 53) — в отличие от OpenWrt, где жёсткий
слой просто вешает ipset-директиву на уже существующий LAN-резолвер,
здесь буквально не на что было вешать наблюдение за доменами. Новый
бэкенд (ks_apply_keenetic) поднимает отдельный, выделенный экземпляр
Entwarednsmasq-fullисключительно как наполнитель ipset: PREROUTING
перенаправляет LAN-трафик на порт 53 на этот теневой экземпляр вместо
ndnproxyнапрямую, тот транзитом пересылает каждый запрос на
127.0.0.1:53(ответ клиенту не меняется) и попутно заносит
резолвленные IP отслеживаемых доменов в тот же ipset, на который
смотрит REJECT-правилоFORWARD. Подробности механики —
docs/functionality_doc/kill-switch.md.
Исправлено
- Два бага всплыли только под реальным трафиком на живом Keenetic Hero
4G+/KN-2311, не в код-ревью:iptables REDIRECTпереписывает адрес
назначения на адрес входящего интерфейса, а не на127.0.0.1—
теневой dnsmasq, слушавший только loopback, вообще не видел
LAN-запросы (тихий таймаут без единой ошибки). REJECT-правило на
FORWARD, добавленное в конец цепочки, никогда не срабатывало —
собственные цепочки NDM (_NDM_FORWARDи др.) уже принимали обычный
LAN→WAN трафик раньше в той же цепочке. Оба исправлены вставкой в
начало соответствующей цепочки вместо добавления в конец. - Упавший теневой dnsmasq — реальный отказ, которого нет на OpenWrt: без
защиты DNS-редирект, оставшийся взведённым на мёртвый процесс,
заблокировал бы DNS всей LAN, а не только kill-switch-профилей.
Редирект теперь взводится только после подтверждения, что
свежезапущенный экземпляр реально поднялся; новый боевой хук + cron
раз в минуту (только KeeneticOS) самолечит упавший процесс. Проверено
вживую:kill -9теневого процесса — DNS продолжила резолвиться
(fail-open сработал), вотчдог перезапустил его на следующем тике. - Гонка при перестройке правил, обнаруженная тем же вотчдогом: ручное
включение/выключение kill-switch, пересекшееся по времени с
cron-тиком, могло оставить дублированные iptables-правила. Добавлен
тот жеmkdir-мьютекс, что уже используетgenroute.sh's regen-лок,
плюс обёрткаiptables -w(тот же класс фикса, что уже применён к
redirect.shв 2.0.0, легаси xtables-лок общий на весь роутер). - Восстановление kill-switch при переустановке (
install.sh) теперь
работает на обеих платформах — раньше на KeeneticOS вместо этого
просто логировалось предупреждение "пока не поддержано".
uninstall.shтеперь корректно сворачивает состояние жёсткого
kill-switch на KeeneticOS (теневой процесс, ipset, обе цепочки,
боевой хук) — раньше эта секция вообще не знала о существовании
KeeneticOS-бэкенда.
XKeen SmartRoute v2.0.0
Полноценная поддержка KeeneticOS — второй платформы проекта наравне с
OpenWrt. Всё в этом релизе проверено вживую на реальном железе (Keenetic
Hero 4G+ KN-2311 и OpenWrt 23.05/mt7621), включая полный цикл
uninstall → install тестовой ветки на обоих роутерах перед мержем.
Добавлено
- Установка на KeeneticOS одной командой.
install.shопределяет
платформу и на KeeneticOS ставит xkeen, xkeen-UI (порт 1000) и панель
smartroute-gateway (порт 1001, здесь — единственный полноценный UI, LuCI
на KeeneticOS нет) поверх уже поднятого пользователем Entware на внешнем
USB-накопителе. Подробная инструкция по подготовке флешки и Entware —
docs/install-keenetic.md. - Прозрачный перехват LAN-трафика на KeeneticOS — второй бэкенд
lib/redirect.sh(rd_write_iptables) поверх легасиiptables/
ip6tables, того же пространства правил, которым управляет NDM-firewall
самого роутера (в отличие от OpenWrt 22.03+, который перешёл на
nftables/fw4). Без этого перехвата не работает ни один
профиль/kill-switch — а штатныйxkeen -apна KeeneticOS оказался
рабочим, но именно поэтому его редиректы не может использовать fw4-путь,
которого там просто нет. Включение перехвата и защита от утечек
DNS/IPv6/QUIC работают идентично OpenWrt. - Kill-switch по умолчанию fail-open, с опциональной защитой от отказа
Xray. Раньше падение Xray-процесса означало полный обрыв интернета на
перехватываемых портах — по многочисленным просьбам это неверно понятое
поведение исправлено: по умолчанию перехват сам отключается, если Xray не
отвечает, и трафик идёт напрямую, как будто SmartRoute не установлено.
Старое поведение (жёсткий обрыв вместо утечки) осталось как отдельный
переключатель «Защита от отказа Xray» на вкладке «Защита от утечек» —
для тех, кому важнее ноль байт в обход правил, чем сохранение интернета.
Auto-resync при каждом старте/стопе/рестарте Xray плюс cron-вотчдог раз в
минуту (redirect.sh reapply) закрывают окно, где панель ещё показывает
«включено», а реальные правила уже не соответствуют состоянию Xray. - Мгновенная реакция на упавший активный сервер профиля. Раньше
сервер, выбранныйsr_pick_top1для профиля, при поломке продолжал
получать трафик до следующего планового пересчёта (cron, раз в 3
минуты) — теперьgateway/failover.go, и так уже опрашивавший
ObservatoryService каждые 20с, реагирует сразу: как только реально
используемый профилем сервер помечается «мёртв», сразу триггерится
пересчёт+рестарт (genroute.sh regen-fast), без ожидания следующего
тика. Окно обрыва сокращается с «до 3 минут» до ~20 секунд — рестарт
Xray для применения нового сервера по-прежнему нужен (живой балансировщик
Xray заблокирован апстрим-багом XTLS/Xray-core#6642), так что обрыв не
исчезает полностью, но становится намного короче.
Исправлено
- Гонка рестарта Xray стекала до 6 живых процессов после жёсткой
(по питанию) перезагрузки роутера, полностью обрывая интернет —
pgrep -x xrayне успевал за переходомsu→execпод тяжёлой
boot-time I/O-нагрузкой. Новыйsr_xray_pids()матчит по полной
командной строке, закрывая гонку. - Панель на KeeneticOS ощущалась «зависшей» — API-ответы кэшировались
браузером безCache-Control, а сохранение профиля синхронно ждало
рестарта Xray до минуты. Оба фикса перенесены и подтверждены на
KeeneticOS. install.shне работал на OpenWrt 25.12+ — этот релиз заменил
opkgнаapk, скрипт был жёстко завязан на первый.- Xray на KeeneticOS не перезапускался вообще после установки —
три независимых бага в одной секцииinstall.sh(устаревший формат
02_transport.json, отсутствующий пользовательxkeenдляsu,
сборка Xray, несовместимая с этим CPU); заодно устаревшийxray_s
(1.8.4) заменён на полноценныйxray-core(26.2.6). xkeen-UIникогда не ставился без интерактива — интерактивные
запросы и нестабильный спиннер апстрим-установщика блокировали
автоматическую установку.redirect.sh/killswitch.shмолча «успешно» ничего не делали на
KeeneticOS — обе команды писали вuci/nftables, которых там нет, и
завершались с кодом успеха, не применив ни одного правила.- Гонка блокировки
xtablesпри частых переключениях защит на
KeeneticOS — новый cron-вотчдог (раз в минуту) мог столкнуться с
ручным переключением тумблера за захват легасиxtables-лока; под
set -euэто обрывало пересборку цепочки правил на середине. Все
вызовыiptables/ip6tablesв KeeneticOS-бэкенде теперь ждут
освобождения лока вместо немедленного отказа. uninstall.shоставлял живыми iptables-правила перехвата на
KeeneticOS навсегда — в отличие от OpenWrt, гдеfw4просто
перестаёт грузить удалённый.nft-файл, на KeeneticOS правила
live-only и требуют явного снятия, покаredirect.shещё не удалён.
Обнаружено и исправлено во время полного цикла деинсталляции этой
ветки перед мержем.- Минимальная поддерживаемая версия OpenWrt в требованиях исправлена на
22.03+ (было ошибочно указано 21.02+ — nftables/fw4 стал дефолтом
только в 22.03).
Изменено
install.sh:REPO_RAWтеперь переопределяем через переменную
окружения — можно install-тестировать ещё не смёрженную ветку целиком,
не трогая сам скрипт.docs/install-keenetic.mdдополнен и добавлен в индекс документации
обоих README (существовал, но нигде не был на него ссылки).
XKeen SmartRoute v1.2.4
Исправлено
- Индикатор «онлайн» и цифры трафика на странице профилей вводили в
заблуждение, когда несколько профилей делят один сервер. Xray считает
трафик по тегу outbound'а, а не по тому, какое правило маршрутизации его
туда направило — так что если, скажем, ChatGPT и Claude сейчас указывают
на один и тот же сервер, любой трафик через него зажигает «онлайн» у
обоих профилей и показывает одинаковые отдачу/приём, даже если реально
работает только один. Это не баг маршрутизации (у каждого профиля
по-прежнему свои собственные правила в05_routing.smartroute.json) —
чисто отображение сигнала, который в принципе не детализируется по
профилю на нашей стороне. Оба интерфейса (LuCI и панель) теперь честно
показывают это: подсказка у индикатора и пометка*у полосок трафика
перечисляют, с какими другими профилями сейчас общий сервер, вместо
того чтобы притворяться независимым замером на каждый профиль.
Domain/IP lists — 2026-08-31
Domain/IP list update — 2026-08-31
- YouTube (already in geosite -- IP snapshot is informational only) (
lists/ip/youtube.lst): 18 IP(s) total (+10 / -2)
XKeen SmartRoute v1.2.3
Исправлено
packetEncodingтерялся при импорте VLESS-подписки. Некоторые узлы
несут в ссылке подпискиpacketEncoding=xudp—build_outboundэтот
параметр не читал вообще, ни в какой форме (подтверждено сверкой сырой
строки подписки с нашим сгенерированным outbound'ом для одного и того
же узла). Теперь передаётся вsettings.vnext[].users[].packetEncoding,
как и в самой подписке — тот же принцип, что уже применён кextra-полям
XHTTP: не додумывать, что параметр не нужен, а передавать то, что просит
сама подписка. Не выделено в изолированный тест как единственная причина
конкретного вживую воспроизведённого сбоя в этой же сессии (тот, похоже,
был по большей части из-за перегруженного шлюза Double VPN) — но пропуск
реального поля схемы сам по себе достаточное основание для фикса.
XKeen SmartRoute v1.2.2
Исправлено
- Xray не запускался после жёсткой (по питанию) перезагрузки роутера.
dmesgна затронутом роутере показалUBIFS: recovery needed/
recovery completedпри монтировании после сбоя — flash-файловая
система восстанавливала журнал, и04_outbounds.smartroute.json
(файл outbound'ов, который реально читает Xray) остался 0 байт, хотя
исходник (state/outbounds.json, из которого он генерируется) уцелел
без повреждений. В отличие от05_routing.smartroute.json/
07_observatory.smartroute.json, которыеgenroute.shперегенерирует
по cron каждые 3 минуты и потому уже самовосстанавливаются после такой
же потери данных, этот файл пишется только при импорте/обновлении
подписки — без дополнительной проверки повреждённая копия оставалась
сломанной бесконечно, блокируя вообще любой старт/рестарт Xray.
_sr_xray_validateтеперь при каждом запуске проверяет, что файл
существует и парсится как JSON, и при необходимости молча
пересобирает его изstate/outbounds.jsonтем же преобразованием,
что используетsubscription.sh.
XKeen SmartRoute v1.2.1
Быстрый фикс: на живом роутере, поставленном с нуля прямо этим install.sh,
обнаружились два независимых бага, из-за которых стек не заработал сразу
после установки — оба воспроизведены и исправлены вживую в одной сессии.
Исправлено
-
rpcd-бэкенд LuCI-плагина не находилjq— в отличие от
lib/*.sh,luci.xkeen-smartrouteне прописывалPATHдо
Entware'овских/opt/sbin//opt/bin, аrpcdисполняет
script-protocol бэкенды с голым системнымPATH. Все ~100 прямых
вызововjqв файле (включаяwrap_array) падали с «not found», а
wrap_arrayэту ошибку проглатывал и отдавал пустой массив вместо
ошибки — «Подписок пока нет» (и то же для серверов/профилей/категорий)
в LuCI выглядело как отсутствие данных, хотя реальное состояние на
диске было корректным. Добавлен тот жеexport PATH, что уже был у
lib/common.sh, с той же причиной. -
Xray не запускался вообще после установки с нуля. Два независимых
бага в одном и том же блокеinstall.sh(«xkeen ещё не установлен»),
пропускаемом при повторном/незавершённом запуске — та же категория, что
и три бага переустановки, найденные 24.08, просто на других шагах:- Неймификация
02_transport.json(устаревший глобальный формат
transport, который новый Xray-core уже не поддерживает — «Global
transport config has been removed») не происходила, и Xray отказывал
в старте на валидации конфига. - Создание пользователя
xkeen(нуженS24xray'омуsu) тоже не
происходило —suпадал с «No passwd entry for user 'xkeen'», Xray
не запускался вообще, а это маскировалось под ранее известную гонку
чтения-confdir(0 из 10 файлов вместо обычного «одного потерянного»).
Оба шага (плюс переустановка Entware-сборки Xray) вынесены из
одноразового блока в секцию, которая выполняется при каждом запуске
install.sh— как раньше уже сделали для00_api.smartroute.json.
Заодноlib/common.sh(_sr_xray_validate) теперь сам проверяет и
чинит оба состояния при каждом рестарте Xray — защита не только на
момент установки, но и на всё время работы системы. - Неймификация
XKeen SmartRoute v1.2.0
Итог планового аудита технического долга (2026-08-22): 4 критичных, 8
высоких, ~34 средних и 14 низких находки закрыты, каждая проверена вживую на
реальном роутере. Подробный отчёт по каждой находке — в истории коммитов
develop.
Безопасность
- Жёсткий kill-switch не работал вообще на стоковом OpenWrt — правило
firewall ссылалось на ipset, который никто не создавал (секцияconfig ipsetотсутствовала), так что при падении Xray трафик профиля с
включённым kill-switch не блокировался. Добавлена сама firewall-секция +
современнаяdhcp-секция вместо устаревшего inline-синтаксиса;
install.shтеперь сам ставитdnsmasq-full; проверка возможностей
dnsmasq перед включением с понятной ошибкой, если их нет. Заодно —
устаревшие IP отключённого профиля больше не утекают в правило другого
профиля при повторном включении (firewall reloadне подчищает
осиротевший nftables-набор сам). - Панелью мог управлять любой сайт при пустом пароле — wildcard CORS,
открытыйOPTIONS *, WebSocket без проверки Origin.corsWrapи
upgrader.CheckOriginтеперь сверяют Origin с реальнымHostзапроса;
найден и закрыт попутный баг того же класса — два хендлера ставили
собственныйAccess-Control-Allow-Origin: *поверх уже правильного
значения. - Хранимая XSS через адрес сервера подписки в обоих UI (LuCI и панель) —
враждебная подписка могла выполнить произвольный JS в авторизованной
сессии администратора. Свыше 12 мест рендеринга переведены на безопасный
вывод текста вместоinnerHTML. - Путь traversal через
/в имени профиля —save_profile/
delete_profile/killswitch_setмогли писать/удалять файл вне каталога
профилей. Имя с/теперь отклоняется. - URL подписки (с секретным токеном) мог попасть в лог при ошибке
импорта, файл подписок хранился с правами 0644. Токен обрезается перед
логированием, файл — 0600.
Исправлено
- Истечение сессии панели показывало пустой экран вместо редиректа на
логин —401теперь централизованно ловится и вызывает экран входа. uninstall.shмог зависать (xkeen -restartбез таймаута) и оставлял
живыми часть состояния (редирект трафика, gateway, kill-switch) после
удаления.- 12 обработчиков
rpcd-скрипта возвращали «успех» независимо от
реального кода выхода — в частности, включение kill-switch могло
показывать «включено» без единой реальной защиты. Оба UI теперь
откатывают контрол и показывают настоящую ошибку. - Потеря выбора серверов в свёрнутых группах при сохранении профиля и
Double VPN-пула (в LuCI это приводило к потере вообще всех выбранных
серверов при любой перерисовке). - Отключение клиента (закрытие вкладки/потеря сети) во время
refresh_subscription/import_subscriptionмогло оборвать запись
файлов состояния на середине — RPC-вызовы панели больше не привязаны к
времени жизни HTTP-соединения. - Импорт подписки был O(n²) (пересериализация всего списка серверов на
каждый новый сервер) — теперь линейный. - Xray перезапускался даже когда обновление всех подписок целиком
провалилось; IPv6-литералы в квадратных скобках калечились при парсинге
хоста. health.jsonрос монотонно и никогда не подчищался; добавлены
таймауты/keep-alive на HTTP-сервере панели (защита от slowloris и
зависших WebSocket-пиров);tailFileне переоткрывал файл логов при
ротации.- ~4300 лишних строк лога в сутки на установке без единого
balancer-профиля — теперь логируется только переход состояния. redirect.shудалял файл состояния при неудачной проверке firewall,
хотя лог утверждал обратное — теперь делает бэкап и восстанавливает при
отказе.- Gateway-профиль (Clash-совместимый
PUT /proxies/{name}) терял поля
devices/ip_ranges/removed_serversпри сохранении. - Битый файл одного профиля обрушивал список профилей целиком; расхождение
словарей RU/EN на 19+ ключей; несколько более мелких находок (нет
confirm()перед удалением профиля, параллельные poll-циклы панели,
расхождение окна опроса LuCI/панель, ACL с 5 неиспользуемыми
деструктивными методами логов) — полный список см. в истории коммитов.
Исправлено (найдено во время полного цикла переустановки на тестовой ветке)
install.sh: переустановка не была по-настоящему идемпотентной.
Обнаружено живым прогономuninstall.sh(без--purge) →install.sh
на тестовой ветке — три независимых бага:- Cron мог остаться полностью пустым после переустановки: под
set -eu
crontab -l | grep -v ...завершается с ненулевым кодом, если у
root'а ещё нет crontab (ровно так послеuninstall.shи на первой
установке) — обрывало подстановку до того, как записались реальные
задачи,crontab -получал пустой ввод. Без cron переставали работать
автообновление подписок/списков, ночной рестарт Xray и регенерация
routing/outbounds. 00_api.smartroute.json(gRPC API Xray, без которого панель не видит
трафик/Observatory) и очистка заглушки04_outbounds.jsonбыли
вложены в блок «xkeen ещё не установлен» — при переустановке этот
блок пропускался целиком, и файл не пересоздавался.- Сохранённое состояние (
/etc/xkeen-smartroute/state) переживает
переустановку без--purge, но реальное применение — сгенерированный
04_outbounds.smartroute.json, nftables-цепочка редиректа,
dnsmasq/firewall-секции kill-switch — нет:install.shтеперь
восстанавливает их из сохранённого состояния в конце шага установки
LuCI-модуля.
- Cron мог остаться полностью пустым после переустановки: под
Исправлено (найдено на живом роутере после того, как частые рестарты Xray стали нормой)
Как только рестарты Xray стали происходить регулярно (ночной cron заработал
впервые после фикса выше, плюс каждое сохранение профиля), на реальном
роутере проявились три независимых, ранее незаметных бага самого
Xray-core 26.2.6 — не связанных с сегодняшними правками install.sh, сам
пакет xray-core на этом роутере не менялся уже неделю:
xray run -confdirможет молча потерять один файл конфига при слиянии
— без единой ошибки в логе. Иногда это был файл с правилами
маршрутизации профилей — трафик в этом случае просто уходил через
«первый попавшийся» outbound вместо назначенного профилем сервера.
Подтверждено вживую: до 5 попыток подряд из 10 терялся файл.sr_restart_xray
теперь проверяет, что каждый*.jsonиз confdir реально попал в лог
запуска, и перезапускает Xray заново (до 10 раз), пока это не так.- Собственное правило маршрутизации gRPC API панели никогда не переживало
слияние конфига — не гонка, а стабильно воспроизводимый архитектурный
баг: как только confdir читает ещё один файл с ключомrouting, этот
файл побеждает целиком, без слияния массивов правил. Из-за этого
панель не могла получить от Xray вообще ничего (трафик, Observatory,
«сейчас в сети») — что и стояло за «протухшим на 46 часов» статусом
здоровья серверов. Правило теперь эмититgenroute.sh, в тот же файл,
что уже надёжно побеждает при слиянии (тот же приём, что раньше
применили к резервному правилуredirect/tproxyи к политике сбора
статистики — см. их собственные комментарии в коде). - Запросы трафика по outbound'ам падали с
QueryStats only works its own stats.Manager— известный пробел апстрима (XTLS/Xray-core#2296,
независимо подтверждён в XTLS/Xray-core#4509): нужен отдельный
верхнеуровневый блок"stats": {}, не только флаги в"policy". Добавлен.
Не обошлось без дублей и на нашей стороне — ретраи из первого пункта сами
поначалу дважды спотыкались о set -e в busybox ash (переменная
var="$(cmd)" наследует код возврата команды, даже внутри тела if), из-за
чего save_profile/delete_profile иногда падали без единого сообщения в
логе. Исправлено; 10/10 чистых прогонов после фикса, включая прогон с
реальным рестартом Xray.
Исправлено (найдено при живой проверке уже готовых правок)
- Обновление подписки на 10+ серверах перемешивало их порядок — фикс
O(n²)-импорта (см. выше) писал по одному файлу на сервер с именем вида
sv_$i.jsonбез ведущих нулей; слияние глобом сортирует имена по
алфавиту, а не по числу, так чтоsv_10.jsonвставал раньшеsv_2.json.
Порядок был важен: серверы с автовыбором должны идти первыми в списке.
Имена файлов теперь с ведущими нулями. - Удаление профиля не показывало никакого сообщения об успехе (в отличие
от сохранения, которое явно пишет «Сохранено, xray перезапущен») — добавлено
такое же сообщение об удалении в обоих интерфейсах.
Изменено
- Картинки статики панели сжаты (favicon 924 КБ → часть ~230 КБ суммарно
после сжатия) без потери качества на реальном размере отображения. - 16 копий 4 повторяющихся JS-функций вынесены в общий модуль для каждого
UI. go.mod/CI версия Go больше не может разойтись — CI читает версию из
go.modнапрямую.- Вся документация под
docs/functionality_doc/иdocs/UI_functionality/
и оба README сверены и обновлены по итогам этой сессии правок.
Domain/IP lists — 2026-08-24
Domain/IP list update — 2026-08-24
- YouTube (already in geosite -- IP snapshot is informational only) (
lists/ip/youtube.lst): 10 IP(s) total (+2 / -10)