To periodically backup the configuration of our new routers with Mikrotik RouterOS, I wanted to have a cronjob: get an export of the active configuration, perhaps even a system backup, store in a backup folder and keep them for a defined retention period.

The only existing solution I was able to find was Backup_ROS, written in Java. This was not an option to minimize the system load while keeping maximum flexibility. Additionally, the last changes to the project on SourceForge where commited in 2010 – who wants to use a four year old software with no support by the author?

So I ended up writing the cronjob myself, which resulted in a small bash script.
Backup_RouterOS uses and requires SSH access to the target router, as well as SFTP. There is no additional scheduling or scripting on the device itself, the cronjob works completely from remote. To improve things, the bash script is able to handle more than one router, storing the backups in folders for each router and each day.

To set up the backup script, please feel free to copy it:

  • create a SSH-DSS (no SSH-RSA!) key as the user running the backups:
    ssh-keygen -t dss

    By specifying a non-default location, the cronjob will be more complicated to use, so do not change if possible.

  • copy the public key file (id_dsa.pub) to the router(s), using SFTP, FTP or even drag’n’drop in Winbox. Afterwards, import the SSH public key to the RouterOS user. This shall not be covered here, because there is already a fine article in the MikroTik wiki:
    http://wiki.mikrotik.com/wiki/Use_SSH_to_execute_commands_%28DSA_key_login%29
  • Create the actual cronjob:

    #!/bin/bash    
    TODAY=$(/bin/date +%Y-%m-%d)
    HOUR=$(/bin/date +%H-00)
    COMPACT=$(/bin/date +%Y%m%d_%H%M)
    BASEDIR="/backup/mikrotik"
    ROTATES=7
    ROUTERS="1.2.3.4 1.2.3.5"
    USER="admin"
    if [ "$1" == "debug" ]; then
      set -x
    fi
    for ROUTER in $ROUTERS; do
    mkdir -p $BASEDIR/$TODAY/$ROUTER 2>/dev/null
    /bin/chmod 0750 $BASEDIR;
    
    /usr/bin/ssh $USER@$ROUTER "/export file=export_${COMPACT}" && \
        /usr/bin/scp -q $USER@$ROUTER:/export_${COMPACT}.rsc $BASEDIR/$TODAY/$ROUTER/ && \
        /usr/bin/ssh $USER@$ROUTER "/file remove export_${COMPACT}.rsc"
    
    /usr/bin/ssh $USER@$ROUTER "/system backup save name=backup_${COMPACT}" &>/dev/null && \
        sleep 1 && \
        /usr/bin/scp -q $USER@$ROUTER:/backup_${COMPACT}.backup $BASEDIR/$TODAY/$ROUTER/ && \
        /usr/bin/ssh $USER@$ROUTER "/file remove backup_${COMPACT}.backup"
    
    /usr/bin/find $BASEDIR -mindepth 1 -maxdepth 1 -type d -mtime +$ROTATES -exec rm -rf "{}" \;
    done

    Please change the variables for BASEDIR, ROTATES and USER. The setting “ROUTERS” is a space-separated list of the target routers (ips and hostnames work both).

  • Currently, every router has to be configured to accept the same login name with the same SSH key.
  • How to set up the cronjob itself is also considered basic knowledge. If you are not aware of the configuration, please consult wikipedia 🙂

As always, this cronjob comes without any warranty. Please test and do not use in production before that!

Next Post Previous Post