Python – Acessando e reiniciando o roteador 3G da Claro

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.

LoginRoteadorDWR922_cleitonbueno.com
Figura 01 – Tela login roteador D-Link DWR-922

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.

Figura 02 - Icone Live HTTP Headers
Figura 02 – Icone Live HTTP Headers

Na janela que abrir habilite o modo Capture conforme a Figura 03.

Figura 03 - Habilitando modo Capture
Figura 03 – Habilitando modo Capture

É 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.

Figura 04 - Eventos HTTP Headers do login D-LINK DWR-922
Figura 04 – Eventos HTTP Headers do login D-LINK DWR-922

 

 

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 AuthenticationDigest 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.

Figura 05 - Botão Reiniciar D-LINK DWR-922
Figura 05 – Botão Reiniciar D-LINK DWR-922

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.

Figura 06 - HTTP Header reboot D-LINK DWR-922
Figura 06 – HTTP Header reboot D-LINK DWR-922

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!

Share Button

CC BY-NC-SA 4.0 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.