MikroTik — Daily Backups and Quick-Restore Button

Gianni Costanzi
Nerd For Tech
Published in
8 min readMar 28, 2023

--

I’m using a MikroTik HAP AC² Wireless Router at home and it doesn’t have a console port that you can easily use to access configuration and make changes if you lock yourself out due to a misconfiguration. If you lock yourself out, for example, after a wrong copy-and-paste of firewall rules that prohibits access in SSH and HTTP to your router, the only way to recover access is to reset it to the default configuration and restore a backup or, worst case, reconfigure from scratch. In this small article I show you my backup strategy and how I quickly reboot the router from the last backup in case I make a disaster.

Standard Reset Procedure

I’ll just describe the standard reset procedure in case someone needs to reset the router to the default config:

  1. Shutdown the router and disconnect the power cable
  2. Press the Reset button while connecting the power cable, keep the button pressed until the led light starts blinking and then release it
  3. Configure your PC with IP 192.168.88.2/24
  4. Connect to 192.168.88.1 and upload a backup or reconfigure the router from scratch

Standard Safe Mode

MikroTik router allows you to operate in Safe Mode by pressing CTRL^x, entering commands and then pressing CTRL^x again to make them persistent. In case you lock yourself out while in SAFE mode, changes will be rolled back after the TCP session times-out (few minutes). This can save you but it is limited in the amount of commands you can enter and if you need to copy-and-paste a lot of firewall rules, as it happens to me when I update them, it can’t help you avoiding bad mistakes.

Backup Strategy

The first thing you should do in order to be able to quick restore the configuration is implementing a daily backup procedure, with a script and a proper schedule that runs every night, for example.

This is my backup strategy:

  • Daily backup to USB drive: my backup script saves the plain config and a backup file every night over the same files on a USB drive connected to the USB port of the MikroTik router. This is where my Restore-From-Last-Backup script will look for a specific file to perform a restore of the configuration when I press the mode button over the router.
  • Daily backup to FTP server on my Synology NAS: the same as for the USB drive, with the advantage that I have daily snapshots taken on the Synology NAS that allows me to recover backups of more than one day ago, even if they are overwritten every night. Later I’ll explain why this helped me save some time when I got into troubles :)

USB Drive Initialization

When you connect a USB drive to the MikroTik, you can see it with the following command (the output in this article has been collected on a virtual CHR router, you should be able to adapt it to your router):

# Find the name of the drive/partition
[admin@mik-test-GW] /disk> /disk/print
Flags: E, M, F - FORMATTING; b - BLOCK-DEVICE
Columns: SLOT, MODEL, SERIAL, SIZE, FREE, FS
# SLOT MODEL SERIAL SIZE FREE FS
0 E slot2
1 E slot3
2 E slot4
3 E slot5
4 E slot6
5 E slot7
6 Mb usb1 virtio vdb 1 073 741 824 1 132 261 376 ext4

# Fortmat the drive/partition with ext4
[admin@mik-test-GW] /disk> /disk/format-drive usb1 file-system=ext4 label=usb-drive
file-system: ext4
formatted: 100%

On my HAP AC² after upgrading to RouterOS 7.8 the drives changed their names and I can see both the main drive as usb1 and the formatted partition as usb1-part1. In this case I use usb1-part1 in my real scripts:

[gianni@MikroTik] > /disk/print
Flags: B - BLOCK-DEVICE; M, F - FORMATTING; p - PARTITION
Columns: SLOT, MODEL, SERIAL, INTERFACE, SIZE, FREE, FS
# SLOT MODEL SERIAL INTERFACE SIZE FREE FS
0 B usb1 OCZ RALLY2 1234560D000397 USB 2.00 480Mbps 16 039 018 496
1 BMp usb1-part1 @1'024-16'039'018'496 16 039 017 472 16 007 348 224 fat32

Backup Script

This script creates every night the following files on the USB drive:

  • nightly_export.rsc: contains the plain-text full configuration (add show-sensitive to the export command to include passwords)
  • nightly_backup.backup: contains a full backup that can be used to restore the config from scratch

It also uploads the following files to an FTP server (ROUTER-NAME is the identity of the router, i.e. the name you assign to it, mik-test-GW in my tests):

  • sched-export-ROUTER-NAME.rsc: plain-text full configuration
  • sched-backup-ROUTER-NAME.backup: full backup
