Впервые здесь? Прочтите это первым 👋

Никогда не слышали про Marzban, «VPS» или «панель»? Отлично — здесь вся суть объясняется простыми словами. Опыт не нужен совсем.

Одним предложением: NexusPanel — это программа, которая позволяет запустить собственный VPN-сервис и продавать к нему доступ — немного похоже на то, как если бы вы держали свой маленький Netflix, только продаёте вы приватное, разблокированное и более быстрое интернет-соединение.

Вы арендуете дешёвый сервер, устанавливаете на него NexusPanel и получаете удобную веб-панель. В этой панели вы создаёте клиентов, и каждый клиент получает ссылку, которую вставляет в бесплатное приложение на телефоне. Он нажимает «подключиться» — и его интернет теперь идёт через ваш сервер. Вы берёте с него плату каждый месяц. Вот и весь бизнес.

Аналогия с магазином

Если вы представляете, как держать небольшой магазин, вы уже понимаете NexusPanel. Вот как всё устроено:

🧑‍💼
Вы

Владелец

Вы ведёте бизнес, назначаете цены и добавляете клиентов. Программистом быть не обязательно.

🖥️
VPS

Здание вашего магазина

Компьютер, который вы арендуете в дата-центре (≈ $5/месяц). Здесь живёт ваша панель. Провайдеры: Hetzner, Contabo, DigitalOcean…

🎛️
NexusPanel

Ваша касса и витрины

Панель управления, в которую вы заходите через браузер. Добавляйте клиентов, следите за трафиком, получайте оплату — всё отсюда.

🌍
Нода

Филиал за рубежом

Дополнительный сервер, например в Германии или Финляндии, чтобы клиенты могли выбирать, через какую страну подключаться. Необязательно — можно начать без нод.

🔗
Ссылка-подписка

Членская карта

Одна веб-ссылка, которую вы даёте каждому клиенту. В ней зашиты все настройки подключения — это всё, что ему когда-либо понадобится.

📱
Клиентское приложение

Дверь клиента

Бесплатное приложение (Happ, v2rayNG, Streisand…). Он один раз вставляет ссылку, нажимает «подключиться» — готово. Вы никогда не трогаете его телефон.

Так что же такое «Marzban»?
Marzban — это популярный бесплатный инструмент, которым люди годами пользуются ровно для этого. Он работает — но вы остаётесь сами по себе: ни поддержки, обновления вручную и никаких современных функций обхода блокировок. NexusPanel — это его взрослая версия с поддержкой. Если вы уже используете Marzban, вы можете перенести всё одной командой, и ваши клиенты ничего не заметят (их ссылки продолжат работать). Если же вы никогда с ним не сталкивались — тем лучше, вы начинаете с чистого листа и обходите все сложные этапы.

Как на самом деле движутся деньги

  1. Кому-то нужен приватный или разблокированный интернет, и он платит вам (принимайте криптовалюту автоматически через встроенный Telegram-бот или берите оплату любым удобным способом).
  2. Вы открываете NexusPanel и создаёте для него пользователя — задаёте срок действия и объём трафика. Занимает около 10 секунд.
  3. Вы отправляете ему ссылку-подписку.
  4. Он вставляет её в бесплатное приложение и нажимает «подключиться». Он в сети через ваш сервер.
  5. В следующем месяце он платит снова, чтобы оставаться активным. Повторяйте с любым числом клиентов.
Вам не нужно разбираться в сложных технологиях
Слова вроде 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 / устройств
Ограничение на количество телефонов или компьютеров, которые один клиент может использовать одновременно — мешает делиться паролем и съедать ваш трафик.
Самое сложное позади
Если всё это в общих чертах понятно — вы знаете достаточно, чтобы вести NexusPanel. Перейдите к разделу С чего начать и выберите путь.

С чего начать

Три пути. Выберите тот, что подходит вам, и вы запуститесь меньше чем за 10 минут.

NexusPanel — это мультиарендная VPN-панель: вы продаёте субаккаунты, ваши клиенты подключаются через любой v2ray-клиент, а вы держите всё в одной панели. Если вы новичок, самый быстрый способ увидеть, что она умеет, — бесплатный пробный период. Если вы уже используете Marzban, инструмент миграции перенесёт всё одной командой — пользователей, администраторов, хосты, сертификаты, и даже ваши существующие ссылки-подписки продолжат работать. Если вы используете Remnawave — то же самое, отдельной командой (см. Миграция с Remnawave).

Путь A · Без установки

Попробуйте бесплатный период

Откройте Telegram-бот, введите /start и получите бесплатный 14-дневный Pro-триал, без карты. С ним вы можете развернуть собственную панель и опробовать всё до оплаты.

⏱ 2 мин 💳 Карта не нужна
Открыть Telegram-бот →
Путь B · Новый VPS

Установка на чистом сервере

Одна команда на чистом VPS с Ubuntu 20.04+. Скрипт спросит вашу лицензию, домен и пароль администратора — вот и всё. SSL настраивается автоматически, если вы направите домен на сервер.

⏱ 5 мин 🖥 1 ГБ ОЗУ минимум
Команда установки ↓
Путь C · Переход с Marzban

Переход с Marzban

Тот же VPS, без перенастройки у клиентов. Инструмент миграции сначала делает пробный прогон и обратим — вы видите каждое изменение до того, как что-то будет затронуто, и можете откатиться в любой момент до финального переключения.

⏱ 10 мин 🔁 С возобновлением и откатом
Руководство по миграции ↓
Путь D · Переход с Remnawave

Переход с Remnawave

Одна команда переносит пользователей и их учётные данные из Remnawave в NexusPanel. Ссылки-подписки клиентов продолжают работать без перенастройки.

⏱ 10 мин 🔁 С пробным прогоном и откатом
Руководство по миграции ↓
Почему миграция безопасна
Инструмент никогда не пишет в вашу базу Marzban. Он делает снимок Marzban в копию только для чтения, строит состояние Nexus из этой копии и подменяет контейнеры лишь на самом последнем шаге. Если перед этой подменой что-то выглядит не так, вы прерываете процесс, и Marzban продолжает работать как ни в чём не бывало. Ваши существующие ссылки-подписки тоже продолжат работать после миграции — Nexus переносит JWT-секрет Marzban, поэтому каждая ссылка https://your-panel/sub/<token>, которая уже есть у ваших пользователей, остаётся рабочей.

Что вам понадобится

  • VPS с Ubuntu 20.04+ (или любым дистрибутивом семейства Debian), минимум 1 ГБ ОЗУ, рекомендуется 2 ГБ
  • Root-доступ по SSH к этому VPS
  • Домен, направленный на VPS (необязательно — даёт настоящий сертификат HTTPS без предупреждений; без него всё равно будет HTTPS, но с самоподписанным сертификатом, который один раз покажет предупреждение в браузере)
  • Лицензия NexusPanel (возьмите её в Telegram-боте, подойдёт бесплатный 14-дневный пробный период)

Как получить помощь

Если что-то не работает, попробуйте по порядку:

  1. Проверьте логи панели: cd /opt/panel && docker compose logs --tail 100
  2. Прочтите нужный раздел этой документации (боковое меню слева)
  3. Напишите нам в Telegram — ссылка в боте, отвечаем за часы, а не за дни

Что такое NexusPanel

Простыми словами
Это панель, в которую вы заходите, чтобы вести VPN-бизнес: добавлять клиентов, раздавать ссылки для подключения, видеть, кто онлайн, и получать оплату — всё в одном месте. Всё это для вас в новинку? Начните с раздела Впервые здесь? Прочтите это первым.

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 ГБ+
CPU1 vCPU2 vCPU
Диск10 ГБ20 ГБ+ (SSD)
Docker20.10+Последняя стабильная
ДоменНеобязательноРекомендуется (для SSL)
Примечание
Docker и Docker Compose устанавливаются автоматически скриптом быстрой установки, если их нет.

