Heute im Programm: Wo sonst können Sie Google Apps Script anwenden, wenn die normalen Ideen vorbei sind. Automatisierung der Arbeit mit VPNBook durch eine Reihe von Skripten in verschiedenen Sprachen, die ich nicht kenne. Nedo-cURL von Mikrotik. Telegramm durch einen Ort, um nicht in einem anderen zu sein, erlaubt Selbstüberwachung.
Teil 1. Ohne Titel
Vor einem Jahr schrieb ich einen Hinweis „
Fast OCR, um ein VPNBook-Passwort zu erhalten. PHP + Mikrotik “ darüber, wie die automatische Passwortabfrage im Mikrotik-Router für den kostenlosen VPN-Zugang über VPNBook eingerichtet wird. Der Anfang der Geschichte ist da.
Seitdem ist viel Wasser geflossen, in Russland haben sie die VPNBook-Site blockiert, aber nicht die öffentlichen VPN-Server selbst, die darauf veröffentlicht werden. Das PHP-Skript zum Dekodieren eines PNG-Bildes eines Kennworts in eine Textzeichenfolge sollte jetzt auch funktionieren, wenn es auf einem Server gestartet wird, dessen Datenverkehr nicht durch das Blockierungssystem geleitet wird. Als ich vor einiger Zeit mit dem Google Apps Script (GAS)
-Dienst script.google.com experimentierte , entschied ich mich, das PHP-Skript auf einem externen Webserver aufzugeben und es teilweise oder vollständig durch ein GAS-Skript zu ersetzen, das als Web App (Webanwendung) ausgeführt wird. Ich habe die Ausführungsrichtlinien und die GAS-Einschränkungen nicht verstanden, aber alles, was ich getan habe, funktioniert in einem kostenlosen Google-Konto und verlangt noch kein Geld. Ich habe nicht das Ziel, Google Apps Script detailliert zu beschreiben. GAS basiert auf der JavaScript-Sprache, Sie können JS-Bibliotheken von Drittanbietern verwenden, Sie können das Skript als Webanwendung veröffentlichen, die jedem ohne Autorisierung zur Verfügung gestellt werden kann. Die Möglichkeiten der aktuellen GAS-Implementierung reichten mir nicht aus, sodass ich nach Lösungen suchen musste.
Zuerst habe ich beschlossen, einen Proxy für PNG-Bilder zu schreiben. Das Web-Skript musste ein Passwort-Image von der VPNBook-Website anfordern (ich erinnere mich, dass das Passwort dort in PNG veröffentlicht wurde) und es dem Client geben, der dieses Skript zum Dekodieren aufrief. So kommen Sie um das Schloss herum. Hier traf die erste Einschränkung von GAS ein. Es stellt sich heraus, dass das Skript kein MIME-Bild / PNG rendern kann, sondern nur Textformate, JSON, TEXT, XML usw. Aber es gab einen Weg, dies zu umgehen. Sie können PNG in Base64 codieren und eine Textzeichenfolge an den Client zurückgeben. Es gibt ähnliche Skripte im Internet, zum Beispiel
techslides.com/image-proxy-with-google-app-scripts . Ich habe nur einen von ihnen vereinfacht. Ich brauchte nur ein Bild und gab nur Base64-Strings aus. Das Ergebnis ist ein Skript, das nur aus einer doGet-Funktion besteht - einem GET-Anforderungshandler, der als Antwort eine Zeichenfolge zurückgibt.
function doGet() { var response = UrlFetchApp.fetch('https://www.vpnbook.com/password.php'); var b64 = Utilities.base64Encode(response.getContent());
Beispiel für eine Browserausgabe:
iVBORw0KGgoAAAANSUhEUgAAAGQAAAANAQMAAABl11mFAAAABlBMVEX29vZMTExY89ZbAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAVUlEQVQImWNgIBrwSzCw/2ZgOADhSc5gYJCG8wxQedLdCcYFNXcgPHOZsxuSZxx7BuFZzsjdcJi34TBU5Y3cjc3IvM3McJ7kjNxtzDwwffwSIB7UTACt/h52C5DFqQAAAABJRU5ErkJggg==
Als nächstes kommt das PHP-Skript, das mit Resource Locking auf dem Server innerhalb der Zone platziert werden kann. Es ist dem Skript aus dem vorherigen Artikel sehr ähnlich, abgesehen von einer kleinen Änderung der Parameter des cURL-Aufrufs. Sie müssen zulassen, dass cURL vorübergehend über HTTP / 1.1 verschoben wird, da Wenn GAS aufgerufen wird, wird es von der Web-Skript-Adresse zu einer dynamischen temporären Adresse umgeleitet:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
Und Base64-Dekodierung:
$imgOCR = imagecreatefromstring(base64_decode($output));
Dieses PHP-Skript decodiert das PNG-Passwort und gibt es als Textzeichenfolge zurück. Weiter wie im ersten Artikel im Teil über Mikrotik. Der Router ermittelt das Passwort mit fetch.
Das Ergebnis war ein solches Arbeitsschema von 2 Zwischendiensten vor Mikrotik.
Teil 2. Drücken Sie auf GAS. Befreien Sie sich von PHP-Decoder-Skript
Während der Experimente mit GAS entstand die Idee, den Passwortdecoder in PHP ganz aufzugeben und in GAS umzuschreiben. Und hier wurde ein großes Problem entdeckt: Google-Skript verfügt nicht über PNG-Verarbeitungsfunktionen. Das einzige, was getan werden kann, ist, PNG in ein Byte-Array zu konvertieren. Manipulationen mit Bildteilen und Pixeln waren ausgeschlossen. Ich bin auf der Suche nach der JS-Bibliothek für die Arbeit mit PNG auf Github gestiegen und habe viele gefunden: PNG.js, UPNG.js, pngjs. Einige unterstützen die 1-Bit-Farbtiefe eines PNG-Pixels (Bild mit Passwort) nicht. Sie zogen verschiedene zlib-Komprimierungsbibliotheken mit. Im Allgemeinen schien mir alles etwas umständlich zu sein, und ich beschloss, selbst einen primitiven Konverter nur für mein PNG-Bild in eine Bitmap mit der Funktion zu schreiben, auf Pixel über XY-Koordinaten zuzugreifen. Dann kam ein komplettes Eintauchen in das PNG-Format: Hex-Editor, Lesestandards, jede Menge Beschreibungen im Netzwerk. Und schließlich stieß ich auf den PNG-Abschnitt der IDAT-Datei, der mit zlib gepackt war und eine Reihe von Pixeln enthielt.
Es wurde eine Funktion zum Entpacken von zlib benötigt, die natürlich nicht in GAS enthalten war. Überraschenderweise haben sie gzip / ungzip und zip / unzip, aber keine zlib. Nachdem ich über gzip gelesen hatte (die zweite Stufe des Eintauchens nach dem PNG-Format), kam ich zu dem Schluss, dass es nicht möglich sein würde, ein „Fahrrad“ in Form eines gzip-Quasi-Archivs aus der IDAT-Sektion zusammenzustellen, obwohl hier und da ZLIB-Komprimierung verwendet wird. Weil Um ein gültiges gzip-Archiv zu erstellen, müssen Sie die Länge der entpackten Daten kennen, die ich nicht bekommen könnte, ohne sie zu entpacken :) Und mit der falschen Länge betrachtete GAS das Archiv als beschädigt. Am Ende habe ich mich an Github gewandt und eine großartige Lösung gefunden: die Skriptbibliothek zlib.js für Google Apps (https://github.com/hinimub/zlib.js/blob/develop/README.en.md). Das speziell für die Integration in GAS-Projekte durch Projektschlüsselbibliotheken vorbereitet wurde. Dann begann das Rätsel zu konvergieren. Nach dem Schreiben der Dekomprimierung des Pixelarrays und der Funktion zum Zugreifen auf die Koordinaten des XY-Pixels konnte das Decoderskript von PHP nach GAS übertragen werden.
Separat berechnete Hash-Tabelle eines Wörterbuchs mit möglichen Kennwortzeichen. Dies ist eine einmalige Aktion, die ich in einem Drittanbieterprogramm durchgeführt habe (in LabVIEW, hallo, Kollegen). Jedes Zeichen im Bild kann mit 8 Bit (ohne Einrückung) x 10 Zeilen belegt werden. Ein Byte reicht aus, um 8 Pixel einer Zeile eines Zeichens zu codieren. Sie können eine Folge von Pixeln in einer ganzen Zahl (Byte) und das gesamte Zeichen als Folge von 10 Byte speichern. Es werden 10 Hexadezimalzahlen pro Zeichen ausgegeben. Als nächstes wiederholt der GAS-Decoder seinen PHP-Vorgänger.
Das Ergebnis ist ein Skript, das vollständig in GAS funktioniert. function doGet() {
'A', 'FCC6C3C6FCC6C3C3C6FC': 'B', '3E63C1C0C0C0C0C1633E': 'C', 'FCC6C3C3C3C3C3C3C6FC': 'D', 'FEC0C0C0FCC0C0C0C0FE': 'E', 'FFC0C0C0FCC0C0C0C0C0': ‚F function doGet() {
'' C3C3C3C3FFC3C3C3C3C3 ':' H '' 7E18181818181818187E ':' I '' 1E666666466C38 ':' J '' C3C6CCD8F0F0D8CCC6C3 ':' K '' C0C0C0C0C0C0C0C0C0FE ':' L‘, function doGet() {
'C3E3F3F3DBDBCFC7C7C3': 'N', '3C66C3C3C3C3C3C3663C': 'O', 'FEC3C3C3FEC0C0C0C0C0': 'P', '3C66C3C3C3C3DBCF663D': 'Q', 'FEC3C3C3FEF8CCC6C3C3': 'R', ‚7EC3C0C07E333C37E function doGet() {
000B6DBDBDBDBDBDB ':' m '' 000DCE6C3C3C3C3C3 ':' n '' 0003C66C3C3C3663C ':' o '' 000DCE6C3C3C3E6DC ':' p '' 0003B67C3C3C3673B ':' q '' 000DE736060606060 ' function doGet() {
Das Skript implementiert nur die GET-Methode. Wenn Sie eine GET-Anforderung für dieses als Web App veröffentlichte Skript ausführen, enthält die Antwort sofort das dekodierte Kennwort in Form einer Zeichenfolge.
Teil 3. Mikrotik und vorübergehend umgezogen 302
Wir haben also ein Skript, das auf externen Web-App-Servern ausgeführt wird, das unabhängig von Sperren ist und ein Nur-Text-Kennwort zurückgibt. Und es scheint, dass es nichts Einfacheres gibt, als es mit dem Abrufbefehl in RouterOS Mikrotik anzufordern. Aber dann erwartete mich eine weitere Überraschung. Als Antwort auf die Anforderung (reale Adressen geändert) gibt der Abruf "302 Vorübergehend verschoben" zurück.
[admin@MikroTik] /environment> :put ([/tool fetch url="https://script.google.com/macros/s/A.....A/exec" http-method=get output=user as-value]->"data") failure: closing connection: <302 Moved Temporarily "https://script.googleusercontent.com/macros/echo?user_content_key=....."> 173.194.222.138:443 (4) [admin@MikroTik] /environment>
Zu Beginn des Artikels habe ich bereits darüber geschrieben. Beim Zugriff auf die persistente bekannte URL des Web App-Skripts leitet Google zu einer temporären URL weiter, die wiederum eine Antwort auf die Anforderung zurückgibt. Im Gegensatz zu PHP cURL weiß fetch RouterOS jedoch nicht, wie man Weiterleitungen durchläuft, sondern gibt einen Fehler zurück. Aber forum.mikrotik.com hat nicht sofort, aber es gab eine Problemumgehung. Sie können die Standardabrufausgabe von der Konsole in eine Datei umleiten, indem Sie die asynchrone Ausführung in einer separaten Task mit dem folgenden Befehl aufrufen: execute. Sie können dann die Weiterleitungs-URL abrufen und bereits mit der neuen Adresse erneut abrufen. Welches wird unten getan.
Hier finden Sie den vollständigen Text des Mikrotik-Skripts für die Arbeit mit der GAS-Web-App Teil 4. Telegramm-GAS-Proxy
Ich beschloss, diesen Teil der nächsten Iteration der Integration des Telegrammdienstes in Mikrotik zu widmen. Die Verwendung von GAS wäre hier von rein akademischem Interesse, wenn nicht der Telegrammdienst, einschließlich api.telegram.org, blockiert würde, über den Bots mit dem Dienst arbeiten. Die Idee wiederholt die Idee am Anfang des Artikels über das Proxying der Anforderung von PNG-Bildern.
In diesem Fall wird die GAS-Web-App auf Proxy-Anfragen von Mikrtotik an api.telegram.org geschrieben. Als Grundlage nahm ich ein fertiges Skript von manzoorwanijk, WPTelegram Google Script
gist.github.com/manzoorwanijk/ee9ed032caedf2bb0c83dea73bc9a28e . Dieses Skript kann viele (aber nicht alle) Telegramm-API-Methoden als Proxy verwenden. In args können Sie ein JSON-Objekt übergeben, das die Anforderungsparameter enthält, z. B.
{"chat_id":"123","text":"HelloWorld"}
. Für meine Aufgabe, Textnachrichten von RouterOS Mikrtotik zu senden, schien die Implementierung jedoch kompliziert und ich habe sie vereinfacht. Letztendlich können Sie im Allgemeinen mehrere Web-App-Skripts schreiben, um verschiedene Telegramm-API-Methoden zu vertreten. Hier ist meine Implementierung für die sendMessage-Methode. Sie können dies weiter vereinfachen, indem Sie den Namen der aufgerufenen sendMessage-Methode und sogar bot_token und chat_id in den Hauptteil der requestHandler-Funktion einbetten.
function doGet(e) { if(typeof e !== 'undefined'){ return ContentService.createTextOutput(requestHandler(e)); } } function doPost(e) { if(typeof e !== 'undefined'){ return ContentService.createTextOutput(requestHandler(e)); } } function requestHandler(e){ if (typeof e.parameter.bot_token === 'undefined'){ return 'Error! Bot token not provided'; } else if (typeof e.parameter.method === 'undefined') { return 'Error! Method name not provided'; } else if (typeof e.parameter.chat_id === 'undefined') { return 'Error! Chat id not provide'; } else if (typeof e.parameter.text === 'undefined') { return 'Error! Text not provide'; } if (e.parameter.method === 'sendMessage') { var data = { "method": "post", "muteHttpExceptions": true, payload : 'chat_id=' + e.parameter.chat_id + '&text=' + e.parameter.text } return UrlFetchApp.fetch('https://api.telegram.org/bot' + e.parameter.bot_token + '/' + e.parameter.method, data).getContentText(); } }
Nach dem Veröffentlichen des Skripts in der Web App können Sie im GET-Browser eine Anforderung ausführen, um Folgendes zu überprüfen:
https://script.google.com/macros/s/A.....A/exec?bot_token=3.....3&method=sendMessage&chat_id=2.....3&text=testtext123
Oder in RouterOS POST Anfrage:
:do { /tool fetch url=("https://script.google.com/macros/s/A.....A/exec") keep-result=no http-method=post http-data=("bot_token=3.....3&method=sendMessage&chat_id=2.....3&text=testtext123") } on-error={ }
Die Anforderung wird in do-on-error eingeschlossen, da der erste Aufruf zum Abrufen, wie oben gezeigt, die Ausnahme "Vorübergehend verschoben 302" auslöst und das Skript ohne den On-Error-Handler an dieser Stelle stoppt. Ein Aufruf zum Abrufen ohne Weiterleitung reicht aus, damit die Nachricht gesendet wird. Ein zweiter Aufruf zum Abrufen ist daher nicht erforderlich, wenn Sie das von der Telegramm-API zurückgegebene JSON-Objekt nicht benötigen.
Teil 5. Schluss
Ich habe meine echten Anwendungen an die Schnittstelle von Google Apps Script mit anderen Diensten gebracht. Sie können sich viel mehr einfallen lassen. Schreiben Sie beispielsweise einen Telegramm-Bot in GAS, der mit einem VPNBook-Kennwort mit Caching-Anforderungen antwortet, um die Belastung des VPNBook (Cache-Dienst) zu verringern. Dies alles wird in einem GAS-Skript ausgeführt. Sie können auf GAS ein Protokollierungssystem oder Sicherungskonfigurationen für Mikrtotik schreiben, die in Google Text & Tabellen- und Google Sheets-Dateien gespeichert werden, und vieles mehr.