[Из песочницы] Автобэкапы сетевого оборудования и хранение их в системе контроля версий
Уточнение: решение настроено для D-Link DFL, cisco 29xx и WatchGuard Firebox, но подходит для всего, что умеет делать бэкапы при подключении по ssh и/или заливать их по расписанию/событию на ftp/tftp сервер.
Всё началось с того, что мой знакомый программист спросил: «А почему ты не хранишь сетевые конфиги в системе контроля версий?». А и правда — подумала я — почему? Большая часть конфигурационных файлов может быть выгружена в текстовом формате (ну, это бинарники, конечно, но в текстовом редакторе открываются и отображается читабельная информация).
В сети у нас около 30 разных D-Link DFL, десяток Cisco 29xx и пара WatchGuard Firebox. К каждому устройству имеют доступ уровня администратора сотрудники ИТ филиала, где оно стоит, плюс ИТ головного офиса. Это влечёт за собой проблемы вида «я не делал бэкап полгода и всё сломал, у вас нет нашего бэкапа?» и «у нас сгорело оборудование последний бэкап делал предыдущий админ, я не знаю куда, настройте нам как было». И если cisco и так автоматически сбрасывает running-config на ftp при каждом сохранении, то с D-Link такого нет. А система контроля версий помогла бы отследить проблемы вида «я не помню, что и когда поменял, но у нас сломалась штука, которая используется раз в месяц». Регламент о резервном копировании не спасает от человеческого фактора и не сделает бэкап за вас, так что лучше предупредить, чем расхлебывать.
Признаюсь честно, до того, как я села писать пост, я не знала про rancid и oxidized. Но они оба не умеют то, что нужно мне в полном объеме. Первый заточен на cisco и со всякой экзотикой работает не очень, второй не имеет авторизации пользователей (хотя это обходится несложными манипуляциями с web-сервером), а, главное, оба они требуют наличия логина и пароля в резервируемую систему. Все D-link DFL поддерживают логин по ключу ssh. Cisco сливает бэкапы сама и вообще не требует коннекта на неё. Соответственно, зачем хранить пароли, периодически меняющиеся, к тому же, если можно логиниться по ключу.
Было решено сделать что-то меня устраивающее самостоятельно.
Собственно, автобэкапы напрашивались давно. А вот система контроля версий — это было свежо.
Итак, задача: собрать все значимые конфиги с сетевого оборудования в одном месте с поддержкой версионности файлов, регулярно их там обновлять в автоматическом режиме, дать возможность админам в другом часовом поясе их скачать простым способом, не звоня мне в 3 утра. Всё это, конечно, бесплатно.
У всех DFL файл конфига называется одинаково, соответственно надо было их при копировании внятно называть. Также не хотелось перенастраивать уже существующую систему заливки running-config на ftp у cisco.
Сначала настраиваем систему контроля версий
Я взяла svn, т.к. svn — единственный из популярных хранит diff бинарников, а не все файлы в истории. Не то, чтобы это было важно на малых объемах, но приятно. В целом, учитываю малый объем конфигурационных файлов, какую систему контроля версий брать — без разницы.
Устанавливается сервер Visual SVN с официального сайта методом далее-далее-готово. Я ставила на сервер под Windows, чтоб коллегам было проще администрировать (пользователей создавать, права раздавать). Далее создаётся репозиторий, в нем необходимые разделы и создаётся (пока) единственный пользователь с полными правами на репозиторий. На винде действия закончены.
Автобэкапы у меня делаются скриптом с одной линуксовой машинки (под Debian).
Сначала ставим svn, чтоб у нас появился клиент:
sudo apt-get install svn
Теперь руками создается копия проекта (создастся в текущей директории):
svn checkout https://servername.mydomain.ru/svn/DFL_BACKUPS/ DFL_BACKUPS --username go
Сейчас у меня в репозитории три раздела:
- Current_backup, где хранятся и перезаписываются конфиги D-Link DFL.
- Old_versions, где хранятся конфиги с приписанной датой для удобства скачивания админами филиалов.
- Cisco, где хранятся конфиги cisco и WatchGuard Firebox (ну, так сложилось).
Начнем с автобэкапов DFL и настройки самого DFL
Коннект идет по ssh. Чтобы не светить пароли в открытом виде, используется пара открытый-закрытый ключ. Закрытый хранится на сервере в /usr/dfl_scripts/sshkeys/dfl_key.
Генерируем пару открытый-закрытый ключ на сервере автобэкапов:
ssh-keygen –t rsa
открытый залит во все DFL и сделано правило доступа по ssh:
Ну и разрешен соответствующий remote management. Порт с дефолтного можно изменить на, например, 2222, хотя доступ и так только с определенных адресов.
Файл с текущей конфигурацией у D-Link DFL лежит в корне и называется config.bak, его можно просто скопировать себе, используя scp.
Итак, скрипт (я порезала список филиалов, чтоб не было простыни):
#!/bin/bash
rm /usr/dfl_scripts/dflbackup/* #очищаем старые файлы бэкапа
dfls=( "amur:10.28.10.254" #перечисляем филиалы
"arhangelsk:10.29.10.254"
"buratia:10.3.10.254"
"volgograd:10.34.10.254"
"voronezh:10.36.10.254"
"irkutsk_210:10.38.20.253"
"irkutsk_260:10.38.20.254"
"yaroslavl:10.76.10.254" )
rm /usr/dfl_scripts/log.txt #очищаем лог-файл
for dfl in "${dfls[@]}" ; do #цикл по всем ДФЛ-кам
filial="${dfl%%:*}" #delete the longest substr :* search from the end of string
ip_addr="${dfl##*:}" #delete the longest substr *: search from the head of string
echo $filial $ip_addr >> /usr/dfl_scripts/log.txt #Пишем в лог текущий филиал
scp -P 2222 -i /usr/dfl_scripts/sshkeys/dfl_key admin@$ip_addr:config.bak /usr/dfl_scripts/dflbackup/$filial.bak 2>>/usr/dfl_scripts/log.txt #скачиваем конфиг с дфл, ошибки пишем тоже в лог
done
FILES=$(ls /usr/dfl_scripts/dflbackup) #Запихиваем имена файлов в массив
now=$(date +"%d_%m_%Y") #записываем в переменную текущую дату
for f in $FILES ; do #цикл по всем файлам в директории (которые уже упиханы в массив)
cp /usr/dfl_scripts/dflbackup/$f /usr/dfl_scripts/DFL_BACKUPS/current_backup/$f #копируем как есть в папку текущего бэкапа
cp /usr/dfl_scripts/dflbackup/$f /usr/dfl_scripts/DFL_BACKUPS/old_versions/${f%.bak}_$now.bak #копируем с датой в папку свалки всех конфигов
done
cd /usr/dfl_scripts/DFL_BACKUPS #переходим в папку svn проекта
svn add * --force -q >> /usr/dfl_scripts/log.txt #добавляем новые файлы. и пишем в лог.
svn commit -m "added backups $now" >> /usr/dfl_scripts/log.txt #коммитим и пишем в лог
/usr/bin/mail it@mydomain.ru < /usr/dfl_scripts/log.txt -s "Отчет о бэкапах DFL" #и отправляем письмо с лог-файлом на почту
Скрипт запихнут в cron и запускается в 8:30 утра ежедневно. Вот так выглядит crontab:
30 08 * * * /usr/dfl_scripts/autobackup.sh
30 06 * * * /usr/dfl_scripts/ciscobackup.sh
00 06 * * 1 /usr/dfl_scripts/fireboxbackup.sh
Теперь про cisco
На самих устройствах настроено что-то вроде этого:
archive
log config
logging enable
logging size 500
hidekeys
path ftp://ftp.mydomain.ru/in/autolog/$H-$T
write-memory
ip ftp username user
ip ftp password mypass
ip scp server enable
В итоге, по команде write-memory текущая конфигурация сбрасывается на ftp. У меня ftp находится на другом сервере, чем сборище автобэкапов. Тут 2 пути: сделать и на том сервере копию репозитория и добавлять конфиги там или копировать конфиги на соседний сервер. В принципе, вся разница в том, делать cp или scp.
На директорию, куда падают конфиги с cisco, я сажаю incron следить за появлением файлов. По появлению файла — переименовываю его как надо и копирую на сервер-сборщик автобэкапов во временную директорию. По отсечке, файлы из временной директории заливаются в svn. Итого я имею в системе контроля версий актуальный конфиг на определенное время раз в день. На мой взгляд, этого достаточно, но система без проблем модифицируется под любые хотелки.
Конфигурация incrontab выглядит так:
/var/ftp/cisco/in/autolog/ IN_CREATE /usr/ftp_scripts/incron_cisco.sh $# $%
Сам скрипт:
#!/bin/bash
if [[ $2 == "IN_MOVED_TO" || $2 == "IN_CREATE" ]]; then
sleep 10
filial="${1%%-*}" #delete the longest substr -* search from the end of string. Обрезаем дату и оставляем только имя устройства
scp -P 2222 -i /usr/ftp_scripts/ssh_key_private /var/ftp/cisco/in/autolog/$1 go@10.10.10.220:/usr/dfl_scripts/ciscobackup/$filial.conf
fi
На сервере автобэкапов по расписанию запускается следующий скрипт:
#!/bin/bash
logfile=/usr/dfl_scripts/log_cisco.txt
rm $logfile
now=$(date +"%d_%m_%Y")
cd /usr/dfl_scripts/DFL_BACKUPS
cp /usr/dfl_scripts/ciscobackup/* /usr/dfl_scripts/DFL_BACKUPS/cisco/
svn add * --force –q >> $logfile
svn commit -m "added cisco backups $now" >> $logfile
/usr/bin/mail it@mydomain.ru < $logfile -s "Отчет о бэкапах cisco и watchguard"
Как видно, тут речь еще и о WatchGuard Firebox. Мне было откровенно лениво делать для них отдельную директорию. Так что бэкапы падают на ftp туда же, куда и cisco. WatchGuard бэкапится отдельным скриптом на полчаса раньше и вообще раз в неделю. Обратите внимание, с версии прошивки 12 изменился синтаксис. Раньше это можно было делать одной командой backup image to ftp, а теперь добавился export. На нём я не смогла настроить логин через ssh по ключу, так что используются пароли.
#!/bin/bash
watchguards=( "10.10.10.20:password1"
"10.97.10.20:password2" )
now=$(date +"%Y_%m_%d")
for wg in "${watchguards[@]}" ; do
ip_addr="${wg%%:*}"
pass="${wg##*:}"
sshpass -p $pass ssh backupuser@$ip_addr -p 4118 << ENDME
backup image WG_$now.fxi
export image WG_$now.fxi 123456qQ to ftp://user:mypass@ftp.mydomain.ru/in/autolog/WG_$ip_addr-$now.fxi
ENDME
Done
У WatchGuard файлы бинарники экспортируются только шифрованные, так что тут с текстовым видом и diff не очень получится. Обратите внимание на ключ шифрования: обязательный заглавные, строчные буквы и цифры, не менее 8 символов. При не соответствии просто не выполняется команда, конкретно не указывается, где ошибка.
Итак, всё сделалось. Теперь ставим клиента на свой рабочий комп под виндой. Просто посмотреть файлы и diff можно и из браузера, а вот скачать версию из определенной ревизии только из клиента. Ставим TorToSiteSVN с официального сайта.
На сервере создаем пользователя с необходимыми правами (на чтение) для филиалов.
Потом надо зайти в клиент через контекстное меню к любому файлу и подключиться к хранилищу. Себе копию хранилища создавать не обязательно, если вы не планируете вносить изменения в файлы. Ну и осторожнее с этим, с копией надо будет работать через систему контроля версий, а не просто как с куском файловой системы.
Чтоб заработали diff«ы на нестандартных тексовых файлах, надо сделать так, чтоб SVN считал эти файлы не бинарными, а текстовыми. Вот так:
svn propset svn:mime-type text/plain current_backup/*.bak
Эту команду выполнить, например, под linux и после сделать commit.
Ну и вот изменения, смотрим глазками. Видим, что менялись правила firewall:
В браузере смотреть удобнее.
Если что стряслось, то админ может скачать нужный бэкап без лишних телодвижений на нужную дату.
Хотя, обычно, хватает последнего актуального.
В некотором роде, получилось изобретение велосипеда. Но оно работает на D-link DFL уже почти год, именно так, как мне надо, и иногда очень выручает.
Надеюсь, кому-то пригодится.
Ссылки:
Про rancid
WatchGuard Firebox CLI manual
Про oxidized