Быстрая установка

Выполните эту единственную команду на чистом VPS, чтобы установить NexusPanel с настройками по умолчанию:

bash
curl -sL https://nexuspanel.store/install | bash

Скрипт запросит у вас:

  1. License Key и Client ID — от @nexuspanelpayment_bot (бесплатный 14-дневный пробный ключ тоже подходит, но установщик всегда требует ключ — установки без лицензии не бывает)
  2. Домен — для SSL через Let's Encrypt (пропустите для работы только по IP)
  3. Имя пользователя и пароль администратора — для панели
  4. Порт панели — по умолчанию 8443

Затем он:

  1. Установит Docker и Docker Compose, если их нет
  2. Скачает ghcr.io/haitovs/nexus:latest (защищённый Cython продакшен-образ)
  3. Создаст /opt/panel/ с .env и docker-compose.yml (имя контейнера: nexus-panel)
  4. Заполнит xray_config.json с включённым access-логом (нужно для применения лимитов IP/устройств)
  5. Запустит панель и выведет URL панели и учётные данные
Уведомления об обновлениях
После установки панель раз в 6 часов делает heartbeat на ваш лицензионный сервер. Автообновление по умолчанию выключено: когда выходит новая версия, панель показывает уведомление «доступно обновление», а вы применяете его командой nexus update на сервере.

Установка одной командой (подробно)

Скрипт установки принимает необязательные флаги для настройки:

bash
# Рекомендуется — передайте свой 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).

Предупреждение «Not Secure» при установке только по IP
Без домена панель всё равно работает по HTTPS, но с самоподписанным сертификатом (для Let's Encrypt нужен домен). Браузер один раз покажет предупреждение «Not Secure» / «Соединение не защищено» при первом открытии панели — нажмите Advanced → Proceed (Chrome) или Visit this website (Safari), чтобы продолжить. Это ожидаемо и безопасно: соединение всё равно зашифровано, просто сертификат не подписан публичным центром сертификации. Позже можно привязать домен для сертификата без предупреждений.

Первые шаги в панели

После входа в панель — вот самый быстрый путь к первому рабочему подключению:

  1. Создайте пользователя — Панель → UsersAdd User. Задайте дату окончания и лимит трафика, затем скопируйте ссылку подписки и передайте её в клиентское приложение (Happ, v2rayNG, Streisand…).
  2. Добавьте ноду (по желанию) — Панель → NodesAdd New Node, скопируйте сгенерированную команду быстрой установки, выполните её на сервере ноды, затем вернитесь и заполните Name + Address, чтобы подключить её. Подробнее в разделе Установка ноды.
  3. Настройте домен подписки — если ссылки подписки должны отдаваться с другого хоста/домена, чем сама панель, задайте XRAY_SUBSCRIPTION_URL_PREFIX в редакторе окружения (Settings → Env) и используйте Save & Restart — эта настройка применяется только после полного перезапуска.

Ручная установка

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

bash
# 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:

bash
# Установить 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 для автоматического продления:

bash
0 3 * * * certbot renew --quiet && docker compose -C /opt/nexuspanel restart

С PostgreSQL

Для продакшен-развёртываний PostgreSQL предпочтительнее SQLite. Установите BACKEND_MODE=modern и используйте драйвер, который реально входит в поставку панели — psycopg2 (синхронный), а не asyncpg:

bash
# Задать в .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:

bash
# Из каталога установки (например /opt/panel)
cp docker-compose.modern.yml docker-compose.yml
docker compose up -d
asyncpg не установлен
Панель поставляется с psycopg2-binary, а не с asyncpg — URL вида postgresql+asyncpg:// не найдёт драйвер. Всегда используйте postgresql+psycopg2://.

Примеры Docker Compose

Classic (SQLite) — то, что реально пишет установщик

yaml — /opt/panel/docker-compose.yml
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_HOST0.0.0.0Адрес привязки сервера
UVICORN_PORT8000HTTP-порт
UVICORN_UDSПуть к Unix-сокету (переопределяет host/port)
UVICORN_SSL_CERTFILEПуть к SSL-сертификату (fullchain.pem)
UVICORN_SSL_KEYFILEПуть к приватному ключу SSL
UVICORN_SSL_CA_TYPEpublicТип CA: public или private
DASHBOARD_PATH/dashboard/URL-путь к веб-панели
ALLOWED_ORIGINSИсточники CORS через запятую
SUDO_USERNAMEИмя первого суперадминистратора
SUDO_PASSWORDПароль первого суперадминистратора
JWT_ACCESS_TOKEN_EXPIRE_MINUTES1440Срок жизни токена в минутах (по умолчанию 24 ч)

База данных

ПеременнаяПо умолчаниюОписание
SQLALCHEMY_DATABASE_URLsqlite:///db.sqlite3Строка подключения к базе данных
SQLALCHEMY_POOL_SIZE10Размер пула соединений
SQLIALCHEMY_MAX_OVERFLOW30Максимум соединений сверх размера пула
BACKEND_MODEclassicclassic (SQLite/Postgres, по умолчанию) или modern (добавляет очередь событий на Redis)
REDIS_URLСтрока подключения к Redis; обязательна при BACKEND_MODE=modern
Строка подключения к PostgreSQL
Используйте postgresql+asyncpg://user:pass@host:5432/dbname для асинхронного PostgreSQL.
Режим modern backend
Задайте BACKEND_MODE=modern и укажите REDIS_URL, чтобы включить очередь событий на Redis. Используйте docker-compose.modern.yml, в котором рядом с панелью поставляется сервис redis:7. Большинству развёртываний это не нужно.

Xray

ПеременнаяПо умолчаниюОписание
XRAY_JSONxray_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_PATHsubСегмент URL-пути для подписок
XRAY_EXCLUDE_INBOUND_TAGSТеги inbound через пробел, которые нужно исключить
XRAY_FALLBACKS_INBOUND_TAGТег inbound, используемый для fallback-маршрутизации

Подписка

ПеременнаяПо умолчаниюОписание
SUB_PROFILE_TITLESubscriptionОтображаемое имя в клиентских приложениях
SUB_SUPPORT_URLСсылка на поддержку, включаемая в информацию о подписке
SUB_UPDATE_INTERVAL12Интервал автообновления у клиента (часы)
EXTERNAL_CONFIGURL внешнего конфига для интеграции с клиентом
USE_CUSTOM_JSON_DEFAULTfalseВключить свой JSON-конфиг для клиента по умолчанию
USE_CUSTOM_JSON_FOR_V2RAYNfalseВключить свой JSON для V2RayN
USE_CUSTOM_JSON_FOR_V2RAYNGfalseВключить свой JSON для V2RayNG
USE_CUSTOM_JSON_FOR_STREISANDfalseВключить свой JSON для Streisand
USE_CUSTOM_JSON_FOR_HAPPfalseВключить свой JSON для Happ
SUB_RATE_LIMIT_PER_MINUTE60Максимум запросов подписки с одного IP в минуту (в процессе, сбрасывается при перезапуске)
SUB_ENABLE_ETAGtrueВозвращать ETag / учитывать If-None-Match, чтобы экономить трафик на неизменившихся подписках
SUB_GZIP_MIN_SIZE512Сжимать gzip ответы подписки больше этого числа байт

Шаблоны

ПеременнаяПо умолчаниюОписание
CUSTOM_TEMPLATES_DIRECTORY/var/lib/panel/templates/Базовый каталог для своих шаблонов
SUBSCRIPTION_PAGE_TEMPLATEsubscription/index.htmlШаблон страницы подписки пользователя
HOME_PAGE_TEMPLATEhome/index.htmlШаблон главной страницы панели
CLASH_SUBSCRIPTION_TEMPLATEclash/default.ymlШаблон подписки Clash
CLASH_SETTINGS_TEMPLATEclash/settings.ymlШаблон настроек Clash
V2RAY_SUBSCRIPTION_TEMPLATEv2ray/default.jsonШаблон подписки V2Ray
V2RAY_SETTINGS_TEMPLATEv2ray/settings.jsonШаблон настроек V2Ray
SINGBOX_SUBSCRIPTION_TEMPLATEsingbox/default.jsonШаблон подписки Sing-box
SINGBOX_SETTINGS_TEMPLATEsingbox/settings.jsonШаблон настроек Sing-box
MUX_TEMPLATEmux/default.jsonШаблон конфигурации мультиплексирования
USER_AGENT_TEMPLATEuser_agent/default.jsonШаблон разбора user-agent
GRPC_USER_AGENT_TEMPLATEuser_agent/grpc.jsonШаблон user-agent для gRPC

Telegram

ПеременнаяПо умолчаниюОписание
TELEGRAM_API_TOKENТокен бота от @BotFather
TELEGRAM_ADMIN_IDID пользователей Telegram для администраторов через запятую
TELEGRAM_LOGGER_CHANNEL_IDID канала для сообщений логов
TELEGRAM_DEFAULT_VLESS_FLOWxtls-rprx-visionVLESS flow по умолчанию для пользователей, созданных ботом
TELEGRAM_PROXY_URLURL прокси для подключений к Telegram API

Уведомления

ПеременнаяПо умолчаниюОписание
NOTIFY_STATUS_CHANGEtrueУведомлять при смене статуса пользователя
NOTIFY_USER_CREATEDtrueУведомлять о создании нового пользователя
NOTIFY_USER_UPDATEDtrueУведомлять об изменении пользователя
NOTIFY_USER_DELETEDtrueУведомлять об удалении пользователя
NOTIFY_USER_DATA_USED_RESETtrueУведомлять о сбросе использованного трафика
NOTIFY_USER_SUB_REVOKEDtrueУведомлять об отзыве подписки
NOTIFY_IF_DATA_USAGE_PERCENT_REACHEDtrueУведомлять при достижении порога трафика
NOTIFY_IF_DAYS_LEFT_REACHEDtrueУведомлять при достижении порога по сроку действия
NOTIFY_LOGINtrueУведомлять о входе администратора
LOGIN_NOTIFY_WHITE_LISTIP, исключаемые из уведомлений о входе
NOTIFY_DAYS_LEFT3,7Пороги «дней до окончания» для уведомлений
NOTIFY_REACHED_USAGE_PERCENT80,90Пороги процента использования
RECURRENT_NOTIFICATIONS_TIMEOUT180Минут между повторными уведомлениями
NUMBER_OF_RECURRENT_NOTIFICATIONS3Максимум повторных уведомлений на событие
DISCORD_WEBHOOK_URLWebhook Discord для уведомлений в стиле Telegram
WEBHOOK_ADDRESSУстаревшее: статические URL webhook через запятую. Для новых настроек используйте интерфейс Webhooks в панели.
WEBHOOK_SECRETУстаревшее: HMAC-секрет для доставки на WEBHOOK_ADDRESS. Webhooks в панели управляют секретами для каждого эндпоинта.

Брендинг (White-Label)

ПеременнаяПо умолчаниюОписание
BRAND_NAMEPanelНазвание панели, отображаемое в интерфейсе и письмах
BRAND_LOGO_URLURL изображения своего логотипа
BRAND_FAVICON_URLURL своего favicon

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

ПеременнаяПо умолчаниюОписание
CAPTCHA_PROVIDERdisabledПровайдер капчи: disabled, turnstile или builtin
TURNSTILE_SITE_KEYSite key Cloudflare Turnstile
TURNSTILE_SECRET_KEYSecret key Cloudflare Turnstile
LOGIN_RATE_LIMIT10/minuteМаксимум попыток входа за окно
LOGIN_LOCKOUT_THRESHOLD10Неудачных попыток до блокировки
LOGIN_LOCKOUT_DURATION_MINUTES30Длительность блокировки в минутах

Логирование

ПеременнаяПо умолчаниюОписание
LOG_LEVELINFOУровень логов: DEBUG, INFO, WARNING, ERROR
LOG_FORMATtextФормат логов: text или json
LOG_FILE_PATHПисать логи в файл (в дополнение к stdout)
LOG_MAX_SIZE_MB10Максимальный размер файла лога до ротации
LOG_BACKUP_COUNT5Сколько ротированных файлов логов хранить

Метрики (Prometheus)

ПеременнаяПо умолчаниюОписание
METRICS_ENABLEDfalseВключить эндпоинт /metrics для Prometheus
METRICS_TOKENBearer-токен, нужный для сбора метрик

Дополнительные переменные

ПеременнаяПо умолчаниюОписание
ACTIVE_STATUS_TEXTActiveСвоя метка для статуса «активен»
EXPIRED_STATUS_TEXTExpiredСвоя метка для статуса «истёк»
LIMITED_STATUS_TEXTLimitedСвоя метка для статуса «ограничен»
DISABLED_STATUS_TEXTDisabledСвоя метка для статуса «отключён»
ONHOLD_STATUS_TEXTOn-HoldСвоя метка для статуса «на удержании»
USERS_AUTODELETE_DAYS-1Автоудаление истёкших пользователей через N дней (-1 = отключено)
USER_AUTODELETE_INCLUDE_LIMITED_ACCOUNTSfalseВключать в автоудаление пользователей, ограниченных по трафику
JOB_CORE_HEALTH_CHECK_INTERVAL10Интервал проверки работоспособности (секунды)
JOB_RECORD_NODE_USAGES_INTERVAL30Интервал записи использования нод
JOB_RECORD_USER_USAGES_INTERVAL10Интервал записи использования пользователей
JOB_REVIEW_USERS_INTERVAL10Интервал проверки пользователей на истечение
JOB_SEND_NOTIFICATIONS_INTERVAL30Интервал отправки уведомлений
DISABLE_RECORDING_NODE_USAGEfalseОтключить запись использования нод
DEBUGfalseВключить режим отладки с горячей перезагрузкой
DOCSfalseВключить 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 / HostTLS Server Name Indication и HTTP-заголовок Host
Security / ALPN / FingerprintПрофиль TLS: none / tls / reality; h2/http1.1; uTLS Chrome/Firefox/Safari
Allow InsecureПропускать проверку TLS-сертификата (используйте только за CDN, где сертификат не виден)
Country codeISO 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:

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. Пользователь может состоять не более чем в одной группе.

bash — 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.

bash — API
# Создать набор 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_agentequals / contains / regextemplate / status / headers
client_osequals / contains / regextemplate / 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. Побеждает первое совпадение.

bash — API
# Создать правило: выдавать шаблон 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

Оставьте области пустыми, чтобы получать все события. Доставка повторяется с экспоненциальной задержкой; после максимального числа попыток событие помечается как неудачное и отбрасывается.

bash — API
# Зарегистрировать эндпоинт
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"]
Устаревший подход через env
WEBHOOK_ADDRESS (URL через запятую) и WEBHOOK_SECRET по-прежнему работают как статическая альтернатива через переменные окружения. Для новых настроек используйте интерфейс панели — он поддерживает секреты, области и историю доставки для каждого эндпоинта.

Страница клиентов

Панель → Клиенты показывает подобранный список рекомендуемых VPN-клиентов со значками платформ, ссылками для скачивания и заметками по использованию. Операторы делятся URL этой страницы с конечными пользователями.

КлиентПлатформыЗаметки
HappiOS / macOS / Windows / AndroidРекомендуется — нативный sub URL, привязка по HWID, офлайн-кэш
v2RayTuniOS / macOS / AndroidПопулярный клиент для iOS, поддержка VLESS-Reality
KaringВсе платформыНа основе Sing-box, сильная кроссплатформенность
ShadowrocketiOS$2.99 в App Store США — надёжен на iOS
V2rayNGAndroidКлассический клиент для Android
FlClashXWindows / macOS / Linux / AndroidСовместим с Mihomo/Clash
StreisandiOS / 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/месБезлимит1030 дней/мес
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
  • Приоритетную поддержку

Сравнение возможностей

ВозможностьПробныйStandardPro
Максимум пользователейБезлимитБезлимитБезлимит
Максимум нодБезлимит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 действительно работать.

Как это работает

  1. Xray пишет по одной строке в $XRAY_ACCESS_LOG на каждое принятое подключение.
  2. Задание enforce_limits запускается каждые 60 секунд, читает хвост лога (с учётом смещения и ротации) и извлекает пары (user_id, client_ip) за последние LIMIT_WINDOW_SECONDS (по умолчанию 600 = 10 минут).
  3. Для каждого пользователя подсчитываются уникальные IP. Если их число превышает ip_limit (или device_limit, если ip_limit не задан) и пользователь сейчас active и ip_limit_mode == "limit", пользователь переводится в статус limited.
  4. Все увиденные IP записываются в user_ip_history. Просмотреть IP по пользователю можно через GET /api/v1/user/{username}/ips.

Необходимая конфигурация xray

При установке по умолчанию это включается автоматически. Для существующих установок панель при запуске автоматически правит ваш xray_config.json, добавляя путь к access-логу. Конфигурация вручную:

json
{
  "log": {
    "loglevel": "warning",
    "access": "/var/lib/panel/xray-access.log"
  }
}

Настраиваемые параметры

Переменная окруженияПо умолчаниюНазначение
XRAY_ACCESS_LOG/var/log/xray/access.logПуть к файлу access-лога Xray
LIMIT_WINDOW_SECONDS600Скользящее окно для подсчёта уникальных IP
LIMIT_ENFORCE_INTERVAL60Как часто (секунды) запускается задание применения лимитов

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

NexusPanel выполняет автоматическое резервное копирование базы данных каждый день в 03:00 UTC через задание backup APScheduler.

Куда сохраняются копии

  • Локальные файлы: /var/lib/panel/backups/backup_YYYYMMDD_HHMMSS.sqlite3 (или .sql для PostgreSQL)
  • Хранятся последние 7 копий; более старые автоматически удаляются
  • Если настроены TELEGRAM_API_TOKEN и TELEGRAM_ADMIN_ID, каждая копия также отправляется вам в Telegram документом, чтобы у вас была копия вне сервера

Резервное копирование вручную

bash
# 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

Восстановление

  1. Остановите панель: cd /opt/panel && docker compose down
  2. Замените файл БД: cp /path/to/backup.sqlite3 /var/lib/panel/db.sqlite3
  3. Перезапустите: 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>.

Ведение бизнеса

Простыми словами
Повседневная работа — это в основном один цикл: клиент платит, вы создаёте ему пользователя, отправляете ссылку. Всё ниже — это тот же цикл плюс несколько настроек, которые позволяют вырасти дальше нескольких десятков клиентов.

Ваш первый клиент

  1. Панель → ПользователиДобавить пользователя.
  2. Укажите имя пользователя, выберите дату истечения и лимит трафика (или оставьте оба без ограничений), выберите протоколы.
  3. Сохраните — панель сразу сгенерирует ссылку на подписку.
  4. Отправьте клиенту ссылку. Он вставляет её в клиентское приложение (см. страницу Клиенты с рекомендациями) и подключается.

Всё это доступно и через 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 вместо этого генерирует готовую к вставке однострочную команду со встроенным сертификатом панели. Никакой записи файла сертификата вручную.

  1. Панель → НодыДобавить новую ноду → вкладка Manual
  2. Нажмите Copy Install Command — команда включает сертификат, порт, порт API и URL панели
  3. Вставьте и выполните на сервере ноды
  4. Введите IP ноды и порты в панели → Add Node
bash — пример сгенерированной команды
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
Файрвол
Откройте входящие TCP 62060 и TCP 62061 на сервере ноды для IP панели. Также откройте любые прокси-порты (443, 80 и т. д.) для конечных пользователей.

Docker Compose для ноды

Это реальный compose-файл, который генерирует установщик в /opt/nexus-panel-node/docker-compose.yml — для справки, если настраиваете его вручную:

yaml — /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, к которым подключаются пользователи) напрямую на хосте.

