Хватит это терпеть: как я написал Telegram-бота для VPS, который не бесит
- четверг, 23 октября 2025 г. в 00:00:06
Всем привет! Меня, как и многих здесь, в какой-то момент достало. Достало логиниться по SSH, чтобы проверить htop. Достало запускать Termius на телефоне, чтобы сделать sudo reboot зависшему инстансу. Достало ставить тяжелые веб-панели, которые жрут ресурсы и открывают лишний порт, только ради того, чтобы посмотреть загрузку диска.
Я админю VPS. Мне нужен был инструмент, который:
Мгновенно даёт сводку по системе.
Работает легковесно, не отъедая ресурсы.
Безопасен (никаких "запусти_от_рута_в_один_пайп").
Надёжен, как швейцарские часы (и не спамит алертами).
Умеет в администрирование этих кастомных приложений.
Я перепробовал готовые решения. Веб-панели — оверинжиниринг и дыра в безопасности. Готовые боты — либо заброшены, либо требуют root-доступ по дефолту, либо умеют только uptime.
Поэтому я сел и написал своего. Встречайте — tgbotvpscp.

Я сразу решил, что не буду делать "ещё одного" бота. Я делал инструмент для себя, а я параноик в плане безопасности и ненавижу "глючные" скрипты.
Первое, что я продумал, — это установка. Мой deploy.sh — это не просто git pull. Это полноценный интерактивный установщик.
Он сразу предлагает выбор:
Secure (Рекомендуемый): Скрипт сам создаёт отдельного системного пользователя tgbot, выдаёт ему права только на нужные директории (/opt/tg-bot), настраивает sudoers только для перезапуска сервиса (для watchdog'а) и запускает всё в изолированном venv. Бот не имеет доступа к root.
Root (Для опытных): Если вам нужен полный фарш — reboot сервера, apt update и чтение всех логов прямо из бота — вы можете выбрать этот режим.
90% аналогов просто предлагают запустить всё от рута. Я считаю это порочной практикой.
Бот — это сервис. А сервисы падают. Поэтому у меня их два: tg-bot.service и tg-watchdog.service.
watchdog.py — это отдельный, максимально "тупой" и надёжный скрипт. Его задача — раз в 5 секунд проверять статус systemctl status tg-bot.service.
Ключевая фишка: он не просто шлёт алерт "всё упало". Он присылает админу одно сообщение и редактирует его, показывая жизненный цикл:
Сервис бота Недоступен 🔴 (и тут же даёт команду systemctl restart)
(если сервис стартует) Сервис бота Активируется 🟡
(когда сервис поднялся) Сервис бота Активен 🟢

Но главная моя боль — ложные срабатывания. Когда я сам перезапускаю бота (например, через deploy.sh или из админки самого бота), я не хочу получать паническое "ШЕФ, ВСЁ УПАЛО!".
Поэтому bot.py перед плановым рестартом создаёт restart_flag.txt. А watchdog.py, прежде чем бить тревогу, проверяет: "Ага, есть restart_flag.txt. Значит, рестарт плановый. Молчу."
Python
# Кусочек из watchdog.py
# ...
else:
logging.warning(f"Сервис бота '{BOT_SERVICE_NAME}' НЕАКТИВЕН. ...")
# Проверка на плановый перезапуск (остается важной!)
if os.path.exists(RESTART_FLAG_FILE):
logging.info(f"Обнаружен плановый перезапуск. Alert-система не вмешивается.")
return
# Это настоящий сбой
if not bot_service_was_down: # Если это *первое* обнаружение сбоя
state_to_report = "down"
alert_type = "bot_service_down"
message_text = f"Сервис бота <b>{BOT_SERVICE_NAME}</b> Недоступен 🔴"
# ...
Это простое, но гениальное решение сэкономило мне кучу нервов.
Мне мало знать, что CPU 10%. Я хочу знать, кто зашёл на мой сервер прямо сейчас. Поэтому я встроил в bot.py (который крутится в asyncio) фоновые задачи, которые непрерывно слушают tail -f на критичные логи.
Бот асинхронно читает auth.log (или secure) и fail2ban.log. Как только там появляется новая строка Accepted ... for ... from ... или fail2ban.actions.* Ban ..., бот парсит её и мгновенно шлёт мне алерт с флагом страны, IP и юзером.

Это даёт невероятное чувство контроля. Я ещё не успел закрыть дверь, а уже знаю, что кто-то (или что-то) зашло на сервер. И, конечно, эти алерты можно тонко настроить в меню "🔔 Уведомления".
Python
# Кусочек из bot.py - запуск мониторов
# ...
if ssh_log_file_to_monitor:
task_logins = asyncio.create_task(reliable_tail_log_monitor(ssh_log_file_to_monitor, "logins", parse_ssh_log_line), name="LoginsMonitor")
background_tasks.add(task_logins)
else: logging.warning("Не найден лог SSH. Мониторинг SSH (logins) не запущен.")
task_bans = asyncio.create_task(reliable_tail_log_monitor(f2b_log_file_to_monitor, "bans", parse_f2b_log_line), name="BansMonitor")
background_tasks.add(task_bans)
# ...
А вот и та самая "узкая задача". Многие из нас используют VPS для кастомных сетевых приложений, часто работающих на Docker. Они зависят от быстро обновляемых Core-библиотек, которые обеспечивают, скажем так, саму логику транспортировки данных. Обновлять их вручную — та ещё морока.
Бот автоматически определяет (по именам Docker-контейнеров) известные типы панелей управления (например, mar***n или a***ia) и обновляет их ядро до последнего стабильного релиза с GitHub в один клик. Код явно указывает на releases/latest/download, так что мы берём именно свежий стабильный билд, а не nightly-сборку.
Ну и вишенка на торте — генератор конфигураций доступа. Многим часто нужно поделиться доступом к своему сервису. Теперь вы можете просто скинуть боту JSON-файл с настройками. Бот на лету парсит его, генерирует конфигурационную ссылку нужного формата (да, ту самую, vless://...) и QR-код для клиента. Максимально удобно.

Этот бот решает мои текущие задачи. Но я уже смотрю в будущее. Сейчас это монолит: один бот на один сервер. Это не масштабируется.
Мой road-map выглядит так:
Архитектура "Агент-Нода". Текущий бот станет "Агентом" (или "Центром управления"). На все VPS будут ставиться легковесные "Ноды" — минималистичные скрипты. Агент будет давать им команды, а ноды — рапортовать о состоянии. Это позволит управлять парком серверов из одного бота.
Модульность. Я вынесу специфичные фичи (обновление Core-библиотек, Fail2Ban) в отдельные модули/плагины. Не нужен мониторинг F2B? Просто отключи модуль в конфиге. Хочешь добавить мониторинг Docker? Пишешь свой docker_plugin.py.
Локализация (EN/RU). Проект уже на GitHub, и я вижу к нему интерес. Первое, что нужно сделать — полная английская локализация.
И это только начало.
Я сделал инструмент, который решил мою головную боль. Он безопасный, надёжный и делает ровно то, что мне нужно, не пытаясь быть комбайном.
Проект полностью open-source (GPL-3.0), написан на современном Python и aiogram 3.x. Если у вас, как и у меня, "чесались руки" сделать удобную админку для своих серверов — добро пожаловать.
Заходите на GitHub, ставьте звезды, предлагайте фичи, форкайте. Давайте сделаем управление VPS удобным, без костылей и дыр в безопасности.
Спасибо за внимание!