📜 ⬆️ ⬇️

Backup Mikrotik with SSH and SCP

If you look back into the past when there was no Ansible or other remote linux administration systems, we used only our own scripts, allowed them to connect to ssh systems using keys. I think many people still use my scripts to replace centralized management systems.

I decided to share my experience.
It was necessary to write a script that can go to a specified number of hosts and backup some configuration files.

The logic of work lined up immediately. Log in to the host via ssh, execute some commands to prepare backups and pick up the finished files using scp

The first step is to create a user who will have access to the necessary data with the necessary rights. Here I think everyone can figure out which group to identify the user. The main thing to remember:
  1. The user name for a login without a password should be the same on all hosts, or you will have to specify your login for each host, which is not convenient;
  2. The user must have access to the host without a password (ssh-keygen to help);
  3. The user must have access to the files that must be collected.

here you can go several ways 1) execute the command in the remote shell to collect the necessary data to be backed up and then pick them up 2) set up cron on the host and execute the data collection command and then, someday, go to the host and pick up the ready backup cakes . Of course we will go the first way.
')
We have this configuration -
10 hosts (Mikrotik) from which you need to get two types of backups - binary (for restoring from scratch) and a configuration without passwords and certificates for uploading to a working config. We also have a machine with debian 8 on board, we’ll call it a server (and it’s not important that it is a container, it’s important that it is debian) and of course where it’s without it is a zabbix-server.



To simplify the task, the zabbix-hostname will be in the mik format (the third octet in the decimal format) .host thus we get -


If someone does not remember - we specify the zabbix hostname in the zabbix-agent configuration file (the agent is not needed here, but still) on the zabbix server in the web-ui.


First we create an RSA key on our server. Why RSA - yes, out of habit, by the way, old RB versions support only DSA, and everything that is newer 6.35 is already working with RSA and DSA, so look at the situation, you can upgrade as I did :) if you already have ready key - skip this step.

ssh-keygen -t RSA

We transfer the contents of the $ HOME / .ssh / id_rsa.pub file from the server to our hosts. I am lazy and for Mikrotik I used winbox.

For Linux, you can make it easier to create a sh script and run it on behalf of the user that we will go to the host for backups ( on the hosts the user should already be ) of such content -
If you have a DSA key then change id_rsa.pub to id_dsa.pub
 #!/usr/bin/env bash hosts=(10.10.0.1 10.10.1.1 10.10.2.1 10.10.3.1 10.10.4.1 10.10.5.1 10.10.6.1 10.10.7.1 10.10.8.1 10.10.9.1) username='user' for host in ${hosts[*]} do cat $HOME/.ssh/id_rsa.pub | ssh -o "StrictHostKeyChecking no" ${user}@${host} 'cat >> ~/.ssh/authorized_keys' done 

We start it and enter in turn passwords for all 10 servers in turn.

There is a catch in the script - I didn’t specifically add a check, otherwise I’ll completely forget how to press the keys -) if you all read it, the catch will not work.

Soooo, what's next, but, for sure, we already know how to walk without a password to all hosts under a user, say user.
We want to get Mikrotik configs. Actually proceed.

Create a script on the server
 #!/usr/bin/env bash hosts=(10.10.0.1_mik0.host_22 \ 10.10.1.1_mik1.host_22 \ 10.10.2.1_mik2.host_22 \ 10.10.3.1_mik3.host_22 \ 10.10.4.1_mik4.host_22 \ 10.10.5.1_mik5.host_22 \ 10.10.6.1_mik6.host_22 \ 10.10.7.1_mik7.host_22 \ 10.10.8.1_mik8.host_22 \ 10.10.9.1_mik9.host_22 ) # bash array of values. All values are arrays too, after remove splitter "_". # Sub array content IP_ZABBIX-HOSTNAME_SSH-DAEMON-PORT cdate=`date +%d-%m-%Y` # System date =) Hi Max dir="/mik_backup/" # Storage for backups cmd="/system backup save name=backup; export file=backup.rsc hide-sensitive" # command that do the preparation of backup username="user" # SSH user zabbix_hp=(10.10.10.10 10051) # IP then PORT age="30" # remove all backups older then 30 days itemname="backup" # zabbix item error_value="1" # error value for trigger value="0" # good value =) for host in ${hosts[*]} # Get values from main list do hostname=($(echo ${host} | tr "_" " ")) # Get values from sub list ssh ${username}@${hostname[0]} -o "StrictHostKeyChecking no" -p${hostname[2]} "${cmd}" new_dir="${HOME}${dir}${hostname[1]}/${cdate}" mkdir -p ${new_dir} scp -P${hostname[2]} ${username}@${hostname[0]}:backup.backup ${new_dir} scp -P${hostname[2]} ${username}@${hostname[0]}:backup.rsc ${new_dir} check=`find ${new_dir} -type f -name backup.*` if [ "${check}" == "" ] then zabbix_sender -z ${zabbix_hp[0]} -p ${zabbix_hp[1]} -s ${hostname[1]} -k ${itemname} -o ${error_value} else zabbix_sender -z ${zabbix_hp[0]} -p ${zabbix_hp[1]} -s ${hostname[1]} -k ${itemname} -o ${value} fi done find ${HOME}${dir} -mindepth 2 -mtime ${age} -type d -exec rm -rf {} \; #clear dirs 