Несколько нод

Чтобы добавить ноды в разных локациях:

  1. Установите сервис ноды на каждый сервер с помощью сгенерированной однострочной команды
  2. В панели добавьте каждую ноду с её публичным IP и портами
  3. Назначьте флаг страны — он управляет и визуальной сеткой, и региональным переупорядочиванием подписки
  4. Перетаскиванием задайте порядок отображения в сетке
  5. Задайте коэффициент использования для каждой ноды (например, 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-токен, отправив учётные данные:

POST /api/v1/admin/token
bash
curl -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.

Эндпоинты 2FA
POST /api/v1/admin/2fa/setup — сгенерировать TOTP-секрет + резервные коды
POST /api/v1/admin/2fa/enable — проверить код и активировать 2FA
POST /api/v1/admin/2fa/disable — деактивировать 2FA

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

POST /api/v1/user

Создать нового пользователя с протоколами, лимитом трафика, сроком действия, лимитом устройств и лимитом IP.

GET /api/v1/users

Список всех пользователей. Автоматически ограничивается по администратору для несудо-аккаунтов.

GET /api/v1/user/{username}

Получить детальную информацию о пользователе, включая статистику использования и ссылки-подписки.

PUT /api/v1/user/{username}

Обновить поля пользователя (лимит трафика, срок действия, статус, протоколы и т. д.).

DELETE /api/v1/user/{username}

Безвозвратно удалить пользователя и все связанные данные.

Массовые операции

POST /api/v1/users/bulk/update
POST /api/v1/users/bulk/delete
POST /api/v1/users/bulk/reset

Экспорт

GET /api/v1/export/users

Скачать всех пользователей в виде CSV-файла.

GET /api/v1/export/subscription-links

Экспортировать все ссылки-подписки в виде обычного текста.

Администраторы

POST /api/v1/admin

Создать нового администратора с ролью (owner, admin, reseller), max_users и max_traffic_bytes.

GET /api/v1/admins

Список всех учётных записей администраторов.

Ноды

GET /api/v1/inbounds

Список всех протокольных inbound-ов.

GET /api/v1/hosts

Получить конфигурации хостов (только sudo).

Аналитика

GET /api/v1/analytics/summary

Сводная статистика для обзора панели.

GET /api/v1/analytics/protocols

Разбивка распределения по протоколам.

GET /api/v1/analytics/nodes/load

Число подключений и трафик по каждой ноде.

GET /api/v1/analytics/nodes/uptime

Проценты аптайма нод.

GET /api/v1/analytics/users/expiring?days=30

Пользователи, у которых срок истекает в течение указанного числа дней.

GET /api/v1/analytics/users/top?limit=10

Топ-пользователи по потреблению трафика.

Сессии

GET /api/v1/sessions/active?hours=24

Активные сессии устройств за последние N часов.

GET /api/v1/sessions/user/{username}

Сессии конкретного пользователя.

DELETE /api/v1/sessions/{session_id}

Принудительно отключить сессию устройства.

Система

GET /api/v1/system

Системная статистика, включая CPU, память и трафик. Несудо-администраторы видят обнулённые значения для чувствительных метрик.

GET /api/v1/health

Эндпоинт проверки работоспособности, возвращающий статус базы данных и ядра Xray.

GET /metrics

Эндпоинт метрик, совместимый с Prometheus. Требует METRICS_ENABLED=true и METRICS_TOKEN для аутентификации.

Полная документация API
Для полных схем запросов/ответов включите DOCS=true в вашем .env и зайдите на http://your-panel/docs для интерактивного Swagger UI.

Telegram-бот

Настройка

  1. Откройте Telegram и напишите @BotFather
  2. Отправьте /newbot и следуйте подсказкам, чтобы создать бота
  3. Скопируйте токен бота (например, 123456789:AAAA...)
  4. Узнайте свой ID пользователя Telegram (напишите @userinfobot)
  5. Добавьте в ваш .env:
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
Лимит IPIP Limit: 5 (limit)Только когда > 0; режим показан рядом
Лимит HWIDHWID Limit: 2Только когда > 0
Есть следующий планHas Next Plan: TrueВсегда
ЗаметкаNote: Paid in advance 6moТолько если не пуста; обрезается до 120 символов
Интеграция с Discord
Задайте DISCORD_WEBHOOK_URL, чтобы получать те же уведомления в канал Discord. Embed-ы Discord включают те же расширенные поля.

Каналы доставки подписок

Доставляйте sub URL через инфраструктуру, которую цензоры не могут заблокировать.

Когда домен вашей панели заблокирован в России, Иране, Китае или Туркменистане, клиенты не могут получить обновления своих подписок. Каналы доставки подписок решают это, публикуя конфиг каждого пользователя в статический файл на инфраструктуре Google / Cloudflare / GitHub / Telegram — на хостах, которые цензоры не могут заблокировать целиком, не сломав массовые приложения, которыми пользуются миллионы.

Требование к лицензии
Каналы доставки подписок требуют тарифа Pro. На более низких тарифах панель показывает баннер с предложением апгрейда.

Как это работает

  1. Вы настраиваете один или несколько каналов в Настройки → Каналы доставки подписок.
  2. Каждый пользователь получает стабильный публичный URL на этом канале (например, https://firebasestorage.googleapis.com/…?alt=media&token=…).
  3. Значок ⊞ (сетка) в каждой строке пользователя в таблице открывает поповер со всеми доступными URL — Direct, зашифрованный Happ и каждый настроенный канал. Копирование или показ QR в два клика.
  4. Когда вы редактируете хосты или конфиг Xray, панель автоматически переопубликовывает всех активных пользователей в Firebase (и другие каналы) в течение ~10–30 секунд через фоновый воркер. Ручной Backfill после рутинных правок конфига не нужен.

Доступные каналы

КаналПровайдерБесплатный лимитЛучше всего для
Firebase StorageGoogle~50K запросов/день на плане SparkОсновной антицензурный канал
Firebase HostingGoogleТот же план Spark, что и у StorageВторая поверхность Firebase (*.web.app) — другой SNI и другой edge CDN в том же проекте, поэтому остаётся доступной, когда Storage заблокирован. Публикуется сайтом целиком, а не по одному пользователю, поэтому обновляется пакетно, а не на каждое изменение.
Cloudflare R2Cloudflare10 ГБ/месяц, без платы за исходящий трафикВторичный; иной поставщик, чем Firebase
GitHub GistGitHub / MicrosoftНеограниченные публичные gist-ыПростой запасной вариант; крайне живучий
GitLab SnippetGitLabНеограниченные публичные сниппетыПодтверждённо доступен в Туркменистане даже в окна жёстких блокировок — второе зеркало рядом с Firebase для тех, кто не может достучаться до него
Доставка через TelegramTelegramБесплатноЭкстренная доставка, когда всё остальное не работает
Пул Nginx-проксиВаши VPSСтоимость VPSПолный контроль оператора над ретранслятором
Тестируйте со стороны панели, а не со своего ноутбука
Кнопка Test (значок обновления в каждой строке канала) загружает реальный тестовый блоб и скачивает его обратно через исходящую сеть панели — а не из вашего браузера. Это важно: ваш локальный DNS может быть в порядке, тогда как регион ваших клиентов блокирует URL. Тест измеряет, может ли сервер панели достучаться до URL, — а именно это определяет, будет ли доставлено обновление подписки.

Firebase Storage

Рекомендуемый первый канал. Бесплатный лимит покрывает ~50K запросов подписки в день. Размещён в IP-пространстве Google — цензоры не могут заблокировать его целиком, не сломав Google Maps, Gmail и множество других приложений.

Однократная настройка на console.firebase.google.com

  1. Создайте проект — Add project → назовите его (например, nexus-subs) → план Spark (бесплатный) → Create.
  2. Включите Storage — Build → Storage → «Get started» → «Start in production mode» → выберите локацию → Done.
  3. Задайте правила хранилища — Storage → Rules → замените на:
firebase rules
rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /sub_{file=**} {
      allow read: if true;
      allow write: if false;
    }
  }
}
  1. Сгенерируйте ключ сервисного аккаунта — Project Settings (⚙) → Service accounts → «Generate new private key» → Download. Относитесь к нему как к паролю.
  2. Найдите имя бакета — Storage → вверху показано gs://your-project.firebasestorage.app. Скопируйте часть после gs://.

