Skip to content

Latest commit

 

History

History
598 lines (457 loc) · 50.3 KB

File metadata and controls

598 lines (457 loc) · 50.3 KB
РосПанель

РосПанель

Self-hosted панель управления VPN на Xray-core — от одного личного сервера до сети нод.

Release Downloads Go Xray-core React Platform Deploy

English · Русский

Что это · Где взять сервер · Быстрый старт · Возможности · CLI · Архитектура · Дисклеймер · Разработка · Поддержать


Что это

РосПанель — self-hosted панель управления VPN на Xray-core. Один процесс поднимает сразу несколько протоколов, а панель даёт веб-интерфейс: пользователи, подписки, тарифы и приём оплаты, маршрутизация, статистика, бэкапы, брендинг — без правки конфигов руками. Когда одного сервера мало, та же панель разрастается в сеть серверов: добавляете ноды — пользователи едут на все сразу.

Самодостаточна: один статический бинарник — ни nginx, ни certbot, ни сторонних скриптов. TLS панель выпускает себе сама через ACME, а домен не обязателен: сертификат встанет и на голый IP. Панель открывается по своему адресу сразу после установки — без DNS, без reverse-proxy и без SSH-туннелей. Конфиг Xray генерируется из состояния панели (JSON руками не трогаете), пользователи добавляются и удаляются на лету без обрыва чужих подключений, а при повреждении БД панель сама поднимается из последнего бэкапа.

Note

Это панель управления (control plane), а не VPN-клиент. Она настраивает и обслуживает ваш собственный сервер. Назначение — образовательное и исследовательское (см. Дисклеймер).


🖥️ Где взять сервер

Панели хватит самого дешёвого VPS: 1 vCPU, 1 ГБ RAM, любой Linux — этого достаточно и для панели, и для Xray на десятки пользователей.

Если ещё не выбрали хостинг — зарегистрируйтесь по ссылкам ниже. Это бесплатный для вас способ поддержать проект: цена та же, а часть от аренды идёт на развитие панели.

VDSina · Aeza · NetGrid · Serv.host · u1Host · Waicore

Спасибо тем, кто регистрируется по этим ссылкам 🙏


🚀 Быстрый старт

Вариант 1 — установочный скрипт (рекомендуется)

Одной командой: скачает релиз, поставит systemd-сервис, запустит и покажет логин.

curl -Ls https://raw.githubusercontent.com/AppsGanin/rospanel/main/install.sh | sudo bash

Домен не обязателен. Скрипт спросит про него: есть домен — введите, нет — нажмите Enter, и панель поднимется на IP сервера. Сертификат Let's Encrypt она получит в обоих случаях: он выдаётся и на IP-адрес, никаких предупреждений в браузере не будет.

Домен можно задать заранее, тогда вопроса не будет: curl -Ls … | sudo ROSPANEL_HOST=vpn.example.com bash.

Вариант 2 — бинарник + systemd вручную

# скачать последний релиз (замените amd64 на arm64 для ARM-серверов)
curl -fsSL -o rospanel \
  https://github.com/AppsGanin/rospanel/releases/latest/download/rospanel-linux-amd64
chmod +x rospanel

# установить как сервис (копирует бинарь в /usr/local/bin, пишет systemd-юнит, стартует)
sudo ./rospanel install
#   сразу с доменом:  sudo ROSPANEL_HOST=vpn.example.com ./rospanel install

# логин и секретный путь печатаются ОДИН раз:
journalctl -u rospanel | grep -A6 FIRST-RUN

Вариант 3 — Docker

docker run -d --name rospanel \
  --network host \
  --cap-add NET_ADMIN \
  -v rospanel-data:/data \
  ghcr.io/appsganin/rospanel:latest

docker logs rospanel | grep -A6 FIRST-RUN

Note

--network host нужен, чтобы Xray слушал 443/TCP, 80/TCP и UDP-порты Hysteria2 напрямую; NET_ADMIN — чтобы панель могла править правила фаервола: port-hopping и лимиты соединений (nftables), бан за перебор (iptables).