I tried as much as possible to comment on everything that happens in the script. Let's look at what is being done here.

Here we say which interpreter will execute the code.
 #!/usr/bin/env bash 

Here we create an array with the data we need to connect to the hosts and send the data to zabbix
 hosts=(10.10.0.1_mik0.host_22 \ 10.10.1.1_mik1.host_22 \ 10.10.2.1_mik2.host_22 \ 10.10.3.1_mik3.host_22 \ 10.10.4.1_mik4.host_22 \ 10.10.5.1_mik5.host_22 \ 10.10.6.1_mik6.host_22 \ 10.10.7.1_mik7.host_22 \ 10.10.8.1_mik8.host_22 \ 10.10.9.1_mik9.host_22 ) 

Here I think only one variable needs to be explained - $ cmd. These are two commands that are executed on Mikrotik consistently. The first creates a binary backup
the second creates a script with settings without uploading passwords and encryption keys.
 cdate=`date +%d-%m-%Y` # System date =) Hi Max dir="/mik_backup/" # Storage for backups cmd="/system backup save name=backup; export file=backup.rsc hide-sensitive" # command to do the preparation of backup username="user" # SSH user zabbix_hp=(10.10.10.10 10051) # IP then PORT age="30" # remove all backups older then 30 days itemname="backup" # zabbix item error_value="1" # error value for trigger value="0" # good value =) 

The main body of the program. At the entrance to the loop, we have an array contained in the $ hosts variable. The cycle works like this - we take the first element of the array, we have it equal to 10.10.0.1_mik0.host_22 and start working with it. The first action we add to the $ hostname variable array created from the first element of the $ hosts array. We do this with the help of the tr command. As a matter of fact, in python we emit the action of the string method .split (). It turns out quite tolerable. We get 3 items in the $ hostname array. The first item is the host ip. The second element is zabbix-hostname. The third element is ssh-port.
Next we access these elements using an index, again python.
Next, create a directory tree for storing files and specify scp which files to take. Please do not kick - if someone tells you how to use scp in this design to access files by mask + in karma.
After we receive the files, we send a success message to zabbix.
Checking the creation of a config is made by simply searching the file in the destination directory. It was possible to make a comparison of md5 on Mikrotik and in the destination directory, but that's another story, although I did it.

 for host in ${hosts[*]} # Get values from main list do hostname=($(echo ${host} | tr "_" " ")) # Get values from sub list ssh ${username}@${hostname[0]} -o "StrictHostKeyChecking no" -p${hostname[2]} "${cmd}" new_dir="${HOME}${dir}${hostname[1]}/${cdate}" mkdir -p ${new_dir} scp -P${hostname[2]} ${username}@${hostname[0]}:backup.backup ${new_dir} scp -P${hostname[2]} ${username}@${hostname[0]}:backup.rsc ${new_dir} check=`find ${new_dir} -type f -name backup.*` if [ "${check}" == "" ] then zabbix_sender -z ${zabbix_hp[0]} -p ${zabbix_hp[1]} -s ${hostname[1]} -k ${itemname} -o ${error_value} else zabbix_sender -z ${zabbix_hp[0]} -p ${zabbix_hp[1]} -s ${hostname[1]} -k ${itemname} -o ${value} fi done 

Here we clean the place. The $ age variable will help us save backups as much as we need.
 find ${HOME}${dir} -mindepth 2 -mtime ${age} -type d -exec rm -rf {} \; #clear dirs 


Now the most trivial.
Create a template on the zabbix server or just a data item of the zabbix_trapper type on our nodes which we added in advance to monitoring in zabbix.
I will not post a template from one data element and one trigger. I think everyone can do it. The main thing to remember, if the hosts are monitored via zabbix-proxy, you should send the data to zabbix-proxy. Otherwise, send everything to the zabbix-server.
It does not even matter what the IP of these hosts will be in the zabbix web ui. It is important that the hostname matches the data in the script.

Ps. All scripts need to throw chmod + x so they can be run without calling the interpreter.
PSS To transfer the scp file list for backup to linux, you can create another array and nest it in a for loop. You can do everything in the form of received parameters. Well, in general, you can have fun.

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


All Articles