/system script
remove [find name=Do-Backup]
add name=Do-Backup policy=ftp,read,write,policy,test,sensitive source={
# automated System - Configuration Backup to USB1 and External FTP
:log info message="<LOG>System Export/Backup to FTP Server and USB Dongle Started"
:local tmpExportFile ("/sched-export-".[/system identity get name].".rsc")
:local tmpBackupFile ("/sched-backup-".[/system identity get name].".backup")
:local usbExportFile "usb1/nightly_export.rsc"
:local usbBackupFile "usb1/nightly_backup.backup"
# Add show-sensitive option to export command to include commands with clear-text passwords
# ex: export show-sensitive file=XXX
/export file=$tmpExportFile
/export file=$usbExportFile
:log info message="<LOG>System saved Export to $tmpExportFile and $usbExportFile"
/system backup save name=$tmpBackupFile
/system backup save name=$usbBackupFile
:log info message="<LOG>System saved Backup to $tmpBackupFile and $usbBackupFile"
# Upload the System Export to External FTP
/tool fetch address=my-ftp-server.homenetwork user=mikrotik password=SECRET_PASSWORD src-path=$tmpExportFile mode=ftp dst-path="/mikrotik/$tmpExportFile" upload=yes
# Upload the System Backup to External FTP
/tool fetch address=my-ftp-server.homenetwork user=mikrotik password=SECRET_PASSWORD src-path=$tmpBackupFile mode=ftp dst-path="/mikrotik/$tmpBackupFile" upload=yes
# Remove temporary export
:foreach i in=[/file find] do={:if ([:typeof [:find [/file get $i name] "sched-backup-"]]!="nil") do={
/file remove $i}
}
# Remove temporary backup
:foreach i in=[/file find] do={:if ([:typeof [:find [/file get $i name] "sched-export-"]]!="nil") do={
/file remove $i}
}
:log info message="<LOG>System Export/Backup Temporary files removed"
:log info message="<LOG>System Export/Backup To FTP Server and USB dongle finished"
}

If you do not want to overwrite the same backup files because you do not have a system that saves the previous n-days’ backups, you may want to add a timestamp to the filenames. You can get current date and time into variables and then use to create unique filenames. Just remember to implement some cleanup mechanism to avoid filling up the space with backups:

# Get time
:local ts [/system clock get time]
:set ts ([:pick $ts 0 2].[:pick $ts 3 5].[:pick $ts 6 8])
# Get Date
:local ds [/system clock get date]
:set ds ([:pick $ds 7 11].[:pick $ds 0 3].[:pick $ds 4 6])

# Use ts and ds to build the filename
# Output will be like /sched-export-mik-test-GW-2023mar26-141710.rsc
:local tmpExportFile ("/sched-export-".[/system identity get name]."-".$ds."-".$ts.".rsc")

Launching the Do-Backup script produces the following logs:

17:14:11 script,info <LOG>System Export/Backup to FTP Server and USB Dongle Started
17:14:12 script,info <LOG>System saved Export to /sched-export-mik-test-GW.rsc and usb1/nightly_export.rsc
17:14:12 script,info <LOG>System saved Backup to /sched-backup-mik-test-GW.backup and usb1/nightly_backup.backup
17:14:12 info fetch: file "disk/sched-export-mik-test-GW.rsc" uploaded
17:14:13 info fetch: file "disk/sched-backup-mik-test-GW.backup" uploaded
17:14:14 script,info <LOG>System Export/Backup Temporary files removed
17:14:14 script,info <LOG>System Export/Backup To FTP Server and USB dongle finished

and the following output on-screen:

[admin@mik-test-GW] /system/script> run 0
Saving system configuration
Configuration backup saved
Saving system configuration
Configuration backup saved
status: finished
uploaded: 6KiBp|C-z pause]
total: 6KiB
duration: 1s

status: finished
uploaded: 29KiB|C-z pause]
total: 29KiB
duration: 1s

These are the files created on the USB drive:

[admin@mik-test-GW] /system/script> /file/print
Columns: NAME, TYPE, SIZE, CREATION-TIME
# NAME TYPE SIZE CREATION-TIME
0 pub directory feb/18/2023 21:19:28
1 skins directory feb/18/2023 16:23:57
2 usb1 disk feb/19/2023 17:14:12
3 usb1/lost+found directory feb/19/2023 16:16:39
4 usb1/nightly_export.rsc script 6.7KiB feb/19/2023 17:14:12
5 usb1/nightly_backup.backup backup 30.0KiB feb/19/2023 17:14:12

