📜 ⬆️ ⬇️

Centralized backup of Mikrotik devices using a bash script

Hello everyone, in my first publication on Habré, I want to share a ready-made solution for backing up Mikrotik devices.

Two types of configuration backups are provided for the microtic, this is a binary backup and export configuration. Binary backup has its advantages and disadvantages. The advantage is that after restoring a binary backup, you have the entire configuration (with users, passwords, imported ssh-keys for users); the disadvantage is that such a backup cannot be restored to another type of device.

In general and in general, this is a full backup, its recovery takes little time and restores the entire configuration. Exporting the configuration as a backup method, in turn, partly smoothes out these shortcomings, being a script for the rebuild mikrotik. The point here is that all the settings that can be exported are displayed. The advantage is that you can see and feel what is exported there, and again the disadvantages include the fact that it also rests on the model. but a little less. Sometimes it's about the number of interfaces, sometimes something else. Also, not all settings can be exported to text (users, files on the device, ssh-keys).

In general and in general, as I made for myself, it is absolutely necessary to have both options for myself and preferably regularly and necessarily automatically. I took the idea from the wiki microtic: one and two .
')
The proposed version of backups by mail or ftp I do not like the fact that everything is either by mail or ftp, all plaintext. Just do not like the fact that you need to keep a box or ftp and mikrotik will send. It is more convenient for me to do everything from the server backups.

In fact, for a ssh backup with your hands, you just need to go to the microsoft, perform a backup and pick it up. Accordingly, it can be automated.

As you already understood, all this was realized with the help of a usual bash-script, then it was a little overgrown with garbage and quietly works. Therefore, I decided to describe it here to get some feedback from those who might be interested.

So, go directly to the script .

Script files


The script uses the executable file and specifies the configuration file as a parameter.

/usr/local/bin/mbkp /etc/mikrotik_backup/xxx-core01.cfg 

Accordingly, a backup script is placed in the / usr / local / bin / directory for ease of searching for it in the PATH, and configuration files are stored in / etc / mikrotik_backup / in accordance with the FHS. File sharing is a purely personal matter, it's just more convenient for me.

Executable script


The very first section contains shebang, checking the configuration file, without specifying which, the script will not be executed. Next are the default variables, rather concise, some of which you can override in the configuration file of a specific device.

 #!/bin/bash # mikrotik-backup script # author Tenhi # Initial checks # Config file should be provided and should be readable [[ -z "$1" ]] && echo "ERR: no config file provided" && exit 1 ! [[ -r "$1" ]] && echo "ERR: cannot read $1" && exit 1 # Default variables ( may be overrided in custom config ) #### Connection #################################### TGT_PORT="22" # default ssh-port TGT_USER="bkpuser" # Default backup user IDL="5s" # Default idle time #### Backup variables ############################## BKP_BINPWD="NvLB37zchdor9Y4E8KSpxibWHATfjstnw" # Default password for binary backup 33cr BKP_EXPPWD="hGAEJKptcCznB2v8RaHkoxiSTYNFZ3suW" # Default password for export 33cr ST_RTN="30" # Default retention time #### Storage variables ############################# ST_ROOT="/mnt/bkp_share/mikrotik" # Default storage root 

Next comes the line that makes the source of the configuration file:

 ####################################################################################################################### # Importing target config where you can override options source $1 ####################################################################################################################### 

After this, there is a section with some variables that are best set after the configuration file and system utilities are imported, which I look for with greater reliability through which:

 #### Utils ############################################################################################# CMD_FIND=$(which find) CMD_MV=$(which mv) CMD_GZ=$(which gzip) CMD_CHO=$(which chown) CMD_CHM=$(which chmod) CMD_MKD=$(which mkdir)" -p " CMD_RM=$(which rm) CMD_DATE=$(date +%Y%m%d_%H%M) # date in format YYYYMMDD_HHmm CMD_SSL=$(which openssl) CMD_SSH=$(which ssh) CMD_SCP=$(which scp) ######################################################################################################## ST_FULL=$ST_ROOT/$ST_HOSTNAME"/" # full path to .backup (/root_storage/hostname/) ST_ARCH=$ST_FULL"archive/" # full path to archive (/root_storage/hostname/archive) TGT_BKPNAME_BIN=$ST_HOSTNAME"_"$CMD_DATE".backup" TGT_BKPNAME_EXP=$ST_HOSTNAME"_"$CMD_DATE".export" SSH_OPT=" -o ConnectionAttempts=5 -o ConnectTimeout=5s \ -o PasswordAuthentication=no -o PreferredAuthentications=publickey \ -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ -o GlobalKnownHostsFile=/dev/null -o CheckHostIP=no " SSH_STR="$CMD_SSH -2 -4 -p $TGT_PORT -l $TGT_USER $TGT_IP $SSH_OPT" SCP_STR="$CMD_SCP -2 -4 -B $SSH_OPT -P $TGT_PORT $TGT_USER@$TGT_IP:/$TGT_BKPNAME_BIN $ST_FULL" 

Then comes the definition of the functions of the script, I will give a description below:

 #### Defining functions ################################################################################ function fn_check_log { # Function for checking need of creating logfile LOG=$ST_ROOT/"LOG.txt" # log-file location if [[ -r $LOG ]] then return 0 else echo " ################################################ # Logfile for mikrotik backups # The format is: # DATE;STATE;FILENAME # author: Tenhi(adm@tenhi.ru) ################################################ " > $LOG fi } function fn_check_readme { # Function for checking need of creating readme README=$ST_ROOT"/README.txt" # README File if [[ -r $README ]] then return 0 else echo " # === # Here you can find backups for all Mikrotiks # Files located in: # hostname/... # Archived backups are in: # hostname/archive/... # You can get backup info for all jobs in LOG.txt # === " > $README fi } function fn_check_directory { # Function for checking||creating full-path dirs if [[ -d $ST_FULL"archive" && -r $ST_FULL"archive" ]] then return 0 else $CMD_MKD $ST_FULL"archive" $CMD_CHO root:root $ST_FULL $CMD_CHM 755 $ST_FULL fi } function fn_mikrotik_cleanup { # Function for cleaning up target mikrotik $SSH_STR "ip dns cache flush" $SSH_STR "console clear-history" } function fn_mikrotik_fixtime { # Function for setting ntp client $SSH_STR "ip cloud set update-time=no; system ntp client set primary-ntp=0.0.0.0 secondary-ntp=0.0.0.0 enabled=yes server-dns-names=pool.ntp.org" } function fn_backup_binary { # Function for saving binary backup # Changed 20170901 T_BKPSTR="system backup save name=$TGT_BKPNAME_BIN dont-encrypt=no password=$BKP_BINPWD" T_BKPCLN="file remove [find name=$TGT_BKPNAME_BIN]" $SSH_STR $T_BKPSTR # Initializing backup sleep $IDL && $SCP_STR # Copy file to storage sleep $IDL && $SSH_STR $T_BKPCLN # Remove created file on mikrotik } function fn_backup_export { # Function for saving exported config # NOTE: decrypt the file # openssl des3 -d -salt -in encryptedfile.txt -out normalfile.txt EXP_TMP_FILE="/tmp/"$RANDOM".export" sleep $IDL && $SSH_STR export > $EXP_TMP_FILE $CMD_SSL des3 -salt -k $BKP_EXPPWD -in $EXP_TMP_FILE -out $ST_FULL$TGT_BKPNAME_EXP".des3" $CMD_RM $EXP_TMP_FILE } function fn_backup_retention { # Function for rotating old backups $CMD_FIND $ST_FULL -mtime +$ST_RTN -type f -exec $CMD_MV {} $ST_ARCH \; $CMD_FIND $ST_ARCH -type f -exec $CMD_GZ {} \; } function fn_log { # Function for recording results to logfile if [[ -r $ST_FULL$TGT_BKPNAME_BIN ]] then echo $CMD_DATE";okay;"$TGT_BKPNAME_BIN >> $LOG else echo $CMD_DATE";fail;"$TGT_BKPNAME_BIN >> $LOG fi if [[ -r $ST_FULL$TGT_BKPNAME_EXP".des3" ]] then echo $CMD_DATE";okay;"$TGT_BKPNAME_EXP".des3" >> $LOG else echo $CMD_DATE";fail;"$TGT_BKPNAME_EXP".des3" >> $LOG fi } 

