Содержание

Установка панели

На этой странице

Установка использует готовые GitHub Releases. Rust, Git, Node.js и Docker на сервере клиента не нужны. Установщик настраивает PostgreSQL, панель, сервис подписок при совместном размещении, фоновые задачи, Telegram-бот (если указан токен) и Caddy с автоматическим HTTPS.

Подготовьте сервер

  • Debian 12 / 13 или Ubuntu 22.04 / 24.04 / 26.04 LTS; systemd; архитектура amd64 или arm64.
  • Рекомендуются 2 vCPU, 2 ГБ RAM и 10 ГБ свободного диска. Установщик остановится при памяти меньше 1 ГБ или свободном месте меньше 3 ГБ.
  • Доступ root по SSH. Существующая установка и её база не перезаписываются.
  • Два разных домена: для панели и подписок. A/AAAA направляются на сервер, где размещается соответствующий сервис. Для отдельной подписки её DNS можно настроить после установки панели.
  • В firewall провайдера откройте TCP 80 и 443. SSH оставьте доступным. Порты PostgreSQL 5432 и служб 8080/8081 остаются локальными. Активный UFW получит только правила для 80/443; остальные правила сохраняются.

Клиентский кабинет и Mini App устанавливаются из админки после запуска панели. До установки кабинета Mini App показывает страницу с объяснением, а не работает через панель напрямую. Ноды устанавливаются отдельно из раздела «Ноды».

Установка через GitHub

На чистом Debian/Ubuntu войдите по SSH как root и выполните:

apt-get update
apt-get install -y git curl ca-certificates
git clone --branch v0.2.6 --depth 1 https://github.com/STEALTHNET-APP/STEALTHNET-SOFTWARE.git /root/stealthnet-installer
cd /root/stealthnet-installer
bash install.sh --version v0.2.6

Откроется мастер: укажите домены панели и подписки, название сервиса, валюту и данные владельца. Установщик сам скачает готовый релиз для архитектуры сервера, проверит SHA256 и установит PostgreSQL, системные службы и HTTPS. Компилировать Rust не требуется.

Репозиторий загрузится в /root/stealthnet-installer, а рабочая панель установится в /opt/stealthnet-software. Обновлять установленную панель затем нужно командой make update из её рабочего каталога.

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

В начале выберите 1 — на этом сервере или 2 — на отдельном сервере.

  • На этом сервере: оба домена направляются на IP панели. Мастер устанавливает sn-sub, настраивает HTTPS и проверяет подписку.
  • На отдельном сервере: на IP панели направляется только её домен. Домен подписки сохранится для клиентских ссылок; его DNS можно настроить позже на IP второй машины. Мастер не устанавливает локальный sn-sub, не создаёт для него сайт Caddy и не ждёт готовности удалённой подписки.
Поле Пример и пояснение
Домен панели panel.example.com — вход администратора; DNS A/AAAA на IP сервера панели
Домен подписки sub.example.com — адрес подключения клиентов; отдельный домен на IP выбранного сервера подписки, без /ID
Название сервиса My VPN — название, которое увидят клиенты
Валюта проекта USD, EUR, RUB, UAH — код из трёх латинских букв для цен и баланса; не сумма и не символ $. Stars настраиваются отдельно

Можно вставить адрес вида https://panel.example.com/: мастер выделит домен. Путь, порт, параметры или логин в адресе не принимаются. При ошибке домена или валюты поле запрашивается повторно; уже введённые ответы сохраняются.

После установки панели для отдельного сервера откройте Настройки → Сервис подписки → Установка → На отдельном сервере, выпустите служебный ключ и выполните команду на второй машине. Затем настройте там DNS/HTTPS и проверьте /ready и реальную ссылку клиента. До этого подписка ещё не готова. Полная инструкция.

Выбор сохраняется в installation.json: обновление и stealthnet doctor проверяют только размещённые на панели службы. Обновление отдельной подписки выполняется на её сервере. В установках прежних версий отсутствие выбора означает прежнее размещение вместе с панелью.

Одна команда

Войдите на сервер по SSH как root и выполните:

bash -c 'set -e; apt-get update -qq; apt-get install -y --no-install-recommends curl ca-certificates; sn_file=$(mktemp); trap '\''rm -f "$sn_file"'\'' EXIT; curl --proto "=https" --proto-redir "=https" --tlsv1.2 -fsSL https://raw.githubusercontent.com/STEALTHNET-APP/STEALTHNET-SOFTWARE/main/install.sh -o "$sn_file"; bash "$sn_file"'

Более короткий вариант, когда curl уже установлен:

curl --proto '=https' --proto-redir '=https' --tlsv1.2 -fsSL https://raw.githubusercontent.com/STEALTHNET-APP/STEALTHNET-SOFTWARE/main/install.sh -o /root/stealthnet-install.sh
bash /root/stealthnet-install.sh

Мастер попросит домены, название сервиса, валюту проекта, логин и пароль владельца. Пустой пароль означает генерацию случайного пароля. Токен Telegram можно пропустить и добавить позже. Пароли и токены не выводятся при вводе и не передаются в аргументах процессов.

Загрузчик определяет архитектуру и тег последнего стабильного релиза, скачивает архив и его SHA256 по HTTPS, проверяет архив и каждый файл из манифеста. Изменённый архив, чужая архитектура, неполный релиз или отсутствие контрольной суммы останавливают установку.

После подготовки базы применяются все миграции по порядку. Демо-клиенты, тарифы и платёжные реквизиты не создаются. Валюта и название берутся из вашего ввода. Службы работают от отдельного пользователя stealthnet; база и ключи доступны только root через файл окружения systemd.

Успешное завершение означает, что API ответил с рабочей базой, службы панели запущены и её HTTPS-домен проверен с проверкой сертификата. При совместном размещении также проверяются /ready и HTTPS подписки; отдельный сервис проверяется после его установки на второй машине. Если сертификат не выпущен, установщик сообщает ошибку, а не готовность.

Данные владельца находятся в /root/stealthnet-access.txt, права 600. Сохраните их в менеджере паролей и удалите этот файл. Он не публикуется через веб-сервер.

После установки

stealthnet doctor                  # релиз, службы, API, база, подписки и HTTPS
stealthnet status                  # состояние служб (бот без токена будет отключён)
stealthnet logs api                # журнал API, также sub / worker / bot
stealthnet bot-token               # добавить/заменить токен бота скрытым вводом
stealthnet admin-password          # сменить пароль существующего администратора

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

Быстрое обновление

На сервере панели от root:

cd /opt/stealthnet-software
make update

То же из любой папки:

stealthnet update

Конкретный опубликованный релиз:

make update VERSION=v0.2.6
# или
stealthnet update --version v0.2.6

Для конкретной версии используйте тег опубликованного релиза.

Обновление проверяет файлы, создаёт PostgreSQL dump и копию конфигурации, применяет миграции, атомарно переключает current, перезапускает службы панели и проверяет их. Ноды и их Xray не перезапускаются. Их обновление выполняется отдельно из раздела нод. Кабинет и отдельный сервис подписок обновляются своими командами.

Верхняя кнопка версии в админке открывает сведения о сборке и проверку GitHub. Проверка выполняется на сервере панели, результат сохраняется на 15 минут; ошибка — на одну минуту. Публикуемые стабильные релизы должны содержать готовые архивы обеих архитектур с SHA256. Страница различает новую версию, актуальную сборку, сборку новее GitHub, отсутствие релизов и ошибку связи. Описание релиза показывается текстом без исполнения HTML.

Резервные копии: /opt/stealthnet-software/backups/<дата-UTC>/. При ошибке запуска новой версии возвращаются прежние бинарники. Уже применённые миграции автоматически не отменяются. Релизы должны использовать обратно совместимые миграции. Восстановление БД из dump — отдельная операция в окно обслуживания: оно отменяет изменения данных после момента копии.

Если установка оборвалась

Панель открылась без оформления

В релизах до 0.1.7 правило Caddy /app* могло возвращать заглушку Mini App вместо /app.css. Браузер сообщал MIME type ('text/html') is not a supported stylesheet. Обновите установленную панель от root:

cd /opt/stealthnet-software
make update VERSION=v0.2.6