Schedule Nightly Backup

The obvious next-step is to schedule the Do-Backup script in order to be run every night:

/system scheduler 
remove [find name=Do-Backup-Schedule]
add name="Do-Backup-Schedule" comment="FTP-backup every night at 00:00" disabled=no policy=ftp,read,write,policy,test,sensitive interval=1d \
on-event="/system script run Do-Backup" start-date=jan/01/1970 start-time=00:00:00

Trigger Restore-From-Last-Backup with Mode Button press

Now it’s time to setup a simple script that saves the actual config on the flash of the router (export_before_boot_from_last_backup.rsc and backup_before_boot_from_last_backup.backup files), asks MikroTik to reload config from the nightly backup on USB drive and answers “y” to the “Restore and reboot?” question asked by the restore operation. We also configure the mode button in order to trigger this script when pressed:

# Restore-From-Last-Backup script
/system script
remove [find name=Restore-From-Last-Backup]
add name=Restore-From-Last-Backup policy=reboot,sensitive,policy,password,test,read,write source={
:log warning message="<LOG>Exporting backup before booting from last backup"
/export file="export_before_boot_from_last_backup.rsc"
/system backup save name="backup_before_boot_from_last_backup.backup"
:log warning message="<LOG>Rebooting from last nightly backup now!"
/system backup load name=usb1/nightly_backup.backup password=""
y
}

# Assign Restore-From-Last-Backup script to the mode button
/system routerboard mode-button
set enabled=yes on-event=Restore-From-Last-Backup

You can now force the execution of the backup script, perform a “fake” breaking change that must be rolled-back and then press the mode button. After the reboot you will find the router with the configuration before the “breaking change” and with the broken config saved on the flash, in case you need to inspect it to understand what has gone wrong:

[admin@mik-test-GW] > /file/print
Columns: NAME, TYPE, SIZE, CREATION-TIME
# NAME TYPE SIZE CREATION-TIME
0 pub directory feb/18/2023 21:19:28
1 skins directory feb/18/2023 16:23:57
2 export_before_boot_from_last_backup.rsc script 6.7KiB feb/19/2023 17:18:15
3 backup_before_boot_from_last_backup.backup backup 30.0KiB feb/19/2023 17:18:17
4 usb1 disk feb/19/2023 17:18:08
5 usb1/lost+found directory feb/19/2023 16:16:39
6 usb1/nightly_backup.backup backup 30.0KiB feb/19/2023 17:18:08
7 usb1/nightly_export.rsc script 6.7KiB feb/19/2023 17:18:08

Why daily backup versioning saved my day

Everything I’ve explained works fine, if you are at home and you can press the reset button as soon as you lock yourself out of the router. But what happens if you lock yourself out and are away from home for some days and your backups on the USB drive and external FTP will get overwritten by a new backup with the broken config? This is what happened to me few weeks ago, when I’ve updated my firewall rules and a typo into the pasted config corrupted a single line, the one the allowed me to connect to the MikroTik router.

In this case it is sufficient to recover the backup from n-days ago on the NAS, put it onto the USB drive with the nightly_backup.backup name and then press the mode button to trigger the restore.

Unfortunately at the time of the issue I was not saving and loading nightly_backup.backup from USB drive and I was looking for it on the flash of the router, so I still needed to do the reset to factory procedure and then perform a restore with the backup file retrieved from the NAS. Moving the nightly backups to the USB drive allows for a quicker restore and avoids the annoying reset procedure.

Trigger Do-Backup before important changes

Just a small hint: if you are planning big changes to the configuration, just trigger the Do-Backup script before starting and maybe temporarily disable the Nightly Backup schedule if you’re working from remote and can’t immediately access the mode button in case of disaster. In this way if you make a mistake you just need to press the mode button as soon as you are back to home ;)

Conclusions

I hope you can find something useful in this article, it may save you some time while experimenting on your MikroTik router at home!

Remember: do the backups and test the recovery procedure before disasters happen!

--

--

Gianni Costanzi
Nerd For Tech

Network Engineer, Music Lover, Motorbike Rider, Amateur Photographer, Nerd-inside