В панели

  1. Настройки → Каналы доставки подписок → Firebase Storage → ⚙
  2. Вставьте имя бакета и JSON сервисного аккаунта (всё содержимое файла)
  3. Включите Enabled, задайте Priority (меньше = предпочтительнее; 10 — хорошее начало)
  4. Сохраните → нажмите Test (значок обновления)

Как читать результат теста

Успешный тест выглядит так:

result
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
Шаг, который не прошёлВероятная причинаРешение
credsJSON сервисного аккаунта неверен или истёкСгенерируйте ключ заново в Firebase Console
uploadStorage не включён или неверные правилаПерепроверьте шаги настройки 2–3
fetchПравило публичного чтения не примененоВставьте правила из шага 3 заново
matchEdge-кэш отдал устаревший блоб (редко)Обычно повторы это скрывают; сообщите о баге, если повторяется
cleanupСервисный аккаунт только для чтенияУдалите блобы nexus_test_* вручную

Применить к существующим пользователям

После того как тест пройдёт, нажмите Backfill внизу карточки «Каналы доставки подписок». Это немедленно запустит загрузки в Firebase для всех активных пользователей через фоновый воркер. Для 200 пользователей ожидайте 30–120 секунд.

Стабильные URL при смене плана
URL Firebase никогда не меняется для конкретного пользователя — перезаписывается только содержимое блоба. Клиенты один раз импортируют URL в свой VPN-клиент, и он автоматически обновляется при каждой смене плана без каких-либо действий с их стороны.

Cloudflare R2

S3-совместимое объектное хранилище без платы за исходящий трафик. Используйте как вторичный канал наряду с Firebase — иной поставщик означает, что региональная блокировка одного не выводит из строя оба.

Настройка на dash.cloudflare.com

  1. R2 (левое меню) → Create bucket → назовите его (например, nexus-subs).
  2. Откройте бакет → Settings → Public access → включите. Скопируйте URL https://pub-<id>.r2.dev.
  3. Вверху справа страницы R2 → Manage R2 API tokens → Create token → Object Read & Write (ограничьте вашим бакетом) → сохраните Access Key ID + Secret.
  4. Ваш Account ID — это 32-символьный hex внизу справа страницы панели R2.

В панели