Обновление создаёт резервную копию и исправляет старое правило в конфигурации, созданной установщиком, сохраняя остальные настройки. После обновления перезагрузите страницу с очисткой кэша (Ctrl+F5 / Cmd+Shift+R). Для своего reverse proxy используйте пути /app и /app/*, без перехвата /app.css. Новые установки и обновления проверяют тип и содержимое основного CSS и JavaScript перед сообщением об успехе. Страница входа показывает версию API без надписи «стенд».

Диагностика незавершённой установки

Журнал: /var/log/stealthnet/install-<дата>.log. Он доступен только root и скрывает введённые секреты. Журналы служб: journalctl -u sn-api -n 100, journalctl -u sn-sub -n 100, journalctl -u caddy -n 100.

Исправьте причину и повторите ту же команду. Незавершённая установка использует сохранённые параметры и ключи, повторно проверяет миграции и запуск. Не удаляйте .env или .install-pending.json, чтобы «начать заново»: они связывают настройку с уже созданной базой. Повторный запуск на готовой панели предлагает обновление, а не создаёт владельца заново.

Частые причины:

Ошибка Что проверить
Нет релиза / HTTP 404 Опубликован ли стабильный GitHub Release, правильный ли тег. Черновики недоступны клиентам.
SHA256 не совпадает Повторить загрузку; если повторяется — проверить файлы релиза. Не отключать проверку.
Нет DNS-записи A/AAAA домена панели; при совместном размещении — также домена подписки. Дождитесь распространения DNS.
HTTPS не проходит IP в DNS, неверная AAAA, TCP 80/443 в firewall провайдера, журнал Caddy, лимиты ACME.
Порт занят Другой сервис на 80/443 или 8080/8081; мастер не выключает его автоматически.
База/роль уже есть Возможно, это существующая установка. Её пароль не будет автоматически заменён.
apt заблокирован Дождаться unattended-upgrades и повторить команду; apt ожидает блокировку до 180 секунд.

Последний шаг остановился на HTTPS / URLError

Если ошибка появилась после строки «Проверяем HTTPS и сертификаты», локальные API, база и сервис подписок уже прошли проверку. Старые версии мастера показывают только URLError: это общий тип ошибки соединения, а не доказательство проблемы с сертификатом.

Выполните на сервере от root:

systemctl is-active caddy sn-api sn-sub
ss -lntp | grep -E ':(80|443|8080|8081)\b'
curl --connect-timeout 5 --max-time 10 -sS http://127.0.0.1:8080/api/health
journalctl -u caddy -n 50 --no-pager

Сверьте DNS домена панели с её публичным IP. При совместном размещении туда же должен вести домен подписки; для отдельной машины её домен проверяется на том сервере. Запись AAAA нужна только при работающем IPv6. Проверьте TCP 80/443 как в firewall сервера, так и в сетевых правилах провайдера; порты приложений 8080/8081 открывать наружу не нужно.

  • Connection refused / «соединение отклонено»: на выбранном IP и порту нет доступного слушателя либо соединение отклоняет firewall. Проверьте адрес, статус Caddy и список портов.
  • Timeout / «время ожидания»: проверьте адрес, маршрутизацию и блокировку трафика.
  • Ошибка сертификата: проверьте журнал Caddy, DNS, доступность портов для ACME и время сервера. Не отключайте проверку TLS.
  • HTTP 502: веб-сервер доступен, но не получает корректный ответ от приложения; проверьте локальный API и маршрут reverse proxy.

После исправления повторите команду установки той же версии. Установка, остановившаяся на шаге 7, ещё не считается завершённой: make update её не завершает. Сохраните .env, .install-pending.json и созданную базу — повторный запуск использует их.

Свой reverse proxy / автоматическая установка

Для уже настроенного nginx/Caddy или автоматизации создайте root-owned JSON с правами 600. Это режим для администратора инфраструктуры, обычному клиенту достаточно мастера.

Обязательные поля: panel_domain, sub_domain, brand, currency, admin_user, admin_password. Необязательные: bot_token (пустая строка отключает бот), proxy (caddy, по умолчанию, или external), subscription_placement (local, по умолчанию, или remote). Домен подписки остаётся обязательным в обоих вариантах: для отдельного сервера можно указать будущий домен без готового DNS. proxy выбирает управление HTTPS, а subscription_placement — сервер подписки; это разные настройки. Пароль: 12–128 символов. Конфигурацию передают файлом, не аргументами командной строки.

chmod 600 /root/install.json
bash /root/stealthnet-install.sh --config /root/install.json

В режиме external установщик не меняет веб-сервер и его firewall. Он проверяет только локальные службы, оставляет пример в /opt/stealthnet-software/Caddyfile.example и явно сообщает, что внешний HTTPS нужно настроить самостоятельно. Проксируйте панель со статикой из current/web, /api/* на 127.0.0.1:8080, подписки на 127.0.0.1:8081. Пути /app и /app/* должны отдавать miniapp-unavailable.html. Caddy-пример содержит эти правила и заголовки.

При закрытом доступе к GitHub можно перенести опубликованный архив и .sha256 по доверенному каналу, проверить sha256sum, безопасно распаковать и выполнить python3 <релиз>/deploy/installer.py install --release-dir <релиз> --config /root/install.json. При таком способе администратор отвечает за проверку внешней SHA256 до запуска; внутренний манифест проверяется установщиком.

Файлы на сервере

Путь Содержимое
/opt/stealthnet-software/.env База, ключ шифрования кодов, токены; root, 600
/opt/stealthnet-software/releases/<версия> Неизменяемые бинарники и статика
/opt/stealthnet-software/current Активный релиз
/opt/stealthnet-software/installation.json Версия и параметры установки без пароля
/var/lib/stealthnet Рабочий каталог служб
/etc/systemd/system/sn-*.service Службы api, sub, bot, worker
/etc/caddy/stealthnet/panel.caddy Домены панели и подписок; другие сайты Caddy сохраняются
/var/log/stealthnet Закрытые журналы установщика

Сохранение .env, особенно CABINET_CODE_KEY, обязательно для восстановления клиентских кодов. Вместе с дампом базы храните копию этого файла вне сервера.

Старые установки из исходников продолжают использовать deploy/update-source.sh через корневой update.sh. Этот режим пересобирает уже загруженные исходники и не переводит существующий стенд на релизную структуру автоматически.

Что сохраняется при обновлении

make update меняет готовый код и применяет новые миграции один раз. Пользователи, подписки, платежи, тарифы, профили, брендинг и тексты находятся в PostgreSQL; обновление не запускает db/seed.sql и не создаёт владельца заново. .env и ключ CABINET_CODE_KEY сохраняются без изменения. Текущая конфигурация reverse proxy и дополнительные настройки systemd при обновлении не переписываются.

Свои изображения размещайте в /opt/stealthnet-software/shared/public/, например logo.svg. При стандартной установке Caddy файл доступен как https://panel.example.com/custom/logo.svg; этот адрес можно указать в брендинге админки. Содержимое shared/ не заменяется релизом и входит в резервную копию обновления. Это публичный каталог: ключи и конфигурационные файлы туда не кладут. Для внешнего прокси настройте аналогичный маршрут /custom/.

Каталоги releases/ и current/web содержат код конкретной версии: свои файлы и ручные правки туда не помещайте. Правки исходников и CSS внутри релиза не являются настройками брендинга. Старый релиз остаётся на диске; при ошибке готовности установщик возвращает прежние бинарники. Возврат бинарников не отменяет применённые миграции; для отката данных используется сохранённый dump.

Владелец и сотрудники

Ошибка «Нет терминала» до вопросов установки

В старом мастере терминал SSH ошибочно открывался как файл с возможностью перемотки. В версии 0.1.6 это исправлено. Если установка остановилась сразу после проверки SHA256 с сообщением «Нет терминала», повторно запустите загрузчик без закрепления старой версии. Файл install.json для обычного интерактивного запуска не нужен; на этом этапе база и учётная запись владельца ещё не создавались.

При запуске через удалённую команду SSH без терминала используйте интерактивный сеанс ssh -t root@SERVER_IP или настройку через --config, описанную выше.

Поиск по документации

СодержаниеВсе категории