Remote-Aktivierung von Mikrotik-Skripten über Telegram

Diese Umsetzung wurde durch Alexander Koryukin inspiriert. GeXoGeN seiner Veröffentlichung „Fernzugriff auf den Computer kostenlos, ohne SMS und ohne Clouds, mit Mikrotik«.

Und ein Kommentar in einer der VK-Gruppen von Kirill Kazakov:

Ja, das ist ganz und gar nicht sicher. Ich würde lieber einen Telegram-Bot schreiben, der nur Befehle von meinem Konto zum Einschalten akzeptiert.

Ich habe beschlossen, einen solchen Bot zu schreiben.

Also, zuerst müssen wir einen Bot in Telegram erstellen.

  • Suchen Sie im Suchfeld nach dem Benutzer @botfather.
  • Klicken Sie auf die Schaltfläche Start am unteren Bildschirmrand.
  • Dann geben wir ihm den Befehl /newbot.

Dann beantworten wir zwei einfache Fragen:

  • Die erste Frage – den Namen des zu erstellenden Bots. MyMikrotikROuter
  • Die zweite Frage – den Nickname des zu erstellenden Bots (sollte auf bot enden). MikrotikROuter_bot

Als Antwort erhalten wir das Token unseres Bots, in meinem Fall ist das:

Verwenden Sie dieses Token, um auf die HTTP-API zuzugreifen: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Remote-Aktivierung von Mikrotik-Skripten über Telegram
Dann müssen wir unseren Bot im Suchfeld nach Namen finden. @MikrotikROuter_bot und auf die Schaltfläche Start klicken.

Nach diesem Schritt müssen wir den Browser öffnen und die folgende Zeile eingeben:

 https://api.telegram.org/botXXXXXXXXXXXXXXXXXX/getUpdates

Wo XXXXXXXXXXXXXXXXXX – das Token Ihres Bots ist.

Es öffnet sich eine Seite, die ungefähr so aussieht:

Remote-Aktivierung von Mikrotik-Skripten über Telegram

Suchen Sie dort nach folgendem Text:

„chat“:{„id“:631290,

Nun haben wir alle notwendigen Informationen, um Skripte für Mikrotik zu schreiben, nämlich:

Bot-Token: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Chat-ID, in den er schreiben soll: 631290

Zur Überprüfung können wir über den Browser darauf zugreifen:

https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage?chat_id=631290&text=test

Wir sollten folgendes Ergebnis erhalten:

Remote-Aktivierung von Mikrotik-Skripten über Telegram

Für unsere Bequemlichkeit fügen wir sofort die Befehle für den Bot hinzu:

Wir finden das Konto mit dem Namen @botfather
Dann schreiben wir ihm den Befehl /setcommands

  • Er wird fragen, zu welchem Bot

Wir schreiben:
@MikrotikROuter_bot

Wir fügen die Befehle hinzu:

  • helloworld< — Testnachricht im Chat 1
  • itsworking — Testnachricht im Chat 2
  • wolmypc — Wecke meinen PC auf

Jetzt, wenn wir im Chat "/" eingeben, sollten wir folgendes erhalten:

Remote-Aktivierung von Mikrotik-Skripten über Telegram

Jetzt wechseln wir zu MikroTik.

In RouterOS gibt es ein Konsolen-Tool zum Kopieren von Dateien über FTP oder HTTP/HTTPS, dieses Tool heißt fetch, und genau das werden wir verwenden.

Wir öffnen terminal und geben ein:

/tool fetch url="https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage?chat_id=631290&text=test " keep-result=no

Bitte beachten Sie, dass in MikroTik ein „“ zur Escape-Technung des „?“ im URL erforderlich ist.

Wir sollten folgendes Ergebnis erhalten:

Remote-Aktivierung von Mikrotik-Skripten über Telegram

Jetzt wechseln wir zu den Skripten:

helloworld

system script add name="helloworld" policy=read source={/tool fetch url="https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage?chat_id=631290&text=Hello,world!" keep-result=no}

itsworking

system script add name="itsworking" policy=read source={/tool fetch url="https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage?chat_id=631290&text=Test OK, it's Working" keep-result=no}

wolmypc

system script add name="wolmypc" policy=read source="/tool wol mac=XX:XX:XX:XX:XX:XX interface=ifname
    /tool fetch url="https://api.telegram.org/boXXXXXXXXXXXXXXXXXXX?chat_id=631290&text=wol OK" keep-result=no"

Bitte geben Sie die richtige MAC-Adresse und den Interface-Namen an, sowie den Bot-Token und chat_id.

Ich werde jetzt etwas erklären, was sie tun:

Das Skript „helloworld“ sendet die Nachricht: „Hallo, Welt!“ in unseren Chat mit dem Bot.
Das Skript „itsworking“ sendet die Nachricht: „Test OK, es funktioniert!“ in unseren Chat mit dem Bot.
Diese Skripte dienen zur Demonstration der Funktionsweise.
Das Skript „wolmypc“ habe ich als eine mögliche Implementierung hinzugefügt.
Nach Ausführung des Skripts wird der Bot in den Chat „wol OK“ schreiben.
Im Grunde kann man jedes beliebige Skript ausführen.

Aufgabe erstellen:

Telegram.src

/system scheduler
add interval=30s name=Telegram on-event=":tool fetch url=("https://api.telegr
    am.org/".$botID."/getUpdates") ;r
    n:global content [/file get [/file find name=getUpdates] contents] ;r
    n:global startLoc 0;r
    n:global endLoc 0;r
    nr
    n:if ( [/file get [/file find name=getUpdates] size] > 50 ) do={r
    nr
    n:set startLoc  [:find $content "update_id" $lastEnd ] ;r
    n:set startLoc ( $startLoc + 11 ) ;r
    n:local endLoc [:find $content "," $startLoc] ;r
    n:local messageId ([:pick $content $startLoc $endLoc] + (1));r
    n:put [$messageId] ;r
    n:#log info message="updateID $messageId" ;r
    nr
    n:set startLoc  [:find $content "text" $lastEnd ] ;r
    n:set startLoc ( $startLoc  + 7 ) ;r
    n:local endLoc [:find $content "," ($startLoc)] ;r
    n:set endLoc ( $endLoc - 1 ) ;r
    n:local message [:pick $content ($startLoc + 2) $endLoc] ;r
    n:put [$message] ;r
    n:#log info message="message $message ";r
    nr
    n:set startLoc  [:find $content "chat" $lastEnd ] ;r
    n:set startLoc ( $startLoc + 12 ) ;r
    n:local endLoc [:find $content "," $startLoc] ;r
    n:local chatId ([:pick $content $startLoc $endLoc]);r
    n:put [$chatId] ;r
    n:#log info message="chatID $chatId ";r
    nr
    n:if (($chatId = $myChatID) and (:put [/system script find name=$messa
    ge] != "")) do={r
    n:system script run $message} else={:tool fetch url=("https://api.teleg
    ram.org/".$botID."/sendmessage?chat_id=".$chatId."&text=I can't t
    alk with you. ") keep-result=no} ;r
    n:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates?
    offset=$messageId") keep-result=no; r
    n} r
    n" policy=
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon 
    start-date=nov/02/2010 start-time=00:00:00
	
add name=Telegram-startup on-event=":delay 5r
    n:global botID "botXXXXXXXXXXXXXXXXXX" ;r
    n:global myChatID "631290" ;r
    n:global startLoc 0;r
    n:global endLoc 0;r
    n:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates") 
    ;" policy=
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon 
    start-time=startup

Lesbarer ZugriffEs ist unklar, warum dasArbeits-Skript keine globalen Daten ausgibt. Ich habe das Skript beim Systemstart hinzugefügt.
Telegram-startup

:delay 5
:global botID "botXXXXXXXXXXXXXXXXXX" ;   token bot
:global myChatID "xxxxxx" ;                               chat_id
:global startLoc 0;
:global endLoc 0;
:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates");

Telegram

:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates") ;
:global content [/file get [/file find name=getUpdates] contents] ;
:global startLoc 0;
:global endLoc 0;

:if ( [/file get [/file find name=getUpdates] size] > 50 ) do={

:set startLoc  [:find $content "update_id" $lastEnd ] ;
:set startLoc ( $startLoc + 11 ) ;
:local endLoc [:find $content "," $startLoc] ;
:local messageId ([:pick $content $startLoc $endLoc] + (1));
:put [$messageId] ;
#:log info message="updateID $messageId" ;

:set startLoc  [:find $content "text" $lastEnd ] ;
:set startLoc ( $startLoc  + 7 ) ;
:local endLoc [:find $content "," ($startLoc)] ;
:set endLoc ( $endLoc - 1 ) ;
:local message [:pick $content ($startLoc + 2) $endLoc] ;
:put [$message] ;
#:log info message="message $message ";

:set startLoc  [:find $content "chat" $lastEnd ] ;
:set startLoc ( $startLoc + 12 ) ;
:local endLoc [:find $content "," $startLoc] ;
:local chatId ([:pick $content $startLoc $endLoc]);
:put [$chatId] ;
#:log info message="chatID $chatId ";

:if (($chatId = $myChatID) and (:put [/system script find name=$message] != "")) do={
:system script run $message} else={:tool fetch url=("https://api.telegram.org/".$botID."/sendmessage?chat_id=".$chatId."&text=Ich kann nicht mit Ihnen sprechen.") keep-result=no} ;
:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates?offset=$messageId") keep-result=no; 
} 

Wie es funktioniert

Wir rufen unsere Nachrichten «getUpdates» alle 30 Sekunden ab und analysieren sie dann, um zu erfahren update_id (Nachrichten-ID) und text (unsere Befehle) und chat_id . Standardmäßig gibt getUpdates zwischen 1 und 100 Nachrichten zurück, zur Vereinfachung löschen wir die Nachricht nach dem Lesen des Befehls. In der Telegram-API steht, dass man die Nachricht mit der Nachrichten-ID + 1 lesen muss.

/getUpdates?offset=update_id + 1

Alles getestet auf Mikrotik rb915 RouterOS 6.37.1
Wenn viele Befehle gleichzeitig gesendet werden, werden sie nacheinander mit einem Intervall von 30 Sekunden ausgeführt.

P.S. Ein großes Dankeschön an Kirill Kazakov für die Idee und meinem Freund Alexander für die Hilfe mit den Skripten.

Links

habrahabr.ru/post/313794
1spla.ru/index.php/blog/telegram_bot_for_mikrotik
core.telegram.org/bots/api
wiki.mikrotik.com/wiki/Manual:Scripting

upd:

03:11:16

Habe die Skripte aktualisiert:

Habe die Überprüfung auf chat_id hinzugefügt
Eine Sicherheitsüberprüfung: Wenn jemand unserem Bot schreibt, antwortet er: » Ich kann nicht mit dir sprechen. «, und wenn er einen Befehl nicht erkennt, antwortet er ähnlich.
Nach Ausführung des Befehls gibt der Bot eine Rückmeldung im Chat (siehe Skript wolmypc)

UDP

Wir haben festgestellt, dass 7Stuntman7 eine Datei mit mehr als ~ 14 Nachrichten nicht mehr von dem Befehl find verarbeitet wird (Einschränkungen von Mikrotik). Daher werde ich das Skript in Zukunft auf Lua umschreiben, danke dafür, ich wusste nichts über Lua. 7Stuntman7 Ich wusste nichts über Lua.

UPD 08.12.2016

In Telegram hat sich anscheinend etwas am „Output“ von getUpdate geändert. Jetzt muss im Hauptskript die Nachrichtenschiebung von 2 auf 1 angepasst werden.

eingeführt wurde, die im Januar dieses Jahres in den Kernel übernommen wurde. Es betrifft ausschließlich die Version 5.1 und tritt in den meisten Fällen auf Systemen mit Samsung-SSD-Speichern auf, bei denen zur Verschlüsselung Daten mit dm-crypt/LUKS über device-mapper/LVM verwendet werden.

:local message [:pick $content ($startLoc + 2) $endLoc] ;

ersetzen mit:

:local message [:pick $content ($startLoc + 1) $endLoc] ;

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster