Hoje no programa: onde mais você pode aplicar o Script do Google Apps se as idéias normais acabarem? Automação do trabalho com o VPNBook por meio de uma cadeia de scripts em diferentes idiomas que eu não conheço. Nedo-cURL por Mikrotik. Telegrama através de um lugar, para não ficar em outro, a auto-supervisão permite.
Parte 1. Sem título
Há um ano, escrevi uma nota "
Quase OCR para obter uma senha do VPNBook. PHP + Mikrotik " sobre como configurar a recuperação automática de senha em um roteador Mikrotik para obter acesso gratuito à VPN via VPNBook. O começo da história está aí.
Desde então, muita água correu; na Rússia, eles bloquearam o site VPNBook, mas não os servidores VPN públicos, que são publicados nele. Agora, esse script PHP para decodificar uma imagem PNG de uma senha em uma sequência de texto também funcionará quando iniciado em um servidor cujo tráfego não é passado pelo sistema de bloqueio. Mas, há algum tempo, experimentando o
serviço script.google.com do Google Apps Script (GAS), decidi abandonar o script PHP em um servidor web externo, substituindo-o parcial ou totalmente por um script GAS em execução como um aplicativo Web (aplicativo Web). Não entendi a política de execução e as restrições de GAS, mas tudo o que fiz funciona em uma conta gratuita do Google e ainda não pede dinheiro. Não tenho o objetivo de descrever o Script do Google Apps em detalhes. O GAS é baseado na linguagem JavaScript, você pode usar bibliotecas JS de terceiros, publicar o script como um aplicativo da Web, que pode ser disponibilizado para todos sem autorização. Os recursos da implementação atual do GAS não eram suficientes para mim, então tive que sair e procurar soluções alternativas.
No começo, decidi escrever um proxy para imagens PNG. O script da web deveria solicitar uma imagem de senha no site do VPNBook (lembro que a senha foi publicada lá em PNG) e fornecê-la ao cliente que chamou esse script para decodificação. Uma maneira de contornar a fechadura. Aqui a primeira restrição do GAS foi cumprida. Acontece que o script não pode renderizar MIME image / png, mas apenas formatos de texto, JSON, TEXT, XML, etc. Mas havia uma maneira de contornar isso. Você pode codificar PNG para Base64 e retornar uma sequência de texto para o cliente. Existem scripts semelhantes na Internet, por exemplo,
techslides.com/image-proxy-with-google-app-scripts . Eu apenas simplifiquei um deles. Eu precisava de apenas uma imagem e emitir apenas seqüências Base64. O resultado é um script que consiste em apenas uma função doGet - um manipulador de solicitações GET que retorna uma string em resposta.
function doGet() { var response = UrlFetchApp.fetch('https://www.vpnbook.com/password.php'); var b64 = Utilities.base64Encode(response.getContent());
Exemplo de saída do navegador:
iVBORw0KGgoAAAANSUhEUgAAAGQAAAANAQMAAABl11mFAAAABlBMVEX29vZMTExY89ZbAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAVUlEQVQImWNgIBrwSzCw/2ZgOADhSc5gYJCG8wxQedLdCcYFNXcgPHOZsxuSZxx7BuFZzsjdcJi34TBU5Y3cjc3IvM3McJ7kjNxtzDwwffwSIB7UTACt/h52C5DFqQAAAABJRU5ErkJggg==
A seguir, vem o script PHP, que pode ser colocado no servidor dentro da zona com bloqueio de recursos. É muito semelhante ao script do artigo anterior, exceto por uma pequena alteração nos parâmetros da chamada cURL. É necessário permitir que o cURL passe por HTTP / 1.1 302 movido temporariamente, porque O GAS, quando chamado, redireciona do endereço de script da web para um endereço temporário dinâmico:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
E decodificação Base64:
$imgOCR = imagecreatefromstring(base64_decode($output));
Esse script PHP decodifica a senha PNG e a retorna como uma sequência de texto. Além disso, como no primeiro artigo da parte sobre Mikrotik. O roteador pega a senha usando buscar.
O resultado foi um esquema de funcionamento de 2 serviços intermediários na frente do Mikrotik.
Parte 2. Pressione GAS. Livre-se do script decodificador PHP
Durante os experimentos com o GAS, surgiu a idéia de abandonar o decodificador de senhas no PHP, reescrevendo-o no GAS. E aqui foi descoberto um grande problema: o script do Google não possui funções de processamento PNG, a única coisa que pode ser feita é converter PNG em uma matriz de bytes. Não houve dúvida de qualquer manipulação com partes e pixels da imagem. Subi no Github em busca de uma biblioteca JS para trabalhar com PNG, encontrei muitos deles: PNG.js, UPNG.js, pngjs. Alguns não suportam a profundidade de cor de 1 bit de um pixel PNG (imagem com senha). Eles puxaram várias bibliotecas de compactação zlib. Em geral, tudo me pareceu um pouco complicado, e decidi escrever sozinho um conversor primitivo apenas para minha imagem PNG em um bitmap com a função de acessar pixels pelas coordenadas XY. Então veio uma imersão completa no formato PNG: editor hexadecimal, padrões de leitura, montes de descrições na rede. E, finalmente, encontrei a seção PNG do arquivo IDAT, embalada com zlib, que continha uma matriz de pixels.
Exigia uma função para descompactar o zlib, que obviamente não estava no GAS. Surpreendentemente, eles têm gzip / ungzip e zip / unzip, mas não zlib. Depois de ler sobre o gzip (o segundo nível de imersão após o formato PNG), cheguei à conclusão de que não seria possível montar uma “bicicleta” na forma de um quase-arquivo gzip na seção IDAT, embora a compactação zlib seja usada aqui e ali. Porque Para criar um arquivo gzip válido, você precisa saber o tamanho dos dados descompactados, o que eu não conseguia obter sem descompactá-los :) E com o tamanho errado, o GAS considerou o arquivo corrompido. No final, virei para o Github e encontrei uma ótima solução: a biblioteca de scripts zlib.js para o Google Apps (https://github.com/hinimub/zlib.js/blob/develop/README.en.md). Que foi especialmente preparado para integração em projetos de GAS através de bibliotecas de chaves de projeto. Então o quebra-cabeça começou a convergir. Após escrever a descompressão da matriz de pixels e a função de acessar as coordenadas do pixel XY, foi possível transferir o script do decodificador do PHP para o GAS.
Calculou separadamente uma tabela de hash de um dicionário de possíveis caracteres de senha. Esta é uma ação única que realizei em um programa de terceiros (no LabVIEW, olá, colegas). Cada caractere na imagem pode ser alocado como 8 bits (sem indentação) x 10 linhas. 1 byte é suficiente para codificar 8 pixels de uma linha de um caractere. Você pode armazenar uma sequência de pixels em um número inteiro (byte) e o caractere inteiro como uma sequência de 10 bytes. Acontece 10 números hexadecimais por caractere. Em seguida, o decodificador GAS repete seu progenitor PHP.
O resultado é um script que funciona totalmente no GAS. 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', 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() {
O script implementa apenas o método GET. Ao executar uma solicitação GET para esse script, publicada como Web App, a resposta conterá imediatamente a senha decodificada na forma de uma sequência.
Parte 3. Mikrotik e Movido Temporariamente 302
Portanto, temos um script que é executado em servidores externos de aplicativos da Web, independentes dos bloqueios e retornando uma senha em texto sem formatação. E parece que não há nada mais fácil do que solicitá-lo com o comando buscar no RouterOS Mikrotik. Mas então outra surpresa me esperava. Em resposta à solicitação (endereços reais alterados), a busca retorna "302 movido temporariamente".
[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>
No começo do artigo, eu já escrevi sobre isso. Ao acessar o URL conhecido persistente do script do Web App, o Google redireciona para um URL temporário, que por sua vez retorna uma resposta à solicitação. Mas, diferentemente do PHP cURL, o Buster RouterOS não sabe como passar por redirecionamentos, mas retorna uma falha. Mas forum.mikrotik.com não o fez imediatamente, mas houve uma solução alternativa. Você pode redirecionar a saída de busca padrão do console para um arquivo chamando a execução assíncrona em uma tarefa separada, envolvendo: execute. Você pode recuperar o URL de redirecionamento e buscar novamente já com o novo endereço. O que é feito abaixo.
Aqui está o texto completo do script Mikrotik para trabalhar com o GAS Web App Parte 4. Proxy de Telegrama GAS
Decidi dedicar esta parte à próxima iteração de integração do serviço Telegram no Mikrotik. Usar o GAS aqui seria de interesse puramente acadêmico se não fosse a realidade de bloquear o serviço Telegram, incluindo o api.telegram.org, por meio do qual os robôs trabalham com o serviço. A ideia repete a ideia no início do artigo sobre solicitação de proxy para imagens PNG.
Nesse caso, o GAS Web App é gravado em solicitações de proxy do Mikrtotik para api.telegram.org. Como base, peguei um script pronto de manzoorwanijk, WPTelegram Google Script
gist.github.com/manzoorwanijk/ee9ed032caedf2bb0c83dea73bc9a28e . Esse script pode usar como proxy muitos métodos da API do Telegram (mas não todos). Em args, você pode transmitir um objeto JSON que contém os parâmetros de solicitação, por exemplo
{"chat_id":"123","text":"HelloWorld"}
. Mas para a minha tarefa de enviar mensagens de texto do RouterOS Mikrtotik, a implementação parecia complicada e eu a simplifiquei. Por fim, você geralmente pode escrever vários scripts do Web App para fazer proxy de vários métodos da API do Telegram. Aqui está minha implementação para o método sendMessage. Isso pode ser simplificado ainda mais, incorporando o nome do método sendMessage que está sendo chamado e até bot_token e chat_id no corpo da função 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(); } }
Depois de publicar o script no Web App, você pode executar uma solicitação no navegador GET para verificar:
https://script.google.com/macros/s/A.....A/exec?bot_token=3.....3&method=sendMessage&chat_id=2.....3&text=testtext123
Ou na solicitação do RouterOS POST:
: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={ }
A solicitação é agrupada em do-on-error, porque, como mostrado acima, a primeira chamada a buscar lançará uma exceção “Movido Temporariamente 302” e o script sem o manipulador de erro irá parar neste momento. Uma chamada para buscar sem encaminhamento é suficiente para que a mensagem seja enviada; portanto, uma segunda chamada para buscar não será necessária se você não precisar do objeto JSON retornado pela API do Telegram.
Parte 5. Final
Eu trouxe meus aplicativos reais na junção do Script do Google Apps com outros serviços. Você pode criar muito mais. Por exemplo, escreva um bot de Telegram no GAS, que responderá com uma senha VPNBook com solicitações de cache para reduzir a carga no VPNBook (Serviço de Cache), e tudo isso estará em um script GAS. Você pode escrever no GAS um sistema de registro ou configurações de backup para o Mikrtotik, que serão colocados nos arquivos do Google Docs e do Google Sheets e muito mais.