Talk:RouterBOARD Bootloader upgrade

From MikroTik Wiki
Jump to navigation Jump to search

After reading several questions in the forums about how to automate firmware updates, I engineered this to resolve the issue.

The basic problem is the that the ROS scripting engine has no facility to allow the firmware update command to executed. The script always runs into a wall when the "y" is required to complete the command.

A basic rundown of the solution is as follows:

ROS script runs at specified interval checking for a difference between the current-firmware version and the update-firmware version. If a difference is detected, the /tool fetch command is used to pass the system public IP address to a php script. The php script initiates an expect telnet session in the shell which logs into the routerboard and issues the necessary commands and responses to update firmware and reboot.

You will need to enable telnet services for the IP address of your webserver.

Part 1, the 'firmwareupdate' script I'll break it up below, but this is how I apply it to client units.

/system script add name=firmwareupdate source=":if ([system routerboard get current-firmware] != [system routerboard get upgrade-firmware]) do={ :log info (\"New Firmware Available \" . [system routerboard get upgrade-firmware]) ; /ip service enable telnet ; :local telnetfileName (\"routerboards/firmware.php\?a=\" . [:pick [/ip address get [/ip address find interface=wlan1] address] 0 [:find [/ip address get [/ip address find  interface=wlan1] address] \"/\"]]); /tool fetch address=\"www.yourserver.com\" src-path=[\$telnetfileName] host=www.yourserver.com ; }"

To actually automate it, create a scheduler event at whatever interval makes you happy.

The actual script is as follows:

:if ([system routerboard get current-firmware] != [system routerboard get upgrade-firmware]) do={ \
     :log info (\"New Firmware Available \" . [system routerboard get upgrade-firmware]) ; \
#we keep all services except winbox disabled on our client routerboards
     /ip service enable telnet ; \
#the following command determines the public IP address and appends it to the URL path of the firmware.php file
     :local telnetfileName (\"routerboards/firmware.php\?a=\" . \
     [:pick [/ip address get [/ip address find interface=wlan1] address] 0 [:find [/ip address get [/ip address find  interface=wlan1] address] \"/\"]]); 
     /tool fetch address=\"www.yourserver.com\" src-path=[\$telnetfileName] host=www.yourserver.com ; \
}


Part 2, the 'firmware.php' script This script can be secured by further PHP or .htaccess files. This basic file will work but you should immediately consider security.

<?php
$a=$_GET['a'];
$passthrucmd="sh /path/to/your/public_html/routerboards/firmware.sh ".$a." >/dev/null 2>/dev/null";
passthru($passthrucmd);
?>

Part 3, the 'firmware.sh' script

#!/bin/bash
expect << EOF
set timeout 20
spawn telnet $1
expect "Login:" 
send "admin\r"
expect "Password:" 
send "yourpassword\r"
expect "*>"
send "sys rou up\r"
expect "*y/n*"
send "y\r"
expect "*>"
send "ip service disable telnet\r"
expect "*>"
send "sys reboot\r"
expect "*y/N*"
send "y\r"
expect "*>"
send "quit\r"

exit

EOF

It seems that this doesn't work under ROS 3.13 or earlier. Your mileage may vary.