- README.md: new Russian product README (what/features/architecture mermaid/install both feeds/build/repo layout/CI/upstream/docs/license) - README.en.md: concise English mirror (root readme was previously English) - README.ru.md: demoted to a pointer stub (was the sing-box-lx fork readme, a competing Russian README) -> points to README.md + engine-fork docs - docs-shater/README.md: folder index Install commands copied verbatim from docs-shater/INSTALL.md; all links verified against existing files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
311 lines
18 KiB
Markdown
311 lines
18 KiB
Markdown
<!-- Язык: **Русский** · [English](README.en.md) -->
|
||
|
||
# shater
|
||
|
||
**Управляемый интернет-шлюз для роутеров на OpenWrt.** Одна коробка превращает
|
||
домашнюю или офисную сеть в прозрачный VPN-шлюз, сетевой блокировщик рекламы,
|
||
трекеров и вредоносных доменов, средство родительского контроля по устройствам
|
||
и живую панель аналитики трафика — всё локально, всё self-hosted, всё
|
||
настраивается из богатой веб-панели.
|
||
|
||
[](LICENSE)
|
||

|
||

|
||
|
||
---
|
||
|
||
## Что это
|
||
|
||
**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-<arch>`), совместимость с 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-<arch>` (всегда свежий фид). Публикация — через
|
||
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.
|