Commit Graph
27 Commits
Author SHA1 Message Date
Dushnilin 24c11bbca8 feat(rulesets): add Twitch preset and resilient CDN fallback 2026-09-14 14:46:28 +03:00
Dushnilin 26431f50d3 feat: per-section MAC/DNS exclusions, boot latency sweep, WDTT/OlcRTC providers, DNS hijack socket collision fix
Features:
- Per-Section MAC Exclusions: nft, generator_routes, section.js, i18n
- Per-Section Routed DNS: connections, generator_routes, nft, validator,
  types.ts, section.js, state.uc, reload.uc
- Boot Latency Sweep: ui.uc latency boot sweep with fixture dispatchers
- WDTT provider: full backend (common, validator, runtime), sing-box
  outbound, diagnostics, component install, updater, i18n, section.js UI
- OlcRTC provider: full backend (common, validator, runtime), sing-box
  outbound, diagnostics, component install, updater, i18n, section.js UI
- WireGuard-over-TURN tunnel (WDTT) and TCP-over-WebRTC tunnel (OlcRTC)
  as sidecar processes with local SOCKS5, routed through sing-box outbound

Bug fixes:
- route.uc: restrict hijack-dns to local DNS inbounds only (dns-in,
  source-dns-in, dns-health-*) — fixes socket collision between sing-box
  and dnsmasq on port 53 via SO_REUSEADDR transparent write-back sockets
- runtime.uc: add Port 53 socket collision diagnostic with auto-fix
  (sing-box restart to clear parasitic UNCONN sockets with Recv-Q)
- runtime.uc: add dnsmasq dns_redirect check with auto-fix — disables
  firewall4 DNAT that causes TProxy to rewrite destination to router :53
- failover.uc: add wdtt/olcrtc to failover candidate actions
- telegram.uc: show WDTT/OlcRTC installed status in /info

Tests: 135/155 shell + 591/591 frontend
2026-09-11 18:04:03 +03:00
Dushnilin bc4f12913f fix(providers): resolve zapret2 startup crash, nft desync EPERM, and mieru ruleset crash loop
- fix(zapret2): add safe_str fallback and avoid default --filter-tcp=443 injection on UDP rules in prepare_strategy_args()
- fix(providers): make individual rule failures non-fatal in start_runtime() so one bad rule does not rollback all running rules
- fix(binaries): dynamic candidate resolution for nfqws and nfqws2 across standard OpenWrt and custom paths (/opt/zapret2/nfq2, /opt/zapret2/nfq, /opt/zapret2, /usr/bin)
- fix(nft): add raw_output notrack chain and mangle_output/forward counter return rules for desync marks (0x40000000, 0x20000000) and musl/nobody skuid (2147483647, 65534) to prevent EPERM rawsend failure on reload
- fix(reload): ensure nft_rebuild is triggered on zapret and zapret2 runtime updates
- fix(singbox): reject mieru outbounds from rule_set download_detour and http_clients dial_detour to prevent fatal startup crash loop
- fix(singbox): detect sing-box 1.14+ and omit deprecated download_detour on remote rule-sets when http_clients is active
- fix(action): pre-seed /etc/config/zapret2 with enabled=0 via core.uci before package install to prevent conflicting upstream daemon startup
- test(ruleset): add verification tests for mieru download_detour and dial_detour rejection
2026-09-10 20:18:00 +03:00
Dushnilin f2865b4bb2 fix: resolve parental & profile blocklists saving and enforcement, add dashboard support for missing protocols 2026-09-09 20:10:30 +03:00
Dushnilin f92c931a72 fix: zapret2 runtime resolution, tailscale proxy installation and protocol labels in server lists 2026-09-08 21:57:42 +03:00
Dushnilin e8c1d9d382 feat: стабильность подписок, порог DNS failover, прямой порт прокси и TorrServer Direct
- subscription: детерминированная сортировка аутбаундов при расчете сигнатуры кэша (защита от перезапусков при shuffle)
- dns: порог последовательных ошибок dns_failover_failure_threshold (защита от флаппинга)
- singbox: выделенный direct_bypass inbound (mixed port 2080) для прямого выхода устройств в обход TPROXY
- torrserver: автоматический bypass cgroups v2 services/torrserver прямо в WAN
- zapret: нормализация устаревших параметров conntrack --ctrack-timeouts
- ui: интеграция управления службами TorrServer Direct и Direct Proxy в LuCI
- tests: новые тесты subscription_order_independence и direct_bypass_torrserver
2026-09-06 21:19:42 +03:00
Dushnilin 404db8ae05 fix(dpi-bypass): TCP keepalive + conntrack tuning + nfqueue watchdog
- sysctl: tcp_keepalive=60/10/3, conntrack_established=600s (was 5 days)
- nfqws/nfqws2: --ctrack-timeouts=30,30,600,30,30,30,30,30 in default strategy
- watchdog: probe_nfqueue checks nfqws/nfqws2 process health every 300s
- watchdog: heal_nfqueue_stopped restarts tachyon if DPI bypass processes die