Настройки → Каналы доставки подписок → Cloudflare R2 → ⚙:

ПолеГде найти
Account ID Cloudflare32-символьный hex из шага 4
Имя бакетанапример, nexus-subs
Access key IDИз шага 3
Secret access keyИз шага 3 (показывается один раз)
База публичного URLhttps://pub-<id>.r2.dev из шага 2
Не подключайте к R2 свой домен
Свои домены блокируются на уровне DNS. Общий хост pub-<id>.r2.dev получает то же преимущество против блокировок, что и Firebase — он общий с тысячами других бакетов R2.

GitHub Gist

Бесплатно, размещено на GitHub (IP Microsoft). Крайне живучий вариант — хороший низкоприоритетный запасной канал, который ничего не стоит.

Настройка

  1. github.com/settings/tokens → Personal access tokens → Tokens (classic) → Generate new token.
  2. Имя: nexus-gists. Область: отметьте ТОЛЬКО gist. Срок: 1 год (поставьте напоминание о продлении).
  3. Скопируйте токен ghp_… — увидеть его снова не получится.

В панели

Настройки → Каналы доставки подписок → GitHub Gist → ⚙ → вставьте PAT → Сохранить → Test.

Доставка через Telegram

Доступен в IR/RU/TM именно в те периоды, когда другие каналы недоступны. Это запасной канал из разряда «панель горит, и у пользователя больше ничего нет».

Это доставка, а не автообновление
Пользователь получает deep-link t.me/<bot>?start=sub_<token>, а не самообновляющийся URL. Он нажимает на него один раз, и бот присылает ему в личные сообщения файл .txt с его конфигом. Задавайте очень высокий Priority (маленький номер приоритета) только если вы настроили обработчик /start у бота — иначе ссылка ведёт на бота, который не отвечает.

Настройка — отдельный бот (рекомендуется)

  1. Напишите @BotFather в Telegram → /newbot → выберите имя и username (должен заканчиваться на bot).
  2. Скопируйте токен, который выдаст BotFather.
  3. Настройки → Каналы доставки подписок → Telegram → ⚙:
    • Username бота: без @
    • Токен бота: вставьте из BotFather
  4. Сохраните → Test. Тест вызывает getMe и проверяет, что возвращённый username совпадает с тем, что вы вставили.

Если у вас уже задан TELEGRAM_API_TOKEN в .env для доставки уведомлений, поле токена бота можно оставить пустым — канал использует эту переменную окружения. Не рекомендуется по соображениям безопасности: утечка токена бота уведомлений раскрыла бы и файлы подписок.

Пул Nginx-прокси

Когда все каналы статического хранилища отключаются или блокируются по регионам, переходите на собственный парк дешёвых ретрансляторов-VPS. Каждый хост в пуле получает свой домен; панель распределяет пользователей по хостам по весу.

Предварительная подготовка

Поднимите дешёвые VPS (Hetzner CCX13 / Contabo и т. п. — €4–5/месяц каждый). На каждом:

bash
# Запустить от root на каждом новом прокси-хосте
curl -sSL https://your-panel.tld/setup_proxy.sh | bash

В панели

Настройки → Каналы доставки подписок → Nginx-прокси → ⚙. Конфигурация в JSON:

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 / GistURL статического хранилища из включённых каналовКопирование + QR
TelegramDeep-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-ами нельзя.

Требуется открытый UDP в файрволе
Hysteria2 использует UDP. Прежде чем добавлять хост для ноды, убедитесь, что UDP-порт (например, 2053) открыт в панели вашего хостинг-провайдера — Contabo, Aeza, PTR по умолчанию блокируют UDP.

Добавить inbound Hysteria2

Панель → НастройкиHysteria2Add Inbound

Требуется sudo-администратор
Inbound-ы Hysteria2 могут создавать и управлять ими только sudo (супер) администраторы. Несудо-администраторы не видят и не редактируют inbound-ы hy2.
ПолеЗначениеЗаметки
Taghy2-mainЛюбое уникальное имя
Listen port2053UDP — должен быть открыт в файрволе
Obfs typesalamanderРекомендуется — скрывает UDP от DPI в CN/IR/RU
Obfs passwordнадёжный случайныйopenssl rand -hex 24
Masquerade URLhttps://www.bing.comHTTPS-сайт, под который hysteria маскируется для DPI-проб
SNIbing.comTLS SNI, предъявляемый клиентам
TLS cert / keyоставьте пустым для автоПанель автоматически генерирует 10-летний самоподписанный сертификат, если не указано

Создание inbound синхронизирует конфигурацию на каждую подключённую ноду и запускает демон hysteria на каждой. SSH не требуется.

Добавить хосты для каждой ноды

Панель → Хосты → нажмите карточку inbound Hysteria2 → Add Host

Добавьте по одной строке-хосту на каждую ноду, на которой хотите открыть hy2:

ПолеПримерОбязательно
RemarkDE Frankfurt hy2Да
Addressde.example.comДа — публичный домен или IP ноды
Port2053Да — UDP-порт на этой ноде
Country codeDEРекомендуется — управляет региональным переупорядочиванием подписки

Генераторы подписок автоматически выдают записи hy2:// для каждого включённого хоста наряду с существующими ссылками VLESS/VMess. Клиенты увидят их при следующем обновлении подписки.

Через API (требуются учётные данные sudo-администратора):

bash
# 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-сервере, обновите одну запись хоста.

Соглашения по портам
TCP inbound-ы: порт middle 50031–50036 → порт ноды 31–36 (совпадает с id ноды). UDP inbound-ы Hysteria2: порты 50041+ назначаются по каждому inbound. Все они автогенерируются из состояния БД панели — вы никогда не правите их вручную.

Первоначальная настройка

Сгенерируйте одноразовую команду установки из панели, затем вставьте её на новом VPS от root:

  1. В панели перейдите в Настройки → Middle-серверы и нажмите Generate install command.
  2. Скопируйте показанную команду — она выглядит так:
bash
curl -fsSLk https://panel.example.com:8443/api/v1/middle-server/i/<token> | sudo bash

Токен одноразовый и истекает через 30 минут. В истории shell не появляется никаких учётных данных.

Ручная / скриптовая установка (без доступа к интерфейсу панели)
bash
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-сервера и выведенный порт.

Повторный запуск безопасен
Скрипт сбрасывает существующие правила перед применением новых. Запускайте его каждый раз, когда добавляете ноду, добавляете inbound Hysteria2 или меняете IP ноды.

Переход на новый middle-сервер

Когда текущий middle-сервер заблокирован или вы хотите перейти на другой VPS:

  1. Подключитесь по SSH к новому VPS и выполните ту же единственную команду выше
  2. В панели → страница Хостов отредактируйте каждый хост, чей адрес указывает на старый IP middle-сервера, и смените его на новый IP. Порты остаются прежними.
  3. Готово — никаких изменений нод, никакой перенастройки у пользователей
Не забудьте про хосты Hysteria2
Если у вас есть хосты Hysteria2, которые маршрутизируются через middle-сервер, обновите и их адреса.

Фронтинг и обход блокировок

Простыми словами
Фронтинг означает, что трафик ваших клиентов внешне выглядит так, будто идёт к Cloudflare, Amazon, Google, Fastly или Bunny — а не к вашему VPS. Чтобы заблокировать вас, цензору пришлось бы заблокировать весь этот облачный сервис целиком, а это сломает миллионы никак не связанных с вами сайтов. Большинство сетей на это не идут, поэтому ваш трафик проходит.

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

ГруппаЧто там
Start hereOverview — карта состояния, страница по умолчанию
PipelineSources (URL подписок конкурентов — для анализа), ② IP Pool (проверяемые адреса-кандидаты), ③ Hosts (ваши действующие фронтинг-записи — сюда же добавляется хост за Cloudflare)
InfrastructureShield (доска статусов с карточкой на каждого провайдера — клик по карточке открывает страницу провайдера) и Setup (где вы добавляете API-ключи провайдеров)

Использовать все провайдеры не обязательно. Начните с одного — Cloudflare проще всего и бесплатен — и добавляйте остальные позже, если нужна избыточность или вы обслуживаете регионы с разной картиной блокировок.

IP-Defender

IP-Defender — это фоновая задача, которая непрерывно проверяет, работает ли ещё каждый фронтинг-хост. Она не ждёт жалобы от клиента.

  1. Healthy (здоров) — хост опрашивается и отвечает нормально.
  2. Suspect (подозрителен) — опросы начинают проваливаться. Одна неудачная проверка ничего не запускает; нужна устойчивая серия сбоев, прежде чем защитник воспримет это всерьёз — так короткий сетевой сбой не приведёт к лишней замене.
  3. Blocked (заблокирован) — сбои продолжаются. Защитник выбирает рабочий адрес того же вида (хост Cloudflare заменяется только на другой адрес Cloudflare, хост AWS — только на другой AWS; смешивание видов ломает сертификат, который ожидает клиент) и обновляет его автоматически.
  4. Cooldown (охлаждение) — после замены старый адрес какое-то время не используется повторно, чтобы хост не «дёргался» туда-сюда.
Можно заменить и вручную
На каждой странице провайдера в Shield есть своё действие для ротации/замены (формулировка отличается: Swap front, Rotate account, Rotate IP…). Если вы уже знаете, что хост заблокирован — клиент пожаловался, или вы сами проверили — не обязательно ждать автоматический детектор.
Fastly и Bunny не умеют быстро ротироваться
Cloudflare, AWS и Google могут переключиться на свежий адрес за секунды. Fastly и Bunny — нет: если их edge заблокирован, вы пересоздаёте CDN/связку с новыми edge-IP, а не получаете мгновенную замену. Учитывайте это при выборе провайдеров для рынка с частыми блокировками.

Поскольку Xray сам по себе не пишет трафик в разрезе по хостам, защитник опирается на активные опросы, а не на графики трафика. Это нормально — вы увидите время «последней проверки» на каждом хосте, а не счётчики трафика в реальном времени.

Cloudflare

Самый простой провайдер для старта — бесплатного тарифа достаточно для фронтинга. Через edge-узлы Cloudflare проходит огромное количество обычных сайтов, поэтому их блокировка задевает много легитимного трафика, и сети на это неохотно идут. Cloudflare в NexusPanel решает две разные задачи, и открываются они по-разному:

  1. В Cloudflare создайте API-токен с правом редактирования DNS для домена, через который будете фронтить.
  2. Панель → DefenderSetup → добавьте учётные данные, провайдер cloudflare, вставьте API-токен.
  3. Фронтинг самого VPN-трафика: Панель → DefenderHosts (Pipeline, шаг 3) → добавьте хост, указывающий на ваш домен за Cloudflare (DNS-запись с «оранжевым облаком»). Отдельную дистрибуцию создавать не нужно — Cloudflare это просто DNS + прокси, и IP-Defender следит за этим хостом как за любым другим.
  4. Доступность ссылки на подписку: Панель → DefenderShield → карточка Cloudflare открывает отдельную страницу, которая ротирует домен, с которого раздаются ссылки на подписку (PRIMARY/STANDBY, с автоматическим escape, если этот домен заблокируют). Это другая задача, не связанная с фронтингом VPN-трафика — она про то, чтобы клиенты могли обновлять конфиг.

AWS CloudFront

CDN от Amazon — другой вендор, отличный от Cloudflare, и это важно: если вы используете оба, сети, заблокировавшей один, придётся отдельно разбираться и со вторым.

  1. В AWS создайте IAM-пользователя с правами CloudFront + Route 53 и сгенерируйте access key.
  2. Панель → DefenderSetup → добавьте учётные данные, провайдер aws, вставьте access key ID и secret.
  3. Панель → DefenderShield → карточка AWS CloudFront, чтобы создать дистрибуцию CloudFront и увидеть её текущий входной IP и статус.

Тарификация AWS CloudFront зависит от использования (в основном от исходящего трафика) — следите за ней, если гоните через неё серьёзный объём трафика.

Google (Cloud Run)

Фронтинг через инфраструктуру Google run.app — те же хостнеймы, что используют бесчисленные обычные приложения Cloud Run.

  1. В Google Cloud создайте сервисный аккаунт с правами Cloud Run + DNS и скачайте его JSON-ключ.
  2. Панель → DefenderSetup → добавьте учётные данные, провайдер google, вставьте ключ сервисного аккаунта.
  3. Панель → DefenderShield → карточка Google Cloud Run, чтобы развернуть и управлять фронтинг-сервисом.

Сервисы Cloud Run должны быть публично доступны, чтобы работать как фронт — панель делает это сама при развёртывании сервиса.

Fastly

Fastly — провайдер с подключением в один клик, точно как Cloudflare, AWS и Google: вы даёте edge-IP, панель строит всё остальное.

  1. В Fastly создайте API-токен с областью действия global (нужна, чтобы создавать CDN-сервисы).
  2. Панель → DefenderSetup → добавьте учётные данные, провайдер fastly, вставьте токен.
  3. Панель → DefenderShield → карточка Fastly → вставьте свои edge-IP Fastly (по одному на строку или через запятую) и нажмите Create CDN. Панель поднимет сервис Fastly, настроенный как ваш текущий, и сама подключит нужный inbound и по одному хосту на каждый edge-IP.

У Fastly нет быстрой ротации: если edge-IP заблокирован, заново запустите Create CDN с новыми edge-IP, а не ждите автоматическую замену.

Bunny CDN

Bunny работает иначе, чем остальные провайдеры: не панель создаёт CDN за вас, а вы создаёте его на bunny.net, а панель его адаптирует.

  1. На bunny.net создайте одну pull zone на тарифе Standard с включёнными WebSockets.
  2. Добавьте в эту pull zone правило для каждой ноды (Edge Rule): Host == bunny-<node>.<ваш-домен>, переопределяющее Origin URL на http://<ip-ноды>:2009 (inbound VLESS BUNNY WS этой ноды). Одно правило на каждую ноду.
  3. Панель → DefenderSetup → добавьте учётные данные, провайдер bunny, вставьте API-ключ вашего аккаунта Bunny.
  4. Панель → DefenderShield → карточка Bunny CDN → нажмите Auto-wire per node. Панель прочитает правила вашей pull zone, сопоставит каждый origin IP с нодой в панели и создаст по одному управляемому хосту Bunny на каждую совпавшую ноду. Перезапускайте при добавлении ноды или исправлении правила.
  5. Нажмите Refresh edge IPs, чтобы засеять опубликованные edge-IP Bunny в пул ротации.

Как и у Fastly, у Bunny нет быстрой ротации — заблокированный edge означает починку pull zone и повторный auto-wire, а не мгновенную замену.

Azure

Azure — это не CDN-фронт вроде остальных: он разворачивает ротируемую VM-ретранслятор (та же идея, что Middle-сервер, только Azure сам поднимает VM и меняет её IP), чтобы у заблокированной ноды появился свежий входной IP без изменений на самой ноде.

  1. Создайте Service Principal: az ad sp create-for-rbac --role Contributor --scopes /subscriptions/<id>.
  2. Панель → DefenderShield → карточка Azure → вставьте tenant ID, client ID, client secret и subscription ID, затем нажмите Verify & connect. У Azure своя форма учётных данных прямо здесь — она не проходит через Setup, как у остальных провайдеров.
  3. Выберите регион (панель предлагает вариант, определённый по вашим подпискам) и нажмите Create relay — это развернёт небольшую VM на Ubuntu со статическим IP, размер выбирается автоматически как самый дешёвый.
  4. Установите middle-агент на полученный IP и переведите его в промоут, как для любого middle-сервера (см. Middle-сервер → Первоначальная настройка).

Если IP ретранслятора позже заблокируют, нажмите Rotate IP на странице Azure, затем заново запустите установку middle-сервера на новом IP и перепроверьте из-под заблокированной сети.

Миграция с Marzban

Простыми словами
Уже используете Marzban? Это переносит всё в NexusPanel — ваших клиентов, настройки и даже их существующие ссылки — одной командой. Ваши клиенты ничего не делают и ничего не замечают. Инструмент сначала показывает каждое изменение и может быть отменён вплоть до финального шага, так что пробовать безопасно.

Инструмент nexus cli migrate переносит живую установку Marzban в NexusPanel без какой-либо перенастройки у конечных пользователей. Он работает на том же хосте, что и Nexus, читает каталог данных Marzban напрямую и использует атомарный конечный автомат из 9 этапов с полным откатом вплоть до команды finalize.

Совместимость JWT
Инструмент миграции извлекает 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 ничего не записывается.

bash
# Посмотреть, что было найдено
nexus cli migrate discover

# Репетиция: снимок + импорт + проверка на черновой БД, без побочных эффектов
nexus cli migrate run --dry-run

Прочтите отчёт о пробном прогоне в /var/lib/nexus/migration/dryrun-<ts>.json. Подтвердите число пользователей, список администраторов и что MARZBAN_LEGACY_JWT_SECRET был извлечён. Исправьте все отмеченные ошибки перед продолжением.

Шаг 2: Боевое переключение

bash
# Боевой прогон — останавливает Marzban, импортирует, перезапускает Nexus
nexus cli migrate run --yes

Критический путь (MARZBAN_STOP → NEXUS_RESTART) занимает ~15–30 секунд. VPN-трафик нод продолжается без перерыва — ноды работают независимо от панели. Недоступен лишь ненадолго эндпоинт URL подписки.

Если VERIFY не проходит, срабатывает автооткат: конфигурации Nexus восстанавливаются, а Marzban перезапускается. Проверьте docker logs nexus-panel --tail 200, чтобы найти первопричину, затем перезапустите.

bash
# После наблюдения за продакшеном в течение нескольких часов:
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 выводит таблицу перенесённых хостов. Проверьте их, а затем:

  1. Проверьте старый URL-подписку Marzban — он должен вернуть валидный конфиг (проверка совместимости JWT)
  2. Проверьте число пользователей: docker exec nexus-panel sqlite3 /var/lib/panel/db.sqlite3 'SELECT COUNT(*) FROM users;'
  3. Выполните nexus cli migrate post-cutover, чтобы найти оставшиеся демоны Marzban (marzguard, cron-хуки certbot)
  4. Если используете Hysteria2: добавьте inbound + по одному хосту на ноду (см. раздел Hysteria2)
  5. Добавьте ноды заново через Панель → Ноды (новый сертификат, порты 62060/62061)
  6. Выполните nexus cli migrate finalize, чтобы освободить снимок, когда всё стабильно
bash — быстрая проверка
# Здоровье
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

Главное преимущество
Существующая ссылка-подписка каждого клиента продолжает работать. В Remnawave ссылка использует непрозрачный короткий идентификатор — NexusPanel сохраняет его при переносе, поэтому старый URL /sub/<token> резолвится и после миграции, клиентам не нужно ничего перенастраивать.

Инструмент nexus cli migrate remnawave подключается к живой панели Remnawave по её API (URL и логин/пароль администратора) и импортирует пользователей в NexusPanel.

bash
# По умолчанию — пробный прогон: подключается, извлекает и показывает, что будет
# импортировано и какие имена конфликтуют, ничего не пишет
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.

bash
# Откат — удаляет ровно тех пользователей и алиасы, которые создал прогон
nexus cli migrate remnawave rollback
ДанныеПереноситсяЗаметки
Пользователи, лимиты и израсходованный трафикДаСрок действия и статус тоже переносятся
Учётные данные по протоколамДаVLESS UUID, пароль Trojan, пароль Shadowsocks
Ссылка-подпискаДаНепрозрачный short-id Remnawave сохраняется как алиас — старый URL продолжает работать
Telegram ID пользователяНетВ NexusPanel у пользователя нет такого поля — инструмент выводит предупреждение
Хосты и нодыНетНастраиваются на стороне NexusPanel; уже перенесённые учётные данные пользователей сразу работают с ними

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

Двухфакторная аутентификация (2FA)

NexusPanel поддерживает 2FA на базе TOTP (совместимо с Google Authenticator, Authy и т. д.):

  1. Перейдите в Настройки в панели
  2. Нажмите Enable 2FA
  3. Отсканируйте QR-код приложением-аутентификатором
  4. Введите 6-значный код для подтверждения
  5. Сохраните резервные коды в безопасном месте

Через API:

bash
# Сгенерировать 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

env
CAPTCHA_PROVIDER="turnstile"
TURNSTILE_SITE_KEY="0x4AAAAAAA..."
TURNSTILE_SECRET_KEY="0x4AAAAAAA..."

Встроенная капча

env
CAPTCHA_PROVIDER="builtin"

Встроенная капча не требует внешних сервисов и генерирует простые математические задачи.

Ограничение частоты запросов

Ограничение частоты запросов к эндпоинту входа включено по умолчанию:

env
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

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:

bash
curl -X PUT /api/v1/admin/admin \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"password": "newSecurePassword123"}'

Как сделать резервную копию

SQLite

bash
# Сначала остановите панель для чистой копии
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

bash
docker compose exec db pg_dump -U nexus nexuspanel > /backups/db-$(date +%Y%m%d).sql
Совет
Также делайте резервные копии вашего .env, xray_config.json и любых своих шаблонов.

Как обновить

bash
cd /opt/nexuspanel

# Скачать последние образы
docker compose pull

# Перезапустить с новой версией
docker compose up -d

# Проверить логи на статус миграций
docker compose logs -f panel

Миграции базы данных выполняются автоматически при запуске. Всегда делайте резервную копию базы перед обновлением.

Как добавить свои шаблоны

Свои шаблоны позволяют управлять выводом подписки для разных клиентов:

  1. Создайте файлы шаблонов в каталоге шаблонов:
bash
mkdir -p /var/lib/nexuspanel/templates/clash
nano /var/lib/nexuspanel/templates/clash/custom.yml
  1. Укажите шаблон в .env:
env
CUSTOM_TEMPLATES_DIRECTORY="/var/lib/panel/templates/"
CLASH_SUBSCRIPTION_TEMPLATE="clash/custom.yml"

Шаблоны поддерживают синтаксис Jinja2 с доступом к данным пользователя, конфигам прокси и настройкам панели.

Настройка страницы подписки

Страница подписки для пользователя (показывается при открытии ссылки-подписки в браузере) полностью настраиваема:

  1. Скопируйте шаблон по умолчанию как отправную точку:
bash
cp -r /opt/nexuspanel/app/templates/subscription \
  /var/lib/nexuspanel/templates/subscription
  1. Отредактируйте /var/lib/nexuspanel/templates/subscription/index.html
  2. Задайте в .env:
env
SUBSCRIPTION_PAGE_TEMPLATE="subscription/index.html"

Доступные переменные шаблона включают: user, sub_url, clash_url, singbox_url, usage, expire_date и brand_name.


Документация NexusPanel — Сделано с заботой.