# shater **Управляемый интернет-шлюз для роутеров на OpenWrt.** Одна коробка превращает домашнюю или офисную сеть в прозрачный VPN-шлюз, сетевой блокировщик рекламы, трекеров и вредоносных доменов, средство родительского контроля по устройствам и живую панель аналитики трафика — всё локально, всё self-hosted, всё настраивается из богатой веб-панели. [![License: GPL-3.0](https://img.shields.io/badge/license-GPL--3.0-blue.svg)](LICENSE) ![targets: x86_64 · aarch64_cortex-a53](https://img.shields.io/badge/targets-x86__64%20%C2%B7%20aarch64__cortex--a53-brightgreen.svg) ![feeds: opkg 24.10 · apk 25.12](https://img.shields.io/badge/feeds-opkg%2024.10%20%C2%B7%20apk%2025.12-orange.svg) --- ## Что это **shater** — это сетевой прокси-стек для роутеров на **OpenWrt / ImmortalWrt / BananaWRT** (Banana Pi BPI-R3, BPI-R4 и совместимые). Он прозрачно (без настройки клиентов) заворачивает весь LAN-трафик через прокси с маршрутизацией по домену, гео и клиенту, фильтрует DNS, собирает статистику и управляется из встроенной веб-панели. Ядро — **форк движка [sing-box](https://github.com/SagerNet/sing-box) через [sing-box-lx](https://github.com/Leadaxe/sing-box-lx)** — вкомпилировано в один Go-бинарь `shaterd` вместе с control-plane, DNS-фильтром, агрегатором статистики и самой веб-панелью. За счёт sing-box поддерживается широкий и актуальный набор протоколов: VLESS/VMess/Trojan/Shadowsocks, Reality/XTLS, WireGuard, **AmneziaWG 2.0**, Hysteria2, TUIC, XHTTP, MASQUE/CONNECT-IP. Интеграция в OpenWrt — тонкий **LuCI-лаунчер**: мини-дашборд и кнопка «Открыть панель», которая по одноразовому токену передаёт браузер в полноценную SPA-панель, поднятую демоном на собственном порту (по умолчанию `:8088`). --- ## Ключевые возможности **Прозрачный прокси и маршрутизация** - TPROXY data-plane для нескольких LAN-интерфейсов (TCP + UDP), сниффинг SNI/Host/QUIC, без утечек DNS. - Правила маршрутизации по источнику (IP/CIDR/MAC/интерфейс/зона), назначению (domain/suffix/keyword/geosite), спискам, порту, протоколу → outbound / selector / chain / direct / block. - Группы узлов с балансировщиком/обсерваторией (least-ping / failover / round-robin), **мульти-хоп цепочки** и выбор egress по правилу. **Надёжность («железно»)** - **Fail-closed kill-switch**: мёртвая группа → block, а не тихая утечка мимо прокси; собственная nft-таблица `inet shater` и свои марки/таблицы, fw4 не трогаем. - Атомарный apply с валидацией движком и `nft -c`, **commit-confirm** с авто-откатом к последней рабочей конфигурации. - Идемпотентный reconcile из hotplug/boot под flock; management-bypass (SSH/LuCI/LAN) всегда в обход. **DNS, фильтрация, блокировки** - Перехват `:53`, DNS движка sing-box в процессе; резолверы DoH/DoT/plain/FakeIP, выбор резолвера по домену. - **Блок-листы с гибкими источниками**: `inline` / `file` / `url` (авто-обновление) / категория `geosite`; hosts-файл, plain-список или AdBlock-стиль `||domain^` компилируются в локальный `.srs`. Эффективный компилированный матчер вместо dnsmasq-мегасписков. - **Block-DoH/DoT** — не даёт устройствам обходить фильтр через свой шифрованный DNS. **Подписки и узлы** - Подписки (VLESS/VMess/Trojan/SS/WG/AmneziaWG), форматы Clash/sing-box/Xray-JSON, интервал обновления + вручную + на загрузке; стабильная идентичность узла между обновлениями; квоты/срок из `subscription-userinfo`. - Ручные узлы: share-ссылки, импорт файла, `wg-quick`/AmneziaWG `.conf`. - Health board: TCP + реальная проба через прокси-путь, exit-IP, «протестировать все». **Контроль по устройствам** - Авто-обнаружение устройств (dhcp.leases + `ip neigh`), имена, живой статус/трафик. - Тумблеры на устройство: прокси on/off, блок-листы on/off, страна/узел выхода; блок/allow домена для одного устройства или для всех; расписания. **Статистика и видимость** - Топ доменов (запрошенные/заблокированные), allowed-vs-blocked, разбивка по устройствам, таймлайны — из DNS-событий движка в процессе (без скрейпинга логов). - Трафик по клиенту/узлу/правилу (байты) из nft-счётчиков; живой query-log. **Панель и профили** - Встроенная SPA-панель (собственный порт, вшита в бинарь): overview, узлы и подписки, правила маршрутизации, DNS/блок-листы, устройства, apply/rollback. - Именованные профили/сцены и WAN-профили (условные оверрайды). Полный список с тегами MVP/T1/T2 — [`docs-shater/FEATURES.md`](docs-shater/FEATURES.md). --- ## Архитектура Один бинарь `shaterd` держит движок, control-plane, DNS-фильтр и веб-сервер панели в одном процессе; OpenWrt-обвязка (тонкий LuCI + procd/system glue) оборачивает его. Конфиг — UCI desired-state; демон рендерит его в конфиг движка и применяет; телеметрия течёт обратно в панель. ```mermaid flowchart TB subgraph BIN["shaterd — один бинарь (форк sing-box-lx)"] ENG["движок sing-box\nпротоколы · Reality · AmneziaWG 2.0 · DNS · routing · stats"] CTRL["control-plane (shater/)\nUCI-модель · генерация конфига · apply/rollback · nft/routing"] FILT["DNS-фильтр + блок-листы + политика по устройствам (shater/)"] STAT["агрегатор статистики (shater/)"] PANEL["веб-сервер панели + вшитая SPA (свой порт, токен-auth)"] end subgraph WRT["OpenWrt-обвязка (openwrt/)"] LUCI["тонкий LuCI — мини-дашборд + кнопка «Открыть панель»"] PROCD["procd init · hotplug · uci-defaults · fw4/routing"] end LUCI -->|"ubus: mint token"| PANEL PROCD --> BIN CTRL --> ENG FILT --> ENG ENG --> STAT STAT --> PANEL ``` Путь трафика: LAN-клиент → `nft tproxy` (mark → tproxy-порт) → tproxy-inbound sing-box (сниффинг SNI/Host/QUIC) → маршрут по правилу → outbound/selector/chain (проксировано) · direct (flow-offload) · block. Подробные диаграммы (auth-handoff, data-plane, DNS-flow, apply-flow) — в [`docs-shater/ARCHITECTURE.md`](docs-shater/ARCHITECTURE.md). --- ## Установка shater поставляется двумя подписанными фидами. Выберите по версии OpenWrt на роутере: - **OpenWrt 24.10** → фид **opkg** (`.ipk`, `Packages.gz`, ключ usign). - **OpenWrt / ImmortalWrt / BananaWRT 25.12+** → фид **apk** (`.apk`, `packages.adb`, EC-ключ). Пакеты ставятся по зависимостям: `shaterd` → `shater-core` → `luci-app-shater` (+ опциональный `byedpi`). `shaterd` подтягивается автоматически как зависимость. ### Путь A — фид opkg (OpenWrt 24.10) ```sh # 1) доверяем ключу фида — ИМЯ файла обязано равняться отпечатку usign-ключа. wget -O /etc/opkg/keys/5ac4b177689cb8e0 \ https://git.qomar.pw/omar/shater/releases/download/latest/shater-feed.pub # 2) добавляем фид (один URL обслуживает все арки). echo "src/gz shater https://git.qomar.pw/omar/shater/releases/download/latest" \ >> /etc/opkg/customfeeds.conf # 3) обновляемся и ставим (shaterd подтянется как зависимость). opkg update opkg install luci-app-shater # -> shater-core -> shaterd opkg install byedpi # опционально: ByeDPI desync-egress ``` Обновление: `opkg update && opkg upgrade shaterd shater-core luci-app-shater byedpi` (обновляйте только эти четыре пакета, не системные). ### Путь B — фид apk (OpenWrt / ImmortalWrt / BananaWRT 25.12+) `/etc/apk/arch` сам выбирает нужный per-arch релиз (apk-релизы раздельны по арке): ```sh # 1) доверяем ключу apk-фида (любое имя *.pem под /etc/apk/keys подходит). wget -O /etc/apk/keys/shater-apk.pem \ "https://git.qomar.pw/omar/shater/releases/download/apk-latest-$(cat /etc/apk/arch)/shater-apk.pem" # 2) добавляем репозиторий — строка указывает на сам ФАЙЛ-ИНДЕКС packages.adb. echo "https://git.qomar.pw/omar/shater/releases/download/apk-latest-$(cat /etc/apk/arch)/packages.adb" \ > /etc/apk/repositories.d/shater.list # 3) обновляемся и ставим (shaterd подтянется как зависимость). apk update apk add luci-app-shater # -> shater-core -> shaterd apk add byedpi # опционально: ByeDPI desync-egress ``` Обновление: `apk update && apk upgrade shaterd shater-core luci-app-shater byedpi`. > Полные инструкции — раздельная установка из `.ipk`/`.apk` вручную, закрепление > версии (`vX.Y.Z` / `apk-vX.Y.Z-`), совместимость с BananaWRT > `25.12-mtk-vendor` — в [`docs-shater/INSTALL.md`](docs-shater/INSTALL.md). ### Включение shater ставится **инертным** (globals выключены), чтобы установка не рвала связь. Настройте узлы/правила (через панель или `uci`), затем включите и примените: ```sh uci set shater.globals.enabled=1 uci commit shater shaterd apply # apply + вооружить commit-confirm на живом демоне shaterd confirm # подтвердить (отменяет авто-откат) ``` `/etc/init.d/shater enable && /etc/init.d/shater start` поднимает демона под procd. Кнопка «Открыть панель» в LuCI чеканит одноразовый токен и передаёт браузер в панель (`:8088` по умолчанию). --- ## Сборка из исходников Ship-артефакт — бинарь `shaterd` со вшитой SPA. Собирается вне дерева SDK скриптом `scripts/build-shaterd.sh`: ```sh scripts/build-shaterd.sh [VERSION] [--fast] ``` Что он делает: (1) собирает панель — `cd panel && npm ci && npm run build` (Vite → `panel/dist`); (2) копирует `panel/dist/*` в `shater/panel/webroot/`, откуда `//go:embed` вшивает **реальную** SPA в бинарь; (3) кросс-собирает под `{amd64, arm64}` с musl-static набором тегов (`CGO_ENABLED=0 GOOS=linux`), stripped/trimmed; (4) прогоняет UPX `--lzma --best` (~42 МБ → ~8–11 МБ); (5) стейджит артефакт в `openwrt/shaterd/files/` для пакета. Затем OpenWrt-пакеты из `openwrt/` собираются каноническим путём SDK. Детали (набор build-тегов, почему `shaterd` — prebuilt-пакет, порядок CI) — в [`docs-shater/INSTALL.md`](docs-shater/INSTALL.md). --- ## Структура репозитория Репозиторий — это оверлей продукта **shater** поверх дерева форка движка **sing-box-lx** (конфликт-фри: движок в апстрим-каталогах, продукт в своих). | Путь | Что это | |------|---------| | `shater/` | Go: control-plane, DNS-фильтр, агрегатор статистики, хост движка | | `panel/` | Админ-SPA (Vite + React + TS) и её Go-сервер | | `openwrt/` | Пакеты: `shaterd`, `shater-core`, `luci-app-shater`, `byedpi` | | `docs-shater/` | Документация продукта (см. таблицу ниже) | | `scripts/` | `build-shaterd.sh` — сборка ship-артефакта | | `ci/` | Скрипты сборки фидов и релизов (SDK, usign/EC, Gitea API) | | `.gitea/workflows/` | `release.yml` — CI: сборка пакетов + подписанные фиды opkg/apk | | `SPECS/` | Конституция форка движка и спеки (Spec Kit) | | `docs-lx/` | Справочник конфигурации фич движка (`lx-config.md`, `.ru.md`) | | `lx-test/`, `submodules/` | Примеры конфигов движка и submodule AmneziaWG-рантайма | | `docs/`, `mkdocs.yml` | **Апстрим** документация sing-box (mkdocs) — как есть | | `adapter/ cmd/ dns/ route/ option/ protocol/ transport/ …` | Дерево движка sing-box-lx | --- ## CI и релизы CI на **Gitea Actions** (`.gitea/workflows/release.yml`) собирает все 4 пакета и публикует **подписанные фиды**: - **opkg (24.10):** один комбинированный релиз, подписан usign-ключом (публичный `dist/shater-feed.pub`, отпечаток `5ac4b177689cb8e0`; секрет — в Gitea-secret `KEY_BUILD`). - **apk (25.12+):** параллельная линия, **по релизу на арку**, подписан EC-ключом (`dist/shater-apk.pem`; секрет — `KEY_APK`). Триггеры: push тега **`vX.Y.Z`** → версионный релиз; `workflow_dispatch` → плавающий `latest`/`apk-latest-` (всегда свежий фид). Публикация — через Gitea API (`ci/gitea-release.sh`). Ключи **никогда не перегенерируются** — это инвалидировало бы доверие на всех развёрнутых роутерах. --- ## Связь с upstream и движок shater вкомпилирует **форк движка sing-box-lx** — тонкий downstream апстрима [SagerNet/sing-box](https://github.com/SagerNet/sing-box), добавляющий набор клиентских фич (XHTTP, AmneziaWG 2.0, MASQUE, расширения наблюдаемости) за build-тегами и живущий **ребейзом на каждый upstream-тег, а не merge**. Форк разрабатывается по Spec Kit; неизменяемые принципы — в [`SPECS/CONSTITUTION.md`](SPECS/CONSTITUTION.md), справочник фич движка — в [`docs-lx/lx-config.ru.md`](docs-lx/lx-config.ru.md). История: **v0.1** (движок на xray-core, полностью рабочая и VM-проверенная версия) сохранена на ветке **[`v0.1`](../../src/branch/v0.1)**. v0.2 схлопнула runtime в один форкнутый бинарь. --- ## Документация | Документ | О чём | |----------|-------| | [`docs-shater/CONTEXT.md`](docs-shater/CONTEXT.md) | **Начните здесь** — контекст проекта, история v0.1→v0.2, testbed/инфра | | [`docs-shater/INSTALL.md`](docs-shater/INSTALL.md) | Сборка ship-артефакта и установка обоих фидов (opkg/apk) | | [`docs-shater/ARCHITECTURE.md`](docs-shater/ARCHITECTURE.md) | One-binary дизайн, auth-handoff, data/DNS/apply-потоки (диаграммы) | | [`docs-shater/FEATURES.md`](docs-shater/FEATURES.md) | Полный список фич с тегами MVP/T1/T2 | | [`docs-shater/ROADMAP.md`](docs-shater/ROADMAP.md) | Фазовый план | | [`docs-shater/DECISIONS.md`](docs-shater/DECISIONS.md) | Почему sing-box, почему форк, split панели, лицензия | | [`docs-shater/DESIGN.md`](docs-shater/DESIGN.md) | Визуальная система панели — «Faceplate», токены, компоненты | | [`docs-shater/PORTING.md`](docs-shater/PORTING.md) | Порт проверенных кусков из v0.1 | Индекс папки — [`docs-shater/README.md`](docs-shater/README.md). --- ## Оборудование Арка `aarch64_cortex-a53` покрывает Banana Pi **BPI-R3** (MT7986/Filogic 830) и **BPI-R4** (MT7988/Filogic 880) — оба таргет OpenWrt `mediatek/filogic`. `x86_64` — QEMU-стенд для тестов. --- ## Лицензия [GPL-3.0](LICENSE) — как у upstream sing-box. Подробности — в [`docs-shater/DECISIONS.md`](docs-shater/DECISIONS.md) (D6). Неофициальный форк, не аффилирован с SagerNet.