Skip to content

About

Мониторинг VPS, панелей и VPN в Telegram | VPS, panel and VPN monitoring in Telegram

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

StackSentry

Мониторинг VPS, панелей и VPN в Telegram.

CI Python Platform License

Русский · English

StackSentry это Telegram-бот для VPS. Он следит за железом, службами, панелями (3X-UI, Marzban, Marzneshin, PasarGuard, Remnawave, S-UI, Hiddify, Outline) и VPN (WireGuard, OpenVPN, AmneziaWG, sing-box, Xray, Shadowsocks, Tailscale), присылает алерты и показывает подписки. Опасные действия (рестарт, обновление системы, перезагрузка) выполняются только по кнопке с подтверждением и только администратором.

Текущая версия: 1.1.3. Проект публичный: документация, политика безопасности. Проверку обновлений можно запустить кнопкой «Проверить обновления» в боте, в разделе «Помощь» Mini App или через sudo stacksentry-menu update-check; она идёт по ветке main. Обновление работает из main без ручной настройки. Для дополнительной защиты можно задать UPDATE_SHA256 в /etc/stacksentry.conf, тогда архив проверяется по пину. GitHub Releases проект не публикует.

Установка одной командой:

bash <(curl -Ls https://raw.githubusercontent.com/Hijackery/stacksentry/main/install.sh)

Альтернативы без curl | bash:

# скачать и проверить установщик отдельно
curl -fsSLo /tmp/stacksentry-install.sh \
  https://raw.githubusercontent.com/Hijackery/stacksentry/main/install.sh
sudo bash /tmp/stacksentry-install.sh

# GitHub CLI
gh api repos/Hijackery/stacksentry/contents/install.sh \
  -H "Accept: application/vnd.github.raw" > /tmp/stacksentry-install.sh
sudo bash /tmp/stacksentry-install.sh

# приватный форк или корпоративный GitHub с токеном
GH_TOKEN=... bash -c 'curl -fsSL -H "Authorization: Bearer $GH_TOKEN" \
  https://raw.githubusercontent.com/Hijackery/stacksentry/main/install.sh | bash'

Мастер скачает код, спросит токены, поставит зависимости, создаст отдельного пользователя, включит автозапуск и проверит, что всё работает.

Содержание

  1. Зачем это нужно
  2. Как это выглядит
  3. Совместимость
  4. Быстрый старт
  5. Подключение к панели
  6. Как устроено
  7. Команды и экраны
  8. Меню настроек stacksentry-menu
  9. Настройки
  10. Безопасность
  11. Обновление и удаление
  12. Если что-то не работает
  13. Документация
  14. Версии и обновление
  15. Разработка
  16. Проект

Зачем это нужно

Панели и VPN показывают состояние, но в них нужно заходить. Бот приносит самое важное в Telegram и не мешает, когда всё в порядке.

Мониторинг CPU, RAM, swap, диск, сеть, load; службы; панель и ядро; стек панелей/VPN; пользователи, подписки и трафик
Панели API 3X-UI, Marzban, Marzneshin, PasarGuard, Remnawave, S-UI, Hiddify, Outline; остальные: детект службы/порта/процесса
Алерты гистерезис без «дребезга», кулдаун, мьют «знаю, до утра»; под алертом сразу «Рестарт» и «Журнал»
Действия рестарт службы и ядра панели, обновления пакетов, релиз-обновление ОС (APT), перезагрузка, безопасные команды
Обновления проверка main; установка с подтверждением и 2FA, опциональный пин UPDATE_SHA256; без GitHub Releases
История почасовые средние CPU/RAM/диска за 24 часа, 7 или 30 дней; p95 и пики
Установка одна команда, адаптивный мастер по ОС/службам/панели, неинтерактивный режим, самопроверка
Универсальность systemd, OpenRC, SysVinit; apt/dnf/yum/zypper/pacman/apk/xbps/emerge/eopkg/pkg; Python 3.10+
Mini App read-only панель в Telegram: обзор, службы, панель, трафик, подписки, история, терминал и встроенная «Помощь»; вход по Telegram (+ TOTP, если 2FA включена)
Терминал stacksentry-menu: настройки, диагностика, рестарт, журнал, обновление; секреты маскируются
Безопасность отдельный непривилегированный пользователь, узкий sudoers, подтверждение и аудит опасных действий

Как это выглядит

Сводка начинается с вердикта: ночью достаточно одного взгляда:

🟢 Состояние сервера: всё в норме · CPU 12% · RAM 41% · Диск 63% · x-ui 🟢 · панель 🟢

CPU  ▓▓░░░░░░░░  12.0% 🟢
RAM  ▓▓▓▓░░░░░░  41.0% 🟢
Диск ▓▓▓▓▓▓░░░░  63.0% 🟢

Алерт с причиной и действиями:

🔴 КРИТИЧНО · Сервис x-ui не работает · 03:12
Статус failed, SubState failed

[♻️ Рестарт x-ui] [📜 Журнал x-ui]
[📊 Текущее состояние] [🏠 В меню]
[😴 Знаю, до утра]

Результат действия с кодом возврата и контекстной кнопкой:

✅ x-ui перезапущен за 1.2 с
Сервис x-ui перезапущен
[📜 Журнал x-ui] [🏠 В меню]

Совместимость

Что Поддержка
Службы systemd (Debian/Ubuntu, RHEL/Rocky/Alma, Fedora, openSUSE, Arch), OpenRC (Alpine, Gentoo), SysVinit
Пакеты apt, dnf, yum, zypper, pacman, apk, xbps, emerge, eopkg, pkg: определяются автоматически
Python 3.10 и новее; установщик подбирает интерпретатор сам
Панели API: 3X-UI, Marzban, Marzneshin, PasarGuard, Remnawave, S-UI, Hiddify, Outline. Остальные VPN/прокси: детект и мониторинг службы/порта/процесса
Рестарт ядра 3X-UI, Marzban, Marzneshin, PasarGuard, S-UI через API; Remnawave/Hiddify/Outline только через службу/контейнер
sudo классический sudo и sudo-rs (Ubuntu 26.04+): правила генерируются без шаблонов и алиасов
Архитектуры x86_64, ARM: всё, где есть Python и поддерживаемая инициализация

Выбрать менеджер служб вручную можно через --init systemd|openrc|sysv. Если systemd нет, бот работает так же: журнал читается из bot.log, а состояние служб помечается как недоступное (без ложных «crit»).

Быстрый старт

1. Что понадобится

  • сервер с Linux (любой поддерживаемый дистрибутив) и, по желанию, панелью;
  • токен Telegram-бота от @BotFather;
  • ваш numeric ID (например, @userinfobot);
  • доступ к панели: токен (3X-UI/Remnawave/S-UI/Hiddify), логин/пароль (Marzban/Marzneshin/PasarGuard) или секретный путь (Outline). Полная матрица в docs/COMPATIBILITY.md.

2. Установка

Установка одной командой:

bash <(curl -Ls https://raw.githubusercontent.com/Hijackery/stacksentry/main/install.sh)

Альтернативы без curl | bash:

# скачать и проверить установщик отдельно
curl -fsSLo /tmp/stacksentry-install.sh \
  https://raw.githubusercontent.com/Hijackery/stacksentry/main/install.sh
sudo bash /tmp/stacksentry-install.sh

# GitHub CLI
gh api repos/Hijackery/stacksentry/contents/install.sh \
  -H "Accept: application/vnd.github.raw" > /tmp/stacksentry-install.sh
sudo bash /tmp/stacksentry-install.sh

# приватный форк или корпоративный GitHub с токеном
GH_TOKEN=... bash -c 'curl -fsSL -H "Authorization: Bearer $GH_TOKEN" \
  https://raw.githubusercontent.com/Hijackery/stacksentry/main/install.sh | bash'

Или через пайп (так можно с sudo):

curl -fsSL https://raw.githubusercontent.com/Hijackery/stacksentry/main/install.sh | sudo bash

Не добавляйте sudo к форме bash <(curl …): sudo закрывает файловый дескриптор process substitution, и bash отвечает bash: /dev/fd/63: No such file or directory. Либо запускайте bash <(…) уже от root (без sudo), либо используйте пайп curl … | sudo bash.

Мастер задаёт вопросы четвёртым шагом, до установки зависимостей, поэтому отвечать нужно в начале. Вопросы читаются с терминала (/dev/tty), так что диалог работает и при установке через пайп.

Что спросит мастер:

  1. токен бота и ID администраторов (токен сразу проверяется через Telegram);
  2. 2FA (TOTP) опционально: при включении код нужен для входа в Mini App и опасных действий, при отказе TOTP не используется;
  3. адрес панели, webBasePath и API-токен (адрес проверяется);
  4. список служб под наблюдением;
  5. необязательный чат для алертов;
  6. для Mini App HTTPS настраивается автоматически (sslip.io + Caddy); для терминала можно указать свой адрес или оставить SSH-туннель.

Mini App, терминал, root-сессия и 2FA ставятся этой же командой. Отдельный install.sh --terminal ... после установки не нужен.

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

sudo stacksentry-menu          # меню: состояние, настройки, рестарт, журнал, обновление
systemctl status stacksentry-bot

Откройте бота в Telegram, нажмите /start → /status. Если что-то не так, бот сам скажет, что именно. /version покажет версию, ОС, пакетный менеджер и выбранную панель; /stack показывает, что найдено на сервере. Mini App и терминал уже установлены: если при установке вы указали публичные HTTPS-адреса, рядом со скрепкой появится кнопка «Панель», а в главном меню появятся «📱 Открыть Mini App» и вкладка «Терминал». Останется только один раз привязать домен: @BotFather → /setdomain (без https://). Это требование Telegram, API для этого шага нет.

Неинтерактивная установка

Для автоматизации и повторной установки: --yes не задаёт вопросы, а берёт значения из переменных окружения или уже готового .env. Если .env полный, он сохраняется как есть; недостающие значения можно передать заранее. Полный набор в unattended-режиме включается явно: --webapp --webapp-origin https://... --terminal --root-terminal --terminal-origin https://....

sudo env \
  TELEGRAM_BOT_TOKEN='123456789:AA...' \
  TELEGRAM_ADMIN_IDS='11111111' \
  PANEL_TYPE='3x-ui' \
  PANEL_URL='https://panel.example.com:2053' \
  PANEL_API_TOKEN='...' \
  bash install.sh --yes

Для Marzban/Marzneshin/PasarGuard вместо токена передайте PANEL_USERNAME и PANEL_PASSWORD; для Outline только PANEL_URL с секретным путём. PANEL_TYPE можно не указывать, мастер возьмёт найденный тип или 3x-ui. Полный список типов и доступов приведён в docs/COMPATIBILITY.md.

Полезные опции: --repo owner/name, --ref ветка, --prefix DIR, --user NAME, --no-start, --force-config, --print-source, --sha256 HASH, --init TYPE, --webapp --webapp-origin https://..., --terminal, --root-terminal, --2fa, --menu. Полный список: bash install.sh --help.

Повторный запуск установщика обновляет код и сохраняет .env/состояние; для проверки обновлений из бота есть /updatecheck, кнопка в «Помощи» и раздел «Помощь» в Mini App. Самообновление работает из main сразу. Если в /etc/stacksentry.conf задан UPDATE_SHA256, архив дополнительно проверяется по этому пину.

Подключение к панели

API панелей

Панель Авторизация Что даёт
3X-UI 2.x/3.x Bearer API token статус, inbound'ы, подписки, трафик, рестарт xray
Marzban PANEL_USERNAME + PANEL_PASSWORD (OAuth2) статус, пользователи, трафик, рестарт xray
Remnawave Bearer API token статус, пользователи, трафик
Marzneshin логин/пароль (OAuth2 /api/admins/token) статус, пользователи, трафик, рестарт backend через переприменение конфига
PasarGuard логин/пароль (OAuth2 /api/admin/token) статус, пользователи, трафик, рестарт core
S-UI PANEL_API_TOKEN в заголовке Token статус, клиенты, трафик, рестарт sing-box
Hiddify PANEL_API_TOKEN (admin UUID) в Hiddify-API-Key статус, пользователи, трафик
Outline секретный путь SB_API_PREFIX в PANEL_URL статус, access keys, трафик

Переключение: sudo stacksentry-menu set PANEL_TYPE s-ui (и адрес/токен), затем рестарт. Для 3X-UI/Remnawave/S-UI/Hiddify используется PANEL_API_TOKEN, для Marzban логин и пароль.

Особенности адресов:

  • S-UI: PANEL_URL указывает на корень панели вместе с её web path, например http://host:2095/app; бот сам добавит /apiv2/.
  • Hiddify: PANEL_URL указывает на корень вместе с admin proxy path, например https://example.com/AbCdEf; бот сам добавит /api/v2/.
  • Outline: PANEL_URL содержит полный адрес с секретным SB_API_PREFIX, например https://host:port/SecretPath; отдельный токен не нужен.
  • 3X-UI: PANEL_BASE_PATH это webBasePath панели; /panel/api добавит бот.

Установщик, меню и бот подстраиваются под сервер. Мастер определяет ОС, пакетный менеджер, службы и тип панели, затем спрашивает только нужное: токен для 3X-UI/Remnawave/S-UI/Hiddify, логин/пароль для Marzban/Marzneshin/PasarGuard или секретный путь для Outline, с проверкой API. stacksentry-menu detect показывает найденное, в меню есть пункт «Тип панели», а рестарт ядра сам выбирает endpoint. Главное меню бота не показывает «Трафик»/«Подписки», пока API не настроен, и показывает команды обновления для фактического пакетного менеджера (APT-специфичные только на APT).

Что детектируется

Панели: 3X-UI, S-UI, Marzban, Marzneshin, PasarGuard, Hiddify, Remnawave, Outline. Прокси/ядра: Xray, V2Ray, sing-box, Hysteria, TUIC, Trojan, NaiveProxy, Mieru, ShadowTLS, Brook, mtg, Shadowsocks, Squid, Dante, 3proxy, GOST. VPN/mesh: WireGuard, AmneziaWG, OpenVPN, IPsec/StrongSwan, SoftEther, Tailscale, ZeroTier, NetBird, Headscale, Nebula.

Определение идёт по юнитам (systemd/OpenRC/SysV), путям конфигов и именам процессов (ps). API-интеграция есть у 3X-UI (inbound'ы, подписки, рестарт xray), Marzban, Marzneshin, PasarGuard, Remnawave, S-UI, Hiddify и Outline (пользователи/клиенты, трафик); остальные показываются как службы/порты и помечаются «API не поддерживается». Docker-контейнеры видны как служба docker, но не опрашиваются через Docker API (это дало бы боту root-эквивалентные права).

Если панели нет: monitor-only

Установщик сам находит панели/VPN по службам, путям и портам. Если поддерживаемая панель не найдена, можно оставить PANEL_URL и PANEL_API_TOKEN пустыми, бот будет наблюдать службы, VPN-стек, железо и алерты, а разделы панели/подписок скажут, что API не настроен. Позже включить API: sudo stacksentry-menu → адрес панели и токен (или переустановка с --panel).

Токен 3X-UI

Токен создаётся в самой панели, а не в Telegram и не в боте.

3X-UI v3.x

  1. «Настройки панели → Учётная запись → API-токен» → создать.
  2. Scope: node-sync (или admin).
  3. Скопируйте значение сразу: панель показывает его один раз, позже остаётся только отметка «задано».

То же по API: POST /panel/api/setting/apiTokens/create с name, scope, expiresAt (нужен уже существующий admin-токен).

3X-UI 2.x

«Настройки → API Tokens» либо из терминала:

sudo x-ui setting -getApiToken true -tokenName monitor-bot -tokenScope node-sync

В v3 эта команда новых токенов не создаёт, она лишь ротирует служебный cli-fallback.

Почему не monitor: этот scope даёт только статус панели. Для inbound'ов и подписок нужен node-sync, для действий в панели: admin.

webBasePath: частая ошибка

Поле webBasePath это отдельная настройка «URL панели» в 3X-UI. Обычно она равна /, и тогда поле в мастере оставляют пустым.

Путь /panel из адресной строки вводить не нужно: интерфейс 3X-UI всегда живёт на .../panel, а API на .../panel/api. Если вписать /panel в webBasePath, получится лишний сегмент .../panel/panel/api.

Установщик проверяет путь до запроса токена (верный путь без токена отвечает 401, неверный 404) и молча исправляет ошибку. Полный адрес, вставленный в это поле, он тоже распознаёт.

Проверка вручную

curl -s -o /dev/null -w '%{http_code}\n' \
  -H 'X-Requested-With: XMLHttpRequest' \
  https://panel.example.com:2053/panel/api/server/status

401 означает, что путь верный и нужен токен. С токеном:

curl -fsS -H "Authorization: Bearer <токен>" \
  https://panel.example.com:2053/panel/api/server/status

Ответ должен содержать "success":true.

Адрес: IP, домен, localhost

  • Если в панели задан «Домен панели» (webDomain), 3X-UI сверяет заголовок Host и отвечает 403 на всё остальное. Тогда в PANEL_URL должно быть ровно это имя, а не IP.
  • Имя должно резолвиться с самого сервера. Если домен указывает на публичный IP и обратного NAT нет, используйте http://127.0.0.1:2053 с тем же PANEL_BASE_PATH. IPv6 пишите в скобках: http://[::1]:2053.
  • http допустим, когда панель слушает localhost: трафик не выходит за пределы машины. Если панель доступна по публичному адресу, используйте только https://, иначе токен и содержимое API идут открытым текстом. Для самоподписанного сертификата не отключайте проверку, а укажите PANEL_CA_BUNDLE.
  • Бот не следует редиректам: если http перенаправляет на https, просто поменяйте схему.

Как устроено

Telegram / Mini App  ⇄  бот (непривилегированный пользователь stacksentry)
                          ├─ psutil / systemctl / journalctl: метрики и службы
                          ├─ inventory: ОС, пакеты, панели, VPN
                          ├─ API панели (8 типов): пользователи, трафик, рестарт ядра
                          ├─ updates: проверка main; установка по pinned SHA
                          └─ sudo stacksentry-ctl (узкий sudoers): рестарт, обновления, reboot, журнал
  • Код: /opt/stacksentry, принадлежит root; бот не может переписать сам себя.
  • Секреты: .env с правами 640 root:stacksentry.
  • Состояние: SQLite в /var/lib/stacksentry (история, аудит, мьюты).
  • Привилегии: только через sudo stacksentry-ctl; список разрешённых подкоманд перечислен точно, без шаблонов.
  • Обновления: выполняются отдельным systemd-юнитом (stacksentry-apt-*.service), потому что бот живёт с ProtectSystem=strict; stacksentry-ctl сам определяет apt/dnf/yum/zypper/pacman/apk/ xbps/emerge/eopkg/pkg.
  • Self-update: установщик запускается отдельным юнитом из main, сохраняет .env и состояние и перезапускает бота; пин UPDATE_SHA256 опционален.
  • Mini App: отдельный read-only сервис на 127.0.0.1:8787 под собственным пользователем stacksentry-webapp; наружу только HTTPS-прокси, вход по Telegram initData.

Команды и экраны

Команда Что показывает
/status вердикт одной строкой, замечания, метрики, службы и панель
/traffic трафик: inbound'ы/клиенты или пользователи панели
/services состояние служб; рестарт и журнал рядом
/panel доступность панели и API, версия и обновления
/subs подписки: сроки, трафик, исчерпанные и отключённые
/history почасовые средние CPU/RAM/диска за сутки
/logs журнал выбранного сервиса, фильтр «только ошибки»
/audit журнал действий бота, фильтры «отказы / действия»
/stack что найдено на сервере: панели, VPN, прокси, службы
/maint обслуживание: обновления пакетов, перезагрузка, команда из allowlist
/run <команда> выполнить диагностическую команду из белого списка
/version версия StackSentry, Python, ОС, пакетный менеджер и панель
/updatecheck проверить обновления StackSentry в main
/help помощь простыми словами: что нажать и что значат цифры

Кнопки дублируют команды; на каждом экране есть «🏠 В меню», так что в тупике оказаться нельзя. Гостям кнопки не показываются. При переходе между меню предыдущий экран заменяется, поэтому вереница сообщений не копится (это не касается «Подробнее» и «Свернуть»: они разворачивают тот же экран).

Команду на сервер можно прислать в любом разделе. Отправьте её сообщением (или /run <команда>). Бот попросит подтверждение и вернёт вывод. Разрешены только безопасные диагностические команды из COMMAND_ALLOWLIST; список покажет /run без аргументов. Произвольный shell недоступен.

Обновления в /maint разделены и отчитываются в чат. Кнопка обновления индексов вызывает команду фактического пакетного менеджера (apt update, dnf makecache, pacman -Sy и т. п.); кнопка обновления системы запускает его штатный upgrade/full-upgrade. phased и «запустить релиз» (do-release-upgrade) доступны только на APT/Ubuntu и на других системах скрыты. Все фоновые задачи бот ведёт сам: когда юнит завершится, в чат придёт код возврата и хвост журнала, вводить journalctl не нужно. Одно действие даёт одно сообщение: «в очереди» → «запущено» → отчёт, без вереницы. Вручную журнал смотреть так: sudo stacksentry-menu apt-logs.

Безопасные команды для диагностики

/run <команда> (или текст в чате) запускает только команды из COMMAND_ALLOWLIST. Все они только читают и запускаются как argv без shell: ни pipes, ни перенаправлений, ни записи. Если команды нет в системе, бот скажет, что она не установлена.

Команда Что показывает
os_logs / os_errors журнал ОС: предупреждения / только ошибки (100 строк)
kernel_logs / dmesg сообщения ядра
xui_logs журнал службы x-ui
xui_service / x-ui status статус панели
failed_units упавшие systemd-юниты
sockets / net_summary слушающие порты / сводка сокетов
addresses / routes IP-адреса / маршруты
top_cpu процессы по CPU и памяти
uname / cpu_info / block_devices система, CPU, диски
log_size / inodes / df -h / free -h / uptime место и ресурсы
upgradable / upgrade_sim доступные обновления / симуляция apt
vmstat / time_status / logged_in / boot_time нагрузка, время, сеансы
journalctl --disk-usage / systemctl list-timers --all журнал и таймеры

Примеры: /run os_logs, /run failed_units, /run sockets. Команда /run без аргументов показывает этот список прямо в боте, с группами и описаниями. У логов (os_logs, xui_logs, kernel_logs, dmesg) под выводом есть кнопки «📜 Ещё 200 строк», «❌ Только ошибки» и «🔎 Поиск» по тексту, как у журналов служб.

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

/status начинается с вердикта, детали спрятаны за «📋 Подробнее». Метрики выровнены моноширинным блоком, время подписано «время сервера». Под алертом сразу есть ♻️ Рестарт, 📜 Журнал и 😴 Знаю, до утра, мьют на 8 часов, хранится в SQLite и переживает перезапуск.

Меню настроек stacksentry-menu

После установки доступна консольная панель:

sudo stacksentry-menu              # интерактивное меню
sudo stacksentry-menu show         # настройки (секреты замаскированы)
sudo stacksentry-menu keys         # какие ключи разрешено менять
stacksentry-menu check PANEL_TIMEOUT 20   # проверка без изменений (без root)
sudo stacksentry-menu set PANEL_TIMEOUT 20
sudo stacksentry-menu restart       # применить
sudo stacksentry-menu detect        # что найдено: ОС, панели, VPN, службы
sudo stacksentry-menu restart-xray  # перезапустить ядро (где поддерживается)
sudo stacksentry-menu apt-logs 100  # журнал фоновых apt-обновлений
sudo stacksentry-menu logs 100

Интерактивное меню рисуется в рамке и сгруппировано по разделам; сверху показано живое состояние службы:

╔════════════════════════════════════════════════════════╗
│        StackSentry: панель управления                 │
│  Служба stacksentry-bot: ● работает                    │
│   Диагностика                                          │
│    1. Состояние службы и последние ошибки              │
│    2. Показать настройки (секреты замаскированы)       │
│    3. Журнал бота (последние 50 строк)                 │
│    4. Что найдено на сервере (ОС, панели, VPN)         │
│────────────────────────────────────────────────────────│
│   Telegram                                             │
│    5. Токен бота (@BotFather)                          │
│    6. ID администраторов                               │
│    7. Чат для алертов                                  │
│   …                                                    │
│   25. Проверить обновления StackSentry                 │
│   26. Удалить бота                                     │
│    0. Выход                                            │
╚════════════════════════════════════════════════════════╝

Что делает каждый пункт и что в него вписать

Пункт Что делает Что ввести Пример
1 состояние службы и последние ошибки - -
2 показывает настройки, секреты замаскированы - -
3 журнал бота, 50 строк - -
4 автоопределение: ОС, пакетный менеджер, панели, VPN, службы - -
5 токен Telegram-бота значение от @BotFather 123456789:AAH...
6 ID администраторов числа через запятую 11111111,22222222
7 чат для алертов ID чата; у групп он отрицательный; пусто: в личку -1001234567890
8 тип панели (PANEL_TYPE) один из поддерживаемых типов s-ui
9 адрес панели (PANEL_URL) схема, хост, порт и (для S-UI/Hiddify) путь панели https://panel.example.com:5580
10 путь панели (PANEL_BASE_PATH) webBasePath 3X-UI; у S-UI/Hiddify путь обычно уже в адресе пусто или mypanel
11 API-токен панели токен 3X-UI/Remnawave/S-UI или admin UUID Hiddify AbCdEf...
12 логин и пароль Marzban (подменю) PANEL_USERNAME, PANEL_PASSWORD admin, ***
13 TLS и CA (подменю) PANEL_VERIFY_TLS: true/false; PANEL_CA_BUNDLE: путь к PEM true, /etc/ssl/panel-ca.pem
14 порог CPU (подменю) CPU_WARN и CPU_CRIT, % 80, 95
15 порог памяти (подменю) MEM_WARN и MEM_CRIT, % 85, 95
16 порог диска (подменю) DISK_WARN и DISK_CRIT, % 85, 93
17 гистерезис и кулдаун (подменю) ALERT_HYSTERESIS в %, ALERT_COOLDOWN в сек 5, 1800
18 за сколько дней предупреждать о подписке целое число дней 3
19 службы под наблюдением имена служб через запятую x-ui,fail2ban
20 уровень логирования DEBUG / INFO / WARNING / ERROR INFO
21 любой ключ из белого списка сначала имя ключа, затем значение DISK_PATH → /
22 перезапуск бота с проверкой - -
23 перезапуск ядра панели подтверждение y y
24 обновление StackSentry (опционально по UPDATE_SHA256) - -
25 проверка обновлений StackSentry - -
26 показать TOTP-секрет / настроить 2FA QR и секрет -
27 статус Mini App и адрес для /setdomain - -
28 удаление yes для подтверждения yes

Пустое значение очищает настройку: sudo stacksentry-menu set PANEL_BASE_PATH "". Для пунктов 5–20 можно не ходить в меню, а сразу писать: sudo stacksentry-menu set KEY VALUE (то же, что пункт 21, но одной командой).

# примеры значений
sudo stacksentry-menu set PANEL_TYPE s-ui
sudo stacksentry-menu set PANEL_URL https://panel.example.com:2095/app
sudo stacksentry-menu set PANEL_BASE_PATH ""          # «URL панели» = /
sudo stacksentry-menu set TELEGRAM_ADMIN_IDS 11111111,22222222
sudo stacksentry-menu set ALERT_CHAT_ID -1001234567890
sudo stacksentry-menu set SERVICES x-ui,fail2ban
sudo stacksentry-menu set CPU_WARN 80
sudo stacksentry-menu set LOG_LEVEL INFO

# проверить значение, ничего не меняя
stacksentry-menu check CPU_WARN 80

# проверить обновления StackSentry и посмотреть журнал пакетных обновлений
sudo stacksentry-menu update-check
sudo stacksentry-menu apt-logs 100

Что важно знать:

  • ввод проверяется: неверный номер показывает диапазон, q для выхода;
  • менять можно только ключи из белого списка (stacksentry-menu keys); значения проверяются до записи;
  • .env перезаписывается атомарно с правами 640 root:<сервисный пользователь>;
  • секреты не печатаются целиком;
  • пути можно переопределить: sudo PREFIX=/opt/бот ENV_FILE=/opt/бот/.env stacksentry-menu;
  • автоочистку экрана можно выключить: STACKSENTRY_NO_CLEAR=1 sudo stacksentry-menu.

Настройки

Все параметры находятся в /opt/stacksentry/.env; пример с комментариями: .env.example. Переменные окружения процесса имеют приоритет над файлом.

Ключ Значение
TELEGRAM_BOT_TOKEN токен бота от @BotFather
TELEGRAM_ADMIN_IDS ID администраторов через запятую
ALERT_CHAT_ID чат для алертов (пусто: админам в личку)
TELEGRAM_API_URL свой Bot API или прокси (по умолчанию официальный)
PANEL_URL адрес панели, например https://panel.example.com:2053
PANEL_BASE_PATH «URL панели» (webBasePath), если задан
PANEL_API_TOKEN токен панели (3X-UI node-sync, Remnawave, S-UI Token, Hiddify admin UUID)
PANEL_TYPE 3x-ui, marzban, marzneshin, pasarguard, remnawave, s-ui, hiddify или outline
PANEL_USERNAME логин Marzban (только для PANEL_TYPE=marzban)
PANEL_PASSWORD пароль Marzban (только для PANEL_TYPE=marzban)
PANEL_VERIFY_TLS проверять TLS-сертификат панели
PANEL_CA_BUNDLE свой CA-файл (PEM); перекрывает PANEL_VERIFY_TLS
PANEL_ALLOW_INSECURE разрешить http:///без TLS для панели не на localhost (не рекомендуется)
PANEL_TIMEOUT таймаут запросов к панели, сек
SERVICES службы под наблюдением, через запятую (x-ui,fail2ban)
DISK_PATH что проверять по месту
CPU_WARN порог предупреждения по CPU, %
CPU_CRIT порог критического CPU, %
MEM_WARN порог предупреждения по памяти, %
MEM_CRIT порог критической памяти, %
DISK_WARN порог предупреждения по диску, %
DISK_CRIT порог критического диска, %
INODE_WARN порог предупреждения по inode, %
INODE_CRIT порог критического inode, %
CHECK_FAILED_UNITS 1: проверять упавшие systemd-юниты
CHECK_FAILED_UNITS_IGNORE юниты-шум через запятую; none показывать все
CHECK_TLS 1: проверять срок TLS-сертификата панели
CHECK_BACKUP_PATH файл или каталог бэкапа для проверки свежести
CHECK_BACKUP_MAX_AGE_H максимальный возраст бэкапа, часов
CHECK_HTTP_URLS внешние HTTP-адреса через запятую
CHECK_DNS_HOSTS DNS-имена через запятую
CHECK_SMART 1: проверять SMART через smartctl (опционально)
ALERT_HYSTERESIS на сколько % метрика должна отойти назад, чтобы снять алерт
ALERT_CONFIRM_CHECKS сколько проверок подряд подтверждают срабатывание (2 отсекает всплески)
ALERT_RECOVERY_CHECKS сколько проверок подряд подтверждают восстановление
ALERT_COOLDOWN как часто повторять активный алерт, сек
ALERT_CRITICAL_CHAT_ID отдельный чат для critical
ALERT_CRITICAL_TOPIC_ID тема в чате critical (для групп с topics)
ALERT_WARNING_CHAT_ID отдельный чат для warning
ALERT_WARNING_TOPIC_ID тема в чате warning
ALERT_QUIET_START начало тихих часов, HH:MM
ALERT_QUIET_END конец тихих часов, HH:MM
EXPIRING_SOON_DAYS за сколько дней подписка считается истекающей
CHECK_INTERVAL период фоновой проверки, сек (минимум 15)
UPDATE_NOTIFY 1: уведомлять админов о новом commit StackSentry в main
UPDATE_CHECK_INTERVAL период фоновой проверки обновлений, сек (минимум 3600)
ACTION_COOLDOWN пауза между одинаковыми действиями, сек
CONFIRM_TTL сколько живёт кнопка подтверждения, сек
TOTP_SECRET секрет TOTP (base32) для 2FA; пусто: 2FA выключена
TOTP_REQUIRED 1: требовать код для входа в Mini App и опасных действий бота
ELEVATION_TTL сколько действует разблокировка после кода, сек
TOTP_MAX_ATTEMPTS сколько попыток ввода кода до блокировки
TOTP_LOCKOUT пауза после перебора кодов, сек
WEBAPP_ENABLED 1: включить read-only Mini App
WEBAPP_HOST адрес прослушивания (по умолчанию 127.0.0.1)
WEBAPP_PORT порт Mini App (по умолчанию 8787)
WEBAPP_PUBLIC_ORIGIN публичный HTTPS-адрес для кнопки в Telegram
WEBAPP_TERMINAL_ORIGIN публичный HTTPS-адрес терминала для вкладки внутри Mini App
WEBAPP_SECRET секрет подписи cookie Mini App (≥ 32 символов)
WEBAPP_SESSION_TTL срок жизни сессии Mini App, сек
WEBAPP_METRICS_TOKEN Bearer-токен для /metrics (пусто: без авторизации)
COMMAND_TIMEOUT таймаут разрешённых команд, сек
COMMAND_ALLOWLIST безопасные команды диагностики (алиасы, см. раздел выше)
STATE_PATH база SQLite
LOG_PATH файл лога
LOG_LEVEL DEBUG / INFO / WARNING / ERROR
LOG_JSON 1: писать логи одной JSON-строкой для journald/агрегатора
SUDO_WRAPPER путь к stacksentry-ctl

Куда приходят алерты

ALERT_CHAT_ID можно оставить пустым, тогда алерты приходят в личку всем ID из TELEGRAM_ADMIN_IDS. Для общего чата добавьте туда бота, отправьте сообщение и узнайте ID (@userinfobot, @getidsbot); у групп он отрицательный, например -1001234567890.

Помните: в алертах есть адреса, подписки и трафик, поэтому в группе их увидят все участники. Команды и кнопки при этом всё равно работают только в личке.

Алерты сначала попадают в SQLite-outbox. Если Telegram недоступен, бот повторит отправку после рестарта, а не потеряет событие. Одинаковые события дедуплицируются.

Переход в аварию и восстановление подтверждаются несколькими проверками подряд (ALERT_CONFIRM_CHECKS, ALERT_RECOVERY_CHECKS): одиночный всплеск CPU, таймаут панели или короткий рестарт службы не превращается в ложную тревогу.

Для разных severity можно задать разные чаты и темы. В тихие часы warning накапливаются и уходят одним дайджестом после ALERT_QUIET_END, а critical доставляется сразу.

Дополнительные проверки

Кроме CPU/RAM/диска бот проверяет inode, упавшие systemd-юниты, срок TLS-сертификата панели, свежесть бэкапа, внешние HTTP-адреса и DNS. Всё включается в .env: CHECK_FAILED_UNITS, CHECK_TLS, CHECK_BACKUP_PATH, CHECK_HTTP_URLS, CHECK_DNS_HOSTS. SMART выключен по умолчанию и требует smartmontools (CHECK_SMART=1). Прогноз заполнения диска строится по истории за неделю и появляется в сводке, когда до 100% остаётся меньше недели.

Наблюдаемость

  • /healthz возвращает ok и версию, /metrics отдаёт Prometheus-метрики (stacksentry_up, версия, число сэмплов и алертов в outbox).
  • WEBAPP_METRICS_TOKEN закрывает /metrics Bearer-токеном.
  • LOG_JSON=1 включает JSON-логи, удобные для journald и агрегаторов.

Mini App (опционально, read-only)

Дашборд в Telegram: обзор, службы, панель, трафик, подписки, история, обновления, терминал (если включён) и вкладка «Помощь» с краткой инструкцией по всем разделам, 2FA и терминалу.

Карточки и строки списков кликабельны: служба открывает состояние и журнал, метрика строит график за 24 часа/7/30 дней с p95 и пиками, проверка показывает причину и что делать, подписка раскрывает клиента и трафик. В шапке есть единый поиск по разделам, службам и подпискам. Закладки служб и настройка блоков дашборда хранятся в браузере.

Обновление можно запросить из вкладки «Обновления»: оно не выполняется напрямую, а создаёт запрос в общей очереди. Бот присылает подтверждение в Telegram, при 2FA требуется свежий код, после чего webapp показывает этапы и прогресс. Обновление переживает перезапуск webapp: запрос и статус хранятся в STATE_DIR/update.

# всё автоматически: публичный IP -> <ip>.sslip.io -> Caddy -> Let's Encrypt
sudo bash install.sh --webapp --no-terminal

# свой домен и готовый TLS-прокси
sudo bash install.sh --webapp --webapp-origin https://sentry.example.com

При обычной установке домен не нужен: установщик берёт публичный IPv4, создаёт бесплатный хост вида 203-0-113-5.sslip.io, ставит Caddy и выпускает сертификат Let's Encrypt. Нужны свободные порты 80 и 443 (если 443 занят, например Xray, используется 8443) и открытый публичный IP. Отключить автонастройку: --no-webapp-auto.

В интерактивной установке мастер покажет публичный IP, будущий адрес и предупреждения, а затем предложит выбор:

  1. Автоматически: sslip.io + Caddy (рекомендуется).
  2. Свой домен: ввести готовый HTTPS-адрес с валидным сертификатом.
  3. Только локально: без публичного адреса, доступ через SSH-туннель.

Если автоматический вариант не сработал, установщик предложит повторить, указать свой домен или оставить Mini App локальным.

Если установлен терминал, установщик спросит, открыть ли его внутри Mini App. При автоматическом HTTPS создаётся отдельный адрес term.<host> и вкладка «Терминал» появляется сама, вручную настраивать Caddy не нужно. Для своего домена можно указать готовый HTTPS-адрес терминала. Вход в терминал всегда защищён Telegram и TOTP. Если публичный терминал не нужен, ответьте n, доступ останется только через SSH-туннель.

После установки остаётся один ручной шаг: привязать домен к боту через @BotFather → /setdomain → например, 203-0-113-5.sslip.io (без https:// и без порта). Затем перезапустите бота: sudo systemctl restart stacksentry-bot. Если Caddy недоступен в репозитории или порты заняты, установщик покажет причину и предложит другой вариант.

  • вход по подписи Telegram (initData), без паролей; только администраторы. Если 2FA включена, дополнительно нужен TOTP-код на новую сессию; если выключена, Mini App не спрашивает код;
  • cookie HttpOnly, срок 1 час (не более 24 ч); при публичном HTTPS используется Secure; SameSite=None (Telegram Web), локально SameSite=Lax; подпись проверяет iat/exp, CSP без сторонних скриптов;
  • сервис stacksentry-webapp слушает 127.0.0.1:8787, наружу только Caddy/Nginx с TLS; без публичного адреса доступен через ssh -L 8787:127.0.0.1:8787 root@сервер → http://127.0.0.1:8787;
  • кнопки появляются только при WEBAPP_ENABLED=1 и заданном WEBAPP_PUBLIC_ORIGIN; установщик выставляет оба значения сам. Без публичного адреса Mini App работает только через SSH-туннель, а кнопок в Telegram нет;
  • при этих условиях бот добавляет кнопку «Панель» в меню чата (Mini App) и inline-кнопку «📱 Открыть Mini App» в главном меню администратора. «Панель» это меню рядом со скрепкой; inline-кнопка находится в самом меню бота и видна только ID из TELEGRAM_ADMIN_IDS;
  • если API панели не настроен, дашборд показывает службы/VPN/железо и пишет, что inbound'ы/подписки недоступны.

Терминал (ставится обычной установкой)

Полноценный shell в браузере это отдельный сервис, не часть бота. Обычная интерактивная установка уже ставит его вместе с root-сессией и вкладкой в Mini App; отдельная команда нужна только для повторной настройки или автоматизации:

sudo bash install.sh --terminal              # только терминал, без root
sudo bash install.sh --root-terminal         # + root-сессия (sudo -i)
sudo bash install.sh --terminal-auto         # автоматически открыть в Mini App
sudo bash install.sh --terminal --terminal-origin https://term.example.com

Что происходит:

  • создаётся отдельный пользователь stacksentry-term и служба stacksentry-terminal;
  • сервис слушает 127.0.0.1:8788, наружу не выставлен;
  • вход: Telegram initData и обязательный код TOTP на каждую сессию. Даже при компрометации Telegram-аккаунта администратора без TOTP войти нельзя;
  • у терминала отдельный TOTP-секрет от входа в Mini App. При первом открытии вкладки «Терминал» в Mini App показываются QR и секрет; после успешного входа QR скрывается и остаётся обычный запрос 6-значного кода. Посмотреть секрет и QR вручную: sudo stacksentry-menu totp; для доступа вне Telegram дополнительно нужен access token из /etc/stacksentry/terminal-secrets.env, 600 root;
  • установщик автоматически создаёт SSH-ключ Ed25519 (/var/lib/stacksentry-term/terminal-ssh/id_ed25519), добавляет публичную часть в authorized_keys пользователя stacksentry-term и использует ключ для локального SSH-подключения к 127.0.0.1. Приватный ключ не покидает сервер; если sshd/ключ недоступны, терминал автоматически работает через локальный PTY;
  • секреты терминала лежат в /etc/stacksentry/terminal-secrets.env с правами 600 root; systemd передаёт их процессу, сам пользователь файл не читает;
  • обычный shell работает под отдельным пользователем stacksentry-shell без sudo; root-сессия доступна только через точное правило stacksentry-term ALL=(root) NOPASSWD: /bin/bash -l. В обычной установке она включена; отключить: --no-root-terminal;
  • секреты терминала (TOTP, тикеты, access token, токен бота) не передаются в PTY: shell получает только PATH/TERM/LANG/HOME/USER;
  • вкладка «Терминал» внутри Mini App появляется, когда задан WEBAPP_TERMINAL_ORIGIN. При авто-HTTPS установщик сам публикует терминал на term.<host> и прописывает адрес; для своего домена используйте --terminal-origin или ответьте на вопрос мастера. Терминал открывается в iframe, initData передаётся через hash, но TOTP всё равно запрашивается отдельно.

Нужен только бот без дополнительных сервисов? Отключите их при установке: --no-webapp, --no-terminal, --no-root-terminal, --no-2fa.

Доступ по умолчанию только с сервера или через SSH-туннель:

ssh -L 8788:127.0.0.1:8788 root@сервер
# затем откройте http://127.0.0.1:8788

Для доступа из Telegram задайте --terminal-origin https://... и поставьте Caddy/Nginx с TLS перед 127.0.0.1:8788.

Root-терминал это полноценный root-shell. TOTP защищает вход, но при компрометации веб-слоя/сессии/зависимостей защита падает. Держите его за VPN/SSH-туннелем, не публикуйте в интернет без второго периметра.

2FA: Mini App и опасные действия

Если 2FA включена, Mini App требует код TOTP при входе. В боте просмотр состояния, журналов и подписок остаётся без кода; код нужен там, где можно сломать сервер (step-up). Иначе каждые 15 минут пришлось бы заново вводить код даже для чтения статуса.

Уровень Что 2FA
🟢 просмотр в боте статус, службы, панель, трафик, подписки, история, аудит нет
📱 Mini App вход в панель код TOTP на новую сессию
🟡 действия рестарт службы/xray, apt update, команда из allowlist код один раз, разблокировка на 15 мин
🔴 разрушительное apt full/phased, релиз-обновление, перезагрузка свежий код (не старше 2 мин)

Как это выглядит:

  1. Открываете Mini App → «Подтвердите вход» → вводите 6 цифр.
  2. В боте нажимаете «Рестарт x-ui» → «🔐 Нужен код 2FA. Отправьте 6 цифр».
  3. Бот удаляет сообщение с кодом, проверяет и пишет «🔓 Действия разблокированы до 14:35».
  4. Появляется обычное подтверждение с последствиями. Дальше 15 минут опасные действия не спрашивают код (разрушительные всегда требуют свежий код).
  5. «🔐 Безопасность» в меню: статус, «Разблокировать», «Заблокировать сейчас».

Включение: установщик спрашивает при установке (по умолчанию да), либо --2fa; отказ (--no-2fa) отключает TOTP. При генерации показываются секрет, otpauth и QR-код для Google Authenticator/Aegis/1Password. Посмотреть секрет и QR позже: sudo stacksentry-menu totp (только root).

Защита: код одноразовый в пределах окна, 3 попытки, блокировка на 5 минут, все успехи и неудачи попадают в аудит. Секрет лежит в .env с правами 640 root:<группа сервиса>; логи его вырезают. Терминал использует отдельный TOTP-секрет и всегда спрашивает код на каждую сессию.

Секреты и хранение

  • Токены бота и панели хранятся в .env с правами 640 root:<группа сервиса>; сервис читает их, но не может переписать файл.
  • Терминал (если включён) хранит свои секреты отдельно: /etc/stacksentry/terminal.env, 600 root, systemd передаёт их процессу через EnvironmentFile. Сам сервисный пользователь файл не читает.
  • Логи чистятся форматтером: токен бота в URL, токены панели/терминала, TOTP и access token вырезаются; initData не логируется; Telegram ID маскируются.
  • База state.db имеет права 0600; в ней есть Telegram ID, аудит и подписки.
  • Шифрование «на уровне приложения» с ключом на том же сервере даёт мало: компрометация хоста всё равно раскрывает ключ. Для защиты диска используйте LUKS/шифрование VPS, бэкапы храните в шифрованном виде. Для терминала добавьте второй фактор (TOTP уже есть) и доступ через VPN/SSH-туннель.

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

  • Бот работает непривилегированным пользователем stacksentry; код и venv принадлежат root, .env доступен службе только на чтение.
  • Все привилегированные операции идут через sudo stacksentry-ctl и узкий sudoers-список из точных команд (без шаблонов в аргументах, так требуют и классический sudo, и sudo-rs). Произвольного shell нет.
  • apt выполняется отдельными systemd-юнитами stacksentry-apt-*.service, они не наследуют песочницу бота; при недоступности transient-юнита есть фолбэк.
  • Опасные действия требуют подтверждения; токен привязан к запросившему администратору и одноразовый; всё пишется в audit_log.
  • Mini App работает под отдельным пользователем без sudo и своей SQLite-базой; его компрометация не даёт писать аудит бота или запускать stacksentry-ctl.
  • Mini App требует TOTP при создании сессии: одного initData при компрометации Telegram-аккаунта недостаточно. Использованные TOTP/initData сохраняются в SQLite и не принимаются повторно после перезапуска. Терминал требует отдельный TOTP на каждую сессию. Root-сессия дополнительно включается только флагом --root-terminal; SSH-ключ терминала хранится на сервере и наружу не выдаётся.
  • Клиент панели не следует редиректам, значения из панели экранируются, токен бота не попадает в логи даже на DEBUG.
  • Повторы ограничены ACTION_COOLDOWN; flood control Telegram обрабатывается повтором с паузой, длинные сообщения режутся по строкам.
  • Команды принимаются только в личном чате; попытки посторонних пишутся в журнал (denied).
  • Установщик умеет проверять контрольную сумму архива (--sha256).
  • Секреты вырезаются из логов форматтером (включая текст исключений), Telegram ID маскируются (…789), stacksentry-menu show/check не печатают секреты.
  • Для самоподписанного сертификата есть PANEL_CA_BUNDLE, вместо отключения проверки TLS можно держать пиннинг.

Ресурсы службы ограничены (MemoryMax=256M, TasksMax=64), вывод команд обрезается (16 КБ) и имеет таймаут.

Самодиагностика

sudo stacksentry-doctor              # конфиг, база, службы, панель
sudo stacksentry-doctor --no-network # без запросов к панели

Обновление и удаление

# обновление (конфиг и состояние сохраняются)
bash <(curl -Ls https://raw.githubusercontent.com/Hijackery/stacksentry/main/install.sh)

# то же из меню
sudo stacksentry-menu          # пункт 24

# проверить обновления, ничего не устанавливая
sudo stacksentry-menu update-check
# или в боте: /updatecheck / «❓ Помощь» → «🔄 Проверить обновления»

# в боте: при наличии обновления появляется «⬆️ Обновить StackSentry»
# (подтверждение + свежий TOTP; .env и состояние сохраняются)

# удалить целиком: служба, sudoers, обёртка, меню, код, база и пользователь
sudo bash install.sh --uninstall

# сохранить базу и пользователя
sudo bash install.sh --uninstall --keep-state

# интерактивное меню установщика
sudo bash install.sh --menu

Удаление печатает одну строку «Бот удалён.» и закрывает stacksentry-menu. При --keep-state остаётся предупреждение о том, что база и пользователь сохранены.

GitHub Releases проект не публикует: проверка и установка идут по main. Пин UPDATE_SHA256 опционален. GitHub может отдавать main из кэша пару минут, update-check это учитывает.

Если что-то не работает

systemctl status stacksentry-bot
journalctl -u stacksentry-bot -n 50 --no-pager
Симптом Что делать
«Синтаксис sudoers невалиден» установщик печатает строку от visudo, пришлите её в issue
«Системные метрики недоступны: /proc/stat» в старой установке остался ProcSubset=pid: sudo sed -i '/^ProcSubset=/d' /etc/systemd/system/stacksentry-bot.service && sudo systemctl daemon-reload && sudo systemctl restart stacksentry-bot
«Токен отклонён» проверьте TELEGRAM_BOT_TOKEN и PANEL_API_TOKEN через sudo stacksentry-menu → «Показать настройки»
inbounds/list недоступен у токена панели нет scope node-sync
Панель отвечает 404 на API проверьте PANEL_URL/PANEL_BASE_PATH (частая ошибка: /panel в webBasePath)
Логи сервиса не видны проверьте правило journal в sudoers и запуск через sudo
Ubuntu 26.04+ sudo-rs запрещает шаблоны в аргументах, установщик это уже учитывает

Нет кнопки Mini App

Проверьте настройки и журнал:

grep -E '^WEBAPP_(ENABLED|PUBLIC_ORIGIN)=' /opt/stacksentry/.env
sudo stacksentry-menu webapp
systemctl status stacksentry-bot stacksentry-webapp caddy
journalctl -u stacksentry-bot -n 100 --no-pager | grep -i 'Mini App'

Кнопки появляются только при WEBAPP_ENABLED=1 и непустом WEBAPP_PUBLIC_ORIGIN (HTTPS), а inline-кнопка только у администратора из TELEGRAM_ADMIN_IDS. Если origin пустой, переустановите Mini App без домена: sudo bash install.sh --webapp --no-terminal, установщик поднимет sslip.io + Caddy автоматически. Если origin задан, но кнопки нет:

  • домен должен быть привязан через @BotFather → /setdomain (для sslip.io только хост, без порта);
  • публичный адрес должен открываться по HTTPS (проверьте Caddy/прокси перед 127.0.0.1:8787);
  • перезапустите бота после правки .env: sudo systemctl restart stacksentry-bot;
  • сообщение Не удалось поставить кнопку Mini App в журнале означает отказ Telegram, чаще всего из-за неверного домена, HTTP вместо HTTPS или недоступного URL.

Подробнее в SECURITY.md и CHANGELOG.md.

Документация

  • docs/COMPATIBILITY.md: ОС, init, пакеты, панели, протоколы, рестарт.
  • docs/ARCHITECTURE.md: компоненты, поток данных, безопасность, расширение.
  • docs/RELEASING.md: версии, проверка и установка обновлений.
  • SUPPORT.md: куда обращаться и что приложить.
  • SECURITY.md: политика и модель безопасности.
  • CONTRIBUTING.md: сборка, проверки, PR.
  • CHANGELOG.md: история изменений.

Версии и обновление

  • Версия: SemVer в stacksentry/__init__.py; видна в боте (/version).
  • GitHub Releases не публикуются: проверка и установка идут по main. Пин UPDATE_SHA256 и UPDATE_REF можно задать для доп. контроля.
  • Проверка обновлений: кнопка «🔄 Проверить обновления» в «Помощи», раздел «Помощь» в Mini App, sudo stacksentry-menu update-check или /updatecheck.
  • Если обновление есть, в боте появляется кнопка «⬆️ Обновить StackSentry». Она требует подтверждения и свежего TOTP (если 2FA включена), сохраняет .env и состояние, затем перезапускает бота.
  • Ручное обновление: sudo stacksentry-menu update (после настройки пина) или повторный запуск установщика с --sha256. Подробности и откат описаны в docs/RELEASING.md.

Разработка

pip install -r requirements-dev.txt
ruff format --check .
ruff check .
mypy .
pytest -q

Тесты не требуют панели, Telegram и systemd: внешние вызовы подменяются. CI гоняет Python 3.10 и 3.13, shellcheck, bash -n и visudo -cf.

Проект

  • SECURITY.md: как сообщить об уязвимости и что уже защищено.
  • CONTRIBUTING.md: окружение, обязательные проверки, стиль.
  • SUPPORT.md: куда обращаться и что приложить.
  • docs/: совместимость, архитектура, обновления.
  • CHANGELOG.md: история изменений.
  • .env.example: все настройки с комментариями.
  • English README.

Лицензия

MIT, см. LICENSE.

About

Мониторинг VPS, панелей и VPN в Telegram | VPS, panel and VPN monitoring in Telegram

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages