Page 1 of 1

Automatic software and firmware updates from internal ftp server

Posted: Sun Aug 26, 2018 2:07 pm
by RouterSurfer
Due these black days of security issues and patching hell, sharing is caring. =)

Below is noobie script for automatic updating a load of mikrotik devices based on device model and profile of device priority.
Code is very basic, mostly from this forum topics, but it works when scheduled running every 20min for example.
Updates launch control happens at internal FTP server side, where you put latest files available in correct folders.

Might be good idea to use this kind of upgrade procedure only inside VPN, where lack of SSL and man-in-the-middle risks should not exists..
Feel free to use, develop etc. and please post developments also for this great community !


# Variable definitions and version information
:local MtikSMTPmessage "Phase 01: FW & SW script launch in 10 sec v.201808261331HH"
:log warning "$MtikSMTPmessage"
:delay 10

:local MtikSMTPsubject
:local MtikSMTPport
:local MtikRByn
:local MtikProfile
:local MtikEupdIntExt
:local MtikEupdFile
:local MtikEupdDestFldr
:local MtikEupdDestFile
:local MtikEupdLoopFldr
:local MtikEupdSrce
:local MtikModel
:local MtikModel2
:local MtikModel3
:local MtikModel4
:local MtikModel5
:local MtikFWcur
:local MtikFWnew
:local curDate [/system clock get date]
:local curTime [/system clock get time]
:local systemName [/system identity get name]
:local curMonth [:pick $curDate 0 3]
:local MtikSMTPport "25"
:local EmailFromAddress "no-reply@company.com"
:local EmailToAddress "notify.firmware@company.com"

## For office networks L2 devices
#:local EmailServer "1.1.1.1"
#:set MtikEupdIntExt "2.2.2.2"

# For remote offices L3 devices
#:local EmailServer "3.3.3.3"
#:set MtikEupdIntExt "4.4.4.4"


## Update order definition for poll automation
## Main firewalls
#:set MtikProfile "MainFWsystem"

## Units primary firewalls
#:set MtikProfile "PriFWsystem"

## Units 4G backup firewalls
#:set MtikProfile "SecFWsystem"

## Home office firewalls
#:set MtikProfile "HomeFWsystem"

## Non routing Layer2 devices
#:set MtikProfile "L2system"

## Group of all HW & virtual phase 1 upgradet devices which are near to fix..
#:set MtikProfile "TestFWsystem"

:set curMonth ( [ :find key="$curMonth" in="jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec" from=-1 ] / 4 + 1)
if ( $curMonth < 10 ) do={
:set curMonth ( "0".$curMonth )
} else={
:set curMonth $curMonth
}
:local curDay [:pick $curDate 4 6]
:local curYear [:pick $curDate 7 13]
:local curHour [:pick $curTime 0 2]
:local curMin [:pick $curTime 3 5]

# Time and date knownledge
:log warning "System name is $systemName and operation time $curDay.$curMonth.$curYear $curHour.$curMin"

if ( $curYear < 2018 ) do={
:log warning "Year check failed, adjusting DNS and NTP servers.."
/ip dns set servers=1.1.1.1,2.2.2.2
/system clock set time-zone-autodetect=no time-zone-name=Europe/Helsinki
/system ntp client
set enabled=yes server-dns-names=time.ad.company.com,time2.ad.company.com,time.company.com,time2.company.com
:set MtikSMTPmessage "Phase 01: Year check failed. Adjusted DNS and NTP settings."
:set MtikSMTPsubject "$systemName $MtikSMTPmessage Operation local time $curDay.$curMonth.$curYear $curHour.$curMin"
:local EmailBody "Autonomous FW & SW maintenance script operation notifications"
/tool e-mail send server=$EmailServer port=$MtikSMTPport from=$EmailFromAddress to=$EmailToAddress subject=$MtikSMTPsubject body=$EmailBody
:delay 5

} else={
:log warning "At least year seems okay."
}

# HW Model based firmware image definitions
set MtikRByn [/system routerboard get routerboard]
:log warning "RB detection $MtikRByn"

if ($MtikRByn =false) do={
:log warning "x86 device detected"
:set MtikEupdDestFldr ""
:set MtikEupdDestFile "routeros-x86-updatefile.npk"
:set MtikEupdLoopFldr ""
} else={

set MtikFWcur [/system routerboard get current-firmware]
:log warning "FW current is $MtikFWcur"

set MtikFWnew [/system routerboard get upgrade-firmware]
:log warning "FW available is $MtikFWnew"

:if ($MtikFWcur = $MtikFWnew) do={
:log warning "FW update not needed."
}

:if ($MtikFWcur != $MtikFWnew) do={
:log warning "FW upgrade need from version $MtikFWcur to $MtikFWnew."
:log warning "System FIRMWARE upgrade launched.."
:set curDate [/system clock get date]
:set curTime [/system clock get time]
:set MtikSMTPmessage "Phase 03: FW upgrade need from version $MtikFWcur to $MtikFWnew. System reboot in 10sec..."
:set MtikSMTPsubject "$systemName $MtikSMTPmessage Operation local time $curDay.$curMonth.$curYear $curHour.$curMin"
/tool e-mail send server=$EmailServer port=$MtikSMTPport from=$EmailFromAddress to=$EmailToAddress subject=$MtikSMTPsubject body=$EmailBody
:delay 5

/system routerboard upgrade
:delay 5
:put y

:log warning "System reboot in 10sec..."
/system scheduler add name=REBOOT interval=10s on-event="/system scheduler remove REBOOT;/system reboot"
: log warning "Script aborted succesfully."
error :error
}

if ($MtikRByn =true) do={
set MtikModel [/system routerboard get model]
set MtikModel2 "RouterBOARD 962UiGS-5HacT2HnT"
set MtikModel3 "951G-2HnD"
set MtikModel4 "RouterBOARD QRT G-2SHPnD r2"
set MtikModel5 "951Ui-2HnD"
}

if ($MtikModel = $MtikModel2 ) do={
:log warning "5GHz device detected"
:set MtikEupdDestFldr ""
:set MtikEupdDestFile "routeros-mipsbe-updatefile.npk"
:set MtikEupdLoopFldr "flash/"
}

if ($MtikModel = $MtikModel3 ) do={
:log warning "2GHz device detected"
:set MtikEupdDestFldr ""
:set MtikEupdDestFile "routeros-mipsbe-updatefile.npk"
:set MtikEupdLoopFldr ""
}

if ($MtikModel = $MtikModel4 ) do={
:log warning "QRT device detected"
:set MtikEupdDestFldr ""
:set MtikEupdDestFile "routeros-mipsbe-updatefile.npk"
:set MtikEupdLoopFldr "flash/"
}

if ($MtikModel = $MtikModel5 ) do={
:log warning "951Ui-2HnD"
:log warning "2GHz device detected"
:set MtikEupdDestFldr ""
:set MtikEupdDestFile "routeros-mipsbe-updatefile.npk"
:set MtikEupdLoopFldr ""
}

# x86 vs. HW segment end.
}

# Anti loop mechanism by year and date file. Only 1 update try per day.
#: log warning "Loop prevent file is $curYear$curMonth$curDay.rsc"
:if ([:len [/file find name=( "$MtikEupdLoopFldr$curYear$curMonth$curDay.rsc" ) ]] > 0) do={
: log warning "Loop prevent file found."
: log warning "Script aborted succesfully."
error :error
}

if ($MtikProfile = "TestFWsystem" ) do={
#set MtikModel [/system routerboard get model]
:set MtikEupdSrce "TestFWsystem/$MtikEupdDestFile"
:log warning "File source $MtikEupdSrce and destination $MtikEupdDestFldr$MtikEupdDestFile"
:log warning "Device update order is $MtikProfile"
}

if ($MtikProfile = "L2system" ) do={
#set MtikModel [/system routerboard get model]
:set MtikEupdSrce "L2system/$MtikEupdDestFile"
:log warning "File source $MtikEupdSrce and destination $MtikEupdDestFldr$MtikEupdDestFile"
:log warning "Device update order is $MtikProfile"
}

if ($MtikProfile = "HomeFWsystem" ) do={
#set MtikModel [/system routerboard get model]
:set MtikEupdSrce "HomeFWsystem/$MtikEupdDestFile"
:log warning "File source $MtikEupdSrce and destination $MtikEupdDestFldr$MtikEupdDestFile"
:log warning "Device update order is $MtikProfile"
}

if ($MtikProfile = "SecFWsystem" ) do={
#set MtikModel [/system routerboard get model]
:set MtikEupdSrce "SecFWsystem/$MtikEupdDestFile"
:log warning "File source $MtikEupdSrce and destination $MtikEupdDestFldr$MtikEupdDestFile"
:log warning "Device update order is $MtikProfile"
}

if ($MtikProfile = "PriFWsystem" ) do={
#set MtikModel [/system routerboard get model]
:set MtikEupdSrce "PriFWsystem/$MtikEupdDestFile"
:log warning "File source $MtikEupdSrce and destination $MtikEupdDestFldr$MtikEupdDestFile"
:log warning "Device update order is $MtikProfile"
}

if ($MtikProfile = "MainFWsystem" ) do={
#set MtikModel [/system routerboard get model]
:set MtikEupdSrce "MainFWsystem/$MtikEupdDestFile"
:log warning "File source $MtikEupdSrce and destination $MtikEupdDestFldr$MtikEupdDestFile"
:log warning "Device update order is $MtikProfile"
}

# Cleanup possible corrupted upgrade files
:if ([:len [/file find name=( "$MtikEupdDestFldr$MtikEupdDestFile" ) ]] > 0) do={
:log warning "Cleanup old file at $MtikEupdDestFldr$MtikEupdDestFile.."
:set curDate [/system clock get date]
:set curTime [/system clock get time]
:log warning "WARNING: OLD FIRMWARE FILE FOUND. DELETING.."
:set MtikSMTPmessage "WARNING: OLD FIRMWARE FILE FOUND. DELETING.."
:set MtikSMTPsubject "$systemName $MtikSMTPmessage Operation local time $curDay.$curMonth.$curYear $curHour.$curMin"
/tool e-mail send server=$EmailServer port=$MtikSMTPport from=$EmailFromAddress to=$EmailToAddress subject=$MtikSMTPsubject body=$EmailBody
:delay 5

/file remove "$MtikEupdDestFldr$MtikEupdDestFile"
}
:delay 5
:log warning "updatefile update file download attempt from $MtikEupdIntExt. If file not available, abort operations."

# Extra SMTP notifys for profile TestFWsystem devices
:set curDate [/system clock get date]
:set curTime [/system clock get time]
if ($MtikProfile = "TestFWsystem" ) do={
:set MtikSMTPmessage "Phase 04: updatefile update file download attempt from $MtikEupdIntExt. If file not available, abort operations."
:set MtikSMTPsubject "$systemName $MtikSMTPmessage Operation local time $curDay.$curMonth.$curYear $curHour.$curMin"
/tool e-mail send server=$EmailServer port=$MtikSMTPport from=$EmailFromAddress to=$EmailToAddress subject=$MtikSMTPsubject body=$EmailBody
:delay 5
}

/tool fetch address=$MtikEupdIntExt src-path=$MtikEupdSrce user=USER password=PASSWORD mode=ftp upload=no dst-path="$MtikEupdDestFldr$MtikEupdDestFile" keep-result=yes
:delay 5

# File transfer ok, prevent update loops for 1 day
:log warning "Create loop protect file for today $curYear$curMonth$curDay.rsc .."
/
/system routerboard export file=( "$MtikEupdLoopFldr$curYear$curMonth$curDay" )

# Extra SMTP notifys for profile TestFWsystem devices
:set curDate [/system clock get date]
:set curTime [/system clock get time]
if ($MtikProfile = "TestFWsystem" ) do={
:set MtikSMTPmessage "Phase 05: Create loop protect file for today.."
:set MtikSMTPsubject "$systemName $MtikSMTPmessage Operation local time $curDay.$curMonth.$curYear $curHour.$curMin"
/tool e-mail send server=$EmailServer port=$MtikSMTPport from=$EmailFromAddress to=$EmailToAddress subject=$MtikSMTPsubject body=$EmailBody
:delay 5
}

# Search for local updatefile update file
:if ([:len [/file find name=( "$MtikEupdDestFldr$MtikEupdDestFile" ) ]] > 0) do={
:log warning "Upgrade file $MtikEupdDestFldr$MtikEupdDestFile found."
:log warning "System reboot in 10sec..."
:set curDate [/system clock get date]
:set curTime [/system clock get time]
:set MtikSMTPmessage "Phase 06: Update file found at $MtikEupdDestFldr$MtikEupdDestFile. REBOOTING in 10 sec.."
:set MtikSMTPsubject "$systemName $MtikSMTPmessage Operation local time $curDay.$curMonth.$curYear $curHour.$curMin"
/tool e-mail send server=$EmailServer port=$MtikSMTPport from=$EmailFromAddress to=$EmailToAddress subject=$MtikSMTPsubject body=$EmailBody
:delay 5
/system scheduler add name=REBOOT interval=10s on-event="/system scheduler remove REBOOT;/system reboot"
}

: log warning "Script finished succesfully."