Главная » Хабрахабр » [Из песочницы] Доступ к linux серверу с помощью Telegram-бота на Python

[Из песочницы] Доступ к linux серверу с помощью Telegram-бота на Python

Довольно часто происходят ситуации, когда доступ к серверу нужен здесь и сейчас. Однако, не всегда подключение по SSH является наиболее удобным способом, потому что под рукой может не оказаться SSH клиента, адреса сервера или связки «пользователь/пароль». Конечно, есть Webmin, который упрощает администрирование, но он также не даёт моментальный доступ.
Поэтому я решил реализовать простое, но любопытное решение. А именно — написать Telegram-бота, который, запускаясь на самом сервере, будет выполнять присылаемые ему команды и возвращать результат. Изучив несколькостатей на эту тему, я понял, что подобных реализаций ещё никто не описывал.

04, но для беспроблемного запуска на других дистрибутивах я постарался сделать всё в общем виде. Данный проект я реализовывал на Ubuntu 16.

Регистрация бота

Регистрируем нового бота у @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» — идентификатор процесса)

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

Бот выполняет присылаемые ему команды. С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

Снова проверим, что всё работает корректно:

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

Вместо заключения

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


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

PHP-Дайджест № 154 (9 – 21 апреля 2019)

В выпуске: Zend Framework переходит под крыло Linux Foundation, новости из PHP Internals, порция полезных инструментов, и многое другое. Свежая подборка со ссылками на новости и материалы. Приятного чтения! Новости и релизы PHP Internals Инструменты pinba-server/pinba-server — Простой pinba-сервер на ...

Язык Bosque — новый язык программирования от Microsoft

Языку дали название Bosque. Буквально несколько дней назад компания Microsoft представила публике новый язык программирования. Главная миссия дизайна языка — лучше быть богатым и здоровым, чем бедным и больным чтобы он был прост и понятен как для человека, так и ...