Для микротика предусмотрены два вида бэкапов конфигурации, это бинарный бэкап и экспорт конфигурации. Бинарный бэкап имеет свои преимущества и недостатки. Преимуществом является то, что после восстановления бинарного бэкапа у вас сохраняется вся конфигурация( с пользователями, паролями, импортированными для пользователей ssh-ключами); недостатком же является то, что такой бэкап нельзя восстановить на другого типа устройство.
В целом и общем это полноценный бэкап, его восстановление занимает мало времени и восстанавливает всю конфигурацию. Экспорт конфигурации как способ бэкапа в свою очередь отчасти сглаживает эти недостатки, являясь скриптом для ребилда микротика. Суть тут в том, что выводятся все настройки, которые могут быть экспортированы. Преимуществом является то, что можно посмотреть и пощупать, что же там экспортируется, а к недостаткам можно опять же отнести то, что это тоже упирается в модель. но чуть меньше. Иногда дело в количестве интерфейсов, иногда ещё в чём-то. Так же не все настройки могут быть экспортированы в текст(пользователи, файлы на усройстве, ssh-ключи).
В целом и общем, как я вынес для себя, совершенно необходимо иметь для себя оба варианта и желательно регулярно и обязательно автоматически. Идею я взял из вики микротика: раз и два.
Предложенный вариант бэкапов по почте или ftp мне не нравится тем, что тут всё либо по почте, либо по ftp, всё plaintext. Так же не нравится то, что надо держать какой-то ящик или ftp и микротики сами будут слать. Мне удобнее всё делать с сервера бэкапов.
По сути для бэкапа по ssh руками достаточно просто зайти на микротик, выполнить бэкап и забрать его. Соответственно это можно автоматизировать.
Как вы уже поняли, реализовалось это всё с помощью обычного bash-скрипта, далее он немного оброс мусором и тихо работает. Поэтому я решил его описать здесь чтобы получить какой-то фидбэк от тех, кому это может быть интересно.
Итак, переходим непосредственно к скрипту.
Файлы скрипта
Для работы скрипта используется исполняемый файл и параметром к нему указывается файл конфигурации.
/usr/local/bin/mbkp /etc/mikrotik_backup/xxx-core01.cfg
Соответственно размещается бэкапный скрипт в директории /usr/local/bin/ для простоты поиска оного в PATH, а файлы конфигурации хранятся в /etc/mikrotik_backup/ в соответствии с FHS. Размещение файлов дело сугубо личное, мне просто так удобнее.
Исполняемый скрипт
Самая первая секция содержит shebang, проверки конфигурационного файла, не указав который, скрипт не выполнится. Далее идут дефолтные переменные, достаточно лаконичные, часть из которых вы можете переопределить в файле конфигурации конкретного устройства.
#!/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
Далее идёт строка, которая делает source конфигурационного файла:
#######################################################################################################################
# Importing target config where you can override options
source $1
#######################################################################################################################
После идёт секция с некоторыми переменными, которые лучше задавать после того, как импортируется конфигурационный файл и системные утилиты, которые я для пущей надёжности ищу через 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"
После идёт определение функций скрипта, описание я дам ниже:
#### 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
}
Все функции подписаны, но я немного поясню. Функции fn_check_log fn_check_readme проверяют и создают первичное наполнение файлов LOG.TXT и README.TXT
fn_check_directory проверяет создана ли директория для устройства, которое вы описываете в директиве ST_HOSTNAME="" в конфиг-файле
fn_mikrotik_cleanup выполняет очистку кэша DNS и истории команд в консоли, чтобы не тянуть это в бэкап и в секурных целях.
fn_mikrotik_fixtime вещь опциональная, которая принудительно устанавливает ntp-сервер для обновления времени. В этой функции можно написать всё, что угодно, если вы хотите постоянно это выполнять. Можно так же не пользоваться этой функцией если нет нужды.
fn_backup_binary и fn_backup_export делают бинарный и экспорт-бэкапы соответственно. При чём стоит заметить, что вместо plaintext, создаётся зашифрованный экспорт-файл используя openssl. (Соответственно нужно иметь openssl в системе)
fn_backup_retention упаковывает бэкапы старше чем ST_RTN дней, которую вы задаёте в конфиг файле, если не используете стандарт(30 дней). Функция кладёт их в папку archive
fn_log в самом конце скрипта создаёт запись в файле LOG.TXT о статусе бэкапа
Конфигурационный файл устройства
Касательно файла конфигурации минимальная конфигурация это:
# 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"
Остальные директивы конфиг файлы подробно описаны и являются опциональными, то есть имеют дефолтное значение:
# 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
Если вы хотите зашедулить выполнение, можно использовать пример cron задачи:
# 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
Итак, сразу об использовании в планировщике cron можете копировать и пользоваться моим решеним, но я немного поясню. Естественно все пути должны существовать и файлы должны быть доступны на чтение, а скприт на выполнение. Использование переменных в кроне не возбраняется и немного улучшает читабельность, когда кроновских задач у вас больше 50.
Комментарии (13)
NikiN
10.11.2017 11:40Почему не github.com/ytti/oxidized?
tenhi_shadow Автор
10.11.2017 19:19не знаком с руби, да и не хочу быть знаком.
Тут ещё и в простоте дело, всё с минимумом зависимостей на обычном ssh, единственное это openssl, что надо ставить.
Нет веба, баз данных — нечему ломаться
TerAnYu
12.11.2017 21:19Можно делать без пароля:
dont-encrypt=yes
tenhi_shadow Автор
13.11.2017 11:07ну, это да. Но у себя я хотел сделать так, чтобы пароль был всегда.
tarasius
13.11.2017 11:08Идея. А нельзя ли вытягивать пользователей, файлы и т.д. через SFTP из микротика?
tenhi_shadow Автор
13.11.2017 11:15файлы — без проблем. А пользователей никак не вытянуть.
Пользователь на устройстве микротик не вытягивается никак(насколько я знаю). Да и смысла особого нет его вытягивать, можно написать скрипт, который его так же создаст, задаст пароль и наимпортирует ключей.
Касательно файлов на устройстве — в самом скрипте это уже делается. Когда создаётся бэкап, он кладётся на устройство, а потом с устройства копируется, и сразу же удаляется, ибо если они накопятся, то места под новые бэкапы уже не будет.
создаётся, копируется, удаляется:
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
kibb
13.11.2017 11:08В чем смысл определения полных путей для всех команд, но через which? Это карго-культ — в больших кодовых базах на sh в самом деле определяют полные пути к используемым командам, но:
1. либо явно прописывают системный путь, т.е. /bin/ln, /usr/bin/env…
2. либо меняют текущий PATH
У вас ничего из перечисленного не происходит, CMD_CHO etc затрудняют чтение и не добавляют функциональности.tenhi_shadow Автор
13.11.2017 11:08пожалуй, но лично мне так показалось удобнее
tenhi_shadow Автор
13.11.2017 11:36неудобно читать, но и не нужно задумываться, что-где лежит на разных системах.
chelaxe
Делал подобное. Я сохранял еще лицензию при постановке устройство в систему (система — это 3 скрипта =)) бекапов. И все это благолепие заворачивал в git репозиторий. Коммитил раз в месяц, мне чаще не нужно было. Плюс в том, что можно было различие отследить.
tenhi_shadow Автор
ну тут я ещё сделал пароль по дефолту(нет шанса сделать бэкап без пароля). И костылик для экспорта с «паролем».
Про бэкап лицензии в первый раз слышу, а зачем?
chelaxe
возможно использовать на других устройствах после смерти…
TerAnYu
Можно делать бэз пароля:
dont-encrypt=yes