Apps: "RouterOS", "Bacula v5.2/7.4/9.0", SSH.
Задача: наладить резервное копирование настроек маршрутизаторов "Mikrotik (RouterOS)" посредством "Bacula".
Основная идея в том, чтобы забирать резервные копии можно было максимально просто и безопасно. Технически можно подключится к "Mikrotik (RouterOS)", затребовать создание резервной копии и выгрузить её. Но гораздо надёжнее дополнительно задействовать автоматическое резервное копирование настроек средствами самой "RouterOS", а уже эти файлы забирать, подключаясь к "RouterOS" с сервера резервного копирования "Bacula".
Предварительная настройка на стороне "Bacula".
В несущей операционной системе сервера резервного копирования "Bacula" создаём пару SSH-ключей для беспарольной аутентификации при подключении к "Mikrotik":
# mkdir -p /etc/bacula/.ssh
# ssh-keygen -t rsa -b 2048 -f /etc/bacula/.ssh/mrtr0.example.net_id_rsa -P "" -C "bacula@example.net"
# chown -R bacula:bacula /etc/bacula/.ssh
# chmod -R go-rwx /etc/bacula/.ssh
# ssh-keygen -t rsa -b 2048 -f /etc/bacula/.ssh/mrtr0.example.net_id_rsa -P "" -C "bacula@example.net"
# chown -R bacula:bacula /etc/bacula/.ssh
# chmod -R go-rwx /etc/bacula/.ssh
Соответственно, для каждого нового маршрутизатора заводим отдельный набор SSH-ключей.
Конфигурирование "Mikrotik".
Настроим регулярное автоматическое создание резервных копий средствами самого "Mikrotik":
> /system scheduler add name="backup" on-event="system backup save name=today.backup" start-date=jan/01/1970 start-time=00:00:00 interval=10h comment="" disabled=no
Теперь каждые десять часов в файловой системе маршрутизатора будет создаваться файл резервной копии конфигурации, которая для этой модели (специфика аппаратуры влияет) позволит запустить новое устройство (или восстановить это) парой команд.
Для упрощения последующей наладки выгрузки можно отдать команду создания резервной копии вручную:
> /system backup save name=today.backup
Создаём в "Mikrotik" пользователя, который сможет только подключаться и считывать конфигурацию, не имея возможности изменить её:
> /user group add name=backup policy="ssh,ftp,read,sensitive,!local,!telnet,!reboot,!write,!policy,!test,!winbox,!password,!web,!sniff,!api,!romon,!dude,!tikapp"
> /user add name=bacula group=backup disabled=no
> /user add name=bacula group=backup disabled=no
В описании правил доступа выше флаги имеют следующее значение:
"ssh" - разрешает подключение и аутентификацию посредством SSH,
"ftp" - разрешает использование SCP (при том, что сервис FTP может быть отключён),
"read" - опеределяет глобальный уровень доступа подключающегося пользователя,
"sensitive" - разрешает чтение файлов резервных копий и паролей подсистем вроде PPP.
"ftp" - разрешает использование SCP (при том, что сервис FTP может быть отключён),
"read" - опеределяет глобальный уровень доступа подключающегося пользователя,
"sensitive" - разрешает чтение файлов резервных копий и паролей подсистем вроде PPP.
Загружаем публичную часть ранее заготовленного SSH-ключа в целевой "Mikrotik":
$ scp /etc/bacula/.ssh/mrtr0.example.net_id_rsa.pub admin@mrtr0.example.net:mrtr0.example.net_id_rsa.pub
Привязываем загруженную публичную часть SSH-ключа к специально созданному пользователю "bacula":
> /user ssh-keys import file=mrtr0.example.net_id_rsa.pub user=bacula
> /quit
> /quit
Ради интереса проверяем, сможет ли новый специализированный пользователь изменить конфигурацию:
$ ssh bacula@mrtr0.example.net
> /ip address add address=192.168.1.1/24 interface=ether5
> /ip address add address=192.168.1.1/24 interface=ether5
not enough permissions (9)
Проверяя возможность выгрузки забираем файл "бинарной" резервной копии посредством SCP:
$ scp -o "StrictHostKeyChecking no" -i /etc/bacula/.ssh/mrtr0.example.net_id_rsa bacula@mrtr0.example.net:today.backup ./today.backup
Конфигурирование "Bacula".
В качестве инструмента для подключения и выгрузки резервных копий из "Mikrotik" проще всего использовать агента резервного копирования самого сервера "Bacula" - наверняка он был настроен первым делом.
Таким образом, в описании задачи резервного копирования для каждого конкретного маршрутизатора мы будем опускать описание блока "Client", предполагая, что он уже настроен, просто указывая на него в описании блока "Job".
Приведу здесь отличия и дополнения относительно детально расписанной в публикации "Bacula Jobs configuration" обобщённой конфигурации:
# vi /etc/bacula/client.d/mrtr0.example.net.conf
....
# # Определяем резервируемую область для последующего применения в задаче:
FileSet {
# Задаём произвольное уникальное имя области резервирования
Name = "file-set-mrtr0.example.net"
Include {
Options {
recurse = yes
noatime = yes
}
File = "/var/backups/mikrotik/mrtr0.example.net"
}
}
....
# # Задаём параметры исполнения непосредственно задания резервного копирования:
Job {
# Уникальное имя задания резервного копирования (желательно включающее FQDN резервируемого сервиса)
# (используется как опорное для именований файлов конфигураций и "томов" резервных копий)
Name = "mrtr0.example.net"
....
# Связываем задание с описанием клиента
# (связь с параметром "Name" блока "Client")
Client = "client-bacula.example.net"
....
# Запуск выгрузки резервных копий "Mikrotik":
RunScript {
RunsWhen = Before
FailJobOnError = No
# Зачищаем и воссоздаём место для сохранения "дампа"
Command = "rm -rf /var/backups/mikrotik/mrtr0.example.net"
Command = "mkdir -p /var/backups/mikrotik/mrtr0.example.net"
# Загружаем файл "бинарной" резервной копии конфигурации
Command = "scp -o StrictHostKeyChecking=no -i /etc/bacula/.ssh/mrtr0.example.net_id_rsa bacula@mrtr0.example.net:today.backup /var/backups/mikrotik/mrtr0.example.net/today.backup"
# Запрашиваем и сохраняем набор команд конфигурации
Command = "/bin/bash -c 'ssh -T -o StrictHostKeyChecking=no -i /etc/bacula/.ssh/mrtr0.example.net_id_rsa bacula@mrtr0.example.net \"/export\" > /var/backups/mikrotik/mrtr0.example.net/today.export'"
# Запрашиваем и сохраняем детальный набор команд конфигурации
Command = "/bin/bash -c 'ssh -T -o StrictHostKeyChecking=no -i /etc/bacula/.ssh/mrtr0.example.net_id_rsa bacula@mrtr0.example.net \"/export verbose\" > /var/backups/mikrotik/mrtr0.example.net/today.export.verbose'"
}
#
RunScript {
RunsWhen = After
RunsOnFailure = yes
# По завершению всех процедур задания высвобождаем ресурсы
Command = "rm -rf /var/backups/mikrotik/mrtr0.example.net"
}
}
# # Определяем резервируемую область для последующего применения в задаче:
FileSet {
# Задаём произвольное уникальное имя области резервирования
Name = "file-set-mrtr0.example.net"
Include {
Options {
recurse = yes
noatime = yes
}
File = "/var/backups/mikrotik/mrtr0.example.net"
}
}
....
# # Задаём параметры исполнения непосредственно задания резервного копирования:
Job {
# Уникальное имя задания резервного копирования (желательно включающее FQDN резервируемого сервиса)
# (используется как опорное для именований файлов конфигураций и "томов" резервных копий)
Name = "mrtr0.example.net"
....
# Связываем задание с описанием клиента
# (связь с параметром "Name" блока "Client")
Client = "client-bacula.example.net"
....
# Запуск выгрузки резервных копий "Mikrotik":
RunScript {
RunsWhen = Before
FailJobOnError = No
# Зачищаем и воссоздаём место для сохранения "дампа"
Command = "rm -rf /var/backups/mikrotik/mrtr0.example.net"
Command = "mkdir -p /var/backups/mikrotik/mrtr0.example.net"
# Загружаем файл "бинарной" резервной копии конфигурации
Command = "scp -o StrictHostKeyChecking=no -i /etc/bacula/.ssh/mrtr0.example.net_id_rsa bacula@mrtr0.example.net:today.backup /var/backups/mikrotik/mrtr0.example.net/today.backup"
# Запрашиваем и сохраняем набор команд конфигурации
Command = "/bin/bash -c 'ssh -T -o StrictHostKeyChecking=no -i /etc/bacula/.ssh/mrtr0.example.net_id_rsa bacula@mrtr0.example.net \"/export\" > /var/backups/mikrotik/mrtr0.example.net/today.export'"
# Запрашиваем и сохраняем детальный набор команд конфигурации
Command = "/bin/bash -c 'ssh -T -o StrictHostKeyChecking=no -i /etc/bacula/.ssh/mrtr0.example.net_id_rsa bacula@mrtr0.example.net \"/export verbose\" > /var/backups/mikrotik/mrtr0.example.net/today.export.verbose'"
}
#
RunScript {
RunsWhen = After
RunsOnFailure = yes
# По завершению всех процедур задания высвобождаем ресурсы
Command = "rm -rf /var/backups/mikrotik/mrtr0.example.net"
}
}
Проверяем корректность конфигурации и применяем таковую:
# bacula-dir -c /etc/bacula/bacula-dir.conf -t
# /etc/init.d/bacula-dir reload
# /etc/init.d/bacula-dir reload
Выше я заворачиваю содержимое директивы "Command" в дополнительный контейнер из "/bin/bash" - это требуется потому, что по умолчанию "Bacula FD" запускает свои команды в интерпретаторе "Dash", синтаксис которого отличается от привычного мне "Bash".