# 1344 Network Panel

Панель управления инфраструктурой **VLESS / qWDTT / WDTT / OpenFlux**: серверы по SSH, пользователи, отделы, генератор ссылок, профили, маршрутизация Xray, статистика и аудит.

Стек: **Go** (REST API, один бинарник) · **PostgreSQL** · **Next.js + React + TypeScript + Tailwind + Recharts** (статический экспорт) · установщик `install.sh` и CLI `1344`.

**Лицензия: GPL-3.0-or-later** (текст — в [LICENSE](LICENSE); о совместимости с проектами-протоколами — в [NOTICE.md](NOTICE.md)). Установка: `bash <(curl -Ls https://1344.pl/downloads/network-panel/get.sh)` — сайт проекта: https://1344.pl/projects/network-panel/.

## Язык и удобство

Интерфейс по умолчанию на русском, переключатель RU/EN — в верхней панели и на странице входа (выбор запоминается). Перевод — словарь `frontend/lib/ru.ts`; новые строки находит `node tools/extract-strings.cjs`; непереведённое остаётся на английском. На «Обзоре» пока нет данных — подсказка «С чего начать» из трёх шагов; в OpenFlux-генераторе есть готовые схемы мостов (прямой, прямой + резерв через Яндекс, без VPS).

## SSL для IP-адреса

Как и в 3x-ui, установщик умеет выпускать **доверенный сертификат Let's Encrypt на публичный IPv4** (профиль `shortlived`, ~6 дней, продление — `acme.sh` по cron; для проверки нужен открытый порт 80). Выбирается в режиме «по IP» → `letsencrypt`; остальные варианты — самоподписанный, свой, без SSL. Для установки `acme.sh` используется `curl https://get.acme.sh | sh` (как в 3x-ui). `1344 ssl status|renew|reissue` работают и с этим режимом. Ссылки на идеи: [3x-ui](https://github.com/MHSanaei/3x-ui), [openflux-panel](https://github.com/kfwle/openflux-panel) (MIT; код не копировался — оттуда взята идея схем транспортов; управление выходными узлами OpenFlux по ключам в 1344 пока не реализовано).

## Скрытый путь доступа

Панель монтируется под секретным путём, который задаётся при установке (`PANEL_BASE_PATH`, 8–128 символов `A-Za-z0-9_-`):

```
http(s)://<хост>/<секрет>/login/   → панель
http(s)://<хост>/login/            → 404 (как у обычного nginx)
http(s)://<хост>/api/…             → 404
```

Это слой скрытности поверх паролей и 2FA, **не шифрование** и не замена авторизации: путь виден в адресной строке, истории браузера и логах прокси. Один и тот же релиз-бандл работает с любым путём: фронтенд собирается с плейсхолдером `/__P1344__`, а Go-сервер подставляет настоящий путь при отдаче файлов. Исключение — `GET /api/health` с самого сервера (loopback без proxy-заголовков), он нужен установщику и `1344 doctor`.

## Быстрый старт (чистый VPS: Ubuntu 22.04/24.04/26.04, Debian 11–13)

**Как в 3x-ui, одной строкой** (после публикации релиза: `get.sh` и бандл лежат на вашем хостинге, адрес — в `PANEL_RELEASE_BASE` внутри `get.sh`):

```bash
bash <(curl -Ls https://ВАШ-ХОСТ/get.sh)
```

Без вопросов: установщик скачивает бандл, проверяет SHA-256, выбирает случайный секретный путь (12 символов, например `/y8nVam2pDQb6/`) и случайный HTTPS-порт, выпускает доверенный сертификат Let’s Encrypt на IP (если не вышло — самоподписанный), создаёт Super Admin со случайным логином и паролем и в конце печатает готовую ссылку входа: `https://IP:ПОРТ/ПУТЬ/login/`. Пароль показывается один раз. Любая переменная `PANEL_*` (например `PANEL_BASE_PATH`, `PANEL_HTTPS_PORT`, `PANEL_ADMIN_USER`) переопределяет случайный выбор; `--interactive` вернёт пошаговый режим, `--dry-run` покажет выбор, ничего не меняя. Из локального файла: `PANEL_BUNDLE=./1344-panel-<версия>-amd64.tar.gz bash get.sh`.

Пошаговый режим:

```bash
tar xzf 1344-panel-<версия>-amd64.tar.gz && cd 1344-panel-*
bash install.sh --check     # отчёт о готовности сервера, ничего не меняет
bash install.sh             # пошаговая установка
bash install.sh --quick     # без вопросов (то же, что get.sh)
```

Установщик: IP или домен → секретный путь → порты → SSL → компоненты → firewall → Super Admin (+2FA) → финальная проверка. Подробно — [docs/OPERATIONS.md](docs/OPERATIONS.md). Сборка бандла: `tools/make-bundle.sh` (Linux, Go ≥ 1.22, Node ≥ 18). После установки доступна команда `1344` (`status | start | stop | restart | logs | ssl | firewall | backup | restore | update | doctor | uninstall`). Docker Compose — экспериментально, не проверялся: `docker-compose.yml`, `.env.example`.

## Что внутри

| Раздел | Что делает |
|---|---|
| **Overview** | Счётчики, графики сети/трафика, статус серверов, события, действия админов (обновление каждые 15 с) |
| **Servers** | VPS по SSH (ключ генерирует панель или вставляется; хранится зашифрованным AES-256-GCM), pinning host key, CPU/RAM/диск/сеть каждые 30 с, службы (start/stop/restart с подтверждением), журналы, вкладки Overview/Services/Protocols/Users/Traffic/Logs/Settings |
| **Inbounds (3x-ui)** | Слушающие порты управляемого Xray: VLESS/VMess/Trojan/Shadowsocks × tcp/ws/grpc × none/TLS/REALITY; клиенты inbound’а со своими UUID/паролями, ссылками и QR, лимитом трафика, сроком, массовым созданием, сбросом трафика, подпиской `/sub/<id>` (как в 3x-ui), экспортом ссылок; счётчики трафика по клиенту и порту, автоблокировка по лимиту/сроку; настройки ядра Xray (логи, DNS, блок BitTorrent/приватных адресов) |
| **Users** | CRUD, блокировка, продление, лимит трафика, перенос по отделам, история, массовые действия, поиск/фильтры/сортировка |
| **Departments** | Дерево отделов, ответственный, наследование политик (протоколы, серверы, лимит) с переопределением |
| **Link Generator** | Четыре независимых адаптера, валидация по полям, QR, копирование, экспорт, массовая генерация, импорт ссылок, миграция WDTT → qWDTT |
| **Routing** | Конструктор правил Xray (domain/IP/CIDR/geosite/geoip/порты/network/inbound/sniffing), порядок, приоритеты, вкл/выкл, импорт/экспорт, проверка и предпросмотр `routing` |
| **Profiles** | Библиотека, фильтры, архив, удаление (qWDTT-credential удаляется и на сервере), история, просмотр ссылки (аудит) |
| **Connections** | Живые устройства/трафик credential’ов qWDTT через admin API серверов |
| **Statistics / Logs** | Трафик по пользователям/отделам/серверам, активность, состояние служб; аудит с фильтрами; секреты в логи не пишутся |
| **Settings** | Название, баннер, пароль, 2FA (TOTP + резервные коды), сессии, учётные записи и роли, API-токены, уведомления в Telegram (падение сервера, исчерпание лимита, ошибки применения конфига), скачивание дампа базы |
| **RBAC** | Super Admin / Administrator / Manager (только свой отдел) / Operator / Viewer; проверка на backend |

