Доступ до сервера linux за допомогою Telegram-бота на Python

Часто відбуваються ситуації, коли доступ до сервера потрібен тут і зараз. Однак, не завжди підключення по SSH є найбільш зручним способом, тому що під рукою може не опинитися SSH клієнта, адреси сервера або зв'язки «користувач/пароль». Звичайно є Webmin, що спрощує адміністрування, але він також не дає моментальний доступ.

Тому я вирішив реалізувати просте, але цікаве рішення. А саме — написати Telegram-бота, який, запускаючись на самому сервері, виконуватиме команди, які йому надсилаються, і повертатиме результат. Вивчивши кілька статей на цю тему я зрозумів, що подібних реалізацій ще ніхто не описував.

Цей проект я реалізовував на Ubuntu 16.04, але для безпроблемного запуску на інших дистрибутивах я постарався зробити все у загальному вигляді.

Реєстрація бота

Реєструємо нового бота @BotFather. Відправляємо йому /newbot та далі за текстом. Нам знадобляться токен нового бота і ваш id (отримати його можна, наприклад, у @userinfobot).

Підготовка пітона

Для запуску робота будемо використовувати бібліотеку telebot (pip install pytelegrambotapi). За допомогою бібліотеки subprocess виконуватимемо команди на сервері.

Запуск бота

На сервері створюємо файл bot.py:
nano bot.py

І вставляємо в нього код:

from subprocess import check_output
import telebot
import time

bot = telebot.TeleBot("XXXXXXXXX:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")#токен бота
user_id = 0 #id вашего аккаунта
@bot.message_handler(content_types=["text"])
def main(message):
   if (user_id == message.chat.id): #проверяем, что пишет именно владелец
      comand = message.text  #текст сообщения
      try: #если команда невыполняемая - check_output выдаст exception
         bot.send_message(message.chat.id, check_output(comand, shell = True))
      except:
         bot.send_message(message.chat.id, "Invalid input") #если команда некорректна
if __name__ == '__main__':
    while True:
        try:#добавляем try для бесперебойной работы
            bot.polling(none_stop=True)#запуск бота
        except:
            time.sleep(10)#в случае падения

Замінюємо в ньому токен бота на той, який видав @BotFather, і user_id - на значення id вашого облікового запису. Перевірка id користувача необхідна у тому, щоб бот надавав доступом до вашому серверу лише вам. Функція check_output() виконує передану команду та повертає результат.

Залишилося лише запустити бота. Для запуску процесів на сервері я волію використовувати screen (sudo apt-get install screen):

screen -dmS ServerBot python3 bot.py

(де "ServerBot" - ідентифікатор процесу)

Процес автоматично запуститься у фоновому режимі. Перейдемо в діалог з ботом і перевіримо, що все працює як треба:

Доступ до сервера linux за допомогою Telegram-бота на Python

Сongratulations! Бот виконує команди, що йому надсилаються. Тепер, щоб отримати доступ до сервера, достатньо відкрити діалог з ботом.

Повторення команд

Найчастіше, для моніторингу стану сервера доводиться виконувати одні й самі команди. Тому реалізація повтору команд без їхнього повторного відправлення буде дуже доречною.

Реалізовувати будемо за допомогою inline кнопок під повідомленнями:

from subprocess import check_output
import telebot
from telebot import types #Добавляем импорт кнопок
import time

bot = telebot.TeleBot("XXXXXXXXX:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")#Токен бота
user_id = 0 #id вашего аккаунта
@bot.message_handler(content_types=["text"])
def main(message):
   if (user_id == message.chat.id): #проверяем, что пишет именно владелец
      comand = message.text  #текст сообщения
      markup = types.InlineKeyboardMarkup() #создаем клавиатуру
      button = types.InlineKeyboardButton(text="Повторить", callback_data=comand) #создаем кнопку
      markup.add(button) #добавляем кнопку в клавиатуру
      try: #если команда невыполняемая - check_output выдаст exception
         bot.send_message(user_id, check_output(comand, shell = True,  reply_markup = markup)) #вызываем команду и отправляем сообщение с результатом
      except:
         bot.send_message(user_id, "Invalid input") #если команда некорректна

@bot.callback_query_handler(func=lambda call: True)
def callback(call):
  comand = call.data #считываем команду из поля кнопки data
  try:#если команда не выполняемая - check_output выдаст exception
     markup = types.InlineKeyboardMarkup() #создаем клавиатуру
     button = types.InlineKeyboardButton(text="Повторить", callback_data=comand) #создаем кнопку и в data передаём команду
     markup.add(button) #добавляем кнопку в клавиатуру
     bot.send_message(user_id, check_output(comand, shell = True), reply_markup = markup) #вызываем команду и отправляем сообщение с результатом
  except:
     bot.send_message(user_id, "Invalid input") #если команда некорректна

if __name__ == '__main__':
    while True:
        try:#добавляем try для бесперебойной работы
            bot.polling(none_stop=True)#запуск бота
        except:
            time.sleep(10)#в случае падения

Перезапускаємо бота:

killall python3
screen -dmS ServerBot python3 bot.py

Знову перевіримо, що все працює коректно:

Доступ до сервера linux за допомогою Telegram-бота на Python

Після натискання кнопки під повідомленням бот повинен повторювати команду, від якої надіслано це повідомлення.

Замість висновку

Безумовно, такий метод не претендує стати заміною на класичні способи підключення, однак, він дозволяє досить швидко дізнатися про стан сервера і відправити йому команди, які не потребують складного висновку.

Джерело: habr.com

Додати коментар або відгук