All functions are signed, but I will explain a little. The functions fn_check_log fn_check_readme check and create the initial filling of the files LOG.TXT and README.TXT

fn_check_directory checks whether a directory is created for the device that you describe in the ST_HOSTNAME = directive in the config file

fn_mikrotik_cleanup clears the DNS cache and command history in the console so as not to drag it into backup and for secular purposes.

fn_mikrotik_fixtime is an optional thing that forces the ntp server to update the time. In this function, you can write anything you want, if you want to do it all the time. You can also not use this function if there is no need.

fn_backup_binary and fn_backup_export make binary and export backups, respectively. What is worth noting that instead of plaintext, an encrypted export file is created using openssl. (Accordingly, you need to have openssl in the system)

fn_backup_retention packs backups older than ST_RTN days, which you specify in the config file if you do not use the standard (30 days). The function puts them in the archive folder.

fn_log at the very end of the script creates an entry in the LOG.TXT file about the backup status

Device configuration file


Regarding the configuration file, the minimum configuration is:

 # Target device address (ip or DNS) TGT_IP="nmr01.loc.lan" # Also will be used to form backupname like $ST_HOSTNAME_YYYYMMDD-HHmm.backup|export ST_HOSTNAME="loc-nmr01" 

The rest of the directives config files are described in detail and are optional, that is, they have a default value:

 # Example config for mikrotik-backup script # author Tenhi (adm@tenhi.ru) # Required parameters are uncommented. Optional are commented # You can easly uncomment some of them to override defaults #### Connection #################################### # Target device address (ip or DNS) TGT_IP="" # Target device ssh port # TGT_PORT="22" # Target ssh user # TGT_USER="backupser" # Idle for avoiding ban (or something else) # IDL="1s" #### Backup variables ############################## # Password for binary backup ( default is in main script and there are no chance to do it without password :) ) # BKP_BINPWD="" # Password for export ( default is in main script ) # BKP_EXPPWD="" #### Storage variables ############################# # root backup location # ST_ROOT="/mnt/backup" # will be used to create dir $ST_ROOT/$ST_HOSTNAME # Also will be used to form backupname like $ST_HOSTNAME_YYYYMMDD-HHmm.backup|export ST_HOSTNAME="" # backup retention to archive files older $ST_RTN days to $ST_ROOT/$ST_HOSTNAME/archive/ # ST_RTN="30" #### Logging ####################################### # LOG default location # LOG=$ST_ROOT/$ST_HOSTNAME/"LOG.txt" 

Cron


If you want to run a run, you can use the example cron task:
 # Mikrotik backup script mbkp # Config: MCFG="/etc/mikrotik_backup" MBKP="/usr/local/bin/mbkp" MLOG="/var/log/mikrotik_backup/log" # Tasks: 00 03 * * * $MBKP $MCFG"/xxx-core01.cfg" >>$MLOG 2>>$MLOG # XXX DC New core router node1 

So, you can copy and use my solution right away about using cron in the scheduler, but I'll explain a little. Naturally, all paths must exist and the files must be readable, and the script must be executed. Using variables in the crown is not forbidden and slightly improves readability when you have more than 50 Kronov tasks.

Source: https://habr.com/ru/post/342060/


All Articles