171 lines
17 KiB
Markdown
171 lines
17 KiB
Markdown
# MiniVLESS
|
||
|
||
Маленький персональный Linux-клиент: Tauri 2, Rust, React/TypeScript и отдельный sing-box **1.14.x**. Подключается по VLESS-ссылке к совместимым серверам, в том числе Xray. GUI всегда работает от обычного пользователя.
|
||
|
||
[Скачать Linux-релиз](https://github.com/emil28092005/minivless/releases/latest)
|
||
|
||

|
||
|
||
## Установка готового релиза
|
||
|
||
Скачайте `MiniVLESS_0.1.1_amd64.deb` из Releases и выполните из каталога загрузки:
|
||
|
||
```bash
|
||
sudo apt install ./MiniVLESS_0.1.1_amd64.deb libcap2-bin
|
||
sudo setcap cap_net_admin,cap_net_raw+ep /usr/lib/MiniVLESS/binaries/sing-box
|
||
```
|
||
|
||
Запустите MiniVLESS из меню приложений. Пакет содержит sing-box 1.14.0; capabilities назначаются отдельно и только ему. Если раньше был установлен `/usr/local/lib/minivless/sing-box`, он имеет приоритет — проверьте права именно этого файла. Релиз пока собран для Linux x86_64; это не сборка для Windows/macOS. Контрольные суммы — в `SHA256SUMS` рядом с пакетом.
|
||
|
||
## Использование
|
||
|
||
1. Вставьте `vless://…` — ссылка скрыта и сохраняется только локально.
|
||
2. Выберите режим:
|
||
- **Tunneling включён:** VPN только для отмеченных программ. Остальной трафик — DIRECT.
|
||
- **Tunneling выключен:** VPN для всей системы, независимо от списка программ.
|
||
3. `Refresh` обновляет запущенные приложения. `Add application` позволяет выбрать установленную программу или указать абсолютный путь к её настоящему ELF-бинарнику.
|
||
4. Нажмите `Connect`. `Disconnect` останавливает core и освобождает TUN.
|
||
5. Кнопка **−** в заголовке скрывает окно в системный трей, сохраняя подключение. В меню значка доступны **Show MiniVLESS**, **Disconnect** и **Quit**. Крестик и Quit полностью завершают приложение и останавливают VPN.
|
||
|
||
Если системный трей недоступен (например, GNOME без расширения AppIndicator), кнопка − сворачивает окно в панель задач, откуда его можно вернуть. Для значка трея требуется поддержка StatusNotifier/AppIndicator в рабочем окружении.
|
||
|
||
Пути сохраняются независимо от PID. Несколько процессов одного исполняемого файла объединяются. Отмеченные/добавленные приложения остаются в списке после перезапуска. Переключатель меняет **выборочную маршрутизацию**, а не отключает TUN: TUN используется в обоих режимах.
|
||
|
||
## Требования Linux
|
||
|
||
- Linux с `/dev/net/tun`, nftables и IPv4/IPv6; kernel NFQUEUE (`nfnetlink_queue`, `nft_queue`) нужен для предварительного сопоставления правил sing-box. При его отсутствии core может использовать обычный TUN fallback.
|
||
- GTK 3, WebKitGTK 4.1, системный набор CA, libcap.
|
||
- Для сборки: Node.js 22+, npm, актуальный Rust stable, C/C++ toolchain, pkg-config.
|
||
- Для сетевых тестов: Python 3, OpenSSL, `ip`, `nft`, разрешённые unprivileged user namespaces.
|
||
|
||
Debian/Ubuntu:
|
||
|
||
```bash
|
||
sudo apt install build-essential pkg-config libgtk-3-dev libwebkit2gtk-4.1-dev \
|
||
libayatana-appindicator3-dev librsvg2-dev patchelf libcap2-bin \
|
||
ca-certificates iproute2 nftables python3 openssl
|
||
```
|
||
|
||
## sing-box и права
|
||
|
||
Загрузчик получает фиксированный официальный релиз 1.14.0 для x86_64/aarch64 и проверяет SHA-256 по метаданным GitHub:
|
||
|
||
```bash
|
||
python3 scripts/fetch-sing-box.py
|
||
./binaries/sing-box version
|
||
```
|
||
|
||
Рекомендуется положить core в отдельный каталог с владельцем root, затем выдать capabilities **только ему**:
|
||
|
||
```bash
|
||
sudo install -D -o root -g root -m 0755 binaries/sing-box /usr/local/lib/minivless/sing-box
|
||
sudo setcap cap_net_admin,cap_net_raw+ep /usr/local/lib/minivless/sing-box
|
||
getcap /usr/local/lib/minivless/sing-box
|
||
```
|
||
|
||
Для локальной разработки допустимо:
|
||
|
||
```bash
|
||
sudo setcap cap_net_admin,cap_net_raw+ep "$(realpath binaries/sing-box)"
|
||
```
|
||
|
||
После замены/обновления бинарника capabilities нужно выставить заново. Файловая система должна поддерживать file capabilities и не блокировать их через `nosuid`. **Не запускайте MiniVLESS через sudo.** Приложение проверяет наличие core, его версию, TUN и capabilities; при ошибке показывает команду установки прав. Самостоятельно повышать права оно не пытается.
|
||
|
||
Порядок поиска core: `MINIVLESS_SING_BOX` (явное переопределение), `/usr/local/lib/minivless/sing-box`, ресурс установленного приложения, `binaries/sing-box` проекта в debug-сборке, `binaries/` рядом с исполняемым файлом, `/usr/bin/sing-box`, `/usr/local/bin/sing-box`. Переменная окружения задаёт только путь, не аргументы.
|
||
|
||
## Разработка и сборка
|
||
|
||
```bash
|
||
npm ci
|
||
npm run tauri -- dev
|
||
```
|
||
|
||
Один `npm run dev` запускает только браузерный предпросмотр; подключение в нём отключено.
|
||
|
||
```bash
|
||
npm run tauri -- build --bundles deb
|
||
```
|
||
|
||
Результаты:
|
||
|
||
- `src-tauri/target/release/minivless` — нативное приложение.
|
||
- `src-tauri/target/release/bundle/deb/*.deb` — Debian-пакет с core.
|
||
|
||
Установка пакета: `sudo apt install ./src-tauri/target/release/bundle/deb/*.deb`. Настройку capabilities выполните отдельно, как указано выше. Прямой запуск release-бинарника использует установленный `/usr/local/lib/minivless/sing-box`; можно также положить core в `binaries/` рядом с ним. AppImage не используется: файловые capabilities на смонтированном образе ненадёжны.
|
||
|
||
## Настройки и логи
|
||
|
||
Настройки: `$XDG_CONFIG_HOME/minivless/settings.json`, по умолчанию `~/.config/minivless/settings.json`.
|
||
|
||
Файл имеет права `0600`, каталог — `0700`; запись атомарная. Сохраняются ссылка, пути отмеченных/добавленных программ и положение переключателя. Повреждённые настройки не заменяются молча. Это локальный файл с credential, а не зашифрованное хранилище паролей.
|
||
|
||
Runtime-конфиг создаётся в приватном `runtime-*` под тем же каталогом и удаляется после остановки. Логи — только в памяти, максимум 300 строк по 4096 символов; credential и query-токены удаляются до показа. Полная ссылка не передаётся через аргументы процесса и не попадает в frontend logs. Раскрывающийся блок `Connection logs` показывает диагностику.
|
||
|
||
## Маршрутизация и DNS
|
||
|
||
Используется настоящий TUN sing-box, `auto_route`, Linux nftables `auto_redirect`, IPv4/IPv6 и точные правила `process_path`. В выборочном режиме TUN ограничен UID пользователя, а финальное правило — `direct`. В системном режиме ограничения UID нет, финальное правило — `proxy`. Интерфейс `minivless0`, routing table 2090; собственные routing marks/rules не совпадают со стандартными значениями sing-box.
|
||
|
||
DNS к внешним адресам, включая DNS в LAN, перехватывается средствами TUN/nftables. Запросы выбранных процессов идут по DoH через VLESS; остальные — по DoH напрямую. В системном режиме DNS идёт через VLESS. Используется `1.1.1.1` с проверкой TLS для `cloudflare-dns.com`; домен самого VLESS-сервера разрешается напрямую, чтобы не создавать петлю.
|
||
|
||
**Ограничение общего системного DNS:** при обращении программы к локальному `127.0.0.53` запрос в сеть отправляет systemd-resolved, а не исходная программа. В выборочном режиме такие запросы остаются у системного резолвера и идут DIRECT; установить исходную программу по этому сокету невозможно. Это может влиять на домены, блокируемые системным DNS. Прямые DNS/DoH-соединения выбранной программы маршрутизируются по её executable. В системном режиме исходящие DNS-запросы резолвера тоже входят в VPN. Loopback не перехватывается.
|
||
|
||
Настройки NetworkManager, resolv.conf и systemd-resolved не меняются. У pinned core отключён поиск внешних команд через `PATH`: это предотвращает автоматический вызов `resolvectl` в sing-tun, запросы Polkit и неявные изменения системных DNS-настроек. Используется native nftables backend; fallback через внешние iptables не поддерживается.
|
||
|
||
## Lifecycle
|
||
|
||
Перед стартом выполняется `sing-box check`. `Connected` означает, что core сообщил об успешном старте TUN; доступность конкретного удалённого сервера/credential проверяется реальным трафиком, это не результат speedtest или внешнего healthcheck. Ошибки соединений с сервером видны в логах.
|
||
|
||
Один backend state сериализует Connect/Disconnect. Файловые locks запрещают второй GUI и второй tunnel. Не используются shell-строки, `sh -c` или интерполяция пользовательского ввода. Аргументы передаются через `Command`.
|
||
|
||
GUI запускает маленький guardian в том же бинарнике. Он отслеживает открытый pipe GUI, посылает sing-box SIGTERM, ждёт до 3 секунд и при необходимости завершает его принудительно, затем удаляет runtime-файлы. Так core останавливается даже при SIGKILL GUI. Одного `PR_SET_PDEATHSIG` недостаточно: Linux сбрасывает его при exec с file capabilities. Обычное закрытие окна, SIGINT и SIGTERM ожидают остановки.
|
||
|
||
## Поддержка и ограничения MVP
|
||
|
||
- Поддерживаются обычный VLESS/TCP, TLS, REALITY, `xtls-rprx-vision`, WebSocket (path/Host, явные ed/eh), IPv4/IPv6 и XUDP. Xray на сервере совместим.
|
||
- gRPC, XHTTP, HTTPUpgrade, TCP HTTP headers, нестандартный flow и insecure TLS отклоняются понятной ошибкой.
|
||
- Список приложений сопоставляет `/proc` с Desktop Entries. Shell-launcher не является routing identity; укажите настоящий бинарник. Flatpak/Snap, временные AppImage mount paths, контейнеры и приложения со сторонними сетевыми helper-процессами не гарантируются. Для helper с отдельным executable его нужно отметить отдельно.
|
||
- VPN рассчитан на TCP/UDP. MPTCP не поддерживается core. Локальный loopback и некоторые непосредственно подключённые LAN-маршруты обходят TUN. Это не kill switch.
|
||
- Процесс, который не удалось идентифицировать в выборочном режиме, идёт DIRECT. `/proc` hidepid/ограничения безопасности могут мешать определению executable.
|
||
- Уже открытые соединения следует переподключить после смены режима. Совместная работа с другим активным VPN не гарантируется.
|
||
- Закрытие GUI и его отдельный SIGKILL проверены. Принудительное убийство одновременно guardian и core, сбой ядра/питания не дают гарантий cleanup. Core, который зависает и требует SIGKILL, также может оставить свои nftables-правила до ручной очистки/перезагрузки.
|
||
- Подписки, QR, аккаунты, статистика и автообновление не реализуются.
|
||
|
||
## Проверки
|
||
|
||
```bash
|
||
npm run format
|
||
cargo check --manifest-path src-tauri/Cargo.toml
|
||
cargo test --manifest-path src-tauri/Cargo.toml
|
||
npm run build
|
||
npm run tauri -- build --bundles deb
|
||
```
|
||
|
||
Для backend без GTK:
|
||
|
||
```bash
|
||
cargo test --manifest-path src-tauri/Cargo.toml --no-default-features --lib
|
||
cargo build --manifest-path src-tauri/Cargo.toml --no-default-features --example test_driver
|
||
src-tauri/target/debug/examples/test_driver --emit-configs /tmp/minivless-config-checks
|
||
```
|
||
|
||
Восемь сгенерированных конфигураций (TCP/TLS/REALITY/WS × два режима) проверяются настоящим `sing-box check -c <file>`.
|
||
|
||
Интеграционный тест запускает настоящий локальный VLESS-сервер, HTTP/UDP endpoints и TLS DoH-сервер в **отдельных network namespaces**. Проверяет маршрут по source IP, DNS, штатное отключение и смерть GUI; сравнивает IPv4/IPv6 rules и nftables до/после. Реальный VPN-сервер и Интернет не нужны:
|
||
|
||
```bash
|
||
unshare --user --map-root-user --net python3 tests/netns_integration.py
|
||
```
|
||
|
||
Не запускайте этот тест через host root. Скрипт требует пустое изолированное network namespace и отображение одного UID. `tests/ui-preview.html` — отдельная development-only IPC fixture для проверки React-интерфейса в браузере; в production bundle не входит и не заменяет сетевой тест.
|
||
|
||
## Документация upstream
|
||
|
||
- [Tauri: Linux prerequisites](https://v2.tauri.app/start/prerequisites/)
|
||
- [sing-box: TUN](https://sing-box.sagernet.org/configuration/inbound/tun/)
|
||
- [sing-box: process routing](https://sing-box.sagernet.org/configuration/route/rule/)
|
||
- [sing-box: VLESS](https://sing-box.sagernet.org/configuration/outbound/vless/)
|
||
- [sing-box: DNS over HTTPS](https://sing-box.sagernet.org/configuration/dns/server/https/)
|
||
- [Официальный sing-box 1.14.0](https://github.com/SagerNet/sing-box/releases/tag/v1.14.0)
|
||
|
||
Код MiniVLESS — MIT; sing-box распространяется отдельно по GPL-3.0-or-later. При распространении пакета с core соблюдайте его лицензию и предоставляйте соответствующий исходный код.
|