Hari ini dalam program: Di mana lagi Anda dapat menerapkan Skrip Google Apps jika ide normal berakhir. Otomasi kerja dengan VPNBook melalui serangkaian skrip dalam berbagai bahasa yang saya tidak tahu. Nedo-cURL oleh Mikrotik. Telegram melalui satu tempat, agar tidak berada di tempat lain, pengawasan diri memungkinkan.
Bagian 1. Tanpa Judul
Setahun yang lalu, saya menulis catatan "
Hampir OCR untuk mendapatkan kata sandi VPNBook. PHP + Mikrotik " tentang cara mengatur pengambilan kata sandi otomatis di router Mikrotik untuk akses VPN gratis melalui VPNBook. Awal cerita ada di sana.
Sejak itu, banyak air telah mengalir, di Rusia mereka memblokir situs VPNBook, tetapi bukan server VPN publik itu sendiri, yang dipublikasikan di sana. Script PHP untuk mendekode gambar PNG kata sandi menjadi string teks sekarang juga dapat berfungsi ketika diluncurkan pada server yang lalu lintasnya tidak melewati sistem pemblokiran. Tetapi beberapa waktu lalu, bereksperimen dengan skrip layanan Google Apps Script (GAS )
.google.com , saya memutuskan untuk meninggalkan skrip PHP pada server web eksternal, menggantinya sebagian atau seluruhnya dengan skrip GAS yang berjalan sebagai Aplikasi Web (aplikasi web). Saya tidak memahami kebijakan eksekusi dan pembatasan GAS, tetapi semua yang saya lakukan berfungsi di akun Google gratis dan belum meminta uang. Saya tidak memiliki tujuan untuk menjelaskan Skrip Google Apps secara terperinci. GAS didasarkan pada bahasa JavaScript, Anda dapat menggunakan perpustakaan JS pihak ketiga, Anda dapat mempublikasikan skrip sebagai aplikasi web, yang dapat dibuat tersedia untuk semua orang tanpa otorisasi. Kemampuan implementasi GAS saat ini tidak cukup bagi saya, jadi saya harus keluar dan mencari solusi.
Awalnya saya memutuskan untuk menulis proxy untuk gambar PNG. Skrip web seharusnya meminta gambar kata sandi dari situs VPNBook (saya ingat bahwa kata sandi itu diterbitkan di sana dalam PNG) dan memberikannya kepada klien yang menyebut skrip ini untuk decoding. Cara seperti itu untuk berkeliling. Di sini pembatasan pertama GAS bertemu. Ternyata skrip tidak dapat merender gambar / png MIME, tetapi hanya format teks, JSON, TEXT, XML, dll. Tapi ada cara untuk mengatasi ini. Anda bisa menyandikan PNG ke Base64 dan mengembalikan string teks ke klien. Ada skrip serupa di Internet, misalnya
techslides.com/image-proxy-with-google-app-scripts . Saya hanya menyederhanakan salah satunya. Saya hanya membutuhkan satu gambar dan hanya mengeluarkan string Base64. Hasilnya adalah skrip yang hanya terdiri dari satu fungsi doGet - pengendali permintaan GET yang mengembalikan string sebagai respons.
function doGet() { var response = UrlFetchApp.fetch('https://www.vpnbook.com/password.php'); var b64 = Utilities.base64Encode(response.getContent());
Contoh keluaran browser:
iVBORw0KGgoAAAANSUhEUgAAAGQAAAANAQMAAABl11mFAAAABlBMVEX29vZMTExY89ZbAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAVUlEQVQImWNgIBrwSzCw/2ZgOADhSc5gYJCG8wxQedLdCcYFNXcgPHOZsxuSZxx7BuFZzsjdcJi34TBU5Y3cjc3IvM3McJ7kjNxtzDwwffwSIB7UTACt/h52C5DFqQAAAABJRU5ErkJggg==
Selanjutnya adalah skrip PHP, yang dapat ditempatkan di server di dalam zona dengan penguncian sumber daya. Ini sangat mirip dengan skrip dari artikel sebelumnya, kecuali untuk perubahan kecil dalam parameter panggilan CURL. Anda harus mengizinkan cURL untuk mengakses HTTP / 1.1 302 Dipindahkan Sementara, karena GAS, ketika dipanggil, mengalihkan dari alamat skrip web ke alamat sementara dinamis:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
Dan decoding Base64:
$imgOCR = imagecreatefromstring(base64_decode($output));
Skrip PHP ini menerjemahkan sandi PNG dan mengembalikannya sebagai string teks. Selanjutnya, seperti pada artikel pertama di bagian tentang Mikrotik. Router mengambil kata sandi menggunakan fetch.
Hasilnya adalah skema kerja 2 layanan perantara di depan Mikrotik.
Bagian 2. Dorong GAS. Singkirkan skrip dekoder PHP
Selama percobaan dengan GAS, muncul ide untuk meninggalkan decoder kata sandi dalam PHP, menulis ulang dalam GAS. Dan di sini ditemukan masalah besar: Google script tidak memiliki fungsi pemrosesan PNG, satu-satunya hal yang dapat dilakukan adalah mengubah PNG menjadi array byte. Tidak ada pertanyaan tentang manipulasi dengan bagian gambar dan piksel. Saya naik ke Github mencari perpustakaan JS untuk bekerja dengan PNG, saya menemukan banyak dari mereka: PNG.js, UPNG.js, pngjs. Beberapa tidak mendukung kedalaman warna 1-bit piksel PNG (gambar dengan kata sandi). Mereka menarik berbagai pustaka kompresi zlib. Secara umum, itu semua tampak sedikit rumit bagi saya, dan saya memutuskan untuk menulis sendiri konverter primitif hanya untuk gambar PNG saya ke bitmap dengan fungsi mengakses piksel dengan koordinat XY. Kemudian datang perendaman lengkap dalam format PNG: hex editor, standar membaca, banyak deskripsi di jaringan. Dan akhirnya, saya berlari ke bagian PNG dari file IDAT, dikemas dengan zlib, yang berisi array piksel.
Untuk itu diperlukan fungsi unpacking zlib, yang tentu saja tidak ada di GAS. Anehnya, mereka memiliki gzip / ungzip dan zip / unzip, tetapi tidak ada zlib. Setelah membaca tentang gzip (tingkat kedua perendaman setelah format PNG), saya sampai pada kesimpulan bahwa tidak mungkin untuk merakit "sepeda" dalam bentuk arsip kuasi-gzip dari bagian IDAT, meskipun kompresi zlib digunakan di sana-sini. Karena Untuk membangun arsip gzip yang valid, Anda perlu mengetahui panjang data yang sudah dibongkar, yang tidak bisa saya dapatkan tanpa membukanya :) Dan dengan panjang yang salah, GAS menganggap arsip rusak. Pada akhirnya, saya menoleh ke Github dan menemukan solusi hebat: zlib.js untuk pustaka Skrip Google Apps (https://github.com/hinimub/zlib.js/blob/develop/README.en.md). Yang secara khusus disiapkan untuk integrasi ke dalam proyek GAS melalui perpustakaan kunci proyek. Kemudian teka-teki mulai menyatu. Setelah menulis dekompresi array piksel dan fungsi untuk mengakses koordinat piksel XY, dimungkinkan untuk mentransfer skrip dekoder dari PHP ke GAS.
Dihitung secara terpisah tabel hash dari kamus karakter kata sandi yang mungkin. Ini adalah tindakan satu kali yang saya lakukan dalam program pihak ketiga (di LabVIEW, halo, kolega). Setiap karakter dalam gambar dapat dialokasikan sebagai 8 bit (tanpa indentasi) x 10 baris. 1 byte sudah cukup untuk menyandikan 8 piksel dari satu baris karakter. Anda dapat menyimpan string piksel dalam seluruh angka (byte), dan seluruh karakter sebagai urutan 10 byte. Ternyata 10 angka heks per karakter. Selanjutnya, decoder GAS mengulangi nenek moyang PHP-nya.
Hasilnya adalah skrip yang berfungsi sepenuhnya dalam GAS. function doGet() {
'A', 'FCC6C3C6FCC6C3C3C6FC': 'B', '3E63C1C0C0C0C0C1633E': 'C', 'FCC6C3C3C3C3C3C3C6FC': 'D', 'FEC0C0C0FCC0C0C0C0FE': 'E', 'FFC0C0C0FCC0C0C0C0C0': 'F function doGet() {
'' C3C3C3C3FFC3C3C3C3C3 ':' H '' 7E18181818181818187E ':' aku '' 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() {
Script hanya mengimplementasikan metode GET. Saat menjalankan permintaan GET untuk skrip ini, yang diterbitkan sebagai Aplikasi Web, respons akan segera berisi kata sandi yang didekodekan dalam bentuk string.
Bagian 3. Mikrotik dan Pindah Sementara 302
Jadi, kami memiliki skrip yang berjalan di server Aplikasi Web eksternal, yang tidak tergantung pada kunci dan mengembalikan kata sandi teks biasa. Dan sepertinya tidak ada yang lebih mudah daripada memintanya dengan mengambil perintah di RouterOS Mikrotik. Tapi kemudian kejutan lain menunggu saya. Menanggapi permintaan (alamat asli diubah), ambil pengembalian "302 Pindah Sementara".
[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>
Di awal artikel, saya sudah menulis tentang ini. Saat mengakses URL yang diketahui tetap dari skrip Aplikasi Web, Google mengalihkan ke URL sementara, yang pada gilirannya mengembalikan respons terhadap permintaan. Tapi tidak seperti PHP cURL, mengambil RouterOS tidak tahu bagaimana harus melalui pengalihan, malah mengembalikan kegagalan. Tapi forum.mikrotik.com tidak segera, tetapi ada solusinya. Anda dapat mengarahkan standar mengambil output dari konsol ke file dengan memanggil eksekusi asinkron dalam tugas terpisah dengan membungkus: mengeksekusi. Anda kemudian dapat mengambil URL pengalihan dan mengambil kembali sudah dengan alamat baru. Yang dilakukan di bawah ini.
Berikut adalah teks lengkap skrip Mikrotik untuk bekerja dengan Aplikasi Web GAS Bagian 4. Proxy Telegram GAS
Saya memutuskan untuk mengabdikan bagian ini pada iterasi berikutnya untuk mengintegrasikan layanan Telegram ke Mikrotik. Menggunakan GAS di sini adalah murni kepentingan akademis jika bukan karena kenyataan memblokir layanan Telegram, termasuk api.telegram.org, di mana bot bekerja dengan layanan tersebut. Gagasan ini mengulangi gagasan di awal artikel tentang proksi permintaan gambar PNG.
Dalam hal ini, Aplikasi Web GAS ditulis untuk permintaan proxy dari Mikrtotik ke api.telegram.org. Sebagai dasar, saya mengambil skrip yang sudah jadi dari manzoorwanijk, WPTelegram Google Script
gist.github.com/manzoorwanijk/ee9ed032caedf2bb0c83dea73bc9a28e . Skrip ini dapat mem-proksi banyak metode API Telegram (tetapi tidak semua). Dalam args, Anda dapat mengirimkan objek JSON yang berisi parameter permintaan, misalnya
{"chat_id":"123","text":"HelloWorld"}
. Tetapi untuk tugas saya mengirim pesan teks dari RouterOS Mikrtotik, implementasinya tampak rumit dan saya menyederhanakannya. Pada akhirnya, Anda biasanya dapat menulis beberapa skrip Aplikasi Web untuk mem-proksi berbagai metode API Telegram. Inilah implementasi saya untuk metode sendMessage. Lebih lanjut dapat disederhanakan dengan menanamkan nama metode sendMessage yang disebut, dan bahkan bot_token dan chat_id ke dalam tubuh fungsi requestHandler.
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(); } }
Setelah menerbitkan skrip di Aplikasi Web, Anda dapat menjalankan permintaan di browser GET untuk memeriksa:
https://script.google.com/macros/s/A.....A/exec?bot_token=3.....3&method=sendMessage&chat_id=2.....3&text=testtext123
Atau dalam permintaan POST RouterOS:
: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={ }
Permintaan dibungkus dengan do-on-error, karena, seperti yang ditunjukkan di atas, panggilan pertama untuk mengambil akan mengeluarkan pengecualian "Dipindahkan Sementara 302" dan skrip tanpa penangan kesalahan akan berhenti pada titik ini. Satu panggilan untuk mengambil tanpa meneruskan cukup untuk pesan yang akan dikirim, sehingga panggilan kedua untuk mengambil tidak diperlukan jika Anda tidak perlu objek JSON dikembalikan oleh API Telegram.
Bagian 5. Final
Saya membawa aplikasi saya yang sebenarnya di persimpangan Google Apps Script dengan layanan lain. Anda dapat menghasilkan lebih banyak. Misalnya, tulis bot Telegram di GAS yang akan merespons dengan kata sandi VPNBook dengan permintaan caching untuk mengurangi beban pada VPNBook (Layanan Cache), dan semua ini akan berada dalam satu skrip GAS. Anda dapat menulis pada GAS sistem pencatatan atau konfigurasi cadangan untuk Mikrtotik, yang akan ditempatkan di file Google Docs dan Google Sheets dan banyak lagi.