В данной заметке рассказывается о том, как настроить автоматическое сохранение конфигурации сетевого оборудования, работающего под управлением Cisco IOS и отслеживание изменений с помощью RCS.
Пару слов, зачем это нужно. Конфигурация маршрутизатора относится к числу критически важных данных, поэтому обязательно должно осуществятся её регулярное резервное копирование. Тогда при выходе из строя марщрутизатора можно будет быстро восстановить работу, заменив его и скопировав сохраненный конфиг. Причем сохранять нужно не только последнюю версию, но и несколько предыдущих - если из-за ошибки при настройке возникнут проблемы, это позволит легко вернутся к предыдущей версии. Изменения в конфигурации высылаются администратору по почте. Это особенно удобно, когда одним маршрутизатором управляет несколько человек, поскольку позволяет быть в курсе изменений, сделанных другими.
Для решения этой задачи существует как минимум три программы (помимо скриптов, написанных мной) - ciscoconf
(порт FreeBSD
/usr/ports/net-mgmt/ciscoconf
) и
rancid.
Первая (ciscoconf) копирует конфигурации конфигурацию по RSH и сохраняет в RCS.
Её преимущество - она это может делать сразу после завершения конфигурации отслеживая появление
в логе строчки содержащей %SYS-5-CONFIG_I. Вторая (rancid) более универсальная и позволяет работать не только с
оборудованием Cisco. Для своей работы она требует сохранения в конфиге пароля на доступ по telnet и пароль enable. Я
считаю, что это делать нежелательно из соображений безопасности (но это субъективное мнение, snmp не безопасноее).
Уже после написания этого скрипта я наткнулся еще на один
проект - Pancho. Там так же конфиги копируются
используюя snmp+tftp.
Если вам не хочется читать все, что написано ниже то рекомендую поставить ciscoconf
- её настроить проще,
чем то, что описано далее.
Тем не менее я решил сделать подобную систему самому, поскольку мне не хотелось только ради ciscoconf открывать на маршрутизаторах rsh. Сохранять в открытом виде пароли для доступа к Циске я тем более не стал. Кроме просмотра конфигурации через telnet или по rsh есть еще один способ - дать по snmp команду скопировать конфигурацию на tftp-сервер. Им я и воспользовался. Еще одна причина написания этих скриптов - я думал, что при копировании конфига с помощью snmp+tftp процессор маршрутизатора нагружается меньше, чем при использовании RSH, но проведенные тесты показали, что в обоих случаях нагрузка на процессор примерно одинаковая (загрузка процессора на 3550 при копировании конфига 9,3K 30 раз в минуту в среднем 28%). В двух словах как работает предлагаемся схема: циске по snmp дается команда скопировать конфиг по tftp. Далее этот файл помещается в RCS-архив, а diff высылается администратору. Скрипт написан на perl, с использованием модуля Cisco-CopyConfig и запускается из крона.
Здесь и далее рассматривается настройка на примере FreeBSD. Если у вас еще не настроен tftp-сервер
то сейчас самое время это сделать.
Сначала добавим в систему пользователя netmgr под которым будет работать наша система (запускать под рутом софт, для
работы которого не нужны права рута плохая идея).
Добавьте в /etc/inetd.conf
строчку
tftp dgram udp wait root /usr/libexec/tftpd tftpd -s /var/tftproot -u netmgr -l
(на всякий случай напомню, что после изменения этого файла нужно перезапустить inetd, а если до этого он не был запущен,
то добавить в /etc/rc.conf
строчку inetd_enable="YES"
и запустить его).
Далее нужно обязательно ограничить доступ к tftp-серверу только для адресов используемых вашими маршрутизаторами.
Ни в коем случае нельзя открывать открытым доступ к tftp для всех т. к. если злоумышленник получит ваш конфиг он легко сможет
восстановить все пароли закодированые с помощью service password-encryption (он предназнаен только для того, чтобы скрыть
в конфиге пароли от случайного подглядывания).
Для этого в файле /etc/hosts.allow
прописываем адреса наших марщрутизаторов или подсети в которых они находятся
(если доступ к этим подсетям полностью контролируются).
Например:
tftpd: 192.168.1.64/255.255.255.248 : allow
Не забывайте, что эти строчки должны быть расположены выше строчки
tftpd: 192.168.2.0/255.255.255.240 : allow
tftpd: ALL : deny
ALL : ALL : allow
которая по умолчанию стоит в начале /etc/hosts.allow
.
Далее создаем каталог /var/tftproot и в нем подкаталог /var/tftproot/config для хранения конфигов. Владельцем папки tftproot
делаем netmgr и ставим права 700 чтобы ограничить доступ к конфигам, который в числе прочего содержат пароли.
tftp-сервер дает возможность записывать только в ранее созданный файл, в который имеет доступ на запись пользователь, под которым
запускается tftpd:
touch /var/tftproot/config/router1
touch /var/tftproot/config/router2
chown netmgr /var/tftproot/config/*
Теперь заходим на циску и пробуем скопировать конфиг вручную (192.168.1.1 это адрес нашего сервера, на котором поднят tftp):
router1#
router1#copy running-config tftp://192.168.1.1/config/router1
Address or name of remote host [192.168.1.1]?
Destination filename [config/router1]?
!!!
10230 bytes copied in 0.676 secs (15133 bytes/sec)
router1#
Если копирование прошло успешно, то можно переходить к следующему шагу. Если копирование не удалось то можно проверить:
# sockstat -4l | grep :69
root inetd 3618 4 udp4 *:69 *:*
tail /var/log/xferlog
Настроим доступ на маршрутизатор с сервера по snmp. Создаем ACL которыми будет защищен доступ к snmp на запись и ACL для ограничения серверов, на которые можно копировать конфиг по tftp. В данном случае можно вместо двух сделать один, но в общем случае они могут и различаться:
access-list 10 remark -- hosts permitted to write snmp MIBs on the router
access-list 10 permit 192.168.1.1
access-list 10 deny any log
access-list 11 remark -- tftp servers to/from which config download/upload is permitted
access-list 11 permit 192.168.1.1
access-list 11 deny any log
Указываем snmp-community (которое играет роль пароля) и ACL для доступа на запись:
snmp-server community E9bJFckD RW 10
Указываем куда можно копировать конфиг по tftp:
snmp-server tftp-server-list 11
Для работы этого модуля необходим модуль Net::SNMP который можно установить из портов. Самого CopyConfig в портах нету, поэтому его нужно будет скачать с CPAN и установить вручную.
Для тестирования работы модуля и ранее сделанных настроек напишем простейший скрипт:
#!/usr/bin/perl -w use strict; use Cisco::CopyConfig (); my $tftp_ip = '192.168.1.1'; my $tftp_file = 'config/router1'; my $cisco_ip = '192.168.2.1'; my $comm_s = 'E9bJFckD'; my $config = Cisco::CopyConfig->new( Host => $cisco_ip, Comm => $comm_s ); print "$config->{err}\n" unless $config->copy($tftp_ip, $tftp_file);Конфиг должен скопироваться в
/var/tftproot/config/router1
.
#!/usr/bin/perl use strict; use warnings; use Cisco::CopyConfig (); ##################################################### # ip адрес tftp-сервера на который заливаются конфиги # на этой же машине и должен запускаться скрипт my $tftp_host = '192.168.1.1'; # директория на tftp-сервере куда кладутся конфиги my $dir = 'config'; # директория где лежат RCS-файлы my $home = '/home/netmgr/ciscocong'; # snmp RW community для кошек my %community = ( '192.168.2.1' => 'E9bJFckD', '192.168.2.2' => 'J0uSsO6Yt' ); # имена хостов для кошек, на основе этого именуются файлы my %hosts = ( '192.168.2.1' => 'router1', '192.168.2.2' => 'router2' ); # e-mail на который будут высылаться изменения my $to = 'noc@localhost'; my $path = '/usr/bin'; ##################################################### my $message = ""; foreach my $ip (keys %community ){ my $config = Cisco::CopyConfig->new ( Host => $ip, Comm => $community{$ip} ); my $name = $hosts{$ip}; # если конфигурационного файла в tftproot еще нет, то создаем его if ( ! -r "/var/tftproot/$dir/$name" ) { system "$path/touch /var/tftproot/$dir/$name"; } # даем команду скопировать конфиг с циски по tftp warn "Error while copy conf from $ip to tftp://$tftp_host/$dir/$name: $config->{err}\n" unless $config->copy($tftp_host, "$dir/$name"); # Создаем и инициализируем RCS файл, если его еще нет if ( ! -r "$home/$name,v" ) { system "$path/rcs -q -t-$name -i $home/$name,v /var/tftproot/$dir/$name"; } # удаляем из кофига ntp clock-period, потому что это значение часто меняется system "$path/fgrep -v 'ntp clock-period' /var/tftproot/$dir/$name > $home/$name"; # RCS diff my $msg = `$path/rcsdiff -qu $home/$name`; if ($msg ne '') { $message .= "=== $name =============================================================\n"; $message .= "$msg\n\n"; } # store config in RCS system "$path/ci -q -m'-' -l $home/$name"; } # Отправляем изменения по почте my $now = localtime; open (MAIL, "| $path/mail -E -s \"cisco config diff ($now)\" $to") || die "$!\n"; print MAIL $message; close MAIL;Т. к. скрипт содержит RW snmp-community, назначаем ему права 700, чтоб другие пользователи не могли его прочитать. Все настройки прописываются в начале скрипта. При добавлении новой циски достаточно прописать её в хэшах %community и %hosts. Для проверки работы запускаем скрипт, что ни будь меняем на циске и запускаем снова. Должно прийти письмо. Скрипт нужно прописать в cron пользователя
netmgr
. Для небольшой сети, с редкими изменениями достаточно запускать раз в несколько часов:
# fetch config from cisco, store in RCS and mail diff
3 */3 * * * /home/netmgr/fetchconf.pl
Пример письма, высылаемого скриптом:
=== sr1 ============================================================= --- /home/netmgr/ciscocong/sr1 2004/09/02 11:03:03 1.33 +++ /home/netmgr/ciscocong/sr1 2004/09/10 14:03:03 @@ -1,7 +1,7 @@ ! -! Last configuration change at 14:48:07 MSD Thu Sep 2 2004 by ivanov -! NVRAM config last updated at 10:57:31 MSD Wed Sep 1 2004 by ivanov +! Last configuration change at 16:13:56 MSD Fri Sep 10 2004 by petrov +! NVRAM config last updated at 16:18:32 MSD Fri Sep 10 2004 by petrov ! version 12.1 service nagle @@ -98,9 +98,15 @@ spanning-tree portfast ! interface FastEthernet0/6 - switchport access vlan 1001 + description -- server 75.02 + switchport access vlan 1000 switchport mode access + switchport nonegotiate + switchport port-security + switchport port-security violation restrict no cdp enable + spanning-tree portfast + spanning-tree bpdufilter enable ! interface FastEthernet0/7 switchport access vlan 1001
Небольшое замечание по безопасности - защите сервера на котором работает этот скрипт нужно уделить повышенное внимание, поскольку если злоумышленник получит полный доступ к этому хосту, то он сможет по tftp скопировать на маршрутизаторы измененный конфиг и получит таким образом полный конторль над всеми маршрутизаторами. Желательно размещать подобную систему на сервере, который не имеет открытых во внешний мир сервисов (web, mail, ftp и т. д.)