Баннер сверху ведёт на [t.me/Panel1344](https://t.me/Panel1344) (Settings → General, можно закрыть).

## Форматы, изученные в исходниках (не придуманы)

* **qWDTT** (`SpaceNeuroX/proxy-turn-vk-android`, GPL-3.0): `qwdtt://config?name=&peer=&hashes=&workers=&port=&pass=` (URL-encoded; принимается и `qwdtt:config`) и подписка-JSON `{subscriptionName, profiles:[{name, peer, hashes, workers, port, password}]}`. Серверный модуль имеет HTTPS admin API с Bearer-токеном: `GET/POST /admin/passwords` (пароль генерирует **сервер**), `update|activate|deactivate|delete|unbind-device`. Панель создаёт, приостанавливает и удаляет credential’ы через него.
* **WDTT Legacy** (`amurcanov/proxy-turn-vk-android`, архив): `wdtt://IP:DTLS:WG:LOCAL:PASSWORD:HASH1,HASH2`. Из-за разделителя `:` IPv6 и пароль с `:` невыразимы — адаптер отказывает, а не выдаёт битую ссылку.
* **VLESS**: стандартные share-ссылки Xray + outbound JSON.
* **OpenFlux** (`p1neappleXpress/OpenFlux`, GPL-3.0-or-later): `openflux://v1/` + base64url (без паддинга) от **raw DEFLATE** (уровень 9) от JSON `{name, negotiate, codec, secret, context, mode, transports:[{type, name, url, priority, dial}]}`. Правила валидации повторяют `share.Validate` клиента: direct и несколько транспортов требуют negotiate; секрет ≥ 16 единиц UTF-16; stream-режим — один транспорт cupsonline/mailru без секрета; `oneme` (MAX) в ссылку не попадает. Для сервера с установленным ядром панель создаёт выходной узел под каждый профиль (по образцу `deploy/node-install.sh`: официальный бинарник с проверкой SHA256SUMS, шаблон `openflux-1344@`, `node.conf` с `Role=exit`, `Mode=l4`, транспорт `direct`) и подставляет в ссылку реальные адрес и секрет.

**Как это работает «как в 3x-ui»:** *VLESS* — панель ставит Xray-core (проверка checksum, отдельные пути `/opt/1344-xray`, служба `xray-1344`), создаёт inbound VLESS+REALITY и сама собирает весь конфиг из БД (активные профили = клиенты, правила маршрутизации = routing); ссылки получают параметры реального inbound. *qWDTT* и *OpenFlux* — см. «Ограничения».
* У qWDTT/WDTT/OpenFlux нет движка маршрутизации уровня Xray, поэтому Routing — только для VLESS.

Лицензии: код этих проектов не копировался; форматы реализованы по чтению исходников. Консервативно предполагается GPL-3.0-or-later — см. [NOTICE.md](NOTICE.md); окончательный выбор и файл `LICENSE` — за владельцем проекта.

## Резервные копии

Настройки → «Система и бэкапы»: **скачать дамп базы** и **восстановить из файла** (Super Admin, подтверждение словом `RESTORE`, одна транзакция — битый файл ничего не меняет; после восстановления панель перезапускается). Для восстановления на другом сервере нужен тот же `PANEL_SECRET_KEY`. На хосте то же делают `1344 backup` и `1344 restore`.

## Личная страница ссылок

В карточке пользователя — адрес `/u/<токен>`: все его активные ссылки (qWDTT, WDTT, OpenFlux, VLESS…) на одной странице; с `?raw=1` отдаётся подпиской для приложений. Адрес можно перевыпустить.

## Безопасность

argon2id; сессии — случайный токен в `HttpOnly; Secure; SameSite=Strict` cookie (в БД только SHA-256), CSRF-заголовок, блокировка аккаунта после 5 неудач, rate limit (приложение + nginx), заголовки безопасности и CSP, параметризованные SQL, валидация на сервере. SSH-ключи, токены и пароли профилей — AES-256-GCM (`PANEL_SECRET_KEY`), в ответы API и логи не попадают; просмотр ссылки требует отдельного права и пишется в аудит. SSH-команды — из белого списка, host key пиннится. Сервис — отдельный пользователь, `ProtectSystem=strict`; PostgreSQL только на 127.0.0.1.

## Тесты

```bash
cd backend && go test ./...                                        # адаптеры (в т.ч. OpenFlux), маршрутизация, криптография, TOTP RFC 6238
python3 backend/tests/smoke.py http://127.0.0.1:8080 <admin> <pw>  # сквозной: RBAC, CSRF, блокировки, генераторы, маршрутизация, аудит
cd frontend && npx tsc --noEmit
```
Для панели с секретным путём передайте базовый URL вместе с путём.

## Ограничения

* Серверы протоколов ставятся из панели (вкладка «Серверы → Протоколы»), как в 3x-ui, но **WDTT (устаревший) панель не устанавливает**: он заархивирован, его серверных исходников в репозитории нет — только чтение/экспорт старых профилей и управление уже работающей службой `wdtt`. «Server Agent» нет — достаточно SSH.
* qWDTT-сервер собирается из исходников (`v1.4.4`) на самом VPS и ставится **официальным `deploy.sh`** проекта (он настраивает iptables NAT, sysctl и службу `wdtt`, не запускайте рядом с другим WDTT/qWDTT). Подлинность admin API проверяется закреплением сертификата. Реальное подключение клиента qWDTT проверить нельзя без звонка VK: проверено, что сервер запущен, доступ создаётся сервером и виден в «Подключениях».
* OpenFlux: по одному выходному процессу на профиль (ядро обслуживает одного клиента на выход); лимиты трафика/срока по ключам и графики, как в openflux-panel, пока не сделаны. Режим `l3` не используется, только `l4`.
* Routing: проверка и готовый JSON, автоматической выкладки на Xray нет. Трафик VLESS по пользователям недоступен без Xray stats API.
* Автоблокировка по лимиту блокирует пользователя в панели, но не деактивирует credential на qWDTT-сервере (ручная блокировка — деактивирует).
* Webhook, SMTP, автобэкап из UI — нет (бэкап по расписанию — systemd-таймер). Redis не используется.
* Установщик проверен на Ubuntu 24.04: IP + самоподписанный TLS, IP + HTTP с секретным путём, `--check`, а также `1344 status/backup/restore/update/doctor/ssl/uninstall`. Let’s Encrypt для домена (на `sslip.io`) и для IP выпускались вручную на тестовом VPS теми же командами, что в установщике; **сам установщик с новыми режимами `letsencrypt`/`letsencrypt_ip` целиком не перепрогонялся**. DNS-01, свой сертификат и Docker Compose написаны, но не прогонялись.
* Интерфейс под логином собран и проверен по типам, API — сквозным тестом; визуально под логином в браузере не просматривался (страница входа и гейтинг пути проверены).
