Backup файлов конфигураций оборудования Cisco по расписанию
Так как Cisco очень интересные девайсы и используются во многих серьезных организациях для построения сетей, сетевым администраторам следует предусмотреть способы быстрого восстановления после выхода из строя сети. В случае выхода из строя маршрутизатора или коммутатора, им требуется найти быструю замену для устройств, в случае если проблем с финансированием нет, то скорее всего более менее адекватная дублирующая железка найдеться. Следовательно остается задача организация резервного копирования файлов конфигурации и желательно независимо от желания самого администратора, то есть по расписанию, но есть одна проблема, не на всех версиях ios есть фунции kron.
Проблему решает следующий скрип:
#!/usr/bin/perl
use Net::Telnet ();
use Net::Telnet::Cisco;
use Mail::Sendmail;
my @arrCiscoAddress = ('xxx.yyy.zzz.www',
'xxx.yyy.zzz.www',
'xxx.yyy.zzz.www');
$size = @arrCiscoAddress;
print "Devices Ciscos: ".$size."\n";
my $ip="";
my $usernameCisco="login";
my $passwordCisco="pass";
my $usernameDlink="";
my $passwordDlink="";
my $passwordDlink2108="";
my $devType=0; # 0 - нет; 1 - Cisco; 2 - Dlink3026; 3 - 2108
my $Cisco=0;
my $Dlink3026=0;
my $Dlink2108=0;
my $Unknown=0;
my $is_login=0;
my $is_cmd=0;
my $res="";
my $log_fail="";
my $dead="";
my $alive="";
my $log="";
my $log_t="";
my $t;
my $tmp;
my $mu;
# ----------------------------------------------------------------
$txt = "--- Config download script by dfox ---\n";
print $txt; $log=$log.$txt;
$txt = "Initialization...";
print $txt; $log=$log.$txt;
$txt = "\t\tOK!\n----------------------------\n";
print $txt; $log=$log.$txt;
# ----------------------------------------------------------------
# Пробегаем по списку адресов
# ----------------------------------------------------------------
$b3 = "225";
for($k=0; $k<=$size-1;$k++)
{
$ip=$arrCiscoAddress[$k];
$txt = "trying $ip...";
print $txt; $log=$log.$txt;
$sessionnoc = new Net::Telnet(Timeout => 5, Errmode=>"return");
$sessionnoc->open(Host=>"server.ru", Port => 23);
$session = new Net::Telnet(Timeout => 5, Errmode=>"return");
$session->open(Host=>$ip, Port => 23);
$msg=$session->errmsg;
if(!$msg)
{
$txt = "\t\tOK!\n";
print $txt; $log=$log.$txt;
$alive=$alive.$ip."\n";
#------------------------------------------------------
# проверяем что за девайс
#------------------------------------------------------
$tmp="";
$tmp=$session->get;
$devType=0;
# Cisco
if (index($tmp,"")>=0)
{
$devType=1;
$txt="Device type - Cisco\n";
};
# Dlink3026
if (index($tmp,"DES-3026")>=0)
{
$devType=2;
$txt="Device type - Dlink-3026\n";
};
# Unknown
#if ($devType==0)
#{
# ++$Unknown;
# $txt="Device type - Unknown\n";
#};
#print $devType;
#print $txt; $log=$log.$txt;
#if($devType==0){next;};
#------------------------------------------------------
# логинимся исходя из типа девайса
#------------------------------------------------------
$txt="Logging on... ";
print $txt; $log=$log.$txt;
# Cisco
if ($devType==1)
{
$t=Net::Telnet::Cisco->new(Errmode=>"return",Timeout=>20,Host=>$ip,Input_log=>'tmp_cisco_in.txt',Output_log=>'tmp_cisco_out.txt');
if ($t->login($usernameCisco,$passwordCisco)){$is_login=1;} else{$is_login=0;};
};
# Dlink3026
if ($devType==2)
{
$t=Net::Telnet->new(Timeout => 20, Prompt => '/#/', Host=>$ip, Errmode => "return",Input_log=>'tmp_dlink.txt',Output_log=>'tmp_dlink1.txt');
if ($t->login($usernameDlink,$passwordDlink)) { $is_login=1; } else {$is_login=0;};
};
if($is_login>0){$txt="\t\tOK!\n";} else{$log_fail=$log_fail."$ip\n",$txt="\t\tfailed!\n";$log_t=$log_t."$ip\tlogin_failed!!\n";};
print $txt; $log=$log.$txt;
if($is_login==0){next;};
#------------------------------------------------------
# делаем дело исходя из типа девайса
#------------------------------------------------------
$txt="Uploading cmd...";
print $txt; $log=$log.$txt;
$is_cmd=0;
# Cisco
if ($devType==1 && $is_login>0)
{
if(!($t->is_enabled)) {$t->enable($passwordCisco);};
$t->cmd('terminal length 0');
$mu = $k+1;
if (@lin=$t->cmd("copy running tftp://ftp.ftp.ftp.ftp/cisco_conf/$mu-".$ip."-conf.txt \n\n\n"))
{
$t->cmd("copy vlan.dat tftp://ftp.ftp.ftp.ftp/cisco_conf/$mu-".$ip."-vlan.dat\n\n\n");
$is_cmd=1;
#$res=@lin;
++$Cisco;
$t->cmd("logout");
$t->close;
}
else {$is_cmd=0;};
};
# Dlink3026
if ($devType==2 && $is_login>0)
{
$t->cmd('dis cli');
@lin=$t->cmd("upload config ftp.ftp.ftp.ftp config.dlink.txt");
if (@lin)
{
$is_cmd=1;
#$res=@lin;
++$Dlink3026;
$t->cmd("logout");
$t->close;
}
else {$is_cmd=0;};
};
if($is_cmd)
{
$txt="\t\tOK!\n$res\n";
$log_t=$log_t."$ip\tOK!\n";
}
else
{
$txt="\t\tfailed!\n";
$log_t=$log_t."$ip\tfailed!\n";
}
print $txt; $log=$log.$txt;
$t->close;
}
else
{
$txt = "\t\tfailed!\n";
print $txt; $log=$log.$txt;
$dead=$dead.$ip."\n";
$log_t=$log_t."$ip\ttelnet_failed!!\n";
}
# закрываем сессию
$session->close;
}
# ----------------------------------------------------------------
# Архивируем и удаляем конфиги.
# ----------------------------------------------------------------
#system ("/usr/home/scr/scripts/arch_conf");
# ----------------------------------------------------------------
# шлем почту о резалтах
# ----------------------------------------------------------------
%mail =
(
To => 'admins@domain',
From => 'backups@domain',
Subject => 'Service report about BACKUP',
Message => "Backup devices:\nCisco = $Cisco\n*************\n$log_t\n$log\n",
SMTP => '**********'
);
sendmail(%mail) or die $Mail::Sendmail::error;
print "OK. Log says:\n", $Mail::Sendmail::log;
# ----------------------------------------------------------------
В этом скрипте можно указать список ip адресов сетевых устройств конфиги с которых надо сливать по расписанию. Есть минус в том что логин пароль хранятся в нем в не зашифрованном виде, но это можно доработать. Бекапятся как cisco так и dlink, к которым есть доступ по телнет, ну и в конце отправляется отчет по email. Также на сервере где будет прописываться скрипт(используется у меня на Debian 6) нужно подключить использование следующего пакета Net::Telnet. Так как писалось давно уже и не помню как ставить, ну думаю разберетесь. Сами скрипты заливаются на tftp сервер.
Проблему решает следующий скрип:
#!/usr/bin/perl
use Net::Telnet ();
use Net::Telnet::Cisco;
use Mail::Sendmail;
my @arrCiscoAddress = ('xxx.yyy.zzz.www',
'xxx.yyy.zzz.www',
'xxx.yyy.zzz.www');
$size = @arrCiscoAddress;
print "Devices Ciscos: ".$size."\n";
my $ip="";
my $usernameCisco="login";
my $passwordCisco="pass";
my $usernameDlink="";
my $passwordDlink="";
my $passwordDlink2108="";
my $devType=0; # 0 - нет; 1 - Cisco; 2 - Dlink3026; 3 - 2108
my $Cisco=0;
my $Dlink3026=0;
my $Dlink2108=0;
my $Unknown=0;
my $is_login=0;
my $is_cmd=0;
my $res="";
my $log_fail="";
my $dead="";
my $alive="";
my $log="";
my $log_t="";
my $t;
my $tmp;
my $mu;
# ----------------------------------------------------------------
$txt = "--- Config download script by dfox ---\n";
print $txt; $log=$log.$txt;
$txt = "Initialization...";
print $txt; $log=$log.$txt;
$txt = "\t\tOK!\n----------------------------\n";
print $txt; $log=$log.$txt;
# ----------------------------------------------------------------
# Пробегаем по списку адресов
# ----------------------------------------------------------------
$b3 = "225";
for($k=0; $k<=$size-1;$k++)
{
$ip=$arrCiscoAddress[$k];
$txt = "trying $ip...";
print $txt; $log=$log.$txt;
$sessionnoc = new Net::Telnet(Timeout => 5, Errmode=>"return");
$sessionnoc->open(Host=>"server.ru", Port => 23);
$session = new Net::Telnet(Timeout => 5, Errmode=>"return");
$session->open(Host=>$ip, Port => 23);
$msg=$session->errmsg;
if(!$msg)
{
$txt = "\t\tOK!\n";
print $txt; $log=$log.$txt;
$alive=$alive.$ip."\n";
#------------------------------------------------------
# проверяем что за девайс
#------------------------------------------------------
$tmp="";
$tmp=$session->get;
$devType=0;
# Cisco
if (index($tmp,"")>=0)
{
$devType=1;
$txt="Device type - Cisco\n";
};
# Dlink3026
if (index($tmp,"DES-3026")>=0)
{
$devType=2;
$txt="Device type - Dlink-3026\n";
};
# Unknown
#if ($devType==0)
#{
# ++$Unknown;
# $txt="Device type - Unknown\n";
#};
#print $devType;
#print $txt; $log=$log.$txt;
#if($devType==0){next;};
#------------------------------------------------------
# логинимся исходя из типа девайса
#------------------------------------------------------
$txt="Logging on... ";
print $txt; $log=$log.$txt;
# Cisco
if ($devType==1)
{
$t=Net::Telnet::Cisco->new(Errmode=>"return",Timeout=>20,Host=>$ip,Input_log=>'tmp_cisco_in.txt',Output_log=>'tmp_cisco_out.txt');
if ($t->login($usernameCisco,$passwordCisco)){$is_login=1;} else{$is_login=0;};
};
# Dlink3026
if ($devType==2)
{
$t=Net::Telnet->new(Timeout => 20, Prompt => '/#/', Host=>$ip, Errmode => "return",Input_log=>'tmp_dlink.txt',Output_log=>'tmp_dlink1.txt');
if ($t->login($usernameDlink,$passwordDlink)) { $is_login=1; } else {$is_login=0;};
};
if($is_login>0){$txt="\t\tOK!\n";} else{$log_fail=$log_fail."$ip\n",$txt="\t\tfailed!\n";$log_t=$log_t."$ip\tlogin_failed!!\n";};
print $txt; $log=$log.$txt;
if($is_login==0){next;};
#------------------------------------------------------
# делаем дело исходя из типа девайса
#------------------------------------------------------
$txt="Uploading cmd...";
print $txt; $log=$log.$txt;
$is_cmd=0;
# Cisco
if ($devType==1 && $is_login>0)
{
if(!($t->is_enabled)) {$t->enable($passwordCisco);};
$t->cmd('terminal length 0');
$mu = $k+1;
if (@lin=$t->cmd("copy running tftp://ftp.ftp.ftp.ftp/cisco_conf/$mu-".$ip."-conf.txt \n\n\n"))
{
$t->cmd("copy vlan.dat tftp://ftp.ftp.ftp.ftp/cisco_conf/$mu-".$ip."-vlan.dat\n\n\n");
$is_cmd=1;
#$res=@lin;
++$Cisco;
$t->cmd("logout");
$t->close;
}
else {$is_cmd=0;};
};
# Dlink3026
if ($devType==2 && $is_login>0)
{
$t->cmd('dis cli');
@lin=$t->cmd("upload config ftp.ftp.ftp.ftp config.dlink.txt");
if (@lin)
{
$is_cmd=1;
#$res=@lin;
++$Dlink3026;
$t->cmd("logout");
$t->close;
}
else {$is_cmd=0;};
};
if($is_cmd)
{
$txt="\t\tOK!\n$res\n";
$log_t=$log_t."$ip\tOK!\n";
}
else
{
$txt="\t\tfailed!\n";
$log_t=$log_t."$ip\tfailed!\n";
}
print $txt; $log=$log.$txt;
$t->close;
}
else
{
$txt = "\t\tfailed!\n";
print $txt; $log=$log.$txt;
$dead=$dead.$ip."\n";
$log_t=$log_t."$ip\ttelnet_failed!!\n";
}
# закрываем сессию
$session->close;
}
# ----------------------------------------------------------------
# Архивируем и удаляем конфиги.
# ----------------------------------------------------------------
#system ("/usr/home/scr/scripts/arch_conf");
# ----------------------------------------------------------------
# шлем почту о резалтах
# ----------------------------------------------------------------
%mail =
(
To => 'admins@domain',
From => 'backups@domain',
Subject => 'Service report about BACKUP',
Message => "Backup devices:\nCisco = $Cisco\n*************\n$log_t\n$log\n",
SMTP => '**********'
);
sendmail(%mail) or die $Mail::Sendmail::error;
print "OK. Log says:\n", $Mail::Sendmail::log;
# ----------------------------------------------------------------
В этом скрипте можно указать список ip адресов сетевых устройств конфиги с которых надо сливать по расписанию. Есть минус в том что логин пароль хранятся в нем в не зашифрованном виде, но это можно доработать. Бекапятся как cisco так и dlink, к которым есть доступ по телнет, ну и в конце отправляется отчет по email. Также на сервере где будет прописываться скрипт(используется у меня на Debian 6) нужно подключить использование следующего пакета Net::Telnet. Так как писалось давно уже и не помню как ставить, ну думаю разберетесь. Сами скрипты заливаются на tftp сервер.
Комментарии
Отправить комментарий