🔑 Вход по умолчанию

Поле Значение
Логин admin
Пароль admin
Путь панели /rospanel/

Сразу после установки панель доступна по адресу https://<домен-или-IP>/rospanel/. Точная ссылка дублируется в логе (journalctl -u rospanel | grep -A6 FIRST-RUN или docker logs rospanel | grep -A6 FIRST-RUN).

При первом входе мастер настройки принудительно потребует сменить пароль и предложит сменить путь панели на случайный секрет — дефолтные admin/admin и /rospanel/ работают только до этого шага.

Important

После смены панель доступна только по секретному пути — корень отдаёт страницу-обманку. Без знания /<secret>/ форму логина не найти.

🌐 Добавить ноду

Нода — это чистый Ubuntu-сервер с тем же бинарником в режиме ноды: конфиг ей генерирует панель, отдельно настраивать нечего. Заводится всё из UI: Сервера → Добавить ноду, где нужно указать название и домен-или-IP ноды. Дальше — два способа на выбор.

Способ 1 — команда установки. Панель покажет готовую однострочную команду; выполните её на сервере ноды от root:

curl -Ls https://raw.githubusercontent.com/AppsGanin/rospanel/main/install.sh \
  | sudo bash -s -- --join 'https://<панель>/<node-api-path>/v1/join#<токен>'

Копируйте команду целиком из диалога — и адрес, и токен в ней подставляются автоматически. Токен показывается один раз и живёт 24 часа; <node-api-path> — отдельный неугадываемый сегмент для синка нод (не путь панели и не путь REST API: смена любого из них не отвяжет ноды). Если панель работает на голом IP (сертификат не от публичного CA), панель сама добавит в команду --insecure.

Способ 1b — Docker. Тот же образ, что и у панели, запущенный в режиме ноды. node install пишет systemd-юнит, которому в контейнере некуда лечь, поэтому join передаётся переменной окружения: она читается только пока на томе нет node.json, так что контейнер можно пересоздавать сколько угодно, а потраченный токен в compose ничего не меняет.

services:
  node:
    image: ghcr.io/appsganin/rospanel:latest
    command: node run
    network_mode: host          # Xray слушает 443/TCP, 80/TCP и UDP-порты Hysteria2
    cap_add: [NET_ADMIN]        # nftables: лимиты по IP, port hopping
    environment:
      ROSPANEL_JOIN: 'https://<панель>/<node-api-path>/v1/join#<токен>'
      # ROSPANEL_JOIN_INSECURE: "1"   # только если панель ещё на самоподписанном сертификате
    volumes: [rospanel-node:/data]
    restart: unless-stopped
volumes:
  rospanel-node:

Кнопка «Обновить ноду» в панели подменит бинарник внутри контейнера и завершит процесс, после рестарта вернётся версия из образа — контейнерную ноду обновляют через docker pull и пересоздание контейнера. Том хранит идентичность, повторный join не нужен.

Способ 2 — установка по SSH. Вкладка «Установить по SSH» в том же диалоге: панель сама зайдёт на сервер (адрес, порт, пользователь + пароль или приватный ключ PEM), зальёт свой бинарник и поставит агента — лог установки идёт вживую. Версия ноды гарантированно совпадёт с версией панели. Данные SSH нигде не сохраняются.

Через несколько секунд после установки нода появится в списке как онлайн: она сама стучится к панели исходящим HTTPS, поэтому входящий доступ к ней панели не нужен и пробрасывать ничего не требуется.

systemctl status rospanel-node        # сервис ноды
journalctl -u rospanel-node -f        # лог агента
rospanel node status                  # локальный статус

Note

Один сервер — либо панель, либо нода: они делят 443-й порт. Если на машине уже стоит сервис панели, node install его выключит.


✨ Возможности

🔐 Протоколы, маскировка, TLS