This eliminates the need for manual DNS flush + device restart when DPI
starts blocking connections. Dead connections are now detected in ~90s
instead of hours, and stale conntrack entries expire in 10 min instead
of 5 days.
2026-08-28 20:05:03 +03:00
Dushnilin bd083cc5d3 feat: content blocking в родительском контроле (блокировка доменов на устройство)
Новые опции config schedule:
- blocked_domains: домены для блокировки (full:/keyword:/regex: префиксы)
- mode: block (список) | allow (whitelist — всё кроме списка)
- dns_level: блокировка на DNS-уровне (NXDOMAIN через dns-block-in)
- notify: уведомление в Telegram при попытке доступа

Механизм:
- sing-box: новый dns-block-in inbound (127.0.0.43:1053) с reject-правилами
  для заблокированных доменов; source_ip_cidr для IP-устройств;
  invert для whitelist-режима
- nftables: nat chain dns_block — REDIRECT DNS-запросов устройств на
  dns-block-in; time-based через meta hour для расписаний; MAC-устройства
  матчатся по ether saddr (DHCP-динамические IP поддерживаются)
- route rules reject для always-on расписаний (fallback при обходе DNS)
- telegram worker: проверка nft counters каждые 60s, уведомление о
  заблокированной активности

UI (parental.js):
- колонка Blocked Sites в таблице
- textarea с пресетами: соцсети, видео, игры, взрослый контент,
  мессенджеры, магазины
- mode / dns_level / notify переключатели

Валидация: домены, mode, dns_level, notify в validator.uc
Тесты: tests/content_blocking.sh (98/98 backend, 522/522 frontend)
2026-08-21 05:11:39 +03:00
Dushnilin 0964b79171 fix(ai-chat): fix AI Chat and Assistant to work with LM Studio
- Fix response parsing: check report field, not just message
- Pass user query text to LLM instead of ignoring it
- Append user question to diagnostic prompt with system context
- Increase timeout to 120s for LM Studio responses
- Add command_status_from_args to core/common.uc exports

Closes #38
2026-08-19 15:57:42 +03:00
Dushnilin 999686fea3 fix(ui): display short commit SHA next to Tachyon version in UI and constants 2026-08-11 19:06:00 +03:00
Dushnilin e6e3853f05 fix(errors): перестать глотать сбои записи состояния в пустых catch
Пустых catch в кодовой базе около полусотни, и они не одинаковые. Большинство
выражает намерение: fs.unlink бросает на ENOENT, а вызывающий говорит «пусть
этого файла не будет», и отсутствующий файл это условие уже выполняет; разбор
json в цикле пропускает мусорную строку и берёт следующую. Такие места теперь
несут пояснение, почему пустое тело здесь и есть правильный ответ.

Семь мест к этому классу не относились: там сбой означал потерю состояния, а
дальше код шёл так, будто всё получилось.

Watchdog писал через пустой catch файл лока перезапуска прокси, шкалу
GOMEMLIMIT после OOM, бэкап конфига и метку keepalive. Не лёгший лок означает,
что следующий тик перезапустит прокси заново, а счётчик rate-limit об этом не
узнает; не записанная метка keepalive заставляет init.d считать watchdog мёртвым
и перезапускать его. Все четыре теперь идут через write_state_file, который
логирует отказ. Метка пишется на каждом тике uloop, поэтому безусловная строка
залила бы syslog именно при переполненной файловой системе — там, где лог нужнее
всего; вместо этого каждый путь сообщает о первом отказе и молчит до следующего
успеха, что заодно делает видимым восстановление.

Контроллер разбирал /etc/sing-box/config.json ради портов http и tproxy и при
неудаче молча брал 4534 и 4530. Watchdog после этого опрашивает не тот порт,
вечно считает прокси нерабочим и лечит его по кругу — при том, что в логе нет
ничего, что связало бы это с конфигом. Разбор вынесен в общую функцию, которая
сообщает о непарсящемся конфиге один раз на процесс.

Telegram молча терял карту callback-токенов: токен уже вшит в клавиатуру к
моменту записи, поэтому провал отдаёт пользователю кнопку, которая на нажатие
ответит «кнопка устарела». Обновление списков молча теряло маркер отложенного
применения nft — списки обновлены на диске и до nftables не доехали никогда,
а строкой выше в лог написано, что маркер сохраняется. urltest молча выкидывал
битое регулярное выражение из конфига пользователя, отчего группа тихо
подхватывала меньше outbound-ов, чем сказано в конфиге.

tests/heal_escalation.sh проверял порядок строк по литералу fs.writefile для
лока и обновлён под новый вызов.
2026-08-08 22:32:09 +03:00
Dushnilin 22a236e5d1 feat: commit-level version tracking for same-release updates
Backend:
- constants.uc: add TACHYON_COMMIT_SHA constant (placeholder __COMPILED_COMMIT_SHA__)
- build.sh: capture git rev-parse HEAD and sed-replace commit SHA placeholder
- Makefile: same commit SHA sed replacement for OpenWrt builds
- action.uc: modify check_tachyon() to compare installed commit SHA with
  target_commitish from GitHub release, new status 'outdated_same_release'
