Spesso si verificano situazioni in cui l'accesso al server è necessario qui e ora. Tuttavia, non sempre la connessione SSH è il modo più comodo, poiché potrebbe non esserci un client SSH a disposizione, l'indirizzo del server o le credenziali "utente/password". Certamente, esiste , che semplifica l'amministrazione, ma non fornisce accesso immediato.
Quindi ho deciso di implementare una soluzione semplice ma interessante. Vale a dire, scrivere un bot di Telegram che, funzionando direttamente sul server, eseguirà i comandi che gli vengono inviati e restituirà il risultato. Studiare questo argomento mi ha fatto capire che nessuno ha descritto implementazioni simili.
Questo progetto l'ho realizzato su Ubuntu 16.04, ma ho cercato di farlo in modo generale affinché funzioni su altre distribuzioni senza problemi.
Registrazione del bot
Registriamo un nuovo bot su @BotFather. Inviamogli /newbot e proseguiamo. Ci serviranno il token del nuovo bot e il tuo ID (puoi ottenerlo, ad esempio, da ).
Preparazione di Python
Per eseguire il bot utilizzeremo la libreria telebot (pip install pytelegrambotapi). Utilizzando la libreria subprocess eseguiremo comandi sul server.
Avvio del bot
Sul server creiamo il file bot.py:
nano bot.py
E incolliamo il codice:
from subprocess import check_output
import telebot
import time
bot = telebot.TeleBot("XXXXXXXXX:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")#token del bot
user_id = 0 #ID del tuo account
@bot.message_handler(content_types=["text"])
def main(message):
if (user_id == message.chat.id): #verifichiamo che stia scrivendo proprio il proprietario
comand = message.text #testo del messaggio
try: #se il comando non può essere eseguito, check_output solleverà un'eccezione
bot.send_message(message.chat.id, check_output(comand, shell = True))
except:
bot.send_message(message.chat.id, "Input non valido") #se il comando è errato
if __name__ == '__main__':
while True:
try:#aggiungiamo try per garantire un funzionamento ininterrotto
bot.polling(none_stop=True)#avviamo il bot
except:
time.sleep(10)#in caso di crash
Sostituiamo il token del bot con quello fornito da @BotFather e user_id con il valore dell'ID del tuo account. Il controllo dell'ID utente è necessario affinché il bot fornisca l'accesso al tuo server solo a te. La funzione check_output() esegue il comando fornito e restituisce il risultato.
Non resta che avviare il bot. Per avviare i processi sul server, preferisco usare screen (sudo apt-get install screen):
screen -dmS ServerBot python3 bot.py(dove "ServerBot" è l'identificatore del processo)
Il processo si avvierà automaticamente in modalità in background. Passiamo al dialogo con il bot e verifichiamo che tutto funzioni come dovrebbe:

Congratulazioni! Il bot esegue i comandi che gli vengono inviati. Ora, per accedere al server, è sufficiente aprire un dialogo con il bot.
Ripetizione dei comandi
Spesso, per monitorare lo stato del server, è necessario eseguire gli stessi comandi. Pertanto, implementare la ripetizione dei comandi senza l'invio ripetuto sarà molto utile.
Implementeremo utilizzando pulsanti inline sotto i messaggi:
from subprocess import check_output
import telebot
from telebot import types #Aggiungiamo l'import dei pulsanti
import time
bot = telebot.TeleBot("XXXXXXXXX:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")#Token del bot
user_id = 0 #id del tuo account
@bot.message_handler(content_types=["text"])
def main(message):
if (user_id == message.chat.id): #controlliamo che stia scrivendo proprio il proprietario
comand = message.text #testo del messaggio
markup = types.InlineKeyboardMarkup() #creiamo la tastiera
button = types.InlineKeyboardButton(text="Ripetere", callback_data=comand) #creiamo il pulsante
markup.add(button) #aggiungiamo il pulsante alla tastiera
try: #se il comando non è eseguibile - check_output solleverà un'eccezione
bot.send_message(user_id, check_output(comand, shell = True, reply_markup = markup)) #eseguiamo il comando e inviamo il messaggio con il risultato
except:
bot.send_message(user_id, "Input non valido") #se il comando è errato
@bot.callback_query_handler(func=lambda call: True)
def callback(call):
comand = call.data #leggiamo il comando dal campo data del pulsante
try:#se il comando non è eseguibile - check_output solleverà un'eccezione
markup = types.InlineKeyboardMarkup() #creiamo la tastiera
button = types.InlineKeyboardButton(text="Ripetere", callback_data=comand) #creiamo il pulsante e passiamo il comando in data
markup.add(button) #aggiungiamo il pulsante alla tastiera
bot.send_message(user_id, check_output(comand, shell = True), reply_markup = markup) #eseguiamo il comando e inviamo il messaggio con il risultato
except:
bot.send_message(user_id, "Input non valido") #se il comando è errato
if __name__ == '__main__':
while True:
try:#aggiungiamo un try per un funzionamento continuo
bot.polling(none_stop=True)#avviamo il bot
except:
time.sleep(10)#in caso di crash
Riavviamo il bot:
killall python3
screen -dmS ServerBot python3 bot.py
Controlliamo di nuovo che tutto funzioni correttamente:

Cliccando sul pulsante sotto il messaggio, il bot dovrebbe ripetere il comando da cui è stato inviato questo messaggio.
In conclusione
Senza dubbio, questo metodo non intende sostituire i metodi classici di connessione; tuttavia, consente di ottenere rapidamente informazioni sullo stato del server e di inviargli comandi senza richiedere un'uscita complessa.
Fonte: habr.com