Один конфиг, один набор учёток: VLESS-Vision (TCP/443 + uTLS), VLESS-XHTTP-REALITY (маскировка под чужой TLS), Hysteria2 (UDP + port-hopping). Сверх этого — свои инбаунды на каждом сервере: VLESS / Trojan / Hysteria2 на любом транспорте (TCP, WebSocket, XHTTP, gRPC, HTTPUpgrade) со своим портом, ключами REALITY, диапазоном хопа и тонкой настройкой транспорта (XHTTP extra, HTTP-маскировка, sockopt, доп. поля TLS) — отдельными полями или сырым JSON; конфиг проверяется прямо на нужной машине (xray -test + бинд порта) до сохранения, а неподдерживаемые клиентом связки молча не попадают в Clash/sing-box подписки. Панель спрятана за секретным путём, любой другой путь отдаёт сайт-заглушку (11 шаблонов). Детект прощупывания замечает IP, который сканирует адрес в поисках скрытой панели — запрашивает много несуществующих путей заглушки — и записывает его, чтобы оператор мог просмотреть; ответ при этом не меняется, поэтому сканер видит только заглушку и маскировка сохраняется. Опционально можно дропать IP на файрволе (nftables) и/или слать дневную сводку новых сканеров — оба по умолчанию выключены, безопасный дефолт — только запись. TLS из коробки — ACME (Let's Encrypt / ZeroSSL) с авто-продлением; сертификат можно выпустить и на голый IP, без домена и DNS.

👤 Пользователи

Лимиты трафика и срок с авто-отключением и авто-сбросом квоты (день/неделя/месяц/год), лимит устройств (что именно он считает — см. Привязка устройств ниже) и лимит скорости. Учёт трафика через Xray Stats, онлайн-статус, список подключений; истёкших можно авто-удалять. Поиск и фильтры не тормозят на сотнях юзеров, а групповые операции (вкл/выкл/сброс/продление/удаление) идут одной перезагрузкой Xray. Дашборд — CPU / RAM / swap / диск и VPN-трафик в реальном времени. Карта подключений показывает, откуда подключаются клиенты — уникальные IP по странам (по той же базе geoip, по которой маршрутизирует Xray) и по провайдеру / ASN (по бесплатной базе iptoasn, которую панель качает сама); без внешних сервисов.

Лимит устройств — что он считает. Лимит устройств у пользователя (или заданный его тарифом) — одно число, которое принуждается двумя способами. Само по себе оно ограничивает одновременные уникальные IP-адреса: если юзер подключается с большего числа разных адресов, чем лимит, за окно онлайна — его отрубает от туннелей, пока он не станет ≤ лимита; считается по всем серверам (мастер и ноды), а не по каждому отдельно. 0 — без лимита по IP.

Отключение не мгновенное. Превышение должно продержаться две с половиной минуты — чуть дольше окна онлайна. Так сделано потому, что два самых частых способа превысить лимит — вообще не раздача ссылки: телефон при смене сети бросает старый адрес, а тот числится живым до конца окна, и мобильный оператор сам меняет публичный адрес внутри своего пула (на живом аккаунте видно семь адресов одной сети 176.15.0.0/16 за месяц). Отличить это от второго устройства можно только одним способом — посмотреть, продолжает ли старый адрес использоваться, а для этого нельзя отключать пользователя: отключение и прекращает трафик, по которому судим. Поэтому лимит выжидает, и брошенный адрес успевает выйти из окна сам. Адреса, которыми действительно пользуются одновременно, к концу ожидания все на месте, и отключение происходит как раньше.

Режим Настройки → Подписки → Считать устройства«Только по HWID» убирает подсчёт адресов совсем — ценой единственного, что ограничивает одновременное использование одной ссылки: HWID ограничивает выдачу подписки, а не подключения. По умолчанию считаются оба.

Привязка устройств (HWID). Включите — и то же число ограничивает ещё и число разных установок. Клиенты, поддерживающие стандарт заголовков подписки (Happ, v2RayTun), присылают идентификатор установки; панель привязывает его к аккаунту при первом запросе и считает в лимите. Когда слоты кончились, НОВАЯ установка подписку не получает, а уже привязанные продолжают обновляться — проверка и вставка идут одной транзакцией, так что два клиента не займут последний слот одновременно. (Если личный лимит юзера 0, для HWID берётся общий панельный fallback-лимит.) Список устройств виден в карточке пользователя, в клиентском боте (отдельными строками по IP и по HWID, когда действуют оба) и на странице подписки, где владелец сам отвязывает лишнее вместо письма в поддержку; молчащее устройство освобождает слот по TTL, а смена ссылки подписки отвязывает все. По умолчанию выключено (Настройки → Подписки); после включения клиент, который не присылает идентификатор, подписку не получает вовсе — лимит, который обходится сменой приложения, лимитом не является, — но есть переключатель обслуживать и таких (считая по IP, как раньше), если часть пользователей сидит на них.

Лимит скорости. Персональный потолок в кбит/с — вручную или из тарифа. У Xray нет ограничения полосы на пользователя, поэтому лимит применяется уровнем ниже: планировщиком ядра (HTB) по адресам, с которых пользователь сейчас подключён, в обе стороны. Отсюда три следствия: работает сразу для всех протоколов; за одним NAT-адресом лимит общий; а для Hysteria2 (его алгоритм перегрузки принципиально игнорирует потери) превышение выглядит как потери пакетов, а не как плавное замедление. Ноды шейпят свой трафик по своему списку подключений.

Группы доступа решают, какие подключения достаются пользователю: встроенные лейны и свои инбаунды отмечаются галочками по каждому серверу, юзер без группы получает всё, в нескольких группах — объединение их подключений. Ограничение серверное — учётка просто не попадает в запрещённые инбаунды Xray (а не прячется в UI), поэтому и подписка, и собранная вручную ссылка отдают только разрешённое. Членство правится с обеих сторон — в карточке пользователя и в самой группе, а группы юзера видны в его карточке и списке.

📲 Подписки

/<путь>/<токен> — base64-список плюс страница с QR, deep-links и импортом в популярные клиенты (авто-роутинг-заголовки Happ / INCY / Mihomo), со своими названиями узлов. Ссылку можно сбросить (ротация токена) без смены UUID и паролей. Объявление внутри клиента (Happ, v2RayTun) — короткий текст прямо в приложении.

На странице ровно то, что нужно владельцу аккаунта, и ничего лишнего: карточку отдельных конфигов можно выключить, а при включённой привязке устройств там же виден список своих устройств с кнопкой отвязки — переполненный лимит решается самим пользователем, а не письмом в поддержку.

Правила ответа переопределяют авто-определение формата: упорядоченный список правил оператора, которые матчатся с запросом (User-Agent или HWID-заголовок) — навязать конкретный формат нужному клиенту / ОС / версии (содержит, равно, префикс, regex) или заблокировать клиента целиком (ему отдаётся заглушка). Решает первое совпавшее правило; нет совпадений — обычное авто-определение.

Режим обслуживания — одним переключателем публичные поверхности (страница подписки, статус, заглушка) показывают «сервис недоступен», пока панель, API, синхронизация нод и сами туннели продолжают работать: существующие подключения не рвутся, а оператор всё ещё может войти.

🧭 Маршрутизация и выходы

Категории block / direct / WARP / Opera с приоритетом, пресеты geosite/geoip с авто-загрузкой баз, выход через Cloudflare WARP (WireGuard) и бесплатный Opera VPN с выбором региона. Полосы прокси — независимые выходы, у каждого свои socks5/http-апстримы и правила по зонам с балансировкой по живым (Observatory). Снимки конфигурации (вкладка Снимки в настройках сервера) — история отмены для всего конфига сервера: протоколы, порты, REALITY, маршрутизация, выходы, DNS, заглушка, инбаунды. Сохраните точку возврата вручную и откатитесь, если правка что-то сломала. Откат проходит валидацию xray -test и сначала делает авто-снимок текущего состояния (то есть сам обратим), и намеренно не трогает сертификат и домен — отмена никогда не рискует живым доступом.

🌐 Сеть серверов (мультинода)

Одна панель управляет мастером и любым числом удалённых нод. Сервер добавляется из UI: копируете одну команду для чистого Ubuntu или даёте панели зайти по SSH и поставить агента — лог установки идёт вживую. Нода сама стучится к панели (исходящий HTTPS long-poll), поэтому панели не нужен доступ к нодам, а её переезд ноды не отвязывает. Пользователи, лимиты и тарифы раскатываются на все ноды; трафик и устройства считаются в общие лимиты, а статистика и карточка юзера показывают, сколько трафика прошло через каждый сервер. У каждой ноды есть множитель трафика — коэффициент, задающий, насколько быстро трафик через неё расходует квоту юзера (×2 на дорогой локации, ×0.5 на промо); он влияет только на квоту, но не на побайтовую статистику ноды.

Каждый сервер настраивается отдельно (протоколы, выходы, DNS, ключи REALITY, домен и TLS, geo-базы, заглушка). Нода — тот же бинарник в режиме ноды: конфиг ей генерирует панель, локальный xray -test с откатом страхует от несовместимости версий, обновление идёт из UI со сверкой SHA256.

💳 Тарифы и оплата (опционально)

Планы: цена, срок, лимиты трафика и устройств; цена 0 — бесплатный тариф. Есть пробный период, бесплатный тариф-фоллбэк для истёкших, продление и перенос пользователей. Приём платежей — провайдеры на выбор: ЮКасса, PayPalych, RioPay, RollyPay, SeverPay, Platega, PayPear, AuraPay (карты, СБП, ₽), CryptoBot и Heleket (крипта). Клиент платит в боте или на странице подписки — тариф включается сам. Подтверждает вебхук (подпись проверяется), поллинг страхует, если вебхук не дошёл; обработка идемпотентна, сумма сверяется с заказом. Без провайдеров оплату подтверждает админ.

Warning

Провайдеры оплаты пока не проверены на боевых аккаунтах. Если вы подключили какой-то из них — пожалуйста, сообщите в issue, работает он или нет (какой провайдер, что получилось, что сломалось). Это поможет отметить проверенные провайдеры и починить остальные.

👥 Доступ, роли и аудит

Роли: владелец (может всё, один и неудаляем), администратор (без списка админов), оператор (юзеры, статистика, журнал). Права проверяются на сервере на каждом запросе; новому админу выдаётся временный пароль со сменой при первом входе. Двухфакторная аутентификация (TOTP): каждый админ включает её себе сам — код из приложения (Google Authenticator, Aegis, 1Password) в дополнение к паролю, секрет шифруется в базе и после настройки наружу не выходит; телефон потерян — rospanel totp reset <логин> на сервере; более полная команда rospanel rescue сбросит забытый пароль, снимет второй фактор или пересоздаст владельца, когда войти не может никто. Журнал пользователя — что с ним делали и кто (админ, API-ключ, бот, сам юзер, система), переживает его удаление. Журнал панели (виден владельцу) — входы и неудачные попытки с IP, включение и снятие второго фактора, изменения настроек, бэкапы; пишется только успешное действие, тела запросов — никогда. Журнал панели ищется (по действию, цели, администратору и IP), фильтруется по категории и диапазону дат, а текущая выборка выгружается в CSV одной кнопкой. Оба журнала хранятся 90 дней.

🤖 Интеграции

Админ-бот в Telegram: управление юзерами, тарифы, QR-подписка, бэкапы по расписанию, уведомления о событиях (регистрации, истечения, сбой Xray, оплаты, сертификат).

Клиентский бот: саморегистрация, личное меню с подпиской и статистикой, покупка тарифа — и личные уведомления самому пользователю: подписка заканчивается, трафик на исходе, оплата прошла.

Бот поддержки — третий бот: человек пишет ему в личку, а переписка попадает в вашу форум-группу, по теме на каждого; отвечаете прямо оттуда, и ответ уходит ему в бот.

Рассылки — девять срезов аудитории (все, с аккаунтом и без, активные, истёкшие, у кого скоро закончится, кто давно не заходил, кто ни разу не подключался) с картинкой и кнопкой. Доставка идёт по таблице получателей, поэтому прерванная рассылка продолжается, а не начинается заново, и никто не получает сообщение дважды.

REST API с именованными ключами (Authorization: Bearer), OpenAPI из кода и Swagger UI. Он покрывает обе половины панели: то, чем управляют каждый день — пользователи, тарифы, заказы, серверы, — и саму конфигурацию: настройки, маршрутизацию и DNS по серверам, снимки конфигурации с откатом. Администраторы, API-ключи и секретный путь панели намеренно не выставлены. Вебхуки шлют подписанные HMAC-SHA256 события с ретраями. Метрики Prometheus/<api-путь>/v1/metrics под тем же ключом: пользователи, трафик, скорость, состояние хоста и по серии на каждую ноду. MCP-сервер отдаёт тот же API ИИ-ассистенту, а список инструментов генерируется из того же OpenAPI: вставляете …/v1/mcp/<ключ> в ассистента, который принимает URL, — ставить нигде ничего не нужно. Операции записи выключены, пока их не попросят (адрес с /write). Подробнее — docs/api.md.

Подключить ассистента — это один URL, локально ставить нечего. Создайте ключ в Настройках → API, возьмите оттуда же базовый адрес и вставьте один из двух:

https://vpn.example.com/<api-путь>/v1/mcp/<ключ>          только чтение
https://vpn.example.com/<api-путь>/v1/mcp/<ключ>/write    плюс всё, что меняет состояние

Адрес и есть пароль: он ровно настолько же секретен, как ключ внутри него, и перестаёт работать в момент отзыва ключа. Различаются они только набором инструментов: короткий не может удалить пользователя, хотя ключ внутри него это умеет, — поэтому выдать ассистенту адрес «только чтение» это решение, а не надежда.

Статус-страница — публичная страница (Настройки → Общие) с доступностью серверов и историей аптайма за 90 дней. Только имена и состояние: ни адресов, ни пользователей, ни трафика — и никакой страницы, пока её не включили.

🌍 Язык (RU / EN)

Поверхность Откуда берётся язык
Панель выбор самого админа (на браузер), иначе языки браузера
Страница подписки Accept-Language
Клиентский бот и саппорт язык Telegram каждого человека
Админ-бот настройка панели (Настройки → Telegram)
CLI английский

🎨 Брендинг и тема

Своё название и логотип вместо «РосПанели» — в панели и на странице подписки. Акцентный цвет перекрашивает весь интерфейс, а тёмная тема сама подстраивает текст, статусы и графики.

🛡️ Обнаружение злоупотреблений

Панель сверяет IP-адреса назначения из access-лога Xray со списком вредоносных сетей и записывает только совпадения — обычный трафик никуда не сохраняется. Нужно это ровно для одного: когда прилетает абуз-жалоба на адрес сервера, понять, чей это был трафик.

Список — FireHOL level 1: управляющие серверы ботнетов, атакующие и спам-сети. Отобранный уровень с минимумом ложных срабатываний, без CDN и шаред-хостинга. Рядом — свой список (IP/CIDR), который проверяется первым. Совпадения видны в статистике и в карточке юзера, с привязкой к серверу, который выпустил трафик; при превышении дневного порога уходит уведомление в Telegram. Категории, свой список, порог и обновление — на вкладке Настройки → Блоклисты.

Проверка идёт по адресу, а не по домену, и это не упрощение. Современные клиенты резолвят DNS мимо туннеля и шифруют SNI (ECH), поэтому до сервера доезжает голый IP.

Совпадения хранятся 14 дней — этого хватает на разбор жалобы.

🧰 Эксплуатация и безопасность

Диагностика одной кнопкой: процесс Xray, применение конфига, срок TLS, место на диске, свежесть geo-баз, состояние выходов — каждая проверка с подсказкой. Отдельная проверка подключения коннектится к каждому протоколу как настоящий клиент и убеждается, что трафик проходит наружу, — ловит рассинхрон учёток, TLS или ALPN раньше пользователя. Бэкап / восстановление и сброс — из панели и CLI.

Обновление одной командой: панель сверяет SHA256, прогоняет бинарь вхолостую, снимает бэкап и только потом подменяет себя, храня прошлую версию рядом. Xray-ядро зафиксировано, упавшее супервизор поднимает сам. Сторож закрывает более сложный случай, который не видит обработчик краха, — процесс жив, но перестал обслуживать: он опрашивает API Xray и, если тот не отвечает несколько проверок подряд, перезапускает его (с задержкой против шторма перезапусков) и уведомляет оператора. Работает на мастере и на каждой ноде.

Секреты в БД зашифрованы (AES-GCM). Токены сессий и API-ключи хранятся только хэшами — даже с доступом к таблице чужую сессию не подставить. Подтверждение оплаты и управление админами требуют повторного пароля. Исходящие запросы защищены от SSRF, перебор на инбаундах банится iptables, а число соединений с одного IP ограничено nftables.


🛠️ CLI

rospanel                     запустить панель (обычно через systemd)
rospanel install             установить systemd-сервис и запустить (root)
rospanel uninstall [-y]      снять сервис (данные сохраняются)
rospanel start|stop|restart  управление сервисом
rospanel status              статус сервиса
rospanel update [-y]         обновиться до последнего релиза с GitHub
rospanel backup [файл]       снапшот .tar.gz (БД + ключ шифрования + сертификаты + конфиг Xray)
rospanel restore [-y] <файл> восстановить из снапшота (применится при старте)
rospanel host [-y] [домен|IP] показать/сменить адрес (перевыпуск TLS)
rospanel path                показать URL панели и проверить secrets.key / БД
rospanel totp reset <логин>  снять второй фактор у админа (телефон потерян); без
                             аргументов — у кого он включён
rospanel rescue <под>        вернуть доступ: list | password | unlock | owner
rospanel reset [-y]          сброс к заводским настройкам (стирает БД)
rospanel version             версия
rospanel help                полная справка

Деструктивные команды (reset, restore, host, uninstall) спрашивают подтверждение; флаг -y его пропускает.

Режим ноды

Тот же бинарник умеет работать как управляемая панелью нода. Команду install подставляет диалог «Добавить ноду» в панели — руками её обычно набирать не нужно.

rospanel node install --join '<url>'   присоединиться к панели и поставить сервис (root)
rospanel node run                       агент ноды (точка входа systemd)
rospanel node set-panel <url>           переключить ноду на новый адрес панели
rospanel node status                    локальный статус ноды
rospanel node uninstall [-y]            снять сервис ноды (данные сохраняются)

--join берётся из диалога добавления ноды; токен в нём одноразовый и живёт 24 часа. Как завести ноду от начала до конца — 🌐 Добавить ноду.


🧱 Архитектура

Единственный источник правды — SQLite; конфиг Xray всегда генерируется из неё и применяется супервизором. Веб-панель встроена в бинарник.

Стек: Go 1.26 · Xray-core · SQLite (modernc, без CGO) · React + Vite + Tailwind.


⚠️ Дисклеймер

Программное обеспечение предоставляется «как есть» (as is), без каких-либо гарантий.

Назначение проекта — образовательное и исследовательское: изучение сетевых протоколов, TLS и прокси-технологий, CTF и лабораторные работы по сетевой безопасности, авторизованное тестирование на проникновение и управление собственной инфраструктурой. Проект не предназначен для обхода законных ограничений или иных противоправных действий; механизмы маскировки служат для изучения технологий и проверки устойчивости сервисов в рамках санкционированного тестирования.

Ответственность за установку, настройку, эксплуатацию и соблюдение законов своей юрисдикции несёт оператор сервера. Авторы и контрибьюторы не отвечают за использование проекта третьими лицами.


🧑‍💻 Разработка

# фронтенд (после изменений в web/)
npm --prefix web install
npm --prefix web run build      # → web/dist (вшивается в бинарник)

# бинарник
go build -o rospanel ./cmd/rospanel
./rospanel

Локализация. Словари панели — web/src/i18n/ru.ts и en.ts, типизированные друг по другу: ключ, который есть в одном и забыт в другом, роняет сборку, а не молча подставляет фолбэк. То, что Go рисует сам — боты и страница подписки — лежит в internal/i18n/; бэкенд отдаёт панели ключ с аргументами, а не готовый текст. Третий язык — это по одному словарю с каждой стороны.

Полезные переменные окружения (все опциональны): ROSPANEL_DATA (каталог данных), ROSPANEL_ADMIN_ADDR (loopback-адрес панели, по умолчанию 127.0.0.1:8080), XRAY_BIN, ROSPANEL_HOST, ROSPANEL_ACME_EMAIL.

Защита от флуда (nftables-лимиты на публичных TCP-портах, см. «Эксплуатация») тоже настраивается через окружение — пригодится, если за одним IP сидит целый офис или CGNAT-оператор и клиенты упираются в дефолты:

Переменная Что делает
ROSPANEL_CONNLIMIT=off Полностью выключает лимиты (правила nftables сносятся)
ROSPANEL_CONNLIMIT_MAX Максимум одновременных TCP-соединений с одного IP
ROSPANEL_CONNLIMIT_RATE Максимум новых соединений с одного IP в секунду

Текущее состояние защиты видно в Дашборд → Управление → Диагностика: если nftables не установлен или панель работает не от root, правила молча не применятся — диагностика об этом скажет.

PR и issue приветствуются. Коммиты — в стиле Conventional Commits: на их основе release-please собирает релиз и публикует бинарь + Docker-образ в GHCR.


💝 Поддержать проект

РосПанель развивается в свободное время и распространяется бесплатно. Если панель оказалась полезной — проще всего поддержать через DonationAlerts или Boosty (картой РФ, разово или регулярно). Спасибо! 🙏

Криптой

USDT. Выберите сеть и внимательно скопируйте адрес — сеть отправителя и получателя должны совпадать. Отправляйте только USDT и только в указанной сети: перевод по неверной сети невозвратен. Дешевле всего комиссия в TRON (TRC20) и TON.

Сеть Токен Адрес
TRC20 (Tron) USDT TJwyrPVEZVZ1YrcmDiZTyFjLo3Q2DmEGzs
ERC20 (Ethereum) USDT 0xf9d663146ce902da91911b214c71cc73a5269d1d
Solana USDT 2qAZRTbaUMTfYuZbD1dCYHjkYgxkw4dUYE9XY3JhC2Cs
TON USDT UQDoat731MLYuIw8ayL3Vhhw7zTBbLvRaQFmDvab--CNNI7e

Bybit. Если у вас тоже Bybit — переводом по UID 136462734: мгновенно и без комиссии.

Нет возможности поддержать деньгами? Тоже можно помочь — арендуйте серверы по реферальным ссылкам из раздела Где взять сервер. Вам это ничего не стоит, а проекту помогает.


📄 Лицензия

GNU Affero General Public License v3.0 (AGPL-3.0).

Проект свободен для использования, изменения и self-hosting. Если вы предоставляете доступ к изменённой версии панели по сети (в т.ч. как сервис), вы обязаны открыть исходный код своих изменений на тех же условиях.