Automation reboot CISCO RVS4000 router

It just so happened that after two years of buggy work, the home router began to hang from time to time. This was manifested in the suspension of the WAN port and the absence of the Internet on the entire subnet, the LAN works fine. The solution was not as simple as it might seem at first.

Before using this guide, make a backup copy of your router settings. Choosing the
right minimum solution requires several options to consider.
The first solution, which was subsequently discarded due to the complexity and duration of the implementation, is the arduino + ethernet shield / raspberry PI + relay. This is the case when you do not need to solve all problems in the same familiar way, even if you really want to. At a minimum, you would have to wait for either an ethernet shield or a raspberry PI. But I did not want to wait. Further, it would be logical to assume that since it is impossible to do a reboot in hardware, it can be done in software. Indeed, the router did not completely freeze, and provided the opportunity to log into the admin panel without any problems. 5 minutes googling.

curl -u 'login:password' 'http://192.168.1.1/setup.cgi?todo=reboot'


The link works fine in the browser, but through curl the recipe point blank did not want to work and gave out.

401 Unauthorized

401 Unauthorized

Authorization required.


Variations with post parameters, using the request library did not give a positive result, the server response is still the same. I really did not want to understand the intricacies of authorization. Virtual machine + script on sikuli - with a gun on sparrows. Final solution: use nodejs + coffeescript + phantomjs. It so happened historically that my linux distribution "for experimenting" I have gentoo. Until the last moment, gentoo had a broken ebuild for phantomjs: at first it just wasn’t going to, and then it started to be built, but it still refused to work. It's a shame, but the attempt is not torture.

We create a working environment for crafts and install the dependencies:

mkdir /opt/ext/router_reboot_tool
cd /opt/ext/router_reboot_tool
npm install -g coffeescript
npm install phantomjs phpjs


And here an interesting fact is revealed. When installing phantomjs, it pulls up the finished working binary. Here's a miracle, no need to dance with a tambourine. Then it’s a matter of technology.

check.coffee checks the Internet as best it can, and in case of a crash, it calls reboot.sh:

#!/usr/bin/coffee
fs  = require('fs')
exec= require('child_process').exec
php = require('phpjs')
_old_console_log = console.log
console.log = (t)->
    _old_console_log "[#{php.date('d.m.Y H:i:s')}] #{t}"
check_internet = (get_result)->
    exec 'ping -c1 8.8.8.8', (_skip,result)->
        get_result /1 packets transmitted, 1 received/.test result
if fs.existsSync 'marker'
    console.log 'marker detected'
    fs.unlinkSync 'marker'
    process.exit()
fail_count      = 0
max_fail_count  = 10
check_count     = 0
main_loop = setInterval ()->
    check_count++
    if check_count > 60*5-10
        console.log "wiped (new will started by cron)"
        process.exit()
    check_internet (r)->
        return if fail_count > max_fail_count # дополнительная проверка. Лень пока-что разбираться почему нужна
        # console.log r
        if r
            fail_count = 0
        else
            fail_count++
            console.log "fail #{fail_count}"
        if fail_count > max_fail_count
            console.log "reboot"
            clearInterval main_loop # как ни странно не срабатывает
            fs.writeFileSync 'marker', ''
            exec './reboot.sh', (_skip,result)->
                console.log result
            setTimeout ()->
                fs.unlinkSync 'phantom_marker'
                process.exit()
            , 10000
, 1000

An additional marker file entry is needed in order not to accidentally send 2 reboot requests in a row. This can happen if the Internet disappeared just before the end of the 5-minute interval. And so we are guaranteed to have a gap of at least 5 minutes between reboots of the router.

Surprise number 1 . clearInterval did not want to kill the interval and reboot.sh was called in some cases 4 times due to which my settings on the router flew. Suddenly, two reboot commands in a row at intervals of a second cause a hard reset. The crutch solution remained in the ready-made solution.

reboot.sh is not very logic-wise and smart. Simple and commonplace. Then it will have to be corrected .
#!/bin/bash
coffee -c ./phantom.coffee
./node_modules/phantomjs/bin/phantomjs ./phantom.js

phantom.coffee
console.log "start..."
# fs = require('fs')
# if fs.existsSync 'phantom_marker'
    # console.log "phantom_marker"
    # phantom.exit()
# fs.writeFileSync 'phantom_marker', ''
page = require('webpage').create()
page.onConsoleMessage = (msg)->
    console.log msg
url = 'http://192.168.1.1/Reboot.htm'
page.settings.userName = 'login'
page.settings.password = 'password'
page.open url, ()->
    page.evaluate ()->
        document.getElementsByName('mtenReboot')[0].click()
    console.log 'waiting...'
    setTimeout ()->
        console.log 'exit'
        # fs.unlinkSync 'phantom_marker'
        phantom.exit()
    , 10000


Due to the fact that I wanted to add protection against accidentally starting reboot.sh twice, I added a phantom_marker file entry as an indicator that the process is already running and that you do not need to start another one. But here surprise No. 2 was waiting for me.

Surprise number 2 . scripts for phantomjs do not support modules for nodejs (or just a fs module, or they support, but some old version of modules didn’t make sense in detail). It's a shame, we comment, we make a check in reboot.sh, which is less beautiful, but it works.

Updated reboot.sh:

#!/bin/bash
if [ -a 'phantom_marker' ]
then
  echo "phantom_marker present"
  exit
fi
touch phantom_marker
coffee -c ./phantom.coffee
./node_modules/phantomjs/bin/phantomjs ./phantom.js
unlink phantom_marker

Final touches
chmod +x check.coffee
chmod +x reboot.sh
crontab -e
*/5 * * * * cd /opt/ext/router_reboot_tool && ./check.coffee 2>&1 >> ./log
/etc/init.d/vixie-cron restart


We make the rule already with pens (I believe that there is a way to do this from the console, but I did not have the task of automating the installation of this craft). After updating crontab we reboot cron, otherwise nothing will work.

A couple of tests with manual WAN shutdown showed that the script works as it should. In total, 2-4 hours were spent on finding a solution and solving surprises, which someone may not have, so I decided to put the solution on public display. Modifying scripts for another router is not difficult, you just need to replace the path to the page with the reboot button and pressing the button itself.

What I would like to finish, but did not get my hands on it: remove the crutch for an extra check fail_count.

Also popular now: