VPN·HUB·CRACK
Remnawave с нуля: панель + ноды по шагам · VPN HUB CRACK
Remnawave с нуля: панель + ноды по шагам
Панель Remnawave и ноды
Remnawave это панель на базе Xray-core (движок, на котором работают ноды). Дефолтный docker-compose-prod.yml поднимает три контейнера (проверено на живой установке, см. ниже):
- Панель (remnawave/backend:2) это мозг: пользователи, подписки, ноды. Xray внутри неё нет, она только оркестрирует. Слушает 127.0.0.1:3000 (UI+API) и 127.0.0.1:3001 (метрики). Страницу подписки backend отдаёт сам: на пути /<домен>/api/sub/<shortUuid> (см. SUB_PUBLIC_DOMAIN).
- БД (postgres:17.6, контейнер remnawave-db) и кэш (valkey/valkey:9-alpine, контейнер remnawave-redis): оба только во внутренней docker-сети.
- Нода (remnawave/node) это отдельный сервер: здесь крутится Xray и идёт трафик. Минимум одна.
📖 Незнакомые слова? Термины простыми словами смотрите в Словаре терминов.
ℹ️ Отдельного контейнера
remnawave/subscription-page(порт3010) в дефолтном prod-compose нет: подписку отдаёт сам backend. Этот контейнер ставят опционально и отдельно, только если нужна своя кастомная/ребренд-страница подписки (см. «Подписка → кастомная страница»).
Главное правило безопасности: всё, кроме ноды, слушает только 127.0.0.1; наружу пускайте строго через reverse-proxy с TLS (шифрование HTTPS, тот самый «замочек» в браузере). Это не совет: backend силой отбивает прямой HTTP (ProxyCheckMiddleware: Reverse proxy and HTTPS are required): без прокси с X-Forwarded-Proto: https панель не отвечает вообще. Подробнее читайте в статье «Безопасность».
🚀 Не хочется ставить руками? Всё из этой статьи (панель Remnawave, ноды, сертификаты, базовая защита) MultiScript разворачивает в пару кликов, без терминала. Подробнее: «О MultiScript».
Установка панели (docker compose)
curl -fsSL https://get.docker.com | sh
mkdir /opt/remnawave && cd /opt/remnawave
curl -o docker-compose.yml https://raw.githubusercontent.com/remnawave/backend/refs/heads/main/docker-compose-prod.yml
curl -o .env https://raw.githubusercontent.com/remnawave/backend/refs/heads/main/.env.sample
# секреты (команды из офиц. доков)
sed -i "s/^JWT_AUTH_SECRET=.*/JWT_AUTH_SECRET=$(openssl rand -hex 64)/" .env
sed -i "s/^JWT_API_TOKENS_SECRET=.*/JWT_API_TOKENS_SECRET=$(openssl rand -hex 64)/" .env
pw=$(openssl rand -hex 24); sed -i "s/^POSTGRES_PASSWORD=.*/POSTGRES_PASSWORD=$pw/" .env
sed -i "s|^\(DATABASE_URL=\"postgresql://postgres:\)[^@]*\(@.*\)|\1$pw\2|" .env
docker compose up -d && docker compose logs -f -t
✅ Проверено на живой установке (июнь 2026, xray-стек, бокс 1 ГБ RAM): обе ссылки (
docker-compose-prod.yml,.env.sample) скачиваются; команды-секреты применяются как есть;docker compose up -dподнимает 3 контейнера:remnawave+remnawave-db(postgres:17.6, healthy) +remnawave-redis(valkey, healthy). Панель за reverse-proxy отдаёт UI (<title>Remnawave</title>, HTTP 200) иGET /api/auth/status→{"isRegisterAllowed":true,"isLoginAllowed":false}(т.е. админа ещё нет, регистрируйтесь первым). Влезает в 1 ГБ + swap (≈660 МБ RAM + ~280 МБ swap), но для запаса берите 2 ГБ RAM: на 1 ГБ старт идёт со свопом и без swap-файла словите OOM.
Ключевые переменные .env: FRONT_END_DOMAIN (домен панели), SUB_PUBLIC_DOMAIN (домен подписки, без схемы, по умолчанию <домен>/api/sub), APP_PORT (3000), METRICS_PORT (3001), SHORT_UUID_LENGTH (длина короткого id подписки, 16–64).
⚠️ Изменили
.env→ нужен полный пересоздать:docker compose down && docker compose up -d(обычный restart не перечитывает env).
Суперадмин в .env НЕ задаётся: первый зарегистрировавшийся на домене панели становится супер-админом. Зарегистрируйтесь сразу после старта (иначе кто угодно успеет, это захват панели).
Reverse-proxy (nginx/caddy) обязателен и проксирует всё на 127.0.0.1:3000: UI, API и подписку (/api/sub/...), один домен на всё. Поддомены только в корне (subpath не поддерживается). Caddy сам выдаёт TLS:
panel.example.com {
reverse_proxy 127.0.0.1:3000
}
Для nginx то же самое, но обязательно прокидывайте X-Forwarded-Proto https, иначе панель отобьёт запрос (ProxyCheckMiddleware):
server {
listen 443 ssl http2;
server_name panel.example.com;
# ssl_certificate / ssl_certificate_key — ваш серт (Let's Encrypt)
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https; # ← без этого: "Reverse proxy and HTTPS are required"
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
(Опц.) для своей ребренд-страницы подписки добавьте контейнер
remnawave/subscription-pageи отдельный location/домен на127.0.0.1:3010. В дефолтной установке это не нужно: backend отдаёт подписку сам.
Цепочка, которую надо понять
Config Profile → Inbound → Host → Squad → пользователь
(xray-конфиг) (слушатель) (что видит (тариф/ (подписка)
клиент) доступ)
- Config Profile = полный Xray-JSON для ноды (все inbounds + настройки). Можно «Load from GitHub» (готовый VLESS Reality) и доработать.
- Inbound = один слушатель в профиле (VLESS Reality и т.п.). Нода использует ровно один профиль, в нём отмечаете, какие inbounds на ней включены.
- Host = то, что видит клиент: Remark (имя), Address (куда коннектиться), Port (берётся из inbound), один связанный Inbound, видимость, и Advanced (override SNI/ALPN/fingerprint/path).
- Squad (internal) = тариф/доступ: какие inbounds доступны участникам. Юзер ↔ сквады многие-ко-многим.
Ключевая грабля: создать профиль, включить inbound на ноде и добавить host: этого мало. Пока inbound не добавлен в сквад пользователя, он его не увидит. Доступ = (inbounds в сквадах юзера) ∩ (inbounds на нодах) ∩ (видимые хосты).
Подключение ноды
- На сервере ноды нужен Docker.
- В панели: Nodes → Create new node: имя, страна, Address, Port (=
NODE_PORTноды, дефолт2222), выбрать Config Profile и галочки inbounds. Панель покажет «Important information»: ключ. - Кнопка Copy docker-compose.yml в карточке: там уже подставлены
NODE_PORTиSECRET_KEY. На ноде:
services:
remnanode:
image: remnawave/node:latest
network_mode: host
cap_add: [NET_ADMIN]
restart: always
environment:
- NODE_PORT=2222
- SECRET_KEY=КЛЮЧ_ИЗ_ПАНЕЛИ
docker compose up -d → в панели нода станет online. Панель сама пушит Xray-JSON на ноду (профиль+inbounds) по NODE_PORT, авторизуясь SECRET_KEY.
Легаси-переменные
APP_PORT/SSL_CERTпереименованы вNODE_PORT/SECRET_KEY(мигрируют автоматически при обновлении). Для Reality сертификаты не нужны; для TLS-инбаундов монтируйте серты в панель: она доставит их на ноду.
.env ноды, это её единственный пароль к панели, никому не показывайте.
NODE_PORT и запушила Xray-конфиг. Видно нагрузку CPU, скорость и версию ядра каждой ноды.
Тарифы = сквады (наша схема)
Тарифы = internal-сквады, доступ задаётся набором inbounds в скваде: - Lite: 1 нода. - Pro: все ноды без обхода глушилок. - Maximum: всё + обход глушилок + «Автовыбор». - Reserve+: только обход глушилок. - Family: то же, что Maximum, но на 5 устройств вместо одного.
Апгрейд юзера = добавить его в нужный сквад (можно состоять в нескольких). Лимит устройств задаёт hwidDeviceLimit: у обычных тарифов 1, у Family 5.
Подписка
- URL:
https://<SUB_PUBLIC_DOMAIN>/<shortUuid>. Один и тот же URL отдаёт страницу в браузере и конфиг клиенту (определяет по запросу). - Форматы/ядра: base64 (v2ray-список), xray-json, sing-box, mihomo (наследник Clash). В Clash/Mihomo-шаблоне есть плейсхолдер
$payload$: туда движок вставляет список прокси. - Несколько шаблонов на ядро (2.2.0+): кому какой, рулится External Squads/Routing Rules.
- Каждый видимый Host = один сервер в подписке (база клиентского балансинга, см. «Балансировщики»).
- На юзера:
expireAt(срок),trafficLimit(ГБ), стратегия сбросаDAY/WEEK/MONTH/NO_RESET. Вебхуки об окончании приходят за N дней.
API (для бота)
- REST, база
/api, на домене панели. Авторизация:Authorization: Bearer <token>(токены выдаются в дашборде «API Tokens»). - Создать юзера:
POST /api/usersс параметрамиusername,expireAt,trafficLimit(байты),trafficLimitStrategy,activeInternalSquads(массив UUID сквадов), опц.telegramId,hwidDeviceLimit. В ответе приходитsubscriptionUrl. - Обновить:
PATCH /api/users(поuuid); сброс трафика, enable/disable/delete. Сквады обновляются черезactiveInternalSquads.Точные подпути/регистр полей могут отличаться по минорной версии, поэтому сверяйтесь с живым Swagger (
/docs, включаетсяIS_DOCS_ENABLED=true, в проде держать выключенным/под доступом).
Безопасные правки в проде (наш опыт)
- Переименование профиля/ноды через прямой
UPDATE ... SET name=...в БД безопасно: имя не входит в xray-конфиг, связки и подключение не рвутся. - Правка inbound через UI/API
PATCH /api/config-profilesпересоздаёт inbounds → новые UUID → рвёт связки node↔inbound и squad↔inbound. In-place правка полей realitySettings (target/serverNames) UUID сохраняет; а добавление/удаление inbound их ломает. Всегда бэкап БД до правок (pg_dump).
Бэкап (обязательно)
cd /opt/remnawave
docker compose exec -T remnawave-db pg_dump -U postgres postgres > backup-$(date +%F).sql
tar czf conf-$(date +%F).tgz .env docker-compose.yml
Храните вне сервера. Нет бэкапа БД = потеря всех клиентов.
Дальше: протоколы, каскад, балансировщики, обход блокировок и безопасность.