Впервые здесь? Прочтите это первым 👋
Никогда не слышали про Marzban, «VPS» или «панель»? Отлично — здесь вся суть объясняется простыми словами. Опыт не нужен совсем.
Одним предложением: NexusPanel — это программа, которая позволяет запустить собственный VPN-сервис и продавать к нему доступ — немного похоже на то, как если бы вы держали свой маленький Netflix, только продаёте вы приватное, разблокированное и более быстрое интернет-соединение.
Вы арендуете дешёвый сервер, устанавливаете на него NexusPanel и получаете удобную веб-панель. В этой панели вы создаёте клиентов, и каждый клиент получает ссылку, которую вставляет в бесплатное приложение на телефоне. Он нажимает «подключиться» — и его интернет теперь идёт через ваш сервер. Вы берёте с него плату каждый месяц. Вот и весь бизнес.
Аналогия с магазином
Если вы представляете, как держать небольшой магазин, вы уже понимаете NexusPanel. Вот как всё устроено:
Владелец
Вы ведёте бизнес, назначаете цены и добавляете клиентов. Программистом быть не обязательно.
Здание вашего магазина
Компьютер, который вы арендуете в дата-центре (≈ $5/месяц). Здесь живёт ваша панель. Провайдеры: Hetzner, Contabo, DigitalOcean…
Ваша касса и витрины
Панель управления, в которую вы заходите через браузер. Добавляйте клиентов, следите за трафиком, получайте оплату — всё отсюда.
Филиал за рубежом
Дополнительный сервер, например в Германии или Финляндии, чтобы клиенты могли выбирать, через какую страну подключаться. Необязательно — можно начать без нод.
Членская карта
Одна веб-ссылка, которую вы даёте каждому клиенту. В ней зашиты все настройки подключения — это всё, что ему когда-либо понадобится.
Дверь клиента
Бесплатное приложение (Happ, v2rayNG, Streisand…). Он один раз вставляет ссылку, нажимает «подключиться» — готово. Вы никогда не трогаете его телефон.
Как на самом деле движутся деньги
- Кому-то нужен приватный или разблокированный интернет, и он платит вам (принимайте криптовалюту автоматически через встроенный Telegram-бот или берите оплату любым удобным способом).
- Вы открываете NexusPanel и создаёте для него пользователя — задаёте срок действия и объём трафика. Занимает около 10 секунд.
- Вы отправляете ему ссылку-подписку.
- Он вставляет её в бесплатное приложение и нажимает «подключиться». Он в сети через ваш сервер.
- В следующем месяце он платит снова, чтобы оставаться активным. Повторяйте с любым числом клиентов.
VLESS, Xray, Reality или Hysteria — это просто разные виды туннелей, по которым идут данные. NexusPanel подбирает разумные значения по умолчанию — вы можете вести целый бизнес, так и не узнав, что они означают. Когда станет любопытно, глоссарий объяснит каждое из них одной строкой.
Готовы? Выберите точку старта
Перейдите к разделу С чего начать и выберите один из трёх путей: попробовать бесплатный период (без установки), установить с нуля на новом сервере или перейти с Marzban.
Слова, которые вам встретятся 📖
Каждый термин из этой документации, объяснённый одним простым предложением. Пробегитесь по нему сейчас; возвращайтесь всякий раз, когда какое-то слово вас собьёт с толку.
- VPS virtual private server
- Компьютер, который вы арендуете в дата-центре помесячно. На нём работает ваша панель. ~$4–6/месяц вполне достаточно для старта.
- Панель
- Веб-панель, в которую вы заходите, чтобы всем управлять — это и есть сам NexusPanel. Он живёт на вашем VPS.
- Нода
- Дополнительный сервер в другой локации, привязанный к вашей панели, чтобы клиенты могли выбирать, через какую страну подключаться. Полностью необязательна.
- Пользователь он же клиент
- Один человек, которому вы продаёте доступ. У каждого есть дата окончания, лимит трафика и собственная ссылка-подписка.
- Ссылка-подписка «sub-ссылка»
- Единственная ссылка, которую вы даёте клиенту. Его приложение читает её, чтобы понять, как подключиться. Если вы переходите с Marzban, эти ссылки продолжают работать.
- Клиентское приложение
- Бесплатное приложение, которое устанавливает клиент — например, Happ, v2rayNG, Streisand, Hiddify. Он один раз вставляет в него sub-ссылку.
- Marzban
- Более старая, бесплатная панель «сделай сам», с которой начинали многие операторы. NexusPanel — её обновлённый преемник с поддержкой, и он умеет импортировать конфигурацию Marzban одной командой.
- Remnawave
- Ещё одна панель управления VPN. NexusPanel умеет импортировать пользователей из живой Remnawave-панели по её API одной командой, сохраняя их ссылки-подписки рабочими.
- Лицензия
- Ваш ключ для запуска NexusPanel. Возьмите бесплатный 14-дневный пробный период или платный тариф через Telegram-бот. Без неё панель работает в пробном режиме.
- Домен
- Имя вроде
panel.yoursite.com, указывающее на ваш VPS. Нужно для замочка в браузере (HTTPS). Необязательно, но настоятельно рекомендуется. - SSL / HTTPS
- Замочек в браузере — шифрование, которое защищает входы в систему. NexusPanel настраивает его автоматически, если у вас есть домен.
- Xray
- Бесплатный движок «под капотом», который и перемещает зашифрованный трафик. Напрямую вы его почти не трогаете.
- VLESS / VMess / Trojan / Shadowsocks
- Разные виды туннелей, которые может использовать Xray. Как разные марки машин — все довезут вас до места. VLESS обычно используется по умолчанию.
- Reality / XHTTP / ECH / Finalmask
- Приёмы, благодаря которым ваш трафик выглядит как обычный сёрфинг, и его сложнее заблокировать. Включаются для каждого хоста; значений по умолчанию для начала достаточно.
- Hysteria 2
- Другой, очень быстрый тип туннеля, который особенно хорош на плохих или урезанных сетях. Необязателен; работает рядом с Xray.
- Middle-сервер
- Дешёвый ретранслятор, поставленный перед вашим основным сервером, чтобы обходить блокировки. Продвинутая тема — игнорируйте, пока это реально не понадобится.
- Inbound / Хост
- Конкретная «входная дверь» в ваш сервер (протокол + порт + настройки). В панели уже есть разумные; добавляйте новые по желанию.
- Администратор / Реселлер
- Дополнительные учётные записи, которые вы создаёте. Реселлер управляет своими клиентами в рамках заданных вами лимитов — удобно, когда под вами продают другие.
- Лимит IP / устройств
- Ограничение на количество телефонов или компьютеров, которые один клиент может использовать одновременно — мешает делиться паролем и съедать ваш трафик.
С чего начать
Три пути. Выберите тот, что подходит вам, и вы запуститесь меньше чем за 10 минут.
NexusPanel — это мультиарендная VPN-панель: вы продаёте субаккаунты, ваши клиенты подключаются через любой v2ray-клиент, а вы держите всё в одной панели. Если вы новичок, самый быстрый способ увидеть, что она умеет, — бесплатный пробный период. Если вы уже используете Marzban, инструмент миграции перенесёт всё одной командой — пользователей, администраторов, хосты, сертификаты, и даже ваши существующие ссылки-подписки продолжат работать. Если вы используете Remnawave — то же самое, отдельной командой (см. Миграция с Remnawave).
Попробуйте бесплатный период
Откройте Telegram-бот, введите /start и получите бесплатный 14-дневный Pro-триал, без карты. С ним вы можете развернуть собственную панель и опробовать всё до оплаты.
Установка на чистом сервере
Одна команда на чистом VPS с Ubuntu 20.04+. Скрипт спросит вашу лицензию, домен и пароль администратора — вот и всё. SSL настраивается автоматически, если вы направите домен на сервер.
Команда установки ↓Переход с Marzban
Тот же VPS, без перенастройки у клиентов. Инструмент миграции сначала делает пробный прогон и обратим — вы видите каждое изменение до того, как что-то будет затронуто, и можете откатиться в любой момент до финального переключения.
Руководство по миграции ↓Переход с Remnawave
Одна команда переносит пользователей и их учётные данные из Remnawave в NexusPanel. Ссылки-подписки клиентов продолжают работать без перенастройки.
Руководство по миграции ↓https://your-panel/sub/<token>, которая уже есть у ваших пользователей, остаётся рабочей.
Что вам понадобится
- VPS с Ubuntu 20.04+ (или любым дистрибутивом семейства Debian), минимум 1 ГБ ОЗУ, рекомендуется 2 ГБ
- Root-доступ по SSH к этому VPS
- Домен, направленный на VPS (необязательно — даёт настоящий сертификат HTTPS без предупреждений; без него всё равно будет HTTPS, но с самоподписанным сертификатом, который один раз покажет предупреждение в браузере)
- Лицензия NexusPanel (возьмите её в Telegram-боте, подойдёт бесплатный 14-дневный пробный период)
Как получить помощь
Если что-то не работает, попробуйте по порядку:
- Проверьте логи панели:
cd /opt/panel && docker compose logs --tail 100 - Прочтите нужный раздел этой документации (боковое меню слева)
- Напишите нам в Telegram — ссылка в боте, отвечаем за часы, а не за дни
Что такое NexusPanel
NexusPanel — это современная, многофункциональная панель управления прокси, созданная для VPN-провайдеров и сетевых администраторов. Она даёт единую панель для управления пользователями, нодами, подписками и аналитикой на нескольких серверах.
«Под капотом» полный набор возможностей включает:
- Поддержку нескольких протоколов — VMess, VLESS, Trojan, Shadowsocks через Xray-core, плюс Hysteria 2 как отдельный сайдкар. Расширения транспорта и обфускации (XHTTP, Reality, ECH, фрагментация TLS, Finalmask) настраиваются для каждого хоста в панели.
- Распределённые ноды — подключайте неограниченное число удалённых серверов из одной панели
- Реальные лимиты на пользователя — трафик, срок действия, ограничения по IP и устройствам действительно применяются за счёт разбора access-лога Xray
- Роли администраторов и привязку хостов — уровни «владелец», «администратор», «реселлер» с квотами трафика; назначайте конкретные хосты конкретным администраторам
- REST API — 75+ эндпоинтов для автоматизации и интеграции
- Аналитику в стиле Grafana — трафик во времени, рост числа пользователей, кольцевые диаграммы по протоколам/статусам, топ-потребители, нагрузка по трафику на ноды (с автообновлением)
- Telegram-бот — платёжный бот для клиентов (криптовалюта через NOWPayments) плюс уведомления для администраторов
- Систему лицензий — пробный → платные тарифы с heartbeat раз в 6 часов и уведомлениями об обновлениях Docker-образов
- Зашифрованные Happ-ссылки — настоящие deeplink-и
happ://crypt4/на RSA-4096, скрывающие исходный URL подписки - 2FA — TOTP с QR-кодом и резервными кодами
- Готовность к мобильным устройствам — адаптивная панель с нижней навигацией и выезжающим меню
- Защиту кода — чувствительные Python-модули скомпилированы Cython в бинарники
.so - Действенные уведомления внутри приложения — истекающие пользователи, лимиты трафика, офлайн-ноды, истечение лицензии
Требования
| Компонент | Минимум | Рекомендуется |
|---|---|---|
| ОС | Ubuntu 20.04+ / Debian 11+ | Ubuntu 22.04 LTS |
| ОЗУ | 1 ГБ | 2 ГБ+ |
| CPU | 1 vCPU | 2 vCPU |
| Диск | 10 ГБ | 20 ГБ+ (SSD) |
| Docker | 20.10+ | Последняя стабильная |
| Домен | Необязательно | Рекомендуется (для SSL) |
Быстрая установка
Выполните эту единственную команду на чистом VPS, чтобы установить NexusPanel с настройками по умолчанию:
curl -sL https://nexuspanel.store/install | bash
Скрипт запросит у вас:
- License Key и Client ID — от @nexuspanelpayment_bot (бесплатный 14-дневный пробный ключ тоже подходит, но установщик всегда требует ключ — установки без лицензии не бывает)
- Домен — для SSL через Let's Encrypt (пропустите для работы только по IP)
- Имя пользователя и пароль администратора — для панели
- Порт панели — по умолчанию 8443
Затем он:
- Установит Docker и Docker Compose, если их нет
- Скачает
ghcr.io/haitovs/nexus:latest(защищённый Cython продакшен-образ) - Создаст
/opt/panel/с.envиdocker-compose.yml(имя контейнера:nexus-panel) - Заполнит
xray_config.jsonс включённым access-логом (нужно для применения лимитов IP/устройств) - Запустит панель и выведет URL панели и учётные данные
nexus update на сервере.
Установка одной командой (подробно)
Скрипт установки принимает необязательные флаги для настройки:
# Рекомендуется — передайте свой License Key + Client ID (от @nexuspanelpayment_bot) curl -sL https://nexuspanel.store/install | bash -s -- \ --license YOUR_LICENSE_KEY \ --client YOUR_CLIENT_ID \ --domain panel.example.com \ --port 8443 # То же самое через переменные окружения вместо флагов curl -sL https://nexuspanel.store/install | LICENSE_ID=YOUR_LICENSE_KEY CLIENT_ID=YOUR_CLIENT_ID DOMAIN=panel.example.com bash # Только по IP (без домена) — просто опустите --domain, HTTPS всё равно будет (самоподписанный сертификат) curl -sL https://nexuspanel.store/install | bash -s -- \ --license YOUR_LICENSE_KEY \ --client YOUR_CLIENT_ID
License Key и Client ID обязательны — получите их у @nexuspanelpayment_bot. Запустите bash -s -- --help, чтобы увидеть все флаги (--port по умолчанию 8443, а также --username, --password, --ssl, --migrate).
Когда скрипт завершится, он напечатает URL панели, имя администратора и пароль — используйте их для входа. Не используйте примеры из этой документации (вроде myadmin/securepass123) — они не сработают.
Панель доступна по адресу https://YOUR_DOMAIN:8443/dashboard/ (или https://YOUR_IP:8443/dashboard/ при установке только по IP).
Первые шаги в панели
После входа в панель — вот самый быстрый путь к первому рабочему подключению:
- Создайте пользователя — Панель → Users → Add User. Задайте дату окончания и лимит трафика, затем скопируйте ссылку подписки и передайте её в клиентское приложение (Happ, v2rayNG, Streisand…).
- Добавьте ноду (по желанию) — Панель → Nodes → Add New Node, скопируйте сгенерированную команду быстрой установки, выполните её на сервере ноды, затем вернитесь и заполните Name + Address, чтобы подключить её. Подробнее в разделе Установка ноды.
- Настройте домен подписки — если ссылки подписки должны отдаваться с другого хоста/домена, чем сама панель, задайте
XRAY_SUBSCRIPTION_URL_PREFIXв редакторе окружения (Settings → Env) и используйте Save & Restart — эта настройка применяется только после полного перезапуска.
Ручная установка
Скрипт установки выше — поддерживаемый способ: он сам аутентифицируется в приватном реестре образов, пишет рабочий .env и настраивает файрвол. Чтобы собрать всё вручную:
# 1. Образ приватный — обычный `docker pull` вернёт "denied", пока вы не # авторизуетесь. Обменяйте лицензию на короткоживущий токен для pull: curl -s -X POST https://nexuspanel.store/api/registry-token \ -H 'Content-Type: application/json' \ -d '{"license_id":"YOUR_LICENSE_KEY","client_id":"YOUR_CLIENT_ID"}' # → {"token": "...", "username": "..."} — войдите с ним: echo $TOKEN | docker login ghcr.io -u $USERNAME --password-stdin # 2. Скачать образ docker pull ghcr.io/haitovs/nexus:latest # 3. Написать /opt/panel/.env — все ключи см. в разделе Env Reference ниже. # Минимум: UVICORN_PORT, SUDO_USERNAME, SUDO_PASSWORD, SQLALCHEMY_DATABASE_URL, # LICENSE_ID, CLIENT_ID mkdir -p /opt/panel /var/lib/panel /var/lib/nexus nano /opt/panel/.env # 4. Запустить с docker-compose.yml из раздела "Примеры Docker Compose" ниже cd /opt/panel docker compose up -d # Посмотреть логи docker compose logs -f
С SSL (Certbot)
Чтобы включить HTTPS с бесплатным сертификатом Let's Encrypt:
# Установить certbot apt install -y certbot # Получить сертификат (сначала остановите панель, если используется порт 80) docker compose down certbot certonly --standalone -d panel.example.com # Добавить в .env UVICORN_SSL_CERTFILE="/etc/letsencrypt/live/panel.example.com/fullchain.pem" UVICORN_SSL_KEYFILE="/etc/letsencrypt/live/panel.example.com/privkey.pem" # Примонтировать сертификаты в docker-compose.yml и перезапустить docker compose up -d
Добавьте задание cron для автоматического продления:
0 3 * * * certbot renew --quiet && docker compose -C /opt/nexuspanel restart
С PostgreSQL
Для продакшен-развёртываний PostgreSQL предпочтительнее SQLite. Установите BACKEND_MODE=modern и используйте драйвер, который реально входит в поставку панели — psycopg2 (синхронный), а не asyncpg:
# Задать в .env BACKEND_MODE=modern SQLALCHEMY_DATABASE_URL="postgresql+psycopg2://nexus:${POSTGRES_PASSWORD}@127.0.0.1:5432/nexus" REDIS_URL="redis://127.0.0.1:6379/0" POSTGRES_PASSWORD=$(openssl rand -hex 24)
Не пишите compose-файл вручную — используйте поддерживаемый docker-compose.modern.yml из корня репозитория: он поднимает Postgres 16 + Redis 7 рядом с панелью на network_mode: host:
# Из каталога установки (например /opt/panel)
cp docker-compose.modern.yml docker-compose.yml
docker compose up -d
psycopg2-binary, а не с asyncpg — URL вида postgresql+asyncpg:// не найдёт драйвер. Всегда используйте postgresql+psycopg2://.
Примеры Docker Compose
Classic (SQLite) — то, что реально пишет установщик
services: panel: image: ghcr.io/haitovs/nexus:latest container_name: nexus-panel restart: always env_file: .env network_mode: host dns: [8.8.8.8, 1.1.1.1] volumes: - /var/lib/panel:/var/lib/panel - /var/lib/nexus:/var/lib/nexus - ./.env:/app/env.live - /var/run/docker.sock:/var/run/docker.sock:ro environment: NEXUS_HOST_ENV_FILE: /app/env.live healthcheck: test: ["CMD", "curl", "-skf", "http://127.0.0.1:8443/api/v1/health"] interval: 30s timeout: 5s start_period: 30s retries: 3
network_mode: host обязателен — панель и любой совмещённый нод/middle-relay привязывают порты напрямую на хосте, а монтирование docker-сокета (только для чтения) нужно для one-click SSH-установки нод и middle-серверов. /var/lib/nexus — не опциональный том: там лицензионный модуль кеширует своё состояние, без него панель не может подтвердить лицензию. Замените 8443 в healthcheck на ваш UVICORN_PORT; при обслуживании домена также примонтируйте /etc/letsencrypt:/etc/letsencrypt:ro и укажите UVICORN_SSL_CERTFILE/UVICORN_SSL_KEYFILE на выданный сертификат.
Полный стек (PostgreSQL + Redis)
См. раздел С PostgreSQL выше — используйте поддерживаемый docker-compose.modern.yml вместо ручного compose-файла для Postgres.
Справочник по конфигурации
NexusPanel полностью настраивается через переменные окружения. Задавайте их в файле .env или передавайте напрямую в Docker.
.env.example в .env и раскомментируйте нужные переменные. У всех переменных есть разумные значения по умолчанию.
Сервер
| Переменная | По умолчанию | Описание |
|---|---|---|
UVICORN_HOST | 0.0.0.0 | Адрес привязки сервера |
UVICORN_PORT | 8000 | HTTP-порт |
UVICORN_UDS | — | Путь к Unix-сокету (переопределяет host/port) |
UVICORN_SSL_CERTFILE | — | Путь к SSL-сертификату (fullchain.pem) |
UVICORN_SSL_KEYFILE | — | Путь к приватному ключу SSL |
UVICORN_SSL_CA_TYPE | public | Тип CA: public или private |
DASHBOARD_PATH | /dashboard/ | URL-путь к веб-панели |
ALLOWED_ORIGINS | — | Источники CORS через запятую |
SUDO_USERNAME | — | Имя первого суперадминистратора |
SUDO_PASSWORD | — | Пароль первого суперадминистратора |
JWT_ACCESS_TOKEN_EXPIRE_MINUTES | 1440 | Срок жизни токена в минутах (по умолчанию 24 ч) |
База данных
| Переменная | По умолчанию | Описание |
|---|---|---|
SQLALCHEMY_DATABASE_URL | sqlite:///db.sqlite3 | Строка подключения к базе данных |
SQLALCHEMY_POOL_SIZE | 10 | Размер пула соединений |
SQLIALCHEMY_MAX_OVERFLOW | 30 | Максимум соединений сверх размера пула |
BACKEND_MODE | classic | classic (SQLite/Postgres, по умолчанию) или modern (добавляет очередь событий на Redis) |
REDIS_URL | — | Строка подключения к Redis; обязательна при BACKEND_MODE=modern |
postgresql+asyncpg://user:pass@host:5432/dbname для асинхронного PostgreSQL.
BACKEND_MODE=modern и укажите REDIS_URL, чтобы включить очередь событий на Redis. Используйте docker-compose.modern.yml, в котором рядом с панелью поставляется сервис redis:7. Большинству развёртываний это не нужно.
Xray
| Переменная | По умолчанию | Описание |
|---|---|---|
XRAY_JSON | xray_config.json | Путь к конфигурации ядра Xray |
XRAY_EXECUTABLE_PATH | /usr/local/bin/xray | Путь к бинарнику Xray |
XRAY_ASSETS_PATH | /usr/local/share/xray | Путь к geoip.dat и geosite.dat |
XRAY_SUBSCRIPTION_URL_PREFIX | — | Публичный префикс URL для ссылок-подписок (например, https://sub.example.com). Изменения вступают в силу только после полного перезапуска панели — используйте Save & Restart в редакторе Env, а не перезапуск контейнера. |
XRAY_SUBSCRIPTION_PATH | sub | Сегмент URL-пути для подписок |
XRAY_EXCLUDE_INBOUND_TAGS | — | Теги inbound через пробел, которые нужно исключить |
XRAY_FALLBACKS_INBOUND_TAG | — | Тег inbound, используемый для fallback-маршрутизации |
Подписка
| Переменная | По умолчанию | Описание |
|---|---|---|
SUB_PROFILE_TITLE | Subscription | Отображаемое имя в клиентских приложениях |
SUB_SUPPORT_URL | — | Ссылка на поддержку, включаемая в информацию о подписке |
SUB_UPDATE_INTERVAL | 12 | Интервал автообновления у клиента (часы) |
EXTERNAL_CONFIG | — | URL внешнего конфига для интеграции с клиентом |
USE_CUSTOM_JSON_DEFAULT | false | Включить свой JSON-конфиг для клиента по умолчанию |
USE_CUSTOM_JSON_FOR_V2RAYN | false | Включить свой JSON для V2RayN |
USE_CUSTOM_JSON_FOR_V2RAYNG | false | Включить свой JSON для V2RayNG |
USE_CUSTOM_JSON_FOR_STREISAND | false | Включить свой JSON для Streisand |
USE_CUSTOM_JSON_FOR_HAPP | false | Включить свой JSON для Happ |
SUB_RATE_LIMIT_PER_MINUTE | 60 | Максимум запросов подписки с одного IP в минуту (в процессе, сбрасывается при перезапуске) |
SUB_ENABLE_ETAG | true | Возвращать ETag / учитывать If-None-Match, чтобы экономить трафик на неизменившихся подписках |
SUB_GZIP_MIN_SIZE | 512 | Сжимать gzip ответы подписки больше этого числа байт |
Шаблоны
| Переменная | По умолчанию | Описание |
|---|---|---|
CUSTOM_TEMPLATES_DIRECTORY | /var/lib/panel/templates/ | Базовый каталог для своих шаблонов |
SUBSCRIPTION_PAGE_TEMPLATE | subscription/index.html | Шаблон страницы подписки пользователя |
HOME_PAGE_TEMPLATE | home/index.html | Шаблон главной страницы панели |
CLASH_SUBSCRIPTION_TEMPLATE | clash/default.yml | Шаблон подписки Clash |
CLASH_SETTINGS_TEMPLATE | clash/settings.yml | Шаблон настроек Clash |
V2RAY_SUBSCRIPTION_TEMPLATE | v2ray/default.json | Шаблон подписки V2Ray |
V2RAY_SETTINGS_TEMPLATE | v2ray/settings.json | Шаблон настроек V2Ray |
SINGBOX_SUBSCRIPTION_TEMPLATE | singbox/default.json | Шаблон подписки Sing-box |
SINGBOX_SETTINGS_TEMPLATE | singbox/settings.json | Шаблон настроек Sing-box |
MUX_TEMPLATE | mux/default.json | Шаблон конфигурации мультиплексирования |
USER_AGENT_TEMPLATE | user_agent/default.json | Шаблон разбора user-agent |
GRPC_USER_AGENT_TEMPLATE | user_agent/grpc.json | Шаблон user-agent для gRPC |
Telegram
| Переменная | По умолчанию | Описание |
|---|---|---|
TELEGRAM_API_TOKEN | — | Токен бота от @BotFather |
TELEGRAM_ADMIN_ID | — | ID пользователей Telegram для администраторов через запятую |
TELEGRAM_LOGGER_CHANNEL_ID | — | ID канала для сообщений логов |
TELEGRAM_DEFAULT_VLESS_FLOW | xtls-rprx-vision | VLESS flow по умолчанию для пользователей, созданных ботом |
TELEGRAM_PROXY_URL | — | URL прокси для подключений к Telegram API |
Уведомления
| Переменная | По умолчанию | Описание |
|---|---|---|
NOTIFY_STATUS_CHANGE | true | Уведомлять при смене статуса пользователя |
NOTIFY_USER_CREATED | true | Уведомлять о создании нового пользователя |
NOTIFY_USER_UPDATED | true | Уведомлять об изменении пользователя |
NOTIFY_USER_DELETED | true | Уведомлять об удалении пользователя |
NOTIFY_USER_DATA_USED_RESET | true | Уведомлять о сбросе использованного трафика |
NOTIFY_USER_SUB_REVOKED | true | Уведомлять об отзыве подписки |
NOTIFY_IF_DATA_USAGE_PERCENT_REACHED | true | Уведомлять при достижении порога трафика |
NOTIFY_IF_DAYS_LEFT_REACHED | true | Уведомлять при достижении порога по сроку действия |
NOTIFY_LOGIN | true | Уведомлять о входе администратора |
LOGIN_NOTIFY_WHITE_LIST | — | IP, исключаемые из уведомлений о входе |
NOTIFY_DAYS_LEFT | 3,7 | Пороги «дней до окончания» для уведомлений |
NOTIFY_REACHED_USAGE_PERCENT | 80,90 | Пороги процента использования |
RECURRENT_NOTIFICATIONS_TIMEOUT | 180 | Минут между повторными уведомлениями |
NUMBER_OF_RECURRENT_NOTIFICATIONS | 3 | Максимум повторных уведомлений на событие |
DISCORD_WEBHOOK_URL | — | Webhook Discord для уведомлений в стиле Telegram |
WEBHOOK_ADDRESS | — | Устаревшее: статические URL webhook через запятую. Для новых настроек используйте интерфейс Webhooks в панели. |
WEBHOOK_SECRET | — | Устаревшее: HMAC-секрет для доставки на WEBHOOK_ADDRESS. Webhooks в панели управляют секретами для каждого эндпоинта. |
Брендинг (White-Label)
| Переменная | По умолчанию | Описание |
|---|---|---|
BRAND_NAME | Panel | Название панели, отображаемое в интерфейсе и письмах |
BRAND_LOGO_URL | — | URL изображения своего логотипа |
BRAND_FAVICON_URL | — | URL своего favicon |
Безопасность
| Переменная | По умолчанию | Описание |
|---|---|---|
CAPTCHA_PROVIDER | disabled | Провайдер капчи: disabled, turnstile или builtin |
TURNSTILE_SITE_KEY | — | Site key Cloudflare Turnstile |
TURNSTILE_SECRET_KEY | — | Secret key Cloudflare Turnstile |
LOGIN_RATE_LIMIT | 10/minute | Максимум попыток входа за окно |
LOGIN_LOCKOUT_THRESHOLD | 10 | Неудачных попыток до блокировки |
LOGIN_LOCKOUT_DURATION_MINUTES | 30 | Длительность блокировки в минутах |
Логирование
| Переменная | По умолчанию | Описание |
|---|---|---|
LOG_LEVEL | INFO | Уровень логов: DEBUG, INFO, WARNING, ERROR |
LOG_FORMAT | text | Формат логов: text или json |
LOG_FILE_PATH | — | Писать логи в файл (в дополнение к stdout) |
LOG_MAX_SIZE_MB | 10 | Максимальный размер файла лога до ротации |
LOG_BACKUP_COUNT | 5 | Сколько ротированных файлов логов хранить |
Метрики (Prometheus)
| Переменная | По умолчанию | Описание |
|---|---|---|
METRICS_ENABLED | false | Включить эндпоинт /metrics для Prometheus |
METRICS_TOKEN | — | Bearer-токен, нужный для сбора метрик |
Дополнительные переменные
| Переменная | По умолчанию | Описание |
|---|---|---|
ACTIVE_STATUS_TEXT | Active | Своя метка для статуса «активен» |
EXPIRED_STATUS_TEXT | Expired | Своя метка для статуса «истёк» |
LIMITED_STATUS_TEXT | Limited | Своя метка для статуса «ограничен» |
DISABLED_STATUS_TEXT | Disabled | Своя метка для статуса «отключён» |
ONHOLD_STATUS_TEXT | On-Hold | Своя метка для статуса «на удержании» |
USERS_AUTODELETE_DAYS | -1 | Автоудаление истёкших пользователей через N дней (-1 = отключено) |
USER_AUTODELETE_INCLUDE_LIMITED_ACCOUNTS | false | Включать в автоудаление пользователей, ограниченных по трафику |
JOB_CORE_HEALTH_CHECK_INTERVAL | 10 | Интервал проверки работоспособности (секунды) |
JOB_RECORD_NODE_USAGES_INTERVAL | 30 | Интервал записи использования нод |
JOB_RECORD_USER_USAGES_INTERVAL | 10 | Интервал записи использования пользователей |
JOB_REVIEW_USERS_INTERVAL | 10 | Интервал проверки пользователей на истечение |
JOB_SEND_NOTIFICATIONS_INTERVAL | 30 | Интервал отправки уведомлений |
DISABLE_RECORDING_NODE_USAGE | false | Отключить запись использования нод |
DEBUG | false | Включить режим отладки с горячей перезагрузкой |
DOCS | false | Включить Swagger UI по адресу /docs |
VITE_BASE_API | /api/v1/ | Базовый путь API для сборки фронтенда |
Панель управления
Панель управления NexusPanel — это современное веб-приложение на React, доступное по адресу /dashboard/. Она предоставляет полный интерфейс для управления вашей прокси-инфраструктурой.
Страница обзора
Главная страница панели показывает статистику в реальном времени с одного взгляда:
- Всего пользователей — количество активных, истёкших, ограниченных, отключённых
- Использование трафика — суммарная отдача/загрузка с графиками тренда
- Статус нод — индикаторы онлайн/офлайн с процентом нагрузки
- Недавняя активность — последние создания пользователей, подключения и действия администраторов
- Распределение по протоколам — круговая диаграмма используемых протоколов
Управление пользователями
Страница «Пользователи» поддерживает полное управление жизненным циклом:
- Создание пользователя — задайте имя, лимит трафика, дату окончания, протоколы, лимит устройств, лимит IP
- Редактирование пользователя — меняйте все поля, включая статус (активен, отключён, на удержании)
- Массовые операции — выбирайте нескольких пользователей для массового обновления, сброса трафика или удаления
- Поиск и фильтрация — фильтруйте по статусу, администратору, протоколу или ищите по имени
- Ссылки-подписки — копирование URL подписки, генерация QR-кода
- Статистика использования — отдача/загрузка по каждому пользователю с историческими данными
Ноды
Управляйте удалёнными нодами Xray, подключёнными к панели:
- Добавление ноды — укажите адрес, порт и коэффициент использования
- Статус подключения — онлайн/офлайн в реальном времени с задержкой
- Флаги стран — автоматическое отображение флага по локации ноды (60+ стран)
- Изменение порядка — перетаскивайте или используйте стрелки, чтобы задать порядок отображения
- Сертификат — просмотр и копирование SSL-сертификата ноды для удалённой настройки
- Отслеживание аптайма — исторический процент аптайма по каждой ноде
Хосты и расширенные настройки TLS
У каждого inbound Xray есть одна или несколько строк-хостов, которые говорят генератору подписок, какой адрес, порт и параметры TLS выдавать в клиентских конфигах. Полный набор полей по каждому хосту:
| Поле | Назначение |
|---|---|
| Remark | Отображаемое имя в клиентских приложениях |
| Address | Домен или IP сервера, к которому подключается клиент |
| Port | Переопределить порт прослушивания inbound |
| SNI / Host | TLS Server Name Indication и HTTP-заголовок Host |
| Security / ALPN / Fingerprint | Профиль TLS: none / tls / reality; h2/http1.1; uTLS Chrome/Firefox/Safari |
| Allow Insecure | Пропускать проверку TLS-сертификата (используйте только за CDN, где сертификат не виден) |
| Country code | ISO 3166-1 alpha-2 — управляет региональным переупорядочиванием подписки |
| Allowed / Denied Admins | Ограничить хост конкретными суб-администраторами (пусто = все администраторы) |
ECH (Encrypted Client Hello)
ECH скрывает SNI от пассивных наблюдателей — расширение TLS-рукопожатия шифруется с помощью открытого ключа, опубликованного в DNS. Включается для каждого хоста: переключите ECH и вставьте блоб ECHConfig от вашего провайдера CDN/DNS. Требуется клиент с поддержкой ECH (Happ, Chrome 117+).
Фрагментация TLS
Разбивает TLS ClientHello на меньшие TCP-сегменты, обходя сопоставление DPI с шаблоном по первому пакету. Используйте, когда активна блокировка по SNI, но CDN недоступен.
- Размер фрагмента — байт на фрагмент, например
100-200(случайный диапазон) - Задержка фрагмента — мс между фрагментами, например
10-20
Фрагментация записей TLS
Фрагментирует на уровне записей TLS, а не TCP. Более агрессивно, чем фрагментация ClientHello; используйте, когда стандартная фрагментация TLS всё ещё определяется по отпечатку.
Настройки Noise
Вставляет случайные шумовые пакеты перед настоящим TLS-рукопожатием, чтобы сбить снятие отпечатка по потоку. Поле JSON:
[{"type": "rand", "packet": "10-50", "delay": "5-10"}]
Тип rand отправляет случайные байты; тип str отправляет буквальную hex-строку. Размер пакета и задержка принимают запись диапазоном.
Случайный User-Agent
Делает HTTP User-Agent случайным при каждом запросе, чтобы избежать снятия отпечатка клиента на транспортах WS/HTTP.
Сессии
Отслеживайте активные подключения устройств и управляйте ими:
- Активные сессии — просмотр всех подключённых в данный момент устройств
- Сессии по пользователю — смотрите, какие устройства использует конкретный пользователь
- Отключение — принудительно завершайте отдельные сессии
- История IP — отслеживайте историю подключений пользователя по IP
Аналитика
Комплексная панель аналитики с:
- Сводкой — всего пользователей, активные подключения, трафик, обзор выручки
- Распределением по протоколам — разбивка использования по протоколам (VMess, VLESS и т. д.)
- Нагрузкой на ноды — число подключений и использование трафика по каждой ноде
- Аптаймом нод — процент аптайма за периоды 24 ч, 7 д, 30 д
- Топ-пользователями — крупнейшие потребители трафика
- Истекающими пользователями — пользователи, у которых срок истекает в течение настраиваемого числа дней
Управление администраторами
Ролевая система администраторов с тремя уровнями:
| Роль | Возможности |
|---|---|
| Владелец | Полный доступ: управление администраторами, нодами, системными настройками, всеми пользователями |
| Администратор | Управление пользователями (всеми), просмотр нод и аналитики, ограниченные настройки |
| Реселлер | Управление только своими пользователями, ограничен квотами max_users и max_traffic_bytes |
У каждого администратора могут быть квоты:
max_users— максимальное число пользователей, которое администратор может создатьmax_traffic_bytes— общая квота трафика по всем его пользователям
Настройки
- Двухфакторная аутентификация — включение/отключение TOTP 2FA со страницы настроек
- Конфигурация ядра Xray — редактирование сырого JSON Xray в 2-колоночном виде (редактор слева, живые логи и статус справа)
- Редактор Env — редактирование SMTP, токенов, флагов функций прямо в интерфейсе с маскировкой секретов; Save & Restart перезапускает панель
- Hysteria2 — управление inbound-ами hy2 со страницы настроек (Standard+)
- Информация о лицензии — тариф, оставшиеся дни, текущее/максимальное число пользователей/нод
Группы пользователей
Группы пользователей (называемые Squads в Remnawave) позволяют сегментировать пользователей для управления видимостью inbound-ов и переопределения подписок. Лицензия Pro, только для sudo.
Каждая группа может делать что-то одно или всё из перечисленного:
- Фильтр inbound (
applies_to_inbounds) — CSV тегов inbound. Пользователи в группе получают записи подписки только для соответствующих inbound-ов. Пусто = все inbound-ы. - Переопределение шаблона (
override_template_id) — использовать другой шаблон подписки для участников этой группы. - Переопределение хостов (
override_hosts) — внедрять другие строки-хосты в подписки участников (например, дать VIP-группе хост с прямым IP, скрытый от всех остальных).
Добавляйте пользователей в группу со страницы деталей пользователя или через API. Пользователь может состоять не более чем в одной группе.
# Список групп curl /api/v1/user-groups -H "Authorization: Bearer TOKEN" # Создать VIP-группу, которая получает только inbound-ы hy2 + VLESS-Reality curl -X POST /api/v1/user-groups \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"VIP","applies_to_inbounds":"hy2-main,vless-reality"}' # Добавить пользователя в группу curl -X POST /api/v1/user-groups/1/members \ -d '{"username":"alice"}' -H "Authorization: Bearer TOKEN"
Наборы inbound
Набор inbound — это именованный CSV тегов inbound, который вы назначаете ноде. Когда у ноды есть набор inbound, на ней активируются только эти inbound-ы — остальные подавляются. Используйте это, чтобы запускать разные наборы протоколов на разных нодах: например, нода A получает VLESS+Trojan, нода B — VLESS+hy2.
Лицензия Pro, только для sudo.
# Создать набор inbound curl -X POST /api/v1/inbound-sets \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"UDP nodes","tags":"hy2-main,vmess-ws"}' # Назначить ноде (задать inbound_set_id у ноды) curl -X PUT /api/v1/node/1 \ -d '{"inbound_set_id": 2}' -H "Authorization: Bearer TOKEN"
Правила ответа подписки
Правила подписок позволяют настраивать, как выглядит ответ подписки пользователя, в зависимости от его клиента. Правила сопоставляются со свойствами запроса и применяют действие.
| Поле сопоставления | Операторы | Действия |
|---|---|---|
user_agent | equals / contains / regex | template / status / headers |
client_os | equals / contains / regex | template / status / headers |
Примеры:
- Сопоставление
user_agent contains "Happ"→ действиеtemplate = happ-custom— выдавать оптимизированный под Happ шаблон клиентам Happ - Сопоставление
client_os equals "iOS"→ действиеheaders = {"Content-Type": "text/plain"} - Глобальные правила (только для sudo,
admin_id = NULL) применяются ко всем пользователям независимо от того, какому администратору они принадлежат
Правила вычисляются по возрастанию priority. Побеждает первое совпадение.
# Создать правило: выдавать шаблон sing-box клиентам Karing curl -X POST /api/v1/sub-rules \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Karing","match_field":"user_agent","match_op":"contains", "match_value":"Karing","action":"template","action_arg":"singbox-default"}'
Webhooks
NexusPanel доставляет подписанные HTTP POST-события на любой зарегистрированный вами URL. Каждая доставка содержит заголовок X-Nexus-Signature — HMAC-SHA256 тела с секретом вашего эндпоинта.
Области событий
| Область | События |
|---|---|
user.* | user.created, user.updated, user.deleted, user.expired, user.disabled, user.data_used_reset |
node.* | node.connected, node.disconnected, node.reconnecting |
service.* | service.started, service.stopped |
billing.* | billing.renewed, billing.expired |
errors.* | errors.cert_expired, errors.xray_crash |
hwid.* | hwid.mismatch, hwid.reset |
Оставьте области пустыми, чтобы получать все события. Доставка повторяется с экспоненциальной задержкой; после максимального числа попыток событие помечается как неудачное и отбрасывается.
# Зарегистрировать эндпоинт curl -X POST /api/v1/webhooks \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{"url":"https://my-server/hook","scopes":"user.*,node.*"}' # Ответ содержит секрет (показывается один раз) # Отправить тестовую доставку curl -X POST /api/v1/webhooks/1/test -H "Authorization: Bearer TOKEN" # Проверить подпись в вашем обработчике (пример на Python) # expected = hmac.new(secret, body, sha256).hexdigest() # assert expected == request.headers["X-Nexus-Signature"]
WEBHOOK_ADDRESS (URL через запятую) и WEBHOOK_SECRET по-прежнему работают как статическая альтернатива через переменные окружения. Для новых настроек используйте интерфейс панели — он поддерживает секреты, области и историю доставки для каждого эндпоинта.
Страница клиентов
Панель → Клиенты показывает подобранный список рекомендуемых VPN-клиентов со значками платформ, ссылками для скачивания и заметками по использованию. Операторы делятся URL этой страницы с конечными пользователями.
| Клиент | Платформы | Заметки |
|---|---|---|
| Happ | iOS / macOS / Windows / Android | Рекомендуется — нативный sub URL, привязка по HWID, офлайн-кэш |
| v2RayTun | iOS / macOS / Android | Популярный клиент для iOS, поддержка VLESS-Reality |
| Karing | Все платформы | На основе Sing-box, сильная кроссплатформенность |
| Shadowrocket | iOS | $2.99 в App Store США — надёжен на iOS |
| V2rayNG | Android | Классический клиент для Android |
| FlClashX | Windows / macOS / Linux / Android | Совместим с Mihomo/Clash |
| Streisand | iOS / macOS | Поддерживает свой JSON — задайте USE_CUSTOM_JSON_FOR_STREISAND=true |
Система лицензий
NexusPanel использует центральный лицензионный сервер (nexuspanel.store) для проверки установок и доставки обновлений. Так клиенты распределяются по тарифам, тарифицируются и поддерживаются в актуальном состоянии.
Как работает heartbeat
- Каждые 6 часов панель вызывает
POST /api/validateна лицензионном сервере, передавая своиlicense_id,client_idи полную телеметрию (версия панели, версия Xray, имя хоста, ОС, IP, всего/активных пользователей, всего/активных нод, суммарный трафик, аптайм). - Лицензионный сервер сохраняет это и отвечает
{tier, expires_at, latest_version, update_available, docker_image}. - Если
update_availableистинно и включёнAUTO_UPDATE(по умолчанию), панель в фоне выполняетdocker compose pull && docker compose up -d --force-recreate— вам ничего делать не нужно.
Тарифы
| Тариф | Цена | Пользователи | Ноды | Срок |
|---|---|---|---|---|
| Пробный | Бесплатно | Безлимит | Безлимит | 14 дней |
| Standard | $10/мес | Безлимит | 10 | 30 дней/мес |
| Pro | $30/мес | Безлимит | Безлимит | 30 дней/мес |
Пробный
Без банковской карты, без регистрации — откройте Telegram-бот и введите /start. Вы получите бесплатный 14-дневный Pro-триал без ограничений по пользователям и нодам. Все протоколы и аналитика доступны сразу — достаточно, чтобы оценить на реальном трафике.
Standard — $10/месяц
Для операторов, у которых работает живой сервис. Продолжение работы после пробного периода — до 10 нод, и открывает:
- Протокол Hysteria 2 на всех нодах
- Массовые операции (включить/отключить/сбросить/удалить сотни пользователей разом)
- Доступ к API для автоматизации и интеграций
- Оплату на несколько месяцев (3/6/12 месяцев со скидкой 5%/10%/15%)
Pro — $30/месяц
Всё из Standard, плюс отсутствие ограничения на ноды и полный набор возможностей:
- Неограниченное число нод в любом количестве стран
- ECH (Encrypted Client Hello) — скрывает SNI от DPI
- Finalmask — транспортный слой защиты от снятия отпечатков
- White-label брендинг (свой домен панели + логотип)
- Группы пользователей и наборы inbound для сегментации уровня реселлеров
- Ретрансляцию через Middle-сервер с автогенерируемыми правилами iptables
- Приоритетную поддержку
Сравнение возможностей
| Возможность | Пробный | Standard | Pro |
|---|---|---|---|
| Максимум пользователей | Безлимит | Безлимит | Безлимит |
| Максимум нод | Безлимит | 10 | Безлимит |
| Срок | 14 дней | 30 дней/мес | 30 дней/мес |
| Все протоколы (VLESS, VMess, Trojan, SS) | ✓ | ✓ | ✓ |
| Hysteria 2 | ✓ | ✓ | ✓ |
| Аналитика в стиле Grafana | ✓ | ✓ | ✓ |
| Просмотр живых сессий | ✓ | ✓ | ✓ |
| Журнал аудита | ✓ | ✓ | ✓ |
| Webhooks | — | ✓ | ✓ |
| CLI оператора | ✓ | ✓ | ✓ |
| Массовые операции | — | ✓ | ✓ |
| Доступ к API | — | ✓ | ✓ |
| ECH + Finalmask | — | — | ✓ |
| White-label брендинг | — | — | ✓ |
| Группы пользователей и наборы inbound | — | — | ✓ |
| Ретрансляция через Middle-сервер | — | — | ✓ |
Покупка лицензии
Откройте @nexuspanelpayment_bot в Telegram. Нажмите View Plans, выберите тариф, выберите срок (1/3/6/12 месяцев с растущими скидками), выберите криптовалюту (USDT TRC20, BTC, ETH, LTC, TRX и 200+ других) и отправьте точную показанную сумму на указанный кошелёк. Как только NOWPayments подтвердит платёж, бот выдаст ваши License Key и Client ID.
Льготный период
Если ваша лицензия истекла, панель продолжает работать в льготном режиме 72 часа, чтобы вы могли продлить без простоя. После этого API переходит в режим только для чтения, пока не будет восстановлена действующая лицензия.
Применение лимитов IP и устройств
NexusPanel применяет лимиты IP и устройств по каждому пользователю в реальном времени, разбирая access-лог Xray — а не только при импорте подписки. Именно это заставляет ip_limit и device_limit действительно работать.
Как это работает
- Xray пишет по одной строке в
$XRAY_ACCESS_LOGна каждое принятое подключение. - Задание
enforce_limitsзапускается каждые 60 секунд, читает хвост лога (с учётом смещения и ротации) и извлекает пары(user_id, client_ip)за последниеLIMIT_WINDOW_SECONDS(по умолчанию 600 = 10 минут). - Для каждого пользователя подсчитываются уникальные IP. Если их число превышает
ip_limit(илиdevice_limit, еслиip_limitне задан) и пользователь сейчасactiveиip_limit_mode == "limit", пользователь переводится в статусlimited. - Все увиденные IP записываются в
user_ip_history. Просмотреть IP по пользователю можно черезGET /api/v1/user/{username}/ips.
Необходимая конфигурация xray
При установке по умолчанию это включается автоматически. Для существующих установок панель при запуске автоматически правит ваш xray_config.json, добавляя путь к access-логу. Конфигурация вручную:
{
"log": {
"loglevel": "warning",
"access": "/var/lib/panel/xray-access.log"
}
}
Настраиваемые параметры
| Переменная окружения | По умолчанию | Назначение |
|---|---|---|
XRAY_ACCESS_LOG | /var/log/xray/access.log | Путь к файлу access-лога Xray |
LIMIT_WINDOW_SECONDS | 600 | Скользящее окно для подсчёта уникальных IP |
LIMIT_ENFORCE_INTERVAL | 60 | Как часто (секунды) запускается задание применения лимитов |
Резервные копии
NexusPanel выполняет автоматическое резервное копирование базы данных каждый день в 03:00 UTC через задание backup APScheduler.
Куда сохраняются копии
- Локальные файлы:
/var/lib/panel/backups/backup_YYYYMMDD_HHMMSS.sqlite3(или.sqlдля PostgreSQL) - Хранятся последние 7 копий; более старые автоматически удаляются
- Если настроены
TELEGRAM_API_TOKENиTELEGRAM_ADMIN_ID, каждая копия также отправляется вам в Telegram документом, чтобы у вас была копия вне сервера
Резервное копирование вручную
# SQLite docker exec nexus-panel cp /var/lib/panel/db.sqlite3 /var/lib/panel/backups/manual.sqlite3 # Или возьмите файл напрямую с хоста cp /var/lib/panel/db.sqlite3 ~/panel-backup-$(date +%F).sqlite3
Восстановление
- Остановите панель:
cd /opt/panel && docker compose down - Замените файл БД:
cp /path/to/backup.sqlite3 /var/lib/panel/db.sqlite3 - Перезапустите:
docker compose up -d
BACKUP_DIR — куда пишутся копии (по умолчанию /var/lib/panel/backups)BACKUP_RETENTION — сколько последних копий хранить (по умолчанию 7)
Зашифрованные подписки Happ
Кнопка «H» у каждого пользователя в панели генерирует настоящий deeplink happ://crypt4/<base64> с использованием RSA-4096 PKCS1v15 и официального открытого ключа Happ. После добавления в клиент Happ пользователь не может посмотреть, изменить или поделиться исходным URL подписки.
URL подписки длиннее 501 байта (лимит RSA-4096 + PKCS1v15) автоматически переходят на обычный формат happ://add/<base64>.
Ведение бизнеса
Ваш первый клиент
- Панель → Пользователи → Добавить пользователя.
- Укажите имя пользователя, выберите дату истечения и лимит трафика (или оставьте оба без ограничений), выберите протоколы.
- Сохраните — панель сразу сгенерирует ссылку на подписку.
- Отправьте клиенту ссылку. Он вставляет её в клиентское приложение (см. страницу Клиенты с рекомендациями) и подключается.
Всё это доступно и через API для автоматизации — см. API пользователей, если хотите создавать аккаунты скриптом из собственного магазина или бота.
Лимиты устройств и IP
Лимиты устройств и IP (см. как работает контроль) — это не только защита от злоупотреблений, но и рычаг для ценообразования. Частая структура:
| Тариф | Лимит устройств | Типичное применение |
|---|---|---|
| Персональный | 1–2 | Один человек, одно-два устройства |
| Семейный / Командный | 4–6 | Общий доступ для семьи или небольшой команды, цена выше |
| Безлимитный | 0 (выкл.) | Премиум-тариф без ограничений — и цена соответствующая |
Установите device_limit (или ip_limit) при создании или редактировании пользователя. Клиенты, превысившие лимит, автоматически переводятся в статус limited — следить за этим вручную не нужно.
Админы и реселлеры
Если под вами продают другие люди — друзья, сотрудники или суб-реселлеры — выдайте каждому отдельный логин администратора вместо того, чтобы делиться своим. Полное описание см. в разделе Управление администраторами; коротко:
- Владелец (вы) — видит всё, управляет остальными админами.
- Админ — управляет пользователями, но не настройками панели и не другими админами.
- Реселлер — управляет только своими пользователями, в рамках лимитов
max_usersиmax_traffic_bytes, которые вы задаёте.
Так вы масштабируетесь без необходимости лично проводить каждую продажу: реселлер заходит в свой аккаунт, создаёт и обслуживает своих клиентов, не видя и не трогая чужих.
Самообслуживание через Telegram
После подключения Telegram-бота клиенты сами проверяют свой трафик (/usage), заново получают ссылку (/sub) и смотрят подключённые устройства (/devices) — без обращения к вам. Это снимает большую часть обращений в поддержку вида «а работает ли ещё мой VPN».
Ценообразование
NexusPanel не устанавливает ваши цены — это полностью на ваше усмотрение и зависит от вашего рынка. Для старта большинство операторов учитывают:
- Ваши расходы — VPS панели, ноды, ваша лицензия NexusPanel (см. тарифы и цены), а также трафик, если провайдер берёт за него плату.
- Ваше отличие от конкурентов — больше слотов на устройства, больше локаций нод, приоритетная поддержка, или просто стабильность, когда у конкурентов её нет.
- Ваш рынок — сколько берут похожие сервисы там, где живут ваши клиенты. Пакетные многомесячные тарифы (по аналогии со скидками 3/6/12 месяцев у самой панели) — частый способ повысить удержание клиентов.
Принимайте оплату так, как удобно вам — вручную через Telegram или мессенджеры, через бота для оплаты, или через собственный магазин, который вызывает API пользователей и создаёт аккаунт автоматически после оплаты.
Ноды
Что такое нода
Нода — это удалённый сервер с ядром Xray, который подключается обратно к вашему экземпляру NexusPanel. Ноды позволяют распределять прокси-точки по нескольким серверам и географическим локациям, управляя всем из одной панели.
Панель общается с нодами по защищённому gRPC-соединению с использованием взаимного TLS. Через этот канал передаются конфигурации пользователей и данные о трафике.
Установка ноды
Панель → Ноды → Добавить новую ноду открывает окно с двумя вкладками — выберите подходящую в зависимости от того, есть ли у панели SSH-доступ к серверу ноды.
Auto install (рекомендуется)
Вставьте IP свежего VPS и данные SSH-входа (пароль root или приватный ключ) — панель сделает всё остальное: подключится по SSH, установит Docker и агент ноды со встроенным mTLS-сертификатом, зарегистрирует ноду и дождётся подключения. Ничего копировать и запускать вручную не нужно — пароль/ключ SSH используется один раз и нигде не сохраняется.
Manual (резервный вариант — если панель не может достучаться до ноды по SSH)
Вкладка Manual вместо этого генерирует готовую к вставке однострочную команду со встроенным сертификатом панели. Никакой записи файла сертификата вручную.
- Панель → Ноды → Добавить новую ноду → вкладка Manual
- Нажмите Copy Install Command — команда включает сертификат, порт, порт API и URL панели
- Вставьте и выполните на сервере ноды
- Введите IP ноды и порты в панели → Add Node
curl -sL https://nexuspanel.store/install-node | bash -s -- \ --port 62060 \ --api-port 62061 \ --panel-url 'https://panel.example.com:8443' \ --cert-b64 '<base64-cert>'
Установщик автоматически ждёт снятия блокировок apt/dpkg — его безопасно запускать на только что развёрнутом VPS. Не пропускайте --panel-url: без него аутентификация Hysteria 2 на этой ноде останется отключённой, пока вы не зададите её позже.
Сертификат и порты
NexusNode аутентифицируется в панели с помощью подписывающего сертификата панели:
- Порт подключения к панели:
62060 - Порт API Xray:
62061 - CN сертификата:
Panel— значениеssl_target_nameв конфиге ноды должно совпадать - Сертификат один раз запрашивается из
GET /api/v1/node/settings(или встраивается командой установки) и сохраняется в/var/lib/nexus-panel-node/ssl_client_cert.pem
Docker Compose для ноды
Это реальный compose-файл, который генерирует установщик в /opt/nexus-panel-node/docker-compose.yml — для справки, если настраиваете его вручную:
services: node: image: ghcr.io/haitovs/nexus-node:latest container_name: nexus-panel-node restart: always network_mode: host environment: SERVICE_PORT: 62060 XRAY_API_PORT: 62061 SSL_CERT_FILE: /var/lib/nexus-panel-node/ssl_cert.pem SSL_KEY_FILE: /var/lib/nexus-panel-node/ssl_key.pem SSL_CLIENT_CERT_FILE: /var/lib/nexus-panel-node/ssl_client_cert.pem # Sidecar Hysteria2 — пусто отключает его, пока не передан --panel-url PANEL_HY2_AUTH_URL: "https://panel.example.com:8443/api/v1/hy2-auth" volumes: - /var/lib/nexus-panel-node:/var/lib/nexus-panel-node - /etc/hysteria:/etc/hysteria
network_mode: host означает, что раздела ports: в Docker нет — нода привязывает все порты (сервисный, API и все инбаунды Xray/Hysteria, к которым подключаются пользователи) напрямую на хосте.
Несколько нод
Чтобы добавить ноды в разных локациях:
- Установите сервис ноды на каждый сервер с помощью сгенерированной однострочной команды
- В панели добавьте каждую ноду с её публичным IP и портами
- Назначьте флаг страны — он управляет и визуальной сеткой, и региональным переупорядочиванием подписки
- Перетаскиванием задайте порядок отображения в сетке
- Задайте коэффициент использования для каждой ноды (например,
1.5означает, что трафик считается с множителем 1.5×)
CF-IPCountry (Cloudflare) или локальную базу MaxMind. Задайте country_code на каждой строке-хосте, чтобы это работало.
Устранение неполадок нод
| Проблема | Решение |
|---|---|
| Нода показывает «Offline» | Проверьте, что файрвол разрешает TCP 62060 от панели; проверьте сертификат в /var/lib/nexus-panel-node/ssl_client_cert.pem |
| Connection refused | Убедитесь, что Docker-контейнер запущен: docker compose ps |
| Ошибка сертификата | Скопируйте сертификат из панели заново (GET /api/v1/node/settings); проверьте ssl_target_name = Panel |
| Высокая задержка | Проверьте сетевой маршрут между панелью и нодой; убедитесь, что заданы управление перегрузкой BBR и буферы сокетов 64 МБ |
| Пользователи не могут подключиться через ноду | Проверьте, что прокси-порты (443, 80 и т. д.) открыты для конечных пользователей в файрволе ноды |
Справочник API
Все эндпоинты API находятся под /api/v1/. Включите интерактивный Swagger UI, задав DOCS=true и зайдя на /docs.
Аутентификация
Получите JWT access-токен, отправив учётные данные:
/api/v1/admin/tokencurl -X POST https://panel.example.com:8443/api/v1/admin/token \ -d "username=admin&password=admin&grant_type=password" # Ответ: # {"access_token": "eyJ...", "token_type": "bearer"} # Используйте токен в последующих запросах: curl -H "Authorization: Bearer eyJ..." https://panel.example.com:8443/api/v1/system
Если для администратора включена 2FA, передайте TOTP-код в заголовке X-TOTP-Code.
POST /api/v1/admin/2fa/setup — сгенерировать TOTP-секрет + резервные кодыPOST /api/v1/admin/2fa/enable — проверить код и активировать 2FAPOST /api/v1/admin/2fa/disable — деактивировать 2FA
Пользователи
/api/v1/userСоздать нового пользователя с протоколами, лимитом трафика, сроком действия, лимитом устройств и лимитом IP.
/api/v1/usersСписок всех пользователей. Автоматически ограничивается по администратору для несудо-аккаунтов.
/api/v1/user/{username}Получить детальную информацию о пользователе, включая статистику использования и ссылки-подписки.
/api/v1/user/{username}Обновить поля пользователя (лимит трафика, срок действия, статус, протоколы и т. д.).
/api/v1/user/{username}Безвозвратно удалить пользователя и все связанные данные.
Массовые операции
/api/v1/users/bulk/update/api/v1/users/bulk/delete/api/v1/users/bulk/resetЭкспорт
/api/v1/export/usersСкачать всех пользователей в виде CSV-файла.
/api/v1/export/subscription-linksЭкспортировать все ссылки-подписки в виде обычного текста.
Администраторы
/api/v1/adminСоздать нового администратора с ролью (owner, admin, reseller), max_users и max_traffic_bytes.
/api/v1/adminsСписок всех учётных записей администраторов.
Ноды
/api/v1/inboundsСписок всех протокольных inbound-ов.
/api/v1/hostsПолучить конфигурации хостов (только sudo).
Аналитика
/api/v1/analytics/summaryСводная статистика для обзора панели.
/api/v1/analytics/protocolsРазбивка распределения по протоколам.
/api/v1/analytics/nodes/loadЧисло подключений и трафик по каждой ноде.
/api/v1/analytics/nodes/uptimeПроценты аптайма нод.
/api/v1/analytics/users/expiring?days=30Пользователи, у которых срок истекает в течение указанного числа дней.
/api/v1/analytics/users/top?limit=10Топ-пользователи по потреблению трафика.
Сессии
/api/v1/sessions/active?hours=24Активные сессии устройств за последние N часов.
/api/v1/sessions/user/{username}Сессии конкретного пользователя.
/api/v1/sessions/{session_id}Принудительно отключить сессию устройства.
Система
/api/v1/systemСистемная статистика, включая CPU, память и трафик. Несудо-администраторы видят обнулённые значения для чувствительных метрик.
/api/v1/healthЭндпоинт проверки работоспособности, возвращающий статус базы данных и ядра Xray.
/metricsЭндпоинт метрик, совместимый с Prometheus. Требует METRICS_ENABLED=true и METRICS_TOKEN для аутентификации.
DOCS=true в вашем .env и зайдите на http://your-panel/docs для интерактивного Swagger UI.
Telegram-бот
Настройка
- Откройте Telegram и напишите @BotFather
- Отправьте
/newbotи следуйте подсказкам, чтобы создать бота - Скопируйте токен бота (например,
123456789:AAAA...) - Узнайте свой ID пользователя Telegram (напишите @userinfobot)
- Добавьте в ваш
.env:
TELEGRAM_API_TOKEN="123456789:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" TELEGRAM_ADMIN_ID="987654321" TELEGRAM_LOGGER_CHANNEL_ID=-1001234567890
Перезапустите панель после добавления токена. Бот запустится автоматически.
Команды бота
| Команда | Описание |
|---|---|
/usage | Проверить использование трафика и остаток квоты |
/sub | Получить ссылку-подписку и QR-код |
/stats | Статистика панели (только администратор) |
/devices | Просмотр подключённых устройств |
/help | Список всех доступных команд |
/broadcast | Отправить сообщение всем пользователям (только администратор) |
Настройки уведомлений
Telegram-бот отправляет уведомления о различных событиях, когда это настроено. Управляйте каждым типом уведомлений по отдельности через переменные .env (см. конфигурацию уведомлений).
Уведомления отправляются:
- На ID администраторов — личные сообщения каждому администратору из
TELEGRAM_ADMIN_ID - В канал логов — все события в
TELEGRAM_LOGGER_CHANNEL_ID
Поля, включаемые в уведомления о создании / изменении
Уведомления о создании и изменении пользователя включают следующие поля, если они заданы у пользователя:
| Поле | Отображается как | Когда включается |
|---|---|---|
| Имя пользователя | Username: alice | Всегда |
| Лимит трафика | Traffic Limit: 50 GB | Всегда (показывает «Unlimited», если не задан) |
| Дата окончания | Expire Date: 2026-06-01 | Всегда (показывает «Never», если не задана) |
| Протоколы | Proxies: vless, trojan | Всегда |
| Сброс лимита трафика | Data Limit Reset Strategy: monthly | Всегда |
| Лимит устройств | Device Limit: 3 | Только когда > 0 |
| Лимит IP | IP Limit: 5 (limit) | Только когда > 0; режим показан рядом |
| Лимит HWID | HWID Limit: 2 | Только когда > 0 |
| Есть следующий план | Has Next Plan: True | Всегда |
| Заметка | Note: Paid in advance 6mo | Только если не пуста; обрезается до 120 символов |
DISCORD_WEBHOOK_URL, чтобы получать те же уведомления в канал Discord. Embed-ы Discord включают те же расширенные поля.
Каналы доставки подписок
Доставляйте sub URL через инфраструктуру, которую цензоры не могут заблокировать.
Когда домен вашей панели заблокирован в России, Иране, Китае или Туркменистане, клиенты не могут получить обновления своих подписок. Каналы доставки подписок решают это, публикуя конфиг каждого пользователя в статический файл на инфраструктуре Google / Cloudflare / GitHub / Telegram — на хостах, которые цензоры не могут заблокировать целиком, не сломав массовые приложения, которыми пользуются миллионы.
Как это работает
- Вы настраиваете один или несколько каналов в Настройки → Каналы доставки подписок.
- Каждый пользователь получает стабильный публичный URL на этом канале (например,
https://firebasestorage.googleapis.com/…?alt=media&token=…). - Значок ⊞ (сетка) в каждой строке пользователя в таблице открывает поповер со всеми доступными URL — Direct, зашифрованный Happ и каждый настроенный канал. Копирование или показ QR в два клика.
- Когда вы редактируете хосты или конфиг Xray, панель автоматически переопубликовывает всех активных пользователей в Firebase (и другие каналы) в течение ~10–30 секунд через фоновый воркер. Ручной Backfill после рутинных правок конфига не нужен.
Доступные каналы
| Канал | Провайдер | Бесплатный лимит | Лучше всего для |
|---|---|---|---|
| Firebase Storage | ~50K запросов/день на плане Spark | Основной антицензурный канал | |
| Firebase Hosting | Тот же план Spark, что и у Storage | Вторая поверхность Firebase (*.web.app) — другой SNI и другой edge CDN в том же проекте, поэтому остаётся доступной, когда Storage заблокирован. Публикуется сайтом целиком, а не по одному пользователю, поэтому обновляется пакетно, а не на каждое изменение. | |
| Cloudflare R2 | Cloudflare | 10 ГБ/месяц, без платы за исходящий трафик | Вторичный; иной поставщик, чем Firebase |
| GitHub Gist | GitHub / Microsoft | Неограниченные публичные gist-ы | Простой запасной вариант; крайне живучий |
| GitLab Snippet | GitLab | Неограниченные публичные сниппеты | Подтверждённо доступен в Туркменистане даже в окна жёстких блокировок — второе зеркало рядом с Firebase для тех, кто не может достучаться до него |
| Доставка через Telegram | Telegram | Бесплатно | Экстренная доставка, когда всё остальное не работает |
| Пул Nginx-прокси | Ваши VPS | Стоимость VPS | Полный контроль оператора над ретранслятором |
Firebase Storage
Рекомендуемый первый канал. Бесплатный лимит покрывает ~50K запросов подписки в день. Размещён в IP-пространстве Google — цензоры не могут заблокировать его целиком, не сломав Google Maps, Gmail и множество других приложений.
Однократная настройка на console.firebase.google.com
- Создайте проект — Add project → назовите его (например,
nexus-subs) → план Spark (бесплатный) → Create. - Включите Storage — Build → Storage → «Get started» → «Start in production mode» → выберите локацию → Done.
- Задайте правила хранилища — Storage → Rules → замените на:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /sub_{file=**} {
allow read: if true;
allow write: if false;
}
}
}
- Сгенерируйте ключ сервисного аккаунта — Project Settings (⚙) → Service accounts → «Generate new private key» → Download. Относитесь к нему как к паролю.
- Найдите имя бакета — Storage → вверху показано
gs://your-project.firebasestorage.app. Скопируйте часть послеgs://.
В панели
- Настройки → Каналы доставки подписок → Firebase Storage → ⚙
- Вставьте имя бакета и JSON сервисного аккаунта (всё содержимое файла)
- Включите Enabled, задайте Priority (меньше = предпочтительнее;
10— хорошее начало) - Сохраните → нажмите Test (значок обновления)
Как читать результат теста
Успешный тест выглядит так:
firebase: end-to-end OK in 1840ms ✓ creds (180ms): bucket reachable ✓ upload (650ms): published to https://firebasestorage.googleapis.com/… ✓ fetch (820ms): GET 200 (87 bytes, attempt 1) ✓ match (1ms): content matches ✓ cleanup (180ms): test blob deleted
| Шаг, который не прошёл | Вероятная причина | Решение |
|---|---|---|
creds | JSON сервисного аккаунта неверен или истёк | Сгенерируйте ключ заново в Firebase Console |
upload | Storage не включён или неверные правила | Перепроверьте шаги настройки 2–3 |
fetch | Правило публичного чтения не применено | Вставьте правила из шага 3 заново |
match | Edge-кэш отдал устаревший блоб (редко) | Обычно повторы это скрывают; сообщите о баге, если повторяется |
cleanup | Сервисный аккаунт только для чтения | Удалите блобы nexus_test_* вручную |
Применить к существующим пользователям
После того как тест пройдёт, нажмите Backfill внизу карточки «Каналы доставки подписок». Это немедленно запустит загрузки в Firebase для всех активных пользователей через фоновый воркер. Для 200 пользователей ожидайте 30–120 секунд.
Cloudflare R2
S3-совместимое объектное хранилище без платы за исходящий трафик. Используйте как вторичный канал наряду с Firebase — иной поставщик означает, что региональная блокировка одного не выводит из строя оба.
Настройка на dash.cloudflare.com
- R2 (левое меню) → Create bucket → назовите его (например,
nexus-subs). - Откройте бакет → Settings → Public access → включите. Скопируйте URL
https://pub-<id>.r2.dev. - Вверху справа страницы R2 → Manage R2 API tokens → Create token → Object Read & Write (ограничьте вашим бакетом) → сохраните Access Key ID + Secret.
- Ваш Account ID — это 32-символьный hex внизу справа страницы панели R2.
В панели
Настройки → Каналы доставки подписок → Cloudflare R2 → ⚙:
| Поле | Где найти |
|---|---|
| Account ID Cloudflare | 32-символьный hex из шага 4 |
| Имя бакета | например, nexus-subs |
| Access key ID | Из шага 3 |
| Secret access key | Из шага 3 (показывается один раз) |
| База публичного URL | https://pub-<id>.r2.dev из шага 2 |
pub-<id>.r2.dev получает то же преимущество против блокировок, что и Firebase — он общий с тысячами других бакетов R2.
GitHub Gist
Бесплатно, размещено на GitHub (IP Microsoft). Крайне живучий вариант — хороший низкоприоритетный запасной канал, который ничего не стоит.
Настройка
- github.com/settings/tokens → Personal access tokens → Tokens (classic) → Generate new token.
- Имя:
nexus-gists. Область: отметьте ТОЛЬКО gist. Срок: 1 год (поставьте напоминание о продлении). - Скопируйте токен
ghp_…— увидеть его снова не получится.
В панели
Настройки → Каналы доставки подписок → GitHub Gist → ⚙ → вставьте PAT → Сохранить → Test.
Доставка через Telegram
Доступен в IR/RU/TM именно в те периоды, когда другие каналы недоступны. Это запасной канал из разряда «панель горит, и у пользователя больше ничего нет».
t.me/<bot>?start=sub_<token>, а не самообновляющийся URL. Он нажимает на него один раз, и бот присылает ему в личные сообщения файл .txt с его конфигом. Задавайте очень высокий Priority (маленький номер приоритета) только если вы настроили обработчик /start у бота — иначе ссылка ведёт на бота, который не отвечает.
Настройка — отдельный бот (рекомендуется)
- Напишите
@BotFatherв Telegram →/newbot→ выберите имя и username (должен заканчиваться наbot). - Скопируйте токен, который выдаст BotFather.
- Настройки → Каналы доставки подписок → Telegram → ⚙:
- Username бота: без @
- Токен бота: вставьте из BotFather
- Сохраните → Test. Тест вызывает
getMeи проверяет, что возвращённый username совпадает с тем, что вы вставили.
Если у вас уже задан TELEGRAM_API_TOKEN в .env для доставки уведомлений, поле токена бота можно оставить пустым — канал использует эту переменную окружения. Не рекомендуется по соображениям безопасности: утечка токена бота уведомлений раскрыла бы и файлы подписок.
Пул Nginx-прокси
Когда все каналы статического хранилища отключаются или блокируются по регионам, переходите на собственный парк дешёвых ретрансляторов-VPS. Каждый хост в пуле получает свой домен; панель распределяет пользователей по хостам по весу.
Предварительная подготовка
Поднимите дешёвые VPS (Hetzner CCX13 / Contabo и т. п. — €4–5/месяц каждый). На каждом:
# Запустить от root на каждом новом прокси-хосте curl -sSL https://your-panel.tld/setup_proxy.sh | bash
В панели
Настройки → Каналы доставки подписок → Nginx-прокси → ⚙. Конфигурация в JSON:
{
"hosts": [
{ "host": "alpha.shop", "subscription_path": "sub", "weight": 1 },
{ "host": "beta.shop", "subscription_path": "sub", "weight": 1 },
{ "host": "gamma.shop", "subscription_path": "sub", "weight": 5 }
]
}
Хост с weight: 5 получает в 5 раз большую долю пользователей, чем хост с weight: 1. Сохраните → Test проверяет TLS-рукопожатие для каждого члена пула.
Каналы доставки подписок — интерфейс панели
Поповер подписки (для каждого пользователя)
В каждой строке таблицы пользователей есть значок ⊞ (сетка). Нажатие на него открывает поповер со списком всех URL, которые оператор может дать клиенту:
| Строка | Что это | Копирование + QR |
|---|---|---|
| Direct | Обычный URL /sub/<token>, отдаваемый панелью | Только копирование |
| Happ (зашифрованный) | Зашифрованная форма AES-256-CBC через /user/<u>/encrypt-sub | Только копирование |
| Firebase / R2 / Gist | URL статического хранилища из включённых каналов | Копирование + QR |
| Telegram | Deep-link на доставку через бота | Только копирование |
| Nginx-прокси | URL ретранслятора | Только копирование |
URL предзагружаются при открытии поповера, поэтому копирование безопасно по жесту — нет асинхронной задержки между кликом и записью в буфер обмена.
Бейджи состояния каналов
Каждая строка канала в Настройки → Каналы доставки подписок показывает бейдж состояния по последней проверке. Cron запускается каждые 15 минут. Принудительно запустить свежую проверку можно в любой момент кнопкой Test.
Автопереопубликация при изменении конфигурации
Редактирование хостов или конфига ядра Xray запускает автоматическую рассылку: все активные пользователи, у которых изменилось содержимое подписки, переопубликовываются на каждый настроенный канал в течение ~10–30 секунд. Воркер пропускает пользователей, у которых отрендеренный конфиг не изменился (короткое замыкание по хэшу содержимого), поэтому правка хоста, затрагивающая только 50 из 200 пользователей, вызывает всего 50 записей в Firebase.
Backfill
Кнопка Backfill (внизу карточки «Каналы доставки подписок») немедленно загружает всех активных пользователей на все включённые каналы. Используйте её один раз после добавления нового канала — после этого автопереопубликация поддерживает всё в актуальном состоянии.
Hysteria2
Hysteria2 — это протокол на базе QUIC/UDP, который даёт в 3–5× большую пропускную способность, чем TCP, на сетях «последней мили» с потерями (мобильная связь, 4G в СНГ, Иран). Он работает как отдельный демон рядом с Xray — а не как inbound Xray — потому что Xray-core не поддерживает протокол hysteria2 нативно.
Ограничение по лицензии: Standard и выше. На пробном тарифе записи подписки hy2 видны, но создавать и управлять inbound-ами нельзя.
2053) открыт в панели вашего хостинг-провайдера — Contabo, Aeza, PTR по умолчанию блокируют UDP.
Добавить inbound Hysteria2
Панель → Настройки → Hysteria2 → Add Inbound
| Поле | Значение | Заметки |
|---|---|---|
| Tag | hy2-main | Любое уникальное имя |
| Listen port | 2053 | UDP — должен быть открыт в файрволе |
| Obfs type | salamander | Рекомендуется — скрывает UDP от DPI в CN/IR/RU |
| Obfs password | надёжный случайный | openssl rand -hex 24 |
| Masquerade URL | https://www.bing.com | HTTPS-сайт, под который hysteria маскируется для DPI-проб |
| SNI | bing.com | TLS SNI, предъявляемый клиентам |
| TLS cert / key | оставьте пустым для авто | Панель автоматически генерирует 10-летний самоподписанный сертификат, если не указано |
Создание inbound синхронизирует конфигурацию на каждую подключённую ноду и запускает демон hysteria на каждой. SSH не требуется.
Добавить хосты для каждой ноды
Панель → Хосты → нажмите карточку inbound Hysteria2 → Add Host
Добавьте по одной строке-хосту на каждую ноду, на которой хотите открыть hy2:
| Поле | Пример | Обязательно |
|---|---|---|
| Remark | DE Frankfurt hy2 | Да |
| Address | de.example.com | Да — публичный домен или IP ноды |
| Port | 2053 | Да — UDP-порт на этой ноде |
| Country code | DE | Рекомендуется — управляет региональным переупорядочиванием подписки |
Генераторы подписок автоматически выдают записи hy2:// для каждого включённого хоста наряду с существующими ссылками VLESS/VMess. Клиенты увидят их при следующем обновлении подписки.
Через API (требуются учётные данные sudo-администратора):
# 1. Получить токен с помощью имени и пароля суперадминистратора TOKEN=$(curl -s -X POST /api/v1/admin/token \ -d "username=YOUR_ADMIN&password=YOUR_PASSWORD" \ | jq -r .access_token) # 2. Список inbound-ов hy2 curl /api/v1/hy2-inbounds -H "Authorization: Bearer $TOKEN" # 3. Добавить хост к inbound id=1 curl -X POST /api/v1/hy2-inbounds/1/hosts \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"remark":"DE Frankfurt","address":"de.example.com","port":2053,"country_code":"DE"}'
Проверка и устранение неполадок
После добавления хоста запросите URL подписки — вы должны увидеть запись hy2:// наряду со ссылками VLESS. Импортируйте в Nekobox, sing-box или Happ и подключитесь.
| Проблема | Диагностика |
|---|---|
Нет hy2:// в подписке | Проверьте, что хост включён и задан country_code; убедитесь, что тариф лицензии Standard+ |
| UDP connection refused | Тест: nc -vu <node> 2053 извне ДЦ. Порт не открыт в файрволе провайдера. |
| Таймаут UDP | Провайдер или middlebox «съедает» UDP — попробуйте obfs salamander или другой порт |
| Ошибка TLS | Самоподписанный сертификат: убедитесь, что у клиента allowinsecure: true или укажите отпечаток сертификата |
| Демон не запускается на ноде | docker logs nexus-node 2>&1 | grep hysteria на сервере ноды |
Middle-сервер (NAT-ретранслятор)
Middle-сервер — это дешёвый VPS, который стоит между вашими пользователями и нодами. Он ретранслирует трафик через iptables DNAT, поэтому пользователи подключаются к одному стабильному IP независимо от того, какая нода их обслуживает. Полезно, когда IP ноды блокируют в какой-то стране — замените ноду, заново сгенерируйте NAT на middle-сервере, обновите одну запись хоста.
Первоначальная настройка
Сгенерируйте одноразовую команду установки из панели, затем вставьте её на новом VPS от root:
- В панели перейдите в Настройки → Middle-серверы и нажмите Generate install command.
- Скопируйте показанную команду — она выглядит так:
curl -fsSLk https://panel.example.com:8443/api/v1/middle-server/i/<token> | sudo bash
Токен одноразовый и истекает через 30 минут. В истории shell не появляется никаких учётных данных.
Ручная / скриптовая установка (без доступа к интерфейсу панели)
read -p "Panel URL: " _P read -p "Admin username: " _U read -sp "Admin password: " _W; echo curl -fsSL -k -u "$_U:$_W" "$_P/api/v1/middle-server/bootstrap.sh" | sudo bash unset _P _U _W
Скрипт генерируется из вашего текущего списка нод и inbound-ов Hysteria 2, поэтому перезапускайте его каждый раз, когда добавляете или удаляете что-либо из них.
Скрипт:
- Установит
iptables-persistent - Применит тюнинг ядра (BBR, большие буферы, conntrack)
- Построит все правила DNAT из текущего состояния БД панели
- Выведет таблицу записей-хостов для добавления в панели
После завершения скрипта перейдите на страницу Хостов и добавьте по одной записи-хосту на каждую выведенную скриптом строку, используя IP middle-сервера и выведенный порт.
Переход на новый middle-сервер
Когда текущий middle-сервер заблокирован или вы хотите перейти на другой VPS:
- Подключитесь по SSH к новому VPS и выполните ту же единственную команду выше
- В панели → страница Хостов отредактируйте каждый хост, чей адрес указывает на старый IP middle-сервера, и смените его на новый IP. Порты остаются прежними.
- Готово — никаких изменений нод, никакой перенастройки у пользователей
Фронтинг и обход блокировок
IP-Defender NexusPanel делает всё это за вас: следит за каждым фронтинг-хостом, определяет блокировку и заменяет адрес на рабочий — автоматически или в один клик. Открывается из Панель → Defender, устроенного как конвейер:
| Группа | Что там |
|---|---|
| Start here | Overview — карта состояния, страница по умолчанию |
| Pipeline | ① Sources (URL подписок конкурентов — для анализа), ② IP Pool (проверяемые адреса-кандидаты), ③ Hosts (ваши действующие фронтинг-записи — сюда же добавляется хост за Cloudflare) |
| Infrastructure | Shield (доска статусов с карточкой на каждого провайдера — клик по карточке открывает страницу провайдера) и Setup (где вы добавляете API-ключи провайдеров) |
Использовать все провайдеры не обязательно. Начните с одного — Cloudflare проще всего и бесплатен — и добавляйте остальные позже, если нужна избыточность или вы обслуживаете регионы с разной картиной блокировок.
IP-Defender
IP-Defender — это фоновая задача, которая непрерывно проверяет, работает ли ещё каждый фронтинг-хост. Она не ждёт жалобы от клиента.
- Healthy (здоров) — хост опрашивается и отвечает нормально.
- Suspect (подозрителен) — опросы начинают проваливаться. Одна неудачная проверка ничего не запускает; нужна устойчивая серия сбоев, прежде чем защитник воспримет это всерьёз — так короткий сетевой сбой не приведёт к лишней замене.
- Blocked (заблокирован) — сбои продолжаются. Защитник выбирает рабочий адрес того же вида (хост Cloudflare заменяется только на другой адрес Cloudflare, хост AWS — только на другой AWS; смешивание видов ломает сертификат, который ожидает клиент) и обновляет его автоматически.
- Cooldown (охлаждение) — после замены старый адрес какое-то время не используется повторно, чтобы хост не «дёргался» туда-сюда.
Поскольку Xray сам по себе не пишет трафик в разрезе по хостам, защитник опирается на активные опросы, а не на графики трафика. Это нормально — вы увидите время «последней проверки» на каждом хосте, а не счётчики трафика в реальном времени.
Cloudflare
Самый простой провайдер для старта — бесплатного тарифа достаточно для фронтинга. Через edge-узлы Cloudflare проходит огромное количество обычных сайтов, поэтому их блокировка задевает много легитимного трафика, и сети на это неохотно идут. Cloudflare в NexusPanel решает две разные задачи, и открываются они по-разному:
- В Cloudflare создайте API-токен с правом редактирования DNS для домена, через который будете фронтить.
- Панель → Defender → Setup → добавьте учётные данные, провайдер
cloudflare, вставьте API-токен. - Фронтинг самого VPN-трафика: Панель → Defender → Hosts (Pipeline, шаг 3) → добавьте хост, указывающий на ваш домен за Cloudflare (DNS-запись с «оранжевым облаком»). Отдельную дистрибуцию создавать не нужно — Cloudflare это просто DNS + прокси, и IP-Defender следит за этим хостом как за любым другим.
- Доступность ссылки на подписку: Панель → Defender → Shield → карточка Cloudflare открывает отдельную страницу, которая ротирует домен, с которого раздаются ссылки на подписку (PRIMARY/STANDBY, с автоматическим escape, если этот домен заблокируют). Это другая задача, не связанная с фронтингом VPN-трафика — она про то, чтобы клиенты могли обновлять конфиг.
AWS CloudFront
CDN от Amazon — другой вендор, отличный от Cloudflare, и это важно: если вы используете оба, сети, заблокировавшей один, придётся отдельно разбираться и со вторым.
- В AWS создайте IAM-пользователя с правами CloudFront + Route 53 и сгенерируйте access key.
- Панель → Defender → Setup → добавьте учётные данные, провайдер
aws, вставьте access key ID и secret. - Панель → Defender → Shield → карточка AWS CloudFront, чтобы создать дистрибуцию CloudFront и увидеть её текущий входной IP и статус.
Тарификация AWS CloudFront зависит от использования (в основном от исходящего трафика) — следите за ней, если гоните через неё серьёзный объём трафика.
Google (Cloud Run)
Фронтинг через инфраструктуру Google run.app — те же хостнеймы, что используют бесчисленные обычные приложения Cloud Run.
- В Google Cloud создайте сервисный аккаунт с правами Cloud Run + DNS и скачайте его JSON-ключ.
- Панель → Defender → Setup → добавьте учётные данные, провайдер
google, вставьте ключ сервисного аккаунта. - Панель → Defender → Shield → карточка Google Cloud Run, чтобы развернуть и управлять фронтинг-сервисом.
Сервисы Cloud Run должны быть публично доступны, чтобы работать как фронт — панель делает это сама при развёртывании сервиса.
Fastly
Fastly — провайдер с подключением в один клик, точно как Cloudflare, AWS и Google: вы даёте edge-IP, панель строит всё остальное.
- В Fastly создайте API-токен с областью действия global (нужна, чтобы создавать CDN-сервисы).
- Панель → Defender → Setup → добавьте учётные данные, провайдер
fastly, вставьте токен. - Панель → Defender → Shield → карточка Fastly → вставьте свои edge-IP Fastly (по одному на строку или через запятую) и нажмите Create CDN. Панель поднимет сервис Fastly, настроенный как ваш текущий, и сама подключит нужный inbound и по одному хосту на каждый edge-IP.
У Fastly нет быстрой ротации: если edge-IP заблокирован, заново запустите Create CDN с новыми edge-IP, а не ждите автоматическую замену.
Bunny CDN
Bunny работает иначе, чем остальные провайдеры: не панель создаёт CDN за вас, а вы создаёте его на bunny.net, а панель его адаптирует.
- На bunny.net создайте одну pull zone на тарифе Standard с включёнными WebSockets.
- Добавьте в эту pull zone правило для каждой ноды (Edge Rule):
Host == bunny-<node>.<ваш-домен>, переопределяющее Origin URL наhttp://<ip-ноды>:2009(inbound VLESS BUNNY WS этой ноды). Одно правило на каждую ноду. - Панель → Defender → Setup → добавьте учётные данные, провайдер
bunny, вставьте API-ключ вашего аккаунта Bunny. - Панель → Defender → Shield → карточка Bunny CDN → нажмите Auto-wire per node. Панель прочитает правила вашей pull zone, сопоставит каждый origin IP с нодой в панели и создаст по одному управляемому хосту Bunny на каждую совпавшую ноду. Перезапускайте при добавлении ноды или исправлении правила.
- Нажмите Refresh edge IPs, чтобы засеять опубликованные edge-IP Bunny в пул ротации.
Как и у Fastly, у Bunny нет быстрой ротации — заблокированный edge означает починку pull zone и повторный auto-wire, а не мгновенную замену.
Azure
Azure — это не CDN-фронт вроде остальных: он разворачивает ротируемую VM-ретранслятор (та же идея, что Middle-сервер, только Azure сам поднимает VM и меняет её IP), чтобы у заблокированной ноды появился свежий входной IP без изменений на самой ноде.
- Создайте Service Principal:
az ad sp create-for-rbac --role Contributor --scopes /subscriptions/<id>. - Панель → Defender → Shield → карточка Azure → вставьте tenant ID, client ID, client secret и subscription ID, затем нажмите Verify & connect. У Azure своя форма учётных данных прямо здесь — она не проходит через Setup, как у остальных провайдеров.
- Выберите регион (панель предлагает вариант, определённый по вашим подпискам) и нажмите Create relay — это развернёт небольшую VM на Ubuntu со статическим IP, размер выбирается автоматически как самый дешёвый.
- Установите middle-агент на полученный IP и переведите его в промоут, как для любого middle-сервера (см. Middle-сервер → Первоначальная настройка).
Если IP ретранслятора позже заблокируют, нажмите Rotate IP на странице Azure, затем заново запустите установку middle-сервера на новом IP и перепроверьте из-под заблокированной сети.
Миграция с Marzban
Инструмент nexus cli migrate переносит живую установку Marzban в NexusPanel без какой-либо перенастройки у конечных пользователей. Он работает на том же хосте, что и Nexus, читает каталог данных Marzban напрямую и использует атомарный конечный автомат из 9 этапов с полным откатом вплоть до команды finalize.
JWT_SECRET_KEY Marzban и сохраняет его как MARZBAN_LEGACY_JWT_SECRET в окружении Nexus. Каждая существующая ссылка-подписка Marzban продолжает работать с первого дня — пользователям ничего не нужно импортировать заново.
Предварительные требования
- Marzban версии 0.6.0–0.8.4 (официальный скрипт установки,
marzbanилиmarzban_cli) - NexusPanel установлен на том же хосте или может читать
/var/lib/marzban/ - Свободное место на диске для снимка SQLite-базы Marzban
Шаг 1: Пробный прогон
Всегда сначала делайте пробный прогон. Он делает снимок базы Marzban, повторяет каждый импорт в черновую копию и завершается за секунды. В Nexus или Marzban ничего не записывается.
# Посмотреть, что было найдено nexus cli migrate discover # Репетиция: снимок + импорт + проверка на черновой БД, без побочных эффектов nexus cli migrate run --dry-run
Прочтите отчёт о пробном прогоне в /var/lib/nexus/migration/dryrun-<ts>.json. Подтвердите число пользователей, список администраторов и что MARZBAN_LEGACY_JWT_SECRET был извлечён. Исправьте все отмеченные ошибки перед продолжением.
Шаг 2: Боевое переключение
# Боевой прогон — останавливает Marzban, импортирует, перезапускает Nexus
nexus cli migrate run --yes
Критический путь (MARZBAN_STOP → NEXUS_RESTART) занимает ~15–30 секунд. VPN-трафик нод продолжается без перерыва — ноды работают независимо от панели. Недоступен лишь ненадолго эндпоинт URL подписки.
Если VERIFY не проходит, срабатывает автооткат: конфигурации Nexus восстанавливаются, а Marzban перезапускается. Проверьте docker logs nexus-panel --tail 200, чтобы найти первопричину, затем перезапустите.
# После наблюдения за продакшеном в течение нескольких часов: nexus cli migrate finalize # освобождает снимок, закрывает прогон # Если нужно отменить (только до finalize): nexus cli migrate rollback
Что переносится
| Данные | Переносится | Заметки |
|---|---|---|
| Пользователи (имя, трафик, срок) | Да | Все профили, квоты, UUID сохраняются |
| Прокси / протоколы пользователей | Да | VMess, VLESS, Trojan, Shadowsocks |
| Учётные записи администраторов | Да | Пароли переносятся |
| Хосты (прокси-точки) | Да | Все строки-хосты копируются, поля только для Nexus по умолчанию выключены |
| Inbound-ы Xray | Да | Копируются из xray_config.json Marzban |
| Токен Telegram-бота, флаги NOTIFY_* | Да | Записываются в .env Nexus |
| JWT-секрет (совместимость sub URL) | Да | Сохраняется как MARZBAN_LEGACY_JWT_SECRET — существующие sub URL продолжают работать |
| История напоминаний-уведомлений | Да | Предотвращает повторную отправку уведомлений «истекает через 3 дня» |
| Конфигурации нод | Нет | Nexus использует порты 62060/62061; добавьте ноды заново через панель с новым сертификатом |
| Routing/dns/outbounds Xray | Нет | Только inbound-ы; вставьте свои блоки в Настройки → редактор ядра после миграции |
| Хосты Hysteria2 | Нет | В Marzban нет hy2 — добавьте через Панель → Хосты после миграции |
Чек-лист после миграции
После завершения nexus cli migrate run --yes CLI выводит таблицу перенесённых хостов. Проверьте их, а затем:
- Проверьте старый URL-подписку Marzban — он должен вернуть валидный конфиг (проверка совместимости JWT)
- Проверьте число пользователей:
docker exec nexus-panel sqlite3 /var/lib/panel/db.sqlite3 'SELECT COUNT(*) FROM users;' - Выполните
nexus cli migrate post-cutover, чтобы найти оставшиеся демоны Marzban (marzguard, cron-хуки certbot) - Если используете Hysteria2: добавьте inbound + по одному хосту на ноду (см. раздел Hysteria2)
- Добавьте ноды заново через Панель → Ноды (новый сертификат, порты 62060/62061)
- Выполните
nexus cli migrate finalize, чтобы освободить снимок, когда всё стабильно
# Здоровье curl -sk https://<your-domain>/api/v1/health # Старый sub URL должен вернуть 200 с содержимым конфига curl -sk "https://<your-domain>/sub/<marzban-token>" | head -c 200 # Поиск остатков Marzban nexus cli migrate post-cutover
Миграция с Remnawave
/sub/<token> резолвится и после миграции, клиентам не нужно ничего перенастраивать.
Инструмент nexus cli migrate remnawave подключается к живой панели Remnawave по её API (URL и логин/пароль администратора) и импортирует пользователей в NexusPanel.
# По умолчанию — пробный прогон: подключается, извлекает и показывает, что будет # импортировано и какие имена конфликтуют, ничего не пишет nexus cli migrate remnawave run --url https://ваша-remnawave-панель --username ADMIN --password ... # Применить изменения nexus cli migrate remnawave run --url https://ваша-remnawave-панель --username ADMIN --password ... --run
--yes нужен, только если такое имя пользователя уже есть в NexusPanel — без него боевой прогон откажется выполняться, а не перезапишет данные. --insecure пропускает проверку TLS-сертификата (для Remnawave с самоподписанным сертификатом). --page-size (по умолчанию 250) задаёт размер страницы при обращении к API Remnawave.
# Откат — удаляет ровно тех пользователей и алиасы, которые создал прогон
nexus cli migrate remnawave rollback
| Данные | Переносится | Заметки |
|---|---|---|
| Пользователи, лимиты и израсходованный трафик | Да | Срок действия и статус тоже переносятся |
| Учётные данные по протоколам | Да | VLESS UUID, пароль Trojan, пароль Shadowsocks |
| Ссылка-подписка | Да | Непрозрачный short-id Remnawave сохраняется как алиас — старый URL продолжает работать |
| Telegram ID пользователя | Нет | В NexusPanel у пользователя нет такого поля — инструмент выводит предупреждение |
| Хосты и ноды | Нет | Настраиваются на стороне NexusPanel; уже перенесённые учётные данные пользователей сразу работают с ними |
Безопасность
Двухфакторная аутентификация (2FA)
NexusPanel поддерживает 2FA на базе TOTP (совместимо с Google Authenticator, Authy и т. д.):
- Перейдите в Настройки в панели
- Нажмите Enable 2FA
- Отсканируйте QR-код приложением-аутентификатором
- Введите 6-значный код для подтверждения
- Сохраните резервные коды в безопасном месте
Через API:
# Сгенерировать TOTP-секрет и резервные коды curl -X POST /api/v1/admin/2fa/setup -H "Authorization: Bearer TOKEN" # Активировать 2FA (укажите TOTP-код для проверки) curl -X POST /api/v1/admin/2fa/enable \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{"code": "123456"}' # Вход с 2FA curl -X POST /api/v1/admin/token \ -H "X-TOTP-Code: 123456" \ -d "username=admin&password=admin&grant_type=password"
Защита капчей
Защитите страницу входа от атак перебором с помощью капчи:
Cloudflare Turnstile
CAPTCHA_PROVIDER="turnstile" TURNSTILE_SITE_KEY="0x4AAAAAAA..." TURNSTILE_SECRET_KEY="0x4AAAAAAA..."
Встроенная капча
CAPTCHA_PROVIDER="builtin"
Встроенная капча не требует внешних сервисов и генерирует простые математические задачи.
Ограничение частоты запросов
Ограничение частоты запросов к эндпоинту входа включено по умолчанию:
LOGIN_RATE_LIMIT="10/minute" LOGIN_LOCKOUT_THRESHOLD=10 LOGIN_LOCKOUT_DURATION_MINUTES=30
После 10 неудачных попыток IP блокируется на 30 минут. Ограничитель частоты работает в памяти (в рамках процесса) и сбрасывается при перезапуске сервера.
SSL / TLS
Для продакшен-развёртываний всегда используйте HTTPS. Варианты:
- Прямой SSL — задайте
UVICORN_SSL_CERTFILEиUVICORN_SSL_KEYFILE - Обратный прокси — используйте Nginx или Caddy впереди с терминацией SSL
- Cloudflare — проксируйте через Cloudflare в режиме Full (Strict) SSL
Пример обратного прокси Nginx
server { listen 443 ssl http2; server_name panel.example.com; ssl_certificate /etc/letsencrypt/live/panel.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/panel.example.com/privkey.pem; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
FAQ
Как сменить пароль администратора
Вариант 1: Обновите переменную окружения SUDO_PASSWORD и перезапустите панель.
Вариант 2: Используйте API:
curl -X PUT /api/v1/admin/admin \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{"password": "newSecurePassword123"}'
Как сделать резервную копию
SQLite
# Сначала остановите панель для чистой копии docker compose stop panel cp /var/lib/nexuspanel/db.sqlite3 /backups/db-$(date +%Y%m%d).sqlite3 docker compose start panel # Или используйте онлайн-бэкап SQLite (без простоя) sqlite3 /var/lib/nexuspanel/db.sqlite3 ".backup /backups/db-$(date +%Y%m%d).sqlite3"
PostgreSQL
docker compose exec db pg_dump -U nexus nexuspanel > /backups/db-$(date +%Y%m%d).sql
.env, xray_config.json и любых своих шаблонов.
Как обновить
cd /opt/nexuspanel # Скачать последние образы docker compose pull # Перезапустить с новой версией docker compose up -d # Проверить логи на статус миграций docker compose logs -f panel
Миграции базы данных выполняются автоматически при запуске. Всегда делайте резервную копию базы перед обновлением.
Как добавить свои шаблоны
Свои шаблоны позволяют управлять выводом подписки для разных клиентов:
- Создайте файлы шаблонов в каталоге шаблонов:
mkdir -p /var/lib/nexuspanel/templates/clash nano /var/lib/nexuspanel/templates/clash/custom.yml
- Укажите шаблон в
.env:
CUSTOM_TEMPLATES_DIRECTORY="/var/lib/panel/templates/" CLASH_SUBSCRIPTION_TEMPLATE="clash/custom.yml"
Шаблоны поддерживают синтаксис Jinja2 с доступом к данным пользователя, конфигам прокси и настройкам панели.
Настройка страницы подписки
Страница подписки для пользователя (показывается при открытии ссылки-подписки в браузере) полностью настраиваема:
- Скопируйте шаблон по умолчанию как отправную точку:
cp -r /opt/nexuspanel/app/templates/subscription \ /var/lib/nexuspanel/templates/subscription
- Отредактируйте
/var/lib/nexuspanel/templates/subscription/index.html - Задайте в
.env:
SUBSCRIPTION_PAGE_TEMPLATE="subscription/index.html"
Доступные переменные шаблона включают: user, sub_url, clash_url, singbox_url, usage, expire_date и brand_name.
Документация NexusPanel — Сделано с заботой.