- action.uc: reuse release_json for both version and commit SHA extraction
- updater.uc: add release_commit_sha helper to extract target_commitish
- updates.uc: extend cacheable status to include outdated_same_release

Frontend:
- main.js: handle outdated_same_release status in renderComponentCard
- main.js: include outdated_same_release in shouldShowInstallAfterCheck
- main.js: include outdated_same_release in applyCachedCheckResults

i18n:
- Add 'Update is available for current release' and 'Update is available
  for current release:' to .pot and .ru.po files

78 tests pass.
2026-08-03 21:35:06 +03:00
Dushnilin f05a55c37e fix(core): remove hardcoded fallback version from constants.uc and use dynamic package lookup for APK and OPKG 2026-07-27 16:49:52 +03:00
Dushnilin 197013f043 fix: persistent community subnet storage & reboot fallback for Telegram in section Main 2026-07-27 08:38:55 +03:00
Dushnilin b3e6fcd0c1 fix: load community subnets from /tmp/sing-box/rulesets path & bump v1.2.34 2026-07-26 22:56:16 +03:00
Dushnilin da55799a04 release: v1.2.33 - dynamic community subnets, AmneziaWG action support & flowtable bypass 2026-07-26 22:29:01 +03:00
Dushnilin e98a2c325e fix: community subnets nftables population & Telegram IP ranges
- nft/apply.uc: nft_add_community_subnet_file_for_section now populates
  common_set (tachyon_subnets / tachyon_rule_<Section>_subnets) when section
  is not a priority rule section. Previously, community subnets for normal
  proxy/VPN sections were skipped completely.
- updates.uc: fix typo SUBNETS_TELERAM -> SUBNETS_TELEGRAM in BUILTIN_SUBNET_URLS
- bump version 1.2.31 -> 1.2.32
2026-07-26 21:18:26 +03:00
Dushnilin d8a0d64501 feat: DNS Turbo Cache - persistent FakeIP + startup domain prefetch
- singbox/dns_prefetch.uc: new module, resolves ~70 popular blocked domains
  after startup to warm sing-box FakeIP cache (sleep 10s, then nslookup each)
- lifecycle.uc: DNS_PREFETCH_UC constant + module_background call in start_main
- generator.uc: when dns_turbo_cache=1 use /etc/sing-box/cache.db (persistent)
- settings.js (LuCI): Flag toggle for dns_turbo_cache in DNS settings block
- renderAdvancedSettings.ts: DNS Turbo Cache section with toggle + save
- tachyon.pot / tachyon.po / tachyon.ru.po: translations RU
- constants.uc: bump 1.2.30 -> 1.2.31
- package.json: bump 1.2.30 -> 1.2.31
2026-07-26 20:22:35 +03:00
Dushnilin 96f87d4150 release: bump version to 1.2.30 2026-07-26 18:56:35 +03:00
Dushnilin c65b3b1fb4 feat(core): динамическое определение версии пакета из OPKG/APK манифеста в constants.uc 2026-07-26 14:12:29 +03:00
Dushnilin 7cd48ad5fe fix(updates): порядок объявления функций ucode и автоматический fallback скачивания пакетов (v1.2.29) 2026-07-26 12:54:07 +03:00
Dushnilin 509cf128b8 Merge: объединить изменения из upstream forkop в tachyon, разрешить конфликты и исправить тесты E2E 2026-07-15 17:56:18 +03:00
Dushnilin b60fd322c9 Release 1.0.8: обновить TACHYON_RELEASE_REPO на Dushnilin/tachyon 2026-07-14 09:27:51 +03:00
Dushnilin 46ef97fe89 Release 1.0.6: синхронизировать изменения из upstream и исправить баг фильтра URLTest/Priority 2026-07-14 08:56:31 +03:00
Dushnilin 8c9bb8734b Рефакторинг и стабилизация: обновление установщика, бэкенд-утилит и оптимизация фронтенда
- Установщик (install.sh): внедрена верификация хешей sha256sums.txt, нормализована очерёдность бутстрапа ucode до языковых проверок.
- Сборщик (build.sh): добавлена автоматическая генерация sha256sums.txt для пакетов релиза.
- Бэкенд: права на honeypot FIFO ограничены до 0660 в watchdog.uc, исправлена опечатка в SUBNETS_TELEGRAM, удалён helpers.old.uc.
- Тесты бэкенда: написаны тесты для core_ip, core_url и config_connections.
- Фронтенд: реализовано автопереподключение WebSocket с экспоненциальным бэкоффом, проведена дедупликация виджетов и модальных окон в initController.ts, мигрирован CSS-префикс с fkp_ на tachyon_.
- Тесты фронтенда: добавлен initController.test.ts для тестирования загрузки дашборда.
2026-07-13 20:23:33 +03:00
Dushnilin f57dac6b52 refactor(rebrand): полный ребрендинг в Tachyon и перенос служб watchdog/doctor на Ucode 2026-07-13 14:09:38 +03:00
Dushnilin e89a795566 refactor(rebrand): полный ребрендинг в Tachyon и перенос служб watchdog/doctor на Ucode 2026-07-13 14:03:31 +03:00