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