Backup скрипт на bash архивиращ Линукс отдалечени машини и рутери Mikrotik
Как работи rsync
На този етап в Unix системите rsync е най мощният инструмент за архивиране на данни. След тази кратка команда rsync има в буквалния смисъл хиляди опции и варианти за архивиране на данни. Нека започенм с най простия:
rsync --delete -az /home/samyil/music/ /home/samyil/backup/
Всички файлове от директорията music ще бъдат копирани в backup. След повторно използване на командата всички промени в music ще се случат и в backup като rsync няма да копира цялата директорията като обем отново а ще изпълни само промените. Тоест, ако в music имаме 1000 файла, изтрием един и добавим друг, rsync в backup ще направи същото без да докосва другите 999 файла. Същото ще се случи ако са хиляди директории с хиляди файлове. Сега надявам се започва да става ясно защо е толкова невероятен този инструмент !
Да предположим, че в основната директория music по някаква причина имаме промяна във файловете и искаме да ги въстановим. Тъй като те са 1000 на брой се предполага, че и обема и е твърде голям за да копираме по стандартния начин архивираните данни обратно. Процедурата по връщането на архивираните дани в основната директория е много проста – само разменяме местата на основната и архивиращата директория:
rsync --delete -az /home/samyil/backup/ /home/samyil/music/
В този сценарии директорията backup ще се копира в директорията music.
Както вече казах можем да използваме различни опци според нуждите ни:
rsync --bwlimit 10000 --progress --stats --delete -avzh /home/samyil/music/ /home/samyil/backup/
–bwlimit 10000 ограничава скороста (в случая е 1mb) ако по някаква причина не искаме да си тормозим хард диска или да не запълним капацитета на Интернет връзката ни (rsync може да архивира и през мрежа)
–progress В реално време ни показва копирането на файловете в проценти (ако файловете са големи е много удобно)
–stats след като приключи ще ни покаже много информация от рода на колко файла е проверил, колко обем е трансферирал и много други.
–delete изтрива в архивиращата директория всичко което вече не съществува в основната (има вариант в който може да не искате това)
-a архивира директориите
-v показва повече информация
-z компресира
-h информацията излиза в четим вариант за човека
Доста често има случаи в които в основната директория имаме други такива които не искаме да архивираме, за да изключим от архива трябва за използваме опцията –exclude.
rsync --delete -az --exclude=/home/samyil/music/new --exclude=/home/samyil/music/new2 /home/samyil/music/ /home/samyil/backup/
Каквото и да копираме в new и new2 те няма да се копират в backup.
Rsync владее силата да архивира данни през мрежата, от и на отдалечена машина посредством протокола SSH. С това той се превръща в незаменимо средство за системния администратор който иска да прехврърли криптирани данни били те за архив или за друго.
rsync --delete --stats -avzh -e ssh root@192.168.100.2:/var/www /home/samyil/backup
В случая от отдалечената машина директорията /var/www ще се копира в локалната машина в /home/samyil/backup.
Тъй като в горния пример rsync работи в комбинация с ssh, ако не сте свързвали досега с отдалечената машина стандартно ще бъдете попитани ще приемете ли ключа на SSH.
samyil@desktop:~$ ssh root@192.168.100.2
The authenticity of host '192.168.100.2 (192.168.100.2)' can't be established.
ECDSA key fingerprint is SHA256:OSGw4kv6v+d1mnR/Oczf55aQ89giR6cAJVocUZpfEKI.
Are you sure you want to continue connecting (yes/no)?
Тази досада ще ни пречи в скрипта с който искаме да автоматизираме архивирането на много машини. Когато се изпълнява скрипта за първи път трябва да обиколим преди това всички с SSH и да и приемем ключовете. За да не се случва това ще добавим в скрипта опцията на SSH -o StrictHostKeyChecking=no която на практика изключва промта (yes/no)?
ужас, sshpass ми знае паролата
И така, стигнахме до момента в който можем да архивираме от отдалечена машина но все още не може да автоматизираме процеса защото „някой“ трябва да ни пише паролата на отдалечената машина дори и след като премахнахме първоначалното (yes/no)?. За шок и ужас на паранойците по сигурноста ще инсталирам една много полезна програмка sshpass с която ще автоматизирам изцяло архивирането.
sudo apt-get install sshpass
И ще изпълня rsync със следните опции като този път ще добавя и различен порт на отдалечената машина за SSH.
sshpass -p mypassword rsync --delete --stats -avzh -e 'ssh -o StrictHostKeyChecking=no -p 4444' root@192.168.100.2:/var/www /home/samyil/backup
Вече сме почти готови за написването на скрипт който ще автоматизира архивирането на данни на отдалечени сървъри.
Автоматизираме със скрипт
Създаваме файл backup.sh, копираме следното съдържание в него, конфигурираме си го по нашите нужди и го правим изпълним със sudo chmod +x backup.sh !
#!/bin/bash
#
# Based backup remote linux servers and mikrotik routers
# Require rsync, ssh and sshpass
#
# Samuil Arsov <support@itservice-bg.net>
#
### Global conf ###
RSYNC="rsync --delete --stats -azh"
SSH="-o StrictHostKeyChecking=no"
LOG="/var/log/backup.log"
### Remote linux server config ###
host1() {
PASS="password1";
PORT="22";
SOURCE="root@192.168.100.2:/";
DEST="/home/samyil/hosting1";
EXCLUDE="--exclude /dev --exclude /proc --exclude /sys \
--exclude /tmp --exclude /run --exclude /mnt"
}
host2() {
PASS="password2";
PORT="2222";
SOURCE="root@192.168.100.3:/";
DEST="/home/samyil/hosting2";
EXCLUDE="--exclude /dev --exclude /proc --exclude /sys \
--exclude /tmp --exclude /run --exclude /mnt --exclude \
/var/lib/libvirt --exclude /var/lib/lxcfs --exclude /var/lib/nagios3/"
}
### Remote Mikrotik router config ###
router1() {
PASS="password3";
PORT="4444";
SOURCE="admin@192.168.100.1";
NAME="Mikrotik1.txt";
DEST="/home/samyil/mikrotik";
}
router2() {
PASS="password4";
PORT="8888";
SOURCE="admin@192.168.100.254";
NAME="Mikrotik2.txt";
DEST="/home/samyil/mikrotik";
}
### Banner separated logging server/router ###
banner(){
echo ""
echo "----------------------------------------------------------------"
echo "Source: $SOURCE Destination: $DEST"
}
### Rsync backup remote linux server ###
rsync_script() {
if [ ! -d $DEST ]; then
mkdir -p $DEST
fi
sshpass -p $PASS $RSYNC -e "ssh $SSH -p $PORT" $SOURCE $EXCLUDE $DEST
}
### Export configuration mikrotik routers ###
ssh_script() {
if [ ! -d $DEST ]; then
echo mkdir -p $DEST
fi
sshpass -p $PASS ssh $SSH -p $PORT $SOURCE 'export compact' > $DEST/$NAME
echo "$(stat $DEST/$NAME)"
}
### show space backup dir ###
show_space() {
df -ht ext4
}
case "$1" in
### Start all backup configuration ###
start)
exec &> $LOG
host1; banner; rsync_script
host2; banner; rsync_script
router1; banner; ssh_script
router2; banner; ssh_script
mail -s "host.itservice-bg.net backup" robot@telehost.bg < $LOG
;;
### show space backup dir ###
show)
echo "------------------------------------------------"
show_space
echo "------------------------------------------------"
host1; du -sh $DEST
host2; du -sh $DEST
;;
### show last log ###
log)
echo "------------------------------------------------"
echo "$(cat $LOG)"
;;
*)
### Usage commands ###
clear
echo $"Usage: $0 {start|show|log}"
exit 1
;;
esac
exit 0
Нека да направим така, че скрипта да се изпълнява всяка сутрин в 6 часа сутринта автоматично без човешка намеса. За целта трябва да редактираме /etc/crontab като добавим следния ред:
0 6 * * * root /home/samyil/backup.sh
И рестартираме cron демона за да влязат настройките в сила:
sudo service cron restart
Кратки бележки
В по ранен вариант бях сложил в скрипта проверка дали порта на SSH е достъпен, и ако не е изполванете на rsync се подминава с exit 0. По късно обаче видях, че нямам нужда от това, така или иначе SSH логва, че няма достъп до този порт. Въпреки всичко кода отдолу е полезен и може да се използва за по разширешен вариант (за обяснителни събития например)
nc -w 1 -z $(echo $SOURCE | cut -d "@" -f 2) $PORT
if [ "$?" -eq 1 ]; then
echo "SSH port is disable"
exit 0
fi
Фунцията rsync_script() започва така:
if [ ! -d $DEST ]; then
mkdir -p $DEST
fi
Този код е нужен защото при добавяне на нова машина за архивиране rsync ще види, че няма такава директория и ще спре като изплюе грешка. Това ще е много неудобно ако сървърите които архивираме са повечко и трябва да създадем директорията с mkdir по точния път.
Mikrotik в RouterOS има една вълшебна команда export, нейното предназначение е да покаже цялата конфигурация на рутера в текстов вид.
На практика ако изпълним:
sshpass -p <passtherouter> ssh -p 4444 admin@192.168.100.1 'export compact' > Router.txt
ще получим конфигурацията от рутера на локалната ни машина в текстовия файл Router.txt Този текстов файл става дори по ценен от собствената система за архивиране на Mikrotik защото винаги можеш да си го отвориш, да си го разгледаш и да промениш нещо в конфигурацията преди да започнеш да въстановяваш както често се случва на практика.
echo "$(stat $DEST/$NAME)"
Има много Линукс администратори които не знаят за съществуването на командата stat, не че тя се ползва толкова често но ако ви се е случвало да търсите следи от взлом в Линукс машина след bash_history и auth_log това е програмата която дава супер ценната информация. Нека я изпълним и да видим какво ще ни покаже тя:
Размер и кога за последно е модифициран файла е информациата която искам да логна за да знам копирал ли съм конфигурацията на рутера Mikrotik.
exec &> $LOG
Създава колектор на събитията и започва да логва всичко в $LOG файла. След като се изпълни скрипта логнатите събития се изпращат на мейл с:
mail -s "host.itservice-bg.net backup" robot@telehost.bg < $LOG
Така всяка сутрин след 6 часа сутринта, след като се изпълни скрипта аз получавам пълен отчет на мейла си за архивирането на данните от сървърите и конфигурационните файлове от рутерите който ми служи и като индикатор за броя на файлове и обема на данни по сървърите.
Изпълняване на скрипта
Нека проследим какво се случва ако изпълним скрипта. В първия прозорец стартираме скрипта с командата sudo ./backup.sh start. Тъй като всичко се случва в background режим във втория прозорец изпълняваме ps axf | grep -v grep | grep rsync за да видим има ли такъв процес rsync и какво прави той. В третия прозорец с sudo tail -f /var/log/backup.log в реално време следим логовете които така или иначе след това ще получим на мейла си.
Както се вижда по долу отчета изпратен на мейла е доста подробен, брой на файлове (създадени, изтрити), обем на данни (получени, изпратени) както и тотал на всичко това. Чисто технически поглеждайки отчета само първия сървър е притежател на 829703 файла които се побират 472.91 гигабайта но при архивирането са копирани само 3.22 гигабайта. Всеки който чете това и е стигнал до тук му е ясно каква е разликата да се копират по мрежа 472.91 гигабайта или 3.22 гигабайта, както и натоварване на хард дисковете, процесорно време и не на последно място излишно натоварване на Интернет капацитета.



