Prístup k linuxovému serveru pomocou telegramového bota v Pythone

Pomerne často nastávajú situácie, kedy je potrebný prístup na server tu a teraz. Pripojenie cez SSH však nie je vždy najpohodlnejším spôsobom, pretože nemusíte mať po ruke klienta SSH, adresu servera alebo kombináciu používateľa a hesla. Samozrejme, že mám Webmin, čo zjednodušuje administráciu, no zároveň neposkytuje okamžitý prístup.

Preto som sa rozhodol implementovať jednoduché, ale zaujímavé riešenie. Konkrétne napísať telegramového robota, ktorý po spustení na samotnom serveri vykoná príkazy, ktoré mu boli odoslané, a vráti výsledok. Po štúdiu niektorí články na túto tému som si uvedomil, že takéto implementácie ešte nikto nepopísal.

Tento projekt som implementoval na Ubuntu 16.04, ale pre bezproblémový chod na iných distribúciách som sa snažil urobiť všetko všeobecne.

Registrácia botov

Zaregistrujte nového robota pomocou @BotFather. Posielame ho /newbot a ďalej v texte. Budeme potrebovať nový token bota a vaše ID (môžete ho získať napr @userinfobot).

Príprava Pythonu

Na spustenie robota použijeme knižnicu telebot (pip install pytelegrambotapi). Používanie knižnice subprocess vykonáme príkazy na serveri.

Spustenie robota

Vytvorte súbor bot.py na serveri:
nano bot.py

A vložte do neho kód:

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)#в случае падения

Token bota v ňom nahradíme tokenom vydaným @BotFather a user_id hodnotou id vášho účtu. Kontrola ID používateľa je potrebná, aby robot poskytoval prístup k vášmu serveru iba vám. Funkcia check_output() vykoná zadaný príkaz a vráti výsledok.

Zostáva len spustiť robota. Pre spustenie procesov na serveri uprednostňujem použitie screen (sudo apt-get install screen):

screen -dmS ServerBot python3 bot.py

(kde „ServerBot“ je ID procesu)

Proces sa automaticky spustí na pozadí. Poďme na dialóg s robotom a skontrolujte, či všetko funguje tak, ako má:

Prístup k linuxovému serveru pomocou telegramového bota v Pythone

Gratulujem! Robot vykonáva príkazy, ktoré sú mu odoslané. Teraz, aby ste sa dostali na server, stačí otvoriť dialóg s robotom.

Opakovanie príkazu

Na monitorovanie stavu servera musíte často vykonávať rovnaké príkazy. Preto implementácia opakovaných príkazov bez ich opätovného odoslania bude veľmi nemiestne.

Implementujeme to pomocou vložených tlačidiel pod správami:

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)#в случае падения

Reštartovanie robota:

killall python3
screen -dmS ServerBot python3 bot.py

Znova skontrolujte, či všetko funguje správne:

Prístup k linuxovému serveru pomocou telegramového bota v Pythone

Stlačením tlačidla pod správou musí bot zopakovať príkaz, z ktorého bola táto správa odoslaná.

namiesto záveru

Tento spôsob sa samozrejme netvári ako náhrada za klasické spôsoby pripojenia, umožňuje však rýchlo zistiť stav servera a posielať naň príkazy, ktoré nevyžadujú zložitý výstup.

Zdroj: hab.com

Pridať komentár