Na casa onde mudei recentemente contratei o plano de internet 3G da Claro, outra opção seria internet via-radio ou outras operadora de internet 3G, testei com meu celular e o sinal/qualidade do 3G da Claro atendeu a minha humilde necessidade de pelo menos e-mail e acesso dos meus clientes com SSH que realizo, construir uma distribuição com Yocto Project nem pensar :(.
Então junto ao plano é fornecido um roteador da Claro, um D-LINK DWR-922, no roteador esta conectado uma Beaglebone Black onde uso para um simples “alarme” para minha casa além de outros serviços, porém em dado momento o link da internet fica muito ruim, latência acima de 1s e algumas vezes sem conexão, e no caso só restabelece ao reiniciar o mesmo.
Então pensei em criar uma ferramenta para acessar o roteador e reiniciar o equipamento, para isso adicionei um script no cron do Linux da BBB para a cada 15 minutos realize um ping para o DNS do Google (8.8.8.8) caso falhe em 5 tentativas ele reinicia o equipamento.
Acessando o roteador via web
Primeira coisa foi instalar uma extensão para capturar/exibir o cabeçalho HTTP, como utilizo o Google Chrome instalei o Live HTTP Headers.
Em seguida digitei o IP do roteador e entrei com o usuário e senha na tela de login do roteador, como pode ser visto na Figura 01.
Antes de clicar em Login, devemos habilitar a Captura do headers HTTP, para isso no canto superior direito do navegador clicamos no ícone que tem uma nuvem azul desenhada Figura 02.
Na janela que abrir habilite o modo Capture conforme a Figura 03.
É interessante possuir apenas a aba com o endereço do roteador e a tela de login para não “congestionar” o Capture, agora você pode clicar em Login e teremos na tela do Live HTTP Headers algo como a Figura 04.
Analisando o cabeçalho HTTP
Analisando o resultado da Figura 04 o que nos interessa é o momento do Login que seria a etapa 2, o status 303 na coluna do lado esquerdo, na tela central temos o Header com o resultado desta etapa.
Curiosamente podemos ver que para logar é usado o método GET (Eca D-Link!) e normalmente em outros roteadores, modems, gateways é utilizado um Basic Access Authentication, Digest Access Authentication ou mesmo POST.
Próximo passo é descobrir o que ocorre quando clico no botão Reiniciar na tela principal, conforme a Figura 05.
Aplicando a mesma ideia do Login, capturando os eventos de headers do HTTP, usamos para visualizar o que ocorre ao clicar no botão Reiniciar na Figura 06.
Baseado nas URL’s capturadas chegamos a seguinte conclusão:
Ação | URL |
Login | http://10.11.12.254/log/in?un=admin&pw=admin12&rd=%2Fuir%2Fstatus.htm&rd2=%2Fwanst.htm&Nrd=1 |
Reiniciar | http://10.11.12.254/uri/rebo.htm?rc=&Nrd=0&Nsm=1 |
Olhando ambas URL’s podemos concluir que o link abaixo seria suficiente para o reboot do roteador.
[URL Login] http://10.11.12.254/log/in?un=admin&pw=admin12&rd=%2Fuir%2Fstatus.htm&rd2=%2Fwanst.htm&Nrd=1 [URL Login] http://10.11.12.254/log/in?un=admin&pw=admin12&rd= [URL Reboot] http://10.11.12.254/uri/rebo.htm?rc=&Nrd=0&Nsm=1 [URL Login + Reboot]http://10.11.12.254/log/in?un=admin&pw=admin12&rd=/uri/rebo.htm?rc=&Nrd=0&Nsm=1 [URL Login + Reboot]http://10.11.12.254/log/in?un=admin&pw=admin12&rd=%2Furi%2Frebo.htm?rc=&Nrd=0&Nsm=1
Lembrando que %2F equivale ao ‘/’, mais informações URL Encoding. Segue nossa URL para login e reboot.
http://10.11.12.254/log/in?un=admin&pw=admin12&rd=%2Fuir%2Frebo.htm?rc=&Nrd=0&Nsm=1
Não se preocupe com os campos de IP, usuário e senha na ferramenta haverá campos para preencher estes dados ;)
Criando a ferramenta com Python
Para criar a ferramenta vamos utilizar Python e para manipular as requisições HTTP usarei o modulo urllib2.
#! /usr/bin/env python # -*- coding: utf-8 -*- import urllib2 as http """ Python script to reboot modem/router Claro 3G - D-LINK DWR-922 This script use method GET to reboot router. Example use: $ python reboot_router_claro3G.py """ __author__ = "Cleiton Bueno <cleitonrbueno at gmail.com>" __copyright__ = "Copyright (C) 2015 Cleiton Bueno" __license__ = "The Apache License 2.0 (ASL)" __version__ = "1.0" # Data Router user_router = "user_here" pass_router = "password_here" ip_router = "IP_here" port_router = "80" # URL with filling the fields above, URL with GET to reboot router or status main page to tests url_get_reboot = "http://" + ip_router + ":" + port_router + "/log/in?un=" + user_router + "&pw=" + pass_router + "&rd=%2Fuir%2Frebo.htm?rc=&Nrd=0&Nsm=1" url_get_status = "http://" + ip_router + ":" + port_router + "/log/in?un=" + user_router + "&pw=" + pass_router + "&rd=%2Fuir%2Fstatus.htm&rd2=%2Fuir%2Fwanst.htm&Nrd=1" # Variable global to open URL url_root = url_get_reboot print "Processing URL: %s" % url_root # Handling HTTP Cookie - Session Cookie Router cookieprocessor = http.HTTPCookieProcessor() # Customize it Opener with CookieProcessor opener = http.build_opener(cookieprocessor) # Using here Opener + CookieProcessor http.install_opener(opener) # Open URL with Opener above try: payload_router = http.urlopen(url_root) if payload_router.getcode() == 200: print "\t Rebooting router, waiting..." else: print "\t Fail reboot router!" print "\t * Check parameters [user_route e pass_router]" except http.HTTPError as http_err: print "\tHTTP Error -> %s" % http_err.read() except http.URLError as url_err: print "\tRouter offline ou IP/Port incorrect!" print "\t\tError -> %s " % url_err.reason
Importante salientar aqui são as linhas 22, 23, 24 e 25 onde você irá preencher conforme a configuração do seu roteador, após isso o código é “simples” onde realizo requisição da URL e utilizei dois links, um para status url_get_status[linha 31] do roteador e outra para reiniciar url_get_reboot[linha 30] que deve ser alterado na variável url_root na linha 34 para alterar a ação.
E toda magica acontece na linha 49, anterior a isso são algumas predefinições ou manipuladores para realizar a requisição com sucesso.
Para obter a ferramenta, segue o link do repositório:
http://www.github.com/cleitonbueno/reboot_router.git
O script em anexo neste artigo esta no commit(8f7bd323612a679e95d90d43f023b3be1367a3bf).
Para clonar:
$ git clone http://www.github.com/cleitonbueno/reboot_router.git
Criando script de verificação e agendando a tarefa
Agora a parte divertida, criar a rotina de agendamento para realizar a verificação da internet e no caso de falha, reinicie o roteador.
/etc/cron.d/check_internet
*/15 * * * * /usr/local/bin/check_internet >/dev/null 2&>1
/usr/local/bin/check_internet
#! /bin/bash export LC_ALL=C bin_fping=$(which fping) ip_send_fping="8.8.8.8" # Log # Disable log #FILE_LOG="/dev/null" FILE_LOG="/tmp/check_internet.log" # Check program fping - dependencie [ -x "$bin_fping" ] || { echo "Programa fping não encontrado!"; exit 5; } # Get data/time now date_now=$(date +%d/%m/%Y\ %H:%M:%S) # Send 3 packet ping with 3 retries fping -r5 -q ${ip_send_fping} if [ "$?" == "0" ]; then echo -e "[$date_now] - Online" >> ${FILE_LOG} else /usr/local/bin/reboot_router_claro3G.py >/dev/null 2>&1 echo -e "[$date_now] - Rebooting router..." >> ${FILE_LOG} fi exit 0
O script /usr/local/bin/check_internet realiza “ping” para o endereço 8.8.8.8 com 5 tentativas, em caso de falha irá executar a nossa ferramenta escrita em Python.
A única dependência do script é o fping, que pode ser instalado via apt-get, rpm, yum ou a ferramenta que usar em sua distribuição, e nosso script em Python em /usr/local/bin/reboot_router_claro3G.py.
Verificando o log temporário que gerou no /tmp:
$ cat /tmp/check_internet.log ... [16/12/2015 20:15:01] - Online [16/12/2015 20:30:01] - Online [16/12/2015 20:45:01] - Online [16/12/2015 21:00:02] - Online ... [16/12/2015 01:00:01] - Online [16/12/2015 01:15:02] - Rebooting router... [16/12/2015 01:30:02] - Online ...
No caso acima peguei apenas uma saída da hora que foi reiniciado, o /tmp/check_internet.log não é crucial para o funcionamento do /usr/local/bin/check_internet, só para o caso de monitorar ou verificar histórico de reboots, e pode ser removido do script.
Espero que tenham gostado e que sirva como base para outras analises e poder ser replicado para outros equipamentos, futuramente irei publicar outro usando Basic Auth.
Até a próxima!
Python – Acessando e reiniciando o roteador 3G da Claro by Cleiton